Working Map with overlaping spider and leaflet
This commit is contained in:
parent
f55b01b02c
commit
6cd2a87655
15 changed files with 359 additions and 44 deletions
|
|
@ -66,3 +66,9 @@ MAIL_CONTACT_REMARK="equipe.web@ldc.fr"
|
|||
MAIL_CONTACT_SPONSORING="equipe.web@ldc.fr"
|
||||
MAIL_CONTACT_SERVICE="equipe.web@ldc.fr"
|
||||
MAIL_CONTACT_OTHER="equipe.web@ldc.fr"
|
||||
|
||||
# GOOGLE
|
||||
# - RECAPTCHA
|
||||
GOOGLE_RECAPTCHA_PUBLIC=
|
||||
GOOGLE_RECAPTCHA_PRIVATE=
|
||||
GOOGLE_RECAPTCHA_VERSION=
|
||||
|
|
|
|||
|
|
@ -71,25 +71,37 @@ class StaticPageController extends Controller
|
|||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::unveil)->first();
|
||||
$sectionModels = Section::query()->where('page_id', $staticPageModel->id)->get();
|
||||
$historicalMilestoneModels = HistoricalMilestone::query()->orderBy('year', 'ASC')->get();
|
||||
$siteModel = Site::query()->first();
|
||||
$keySection = $sectionModels->where('section', PageSectionEnum::unveil_pole)->first();
|
||||
$missionsSection = $sectionModels->where('section', PageSectionEnum::unveil_missions)->first();
|
||||
$localSection = $sectionModels->where('section', PageSectionEnum::unveil_local)->first();
|
||||
$siteSection = $sectionModels->where('section', PageSectionEnum::unveil_sites)->first();
|
||||
$historySection = $sectionModels->where('section', PageSectionEnum::unveil_history)->first();
|
||||
$commitmentSection = $sectionModels->where('section', PageSectionEnum::unveil_commitments)->first();
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Site> */
|
||||
$siteModelList = Site::query()->orderBy('order')->get();
|
||||
$keySection = $sectionModels->where('section', PageSectionEnum::unveil_pole)->first();
|
||||
$missionsSection = $sectionModels->where('section', PageSectionEnum::unveil_missions)->first();
|
||||
$localSection = $sectionModels->where('section', PageSectionEnum::unveil_local)->first();
|
||||
$siteSection = $sectionModels->where('section', PageSectionEnum::unveil_sites)->first();
|
||||
$historySection = $sectionModels->where('section', PageSectionEnum::unveil_history)->first();
|
||||
$commitmentSection = $sectionModels->where('section', PageSectionEnum::unveil_commitments)->first();
|
||||
|
||||
// * Calcul Viewbox leaflet map.
|
||||
$viewBox = (object)[
|
||||
// @phpstan-ignore-next-line
|
||||
'lat' => \round($siteModelList->sum(fn (Site $siteModel) =>
|
||||
$siteModel->latitude) / $siteModelList->count(), 6),
|
||||
// @phpstan-ignore-next-line
|
||||
'lng' => \round($siteModelList->sum(fn (Site $siteModel) =>
|
||||
$siteModel->longitude) / $siteModelList->count(), 6)
|
||||
];
|
||||
|
||||
return view('fo.pages.unveil', compact(
|
||||
'viewBox',
|
||||
'staticPageModel',
|
||||
'sectionModels',
|
||||
'historicalMilestoneModels',
|
||||
'siteModel',
|
||||
'siteModelList',
|
||||
'keySection',
|
||||
'missionsSection',
|
||||
'localSection',
|
||||
'siteSection',
|
||||
'historySection',
|
||||
'commitmentSection',
|
||||
'commitmentSection'
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -269,4 +281,4 @@ class StaticPageController extends Controller
|
|||
'nextSiteModel' => $nextSiteModel
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -59,6 +59,8 @@ class SecureHeaders
|
|||
'https://yl.s-web.fr'
|
||||
]) . ';',
|
||||
"img-src 'self' data: blob: " . implode(' ', [
|
||||
// * Leaftlet With OpenStreetmaps
|
||||
'https://tile.openstreetmap.org',
|
||||
// * VITE DEV
|
||||
config('app.debug') ? "https://{$host}:4443" : '',
|
||||
]) . ';',
|
||||
|
|
@ -66,7 +68,6 @@ class SecureHeaders
|
|||
"frame-src 'self' " . implode(' ', [
|
||||
'https://www.google.com/recaptcha/',
|
||||
'https://recaptcha.google.com/recaptcha/',
|
||||
'https://www.google.com/maps/',
|
||||
'https://www.youtube.com',
|
||||
]) . ';',
|
||||
"font-src 'self' data: " . \implode(' ', [
|
||||
|
|
|
|||
0
artisan
Executable file → Normal file
0
artisan
Executable file → Normal file
67
package-lock.json
generated
67
package-lock.json
generated
|
|
@ -13,11 +13,10 @@
|
|||
"@fortawesome/free-regular-svg-icons": "^6.5.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
||||
"@fortawesome/vue-fontawesome": "^3.0.5",
|
||||
"@googlemaps/js-api-loader": "^1.16.6",
|
||||
"@ldc-web/cookie-notice": "^4.0.1",
|
||||
"@sipec/vue3-tags-input": "^3.0.4",
|
||||
"@types/bootstrap": "^5.2.7",
|
||||
"@types/google.maps": "^3.55.4",
|
||||
"@types/leaflet": "^1.9.8",
|
||||
"@types/node": "^20.8.2",
|
||||
"@types/toastify-js": "^1.12.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
|
|
@ -37,6 +36,9 @@
|
|||
"eslint-plugin-vue": "latest",
|
||||
"fslightbox": "^3.4.1",
|
||||
"laravel-vite-plugin": "^0.8.1",
|
||||
"leaflet": "^1.9.4",
|
||||
"leaflet.fullscreen": "^3.0.1",
|
||||
"overlapping-marker-spiderfier-leaflet": "^0.2.7",
|
||||
"postcss-discard-comments": "^6.0.0",
|
||||
"prettier": "latest",
|
||||
"print-js": "^1.6.0",
|
||||
|
|
@ -54,6 +56,7 @@
|
|||
"terser": "latest",
|
||||
"toastify-js": "^1.12.0",
|
||||
"ts-loader": "^9.3.1",
|
||||
"ts-overlapping-marker-spiderfier": "^1.0.3",
|
||||
"typescript": ">=3.3.1 <5.2.0",
|
||||
"typescript-eslint": "latest",
|
||||
"vite": "^4.5.1",
|
||||
|
|
@ -968,15 +971,6 @@
|
|||
"vue": ">= 3.0.0 < 4"
|
||||
}
|
||||
},
|
||||
"node_modules/@googlemaps/js-api-loader": {
|
||||
"version": "1.16.6",
|
||||
"resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.6.tgz",
|
||||
"integrity": "sha512-V8p5W9DbPQx74jWUmyYJOerhiB4C+MHekaO0ZRmc6lrOYrvY7+syLhzOWpp55kqSPeNb+qbC2h8i69aLIX6krQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
|
||||
|
|
@ -1195,6 +1189,12 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/geojson": {
|
||||
"version": "7946.0.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz",
|
||||
"integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/glob": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
|
||||
|
|
@ -1205,10 +1205,11 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/google.maps": {
|
||||
"version": "3.55.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.55.4.tgz",
|
||||
"integrity": "sha512-Ip3IfRs3RZjeC88V8FGnWQTQXeS5gkJedPSosN6DMi9Xs8buGTpsPq6UhREoZsGH+62VoQ6jiRBUR8R77If69w==",
|
||||
"node_modules/@types/googlemaps": {
|
||||
"version": "3.43.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/googlemaps/-/googlemaps-3.43.3.tgz",
|
||||
"integrity": "sha512-ZWNoz/O8MPEpiajvj7QiqCY8tTLFNqNZ/a+s+zTV58wFVNAvvqV4bdGfnsjTb5Cs4V6wEsLrX8XRhmnyYJ2Tdg==",
|
||||
"deprecated": "Types for the Google Maps browser API have moved to @types/google.maps. Note: these types are not for the googlemaps npm package, which is a Node API.",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
|
|
@ -1224,6 +1225,15 @@
|
|||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/leaflet": {
|
||||
"version": "1.9.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.8.tgz",
|
||||
"integrity": "sha512-EXdsL4EhoUtGm2GC2ZYtXn+Fzc6pluVgagvo2VC1RHWToLGlTRwVYoDpqS/7QXa01rmDyBjJk3Catpf60VMkwg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/geojson": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/minimatch": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
|
||||
|
|
@ -4984,6 +4994,18 @@
|
|||
"vite": "^3.0.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/leaflet": {
|
||||
"version": "1.9.4",
|
||||
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
|
||||
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/leaflet.fullscreen": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/leaflet.fullscreen/-/leaflet.fullscreen-3.0.1.tgz",
|
||||
"integrity": "sha512-Lsg49e4AYSjHOhmy+VOm4+O6Urim2UvthydKJI3KzfwC3InYkfvJtv1mWuOb9K7qG4H2MtEut09Dz6noQyJARQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/levn": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
|
||||
|
|
@ -5506,6 +5528,12 @@
|
|||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/overlapping-marker-spiderfier-leaflet": {
|
||||
"version": "0.2.7",
|
||||
"resolved": "https://registry.npmjs.org/overlapping-marker-spiderfier-leaflet/-/overlapping-marker-spiderfier-leaflet-0.2.7.tgz",
|
||||
"integrity": "sha512-U2biV2Ge0SU+4IEmq4BZOglvzA8Aj8G7/hp5v6lBnF9Kd3/Xf6ZEPsJyPOExtLvMxOqlrlTAfl55s6JJDND7Ew==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/p-limit": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
|
||||
|
|
@ -7524,6 +7552,15 @@
|
|||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ts-overlapping-marker-spiderfier": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/ts-overlapping-marker-spiderfier/-/ts-overlapping-marker-spiderfier-1.0.3.tgz",
|
||||
"integrity": "sha512-WqA+tpJHZHpGS8fL1C/cOPue72doG2yfNoxK7cUuLwH108hoQkjd6R52c3hYiFdVc1UvGuA/wXzAJYXPi+L9YQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/googlemaps": "^3.30.7"
|
||||
}
|
||||
},
|
||||
"node_modules/tsconfig-paths": {
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
|
||||
|
|
|
|||
|
|
@ -21,11 +21,10 @@
|
|||
"@fortawesome/free-regular-svg-icons": "^6.5.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
||||
"@fortawesome/vue-fontawesome": "^3.0.5",
|
||||
"@googlemaps/js-api-loader": "^1.16.6",
|
||||
"@ldc-web/cookie-notice": "^4.0.1",
|
||||
"@sipec/vue3-tags-input": "^3.0.4",
|
||||
"@types/bootstrap": "^5.2.7",
|
||||
"@types/google.maps": "^3.55.4",
|
||||
"@types/leaflet": "^1.9.8",
|
||||
"@types/node": "^20.8.2",
|
||||
"@types/toastify-js": "^1.12.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
|
|
@ -45,6 +44,9 @@
|
|||
"eslint-plugin-vue": "latest",
|
||||
"fslightbox": "^3.4.1",
|
||||
"laravel-vite-plugin": "^0.8.1",
|
||||
"leaflet": "^1.9.4",
|
||||
"leaflet.fullscreen": "^3.0.1",
|
||||
"overlapping-marker-spiderfier-leaflet": "^0.2.7",
|
||||
"postcss-discard-comments": "^6.0.0",
|
||||
"prettier": "latest",
|
||||
"print-js": "^1.6.0",
|
||||
|
|
@ -62,6 +64,7 @@
|
|||
"terser": "latest",
|
||||
"toastify-js": "^1.12.0",
|
||||
"ts-loader": "^9.3.1",
|
||||
"ts-overlapping-marker-spiderfier": "^1.0.3",
|
||||
"typescript": ">=3.3.1 <5.2.0",
|
||||
"typescript-eslint": "latest",
|
||||
"vite": "^4.5.1",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ return [
|
|||
'section' => 'section',
|
||||
'news' => 'actualité',
|
||||
'site' => 'site',
|
||||
'logo' => 'logo',
|
||||
'logo' => 'logo de marques',
|
||||
'historicalMilestone' => 'jalon historique|jalons historiques',
|
||||
'slide' => 'slide',
|
||||
'job_video' => 'vidéo métier|vidéos métiers',
|
||||
|
|
|
|||
|
|
@ -224,6 +224,8 @@ return [
|
|||
],
|
||||
'youtube_id' => ':attribute doit être un ID de vidéo Youtube valide',
|
||||
'vimeo_id' => ':attribute doit être un ID de vidéo Vimeo valide',
|
||||
'latitude' => 'Latitude entre -90 et 90 - ex : 48.858502757201',
|
||||
'longitude' => 'Longitude entre -180 et 180 - ex : 2.2944636160339',
|
||||
'custom' => [
|
||||
'of_the' => [
|
||||
'male' => 'du ',
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ body {
|
|||
|
||||
> header {
|
||||
position: fixed;
|
||||
z-index: 50;
|
||||
z-index: 10001;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
@import "./vendor/bootstrap";
|
||||
@import "./vendor/swiper";
|
||||
@import "./vendor/cookie-notice";
|
||||
@import "leaflet";
|
||||
|
||||
// * BASE
|
||||
@import "./base/bootstrap-overload";
|
||||
|
|
|
|||
233
resources/ts/fo/components/LeafletMapVueComponent.vue
Normal file
233
resources/ts/fo/components/LeafletMapVueComponent.vue
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
<template>
|
||||
<div
|
||||
ref="maps"
|
||||
:class="wrapperClasses.concat(' leafleat-wrapper-class')"
|
||||
>
|
||||
<div
|
||||
ref="marker"
|
||||
class="d-none marker-pin text-bg-white px-3 py-1 d-flex justify-content-center align-items-center f-barlow rounded-pill border border-1 border-primary"
|
||||
>
|
||||
<img
|
||||
class="marker-logo mx-1"
|
||||
src=""
|
||||
alt=""
|
||||
>
|
||||
<span>
|
||||
<span class="mx-1 marker-title text-primary fw-bold text-uppercase text-break" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
ref="marker-pannel"
|
||||
class="d-none"
|
||||
>
|
||||
<span class="h4 marker-title" />
|
||||
<div class="marker-desc" />
|
||||
<span class="marker-people">
|
||||
<FontAwesomeIcon icon="fa-solid fa-users" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
import { DivIcon, Icon, Map, Marker, TileLayer, type LatLngExpression, type LatLngTuple } from "leaflet";
|
||||
// @ts-ignore
|
||||
import "overlapping-marker-spiderfier-leaflet";
|
||||
import type { OverlappingMarkerSpiderfier } from "ts-overlapping-marker-spiderfier";
|
||||
// @ts-ignore
|
||||
import "leaflet.fullscreen";
|
||||
import { defineComponent } from "vue";
|
||||
import trans from "../../modules/trans";
|
||||
|
||||
type Site = {
|
||||
name: string;
|
||||
/** WYSIWYG text */
|
||||
description: string;
|
||||
employees: number;
|
||||
coords: {
|
||||
lat: number,
|
||||
lng: number,
|
||||
},
|
||||
logo: {
|
||||
src: string,
|
||||
alt: string;
|
||||
title: string;
|
||||
},
|
||||
divIcon: DivIcon
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
name: "LeafletMapVueComponent",
|
||||
mixins: [trans],
|
||||
components: {FontAwesomeIcon},
|
||||
data(): {
|
||||
wrapperClasses: string[];
|
||||
map: Map;
|
||||
oms: OverlappingMarkerSpiderfier;
|
||||
initialPosition: LatLngExpression;
|
||||
initialZoom: number;
|
||||
siteList: Array<Site>;
|
||||
markerTextLength: number;
|
||||
} {
|
||||
return {
|
||||
wrapperClasses:[],
|
||||
map: {} as Map,
|
||||
oms: {} as OverlappingMarkerSpiderfier,
|
||||
initialPosition: [0, 0],
|
||||
initialZoom: 3,
|
||||
siteList: [],
|
||||
markerTextLength: 20
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
mounted() {
|
||||
const json = String(this.$attrs.json ?? "{}"),
|
||||
data = JSON.parse(json);
|
||||
this.wrapperClasses = data.wrapperClasses ?? [];
|
||||
this.initialPosition = [Number.parseFloat(data.coordinates.lat), Number.parseFloat(data.coordinates.lng)];
|
||||
|
||||
this.parseSiteModelList(data.siteModelList);
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.displayMap();
|
||||
this.setupMarkers();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
displayMap() {
|
||||
const mapWrapper = this.$refs.maps as HTMLDivElement;
|
||||
this.map = new Map(mapWrapper, {
|
||||
// @ts-ignore
|
||||
fullscreenControl: true,
|
||||
fullscreenControlOptions: {
|
||||
position: "topleft"
|
||||
}
|
||||
});
|
||||
(new TileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||
attribution: "© <a href=\"http://www.openstreetmap.org/copyright\">OpenStreetMap</a>"
|
||||
})).addTo(this.map as Map);
|
||||
// * Auto set viewbox
|
||||
(this.map as Map).fitBounds(this.siteList.map(site => Object.values(site.coords)) as LatLngTuple[]);
|
||||
// * Setup OMS
|
||||
// @ts-ignore
|
||||
this.oms = new OverlappingMarkerSpiderfier(this.map as Map, {
|
||||
// spiderfy markers within this range of the one clicked, in px
|
||||
nearbyDistance: 120,
|
||||
// circleSpiralSwitchover: 250,
|
||||
/**
|
||||
* show spiral instead of circle from this marker count upwards
|
||||
* 0 -> always spiral; Infinity -> always circle
|
||||
*/
|
||||
circleSpiralSwitchover: 12,
|
||||
// related to size of spiral (experiment!)
|
||||
circleFootSeparation: 80,
|
||||
// related to size of spiral (experiment!)
|
||||
circleStartAngle: (Math.PI * 2) / 24,
|
||||
// ditto
|
||||
spiralLengthStart: 130,
|
||||
// ditto
|
||||
spiralLengthFactor: 5,
|
||||
});
|
||||
this.oms.addListener("click", (marker: Marker) => {
|
||||
console.log(marker);
|
||||
});
|
||||
this.oms.addListener("spiderfy", () => {
|
||||
this.map.closePopup();
|
||||
});
|
||||
},
|
||||
parseSiteModelList(siteModelList: LaravelModelList) {
|
||||
siteModelList.forEach((site) => {
|
||||
this.siteList.push({
|
||||
name: String(site.name),
|
||||
description: String(site.description),
|
||||
employees: Number.parseInt(String(site.employees)),
|
||||
coords: {
|
||||
lat: Number.parseFloat(String(site.latitude)),
|
||||
lng: Number.parseFloat(String(site.longitude)),
|
||||
},
|
||||
logo: {
|
||||
src: String(site.logo),
|
||||
alt: String(site.logo_alt),
|
||||
title: String(site.logo_title),
|
||||
},
|
||||
divIcon: new DivIcon({
|
||||
className: "leaf-div-icon",
|
||||
html: this.fetchNewMarkerElement(
|
||||
String(site.name),
|
||||
{
|
||||
src: String(site.logo),
|
||||
alt: String(site.logo_alt),
|
||||
title: String(site.logo_title),
|
||||
}
|
||||
),
|
||||
iconSize: [30, 42],
|
||||
iconAnchor: [15, 42]
|
||||
})
|
||||
});
|
||||
});
|
||||
},
|
||||
fetchNewMarkerElement(
|
||||
title: string,
|
||||
logo: {src: string,alt: string,title: string}
|
||||
): HTMLDivElement {
|
||||
const marker = (this.$refs.marker as HTMLDivElement).cloneNode(true) as HTMLDivElement;
|
||||
const logoEl = marker.querySelector(".marker-logo") as HTMLImageElement|null;
|
||||
marker.querySelector(".marker-title")!.textContent = this.truncateString(title, this.markerTextLength);
|
||||
logoEl!.src = logo.src;
|
||||
logoEl!.alt = logo.alt;
|
||||
logoEl!.title = logo.title;
|
||||
marker.classList.remove("d-none");
|
||||
return marker;
|
||||
},
|
||||
setupMarkers() {
|
||||
this.siteList.forEach((site) => {
|
||||
const marker = new Marker(site.coords, {
|
||||
title: site.name,
|
||||
alt: site.name,
|
||||
icon: site.divIcon as Icon
|
||||
});
|
||||
this.map.addLayer(marker);
|
||||
// @ts-ignore
|
||||
this.oms.addMarker(marker);
|
||||
});
|
||||
},
|
||||
truncateString(str: string, limit: number, end: string = "..") {
|
||||
if (str.length <= limit) {
|
||||
return str;
|
||||
}
|
||||
return str.slice(0, limit) + end;
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@import "../../../../node_modules/leaflet.fullscreen/Control.FullScreen.css";
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
|
||||
@import "bootstrap/scss/functions";
|
||||
@import "bootstrap/scss/variables";
|
||||
@import "bootstrap/scss/variables-dark";
|
||||
@import "bootstrap/scss/maps";
|
||||
@import "bootstrap/scss/mixins";
|
||||
@import "bootstrap/scss/vendor/rfs";
|
||||
.leafleat-wrapper-class {
|
||||
.marker-pin {
|
||||
@include rfs(10rem, min-width);
|
||||
}
|
||||
.marker-logo {
|
||||
object-fit: contain;
|
||||
height: auto;
|
||||
|
||||
@include rfs(2rem, width);
|
||||
}
|
||||
.marker-title {
|
||||
@include rfs(0.8rem, font-size);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -15,7 +15,8 @@ import {
|
|||
faPlay,
|
||||
faPlus,
|
||||
faQuestionCircle,
|
||||
faUserGroup
|
||||
faUserGroup,
|
||||
faUsers
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
config.autoReplaceSvg = false;
|
||||
|
|
@ -35,5 +36,6 @@ library.add(faMinus);
|
|||
library.add(faPlus);
|
||||
library.add(faPlay);
|
||||
library.add(faPause);
|
||||
library.add(faUsers);
|
||||
|
||||
dom.watch();
|
||||
|
|
|
|||
|
|
@ -11,6 +11,13 @@ const sassSafelist: UserDefinedSafelist = [
|
|||
/^bs-popover/,
|
||||
/^popover/,
|
||||
/^bg-.*/,
|
||||
/^img-.*/,
|
||||
// * Fonts
|
||||
/^f-.*/,
|
||||
// * Leaflet
|
||||
/^leaflet-.*/,
|
||||
// * Leaflet Fullscreen plugin
|
||||
/^fullscreen-icon$/,
|
||||
// Vue
|
||||
/-(leave|enter|appear)(|-(to|from|active))$/,
|
||||
/^(?!(|.*?:)cursor-move).+-move$/,
|
||||
|
|
|
|||
|
|
@ -503,7 +503,7 @@
|
|||
'name' => 'longitude',
|
||||
'required' => true,
|
||||
'model' => $siteModel ?? null,
|
||||
'helper' => __('crud.helpers.longitude'),
|
||||
'helper' => __('validation.longitude'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -18,10 +18,12 @@
|
|||
@section('content')
|
||||
<section class="unveil">
|
||||
{{-- KEY NUMBERS --}}
|
||||
<section class="key-numbers container my-5 text-center">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2 class="h2 fw-bold text-primary">{{ $keySection->h2_title }}</h2>
|
||||
<section class="key-numbers my-5">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h2 class="h2 fw-bold text-primary text-center">{{ $keySection->h2_title }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
|
|
@ -103,14 +105,23 @@
|
|||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 d-flex justify-content-center">
|
||||
{{-- FIXME: remplacer map --}}
|
||||
<div class="embed-map w-100 my-3">
|
||||
<iframe class="rounded-3"
|
||||
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d10661.469000249905!2d-0.7577479264599797!3d48.083855231712434!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x4809013bc7a7e43f%3A0xe01d7907f663610d!2sSNV%20Laval!5e0!3m2!1sfr!2sfr!4v1709025460315!5m2!1sfr!2sfr"
|
||||
title="{{ __('Carte de nos sites') }}" style="border:0;" allowfullscreen="" loading="lazy"
|
||||
referrerpolicy="no-referrer-when-downgrade"></iframe>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 order-lg-first d-flex justify-content-center">
|
||||
@php
|
||||
$data = [
|
||||
'wrapperClasses' => 'rounded-3 embed-map w-100 my-3',
|
||||
'coordinates' => [
|
||||
'lat' => $viewBox->lat,
|
||||
'lng' => $viewBox->lng,
|
||||
],
|
||||
'siteModelList' => $siteModelList,
|
||||
];
|
||||
@endphp
|
||||
<div class="leaflet-map-vue w-100" data-json='@json($data)'></div>
|
||||
{{-- FIXME: Quelles coordonnées pour la map ? --}}
|
||||
{{-- <iframe class="rounded-3 embed-map w-100 my-3"
|
||||
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d10661.469000249905!2d-0.7577479264599797!3d48.083855231712434!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x4809013bc7a7e43f%3A0xe01d7907f663610d!2sSNV%20Laval!5e0!3m2!1sfr!2sfr!4v1709025460315!5m2!1sfr!2sfr"
|
||||
title="{{ __('Carte de nos sites') }}" style="border:0;" allowfullscreen="" loading="lazy"
|
||||
referrerpolicy="no-referrer-when-downgrade"></iframe> --}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue