1
0

MapConcernements.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  1. <script>
  2. // import { mapActions, mapState } from 'pinia'
  3. import { computed } from 'vue'
  4. import MapBackground from '@components/MapBackground.vue'
  5. // https://brm.io/matter-js/docs/classes/Engine.html
  6. import Matter from "matter-js";
  7. import MatterAttractors from "matter-attractors";
  8. Matter.use(MatterAttractors);
  9. import paper from 'paper';
  10. import { mapState, mapActions } from 'pinia'
  11. import { ConcernementsStore } from '@/stores/concernements'
  12. import { CommonStore } from '@/stores/common'
  13. import ConcernementMapPopup from '@components/ConcernementMapPopup.vue';
  14. // import iconTerraindevie from "@/assets/icons/terraindevie.svg"
  15. // import iconProximite from "@/assets/icons/proximite.svg"
  16. // import iconSuperposition from "@/assets/icons/superposition.svg"
  17. import iconPuissanceagir from "@/assets/icons/puissancedagir.svg"
  18. // import iconAction from "@/assets/icons/action.svg"
  19. import iconDoleancer from "@/assets/icons/doleancer.svg"
  20. export default {
  21. data() {
  22. return {
  23. canvasMap: {
  24. canvas: null,
  25. ctx: null
  26. },
  27. animateEvent: new Event('animate'),
  28. granim: null,
  29. // MATTER
  30. engine: null,
  31. world: null,
  32. // PAPERJS
  33. paper: null,
  34. //
  35. mapPopupData: null,
  36. }
  37. },
  38. provide() {
  39. // https://www.digitalocean.com/community/tutorials/vuejs-vue-html5-canvas
  40. return {
  41. // explicitly provide a computed property
  42. canvasMap: computed(() => this.canvasMap),
  43. matterEngine: computed(() => this.engine)
  44. }
  45. },
  46. computed: {
  47. ...mapState(ConcernementsStore,['map_mode']),
  48. ...mapState(ConcernementsStore,['concernements']),
  49. ...mapState(ConcernementsStore,['concernementsByID']),
  50. ...mapState(ConcernementsStore,['opened_concernement']),
  51. ...mapState(CommonStore,['map_item_ray']),
  52. ...mapState(CommonStore,['hover_elmt']),
  53. ...mapState(CommonStore,['paper_symbol_definitions'])
  54. },
  55. created() {
  56. // MATTER
  57. // create an engine
  58. let engineOptions = {
  59. enableSleeping: true,
  60. timing: {
  61. //timestamp: 0.5,
  62. timeScale: 0.5
  63. }
  64. }
  65. this.engine = Matter.Engine.create(engineOptions);
  66. this.engine.gravity.scale = 0;
  67. this.world = this.engine.world;
  68. },
  69. mounted() {
  70. this.canvasMap.canvas = this.$refs['canvas-map'];
  71. this.canvasMap.ctx = this.canvasMap.canvas.getContext('2d');
  72. let canvas_w = this.canvasMap.canvas.width = this.canvasMap.canvas.parentElement.clientWidth;
  73. let canvas_h = this.canvasMap.canvas.height = this.canvasMap.canvas.parentElement.clientHeight;
  74. console.log(`canvas_w: ${canvas_w}, canvas_h: ${canvas_h}`);
  75. // PAPER
  76. this.paper = paper.setup(this.canvasMap.canvas);
  77. // symbol defintions
  78. this.initPaperSymbols();
  79. // use the paper.view click to get back if no items is clicked
  80. this.paper.view.onClick = function(event) {
  81. console.log("view onClick", this, event.target);
  82. if(event.target._id === "paper-view-0") {
  83. this.resetConcernementOpened();
  84. this.$router.push({
  85. name: 'home',
  86. hash: `#${this.map_mode}`
  87. });
  88. }
  89. }.bind(this);
  90. // MATTER
  91. let wall_w = 1000;
  92. Matter.Composite.add(this.world, [
  93. // walls
  94. Matter.Bodies.rectangle(canvas_w/2, -wall_w/2, canvas_w, wall_w, { isStatic: true }), // top
  95. Matter.Bodies.rectangle(canvas_w/2, canvas_h+wall_w/2, canvas_w, wall_w, { isStatic: true }), // bottom
  96. Matter.Bodies.rectangle(-wall_w/2, canvas_h/2, wall_w, canvas_h, { isStatic: true }), // left
  97. Matter.Bodies.rectangle(canvas_w+wall_w/2, canvas_h/2, wall_w, canvas_h, { isStatic: true }), // right
  98. // make the items never goes under menus
  99. Matter.Bodies.rectangle(550, 25, 900, 50, { isStatic: true }), // menu top
  100. Matter.Bodies.rectangle(550, canvas_h-15, 900, 30, { isStatic: true }) // menu bottom
  101. ]);
  102. // add mouse control
  103. // https://github.com/liabru/matter-js/issues/491#issuecomment-331329404
  104. // this.mouse = Matter.Mouse.create(this.canvasMap.canvas);
  105. this.animate()
  106. },
  107. watch: {
  108. hover_elmt: {
  109. handler (n, o) {
  110. console.log(`watch hover_elmt map: o, n`, o, n);
  111. // over highlight effect on paper items
  112. if (n && n.paper_id) {
  113. let nitem = paper.project.getItem({id: n.paper_id});
  114. console.log('watch hover_element nitem', nitem.definition);
  115. if (!nitem.is_symbol_instance) { // not symbol instance
  116. nitem.bringToFront();
  117. if (nitem.strokeColor) {
  118. nitem.data.prevStrokeColor = nitem.strokeColor.toCSS(true);
  119. nitem.strokeColor = "#01ffe2";
  120. } else {
  121. nitem.data.prevFillColor = nitem.fillColor.toCSS(true);
  122. nitem.fillColor = "#01ffe2";
  123. }
  124. } else { // is a symbol instanceof, then swap
  125. console.log(`symbol instance n.type:${n.type}, nitem`, nitem);
  126. switch (n.type) {
  127. case 'entite':
  128. nitem.definition = this.paper_symbol_definitions.entite_hover;
  129. break;
  130. case 'besoin':
  131. nitem.definition = this.paper_symbol_definitions.besoin_hover;
  132. break;
  133. case 'reponse':
  134. nitem.definition = this.paper_symbol_definitions.reponse_hover;
  135. break;
  136. }
  137. }
  138. }
  139. if (o && o.paper_id) {
  140. let oitem = paper.project.getItem({id: o.paper_id})
  141. console.log('watch hover_element oitem', oitem);
  142. if (!oitem.is_symbol_instance) { // not symbol instance
  143. if (oitem.data.prevStrokeColor) {
  144. oitem.strokeColor = oitem.data.prevStrokeColor;
  145. } else {
  146. oitem.fillColor = oitem.data.prevFillColor;
  147. }
  148. } else { // is a symbol instanceof, then swap
  149. console.log(`symbol instance o.type:${o.type}, oitem`, oitem);
  150. switch (o.type) {
  151. case 'entite':
  152. oitem.definition = this.paper_symbol_definitions.entite;
  153. break;
  154. case 'besoin':
  155. oitem.definition = this.paper_symbol_definitions.besoin;
  156. break;
  157. case 'reponse':
  158. oitem.definition = this.paper_symbol_definitions.reponse;
  159. break;
  160. }
  161. }
  162. }
  163. },
  164. deep: true
  165. }
  166. },
  167. methods: {
  168. ...mapActions(ConcernementsStore,['setMapMode']),
  169. ...mapActions(ConcernementsStore,['resetConcernementOpened']),
  170. // ...mapActions(ConcernementsStore,['openCloseConcernements']),
  171. ...mapActions(CommonStore,['addPaperSymbolDefinition']),
  172. animate () {
  173. Matter.Engine.update(this.engine, 1);
  174. window.requestAnimationFrame(this.animate);
  175. },
  176. initPaperSymbols(){
  177. this.addPaperSymbolDefinition('boussole_bg', this.setPaperBoussoleBGSymbol());
  178. this.addPaperSymbolDefinition('puissanceagir_bg', this.setPaperPuissanceagirBGSymbol());
  179. this.addPaperSymbolDefinition('puissanceagir_icon', this.setPaperPuissanceagirICONSymbol());
  180. this.addPaperSymbolDefinition('doleance_bg', this.setPaperDoleanceBGSymbol());
  181. this.addPaperSymbolDefinition('doleance_icon', this.setPaperDoleanceICONSymbol());
  182. //
  183. this.addPaperSymbolDefinition('entite', this.setPaperEntiteSymbol());
  184. this.addPaperSymbolDefinition('entite_hover', this.setPaperEntiteHoverSymbol());
  185. this.addPaperSymbolDefinition('besoin', this.setPaperBesoinSymbol());
  186. this.addPaperSymbolDefinition('besoin_hover', this.setPaperBesoinHoverSymbol());
  187. this.addPaperSymbolDefinition('reponse', this.setPaperReponseSymbol());
  188. this.addPaperSymbolDefinition('reponse_hover', this.setPaperReponseHoverSymbol());
  189. },
  190. setPaperBoussoleBGSymbol(){
  191. // BOUSSOLE
  192. let children = [];
  193. let ray = this.map_item_ray;
  194. let pos = {x:0, y:0};
  195. // cercles pointillés
  196. for (let i = 1; i < 9; i++) {
  197. let sw = i === 4 || i === 8 ? 0.5 : 0.25;
  198. let da = i === 4 || i === 8 ? null : [5,5];
  199. children.push(new paper.Path.Circle({
  200. center: [pos.x, pos.y],
  201. radius: ray/8*i,
  202. strokeColor: '#fff',
  203. strokeWidth: sw,
  204. dashArray: da
  205. }));
  206. }
  207. // axes
  208. // vertical
  209. children.push(new paper.Path.Line({
  210. from: [pos.x, pos.y - ray],
  211. to: [pos.x, pos.y + ray],
  212. strokeColor: '#fff',
  213. strokeWidth: 0.5
  214. }));
  215. // horizontal
  216. children.push(new paper.Path.Line({
  217. from: [pos.x - ray, pos.y],
  218. to: [pos.x + ray, pos.y],
  219. strokeColor: '#fff',
  220. strokeWidth: 0.5
  221. }))
  222. // fleches
  223. // haute
  224. children.push(new paper.Path({
  225. segments: [
  226. [pos.x - 8, pos.y - ray + 8],
  227. [pos.x, pos.y - ray],
  228. [pos.x + 8, pos.y - ray + 8],
  229. ],
  230. strokeWidth: 0.5,
  231. strokeColor: '#fff',
  232. }));
  233. // milieu
  234. children.push(new paper.Path({
  235. segments: [
  236. [pos.x - 8, pos.y + 8],
  237. [pos.x, pos.y],
  238. [pos.x + 8, pos.y + 8],
  239. ],
  240. strokeWidth: 0.5,
  241. strokeColor: '#fff',
  242. }));
  243. // MOINS - PLUS
  244. // PLUS
  245. // horizontal
  246. children.push(new paper.Path.Line({
  247. from: [pos.x + ray - 5, pos.y - ray],
  248. to: [pos.x + ray + 5, pos.y - ray],
  249. strokeWidth: 2,
  250. strokeColor: '#fff',
  251. }))
  252. // vertical
  253. children.push(new paper.Path.Line({
  254. from: [pos.x + ray, pos.y - ray - 5],
  255. to: [pos.x + ray, pos.y - ray + 5],
  256. strokeWidth: 2,
  257. strokeColor: '#fff',
  258. }))
  259. // MOINS
  260. // horizontal
  261. children.push(new paper.Path.Line({
  262. from: [pos.x - ray - 5, pos.y - ray],
  263. to: [pos.x - ray + 5, pos.y - ray],
  264. strokeWidth: 2,
  265. strokeColor: '#fff',
  266. }))
  267. let fontsize = 4;
  268. let fontFamily = "public_sans";
  269. children.push(new paper.PointText({
  270. point: [pos.x + 4.5, pos.y - ray - 5],
  271. content: `entités qui menacent \u2194 entités qui maintiennent`,
  272. fontSize: fontsize,
  273. fontFamily: fontFamily,
  274. justification: 'center',
  275. fillColor: '#000',
  276. }))
  277. children.push(new paper.PointText({
  278. point: [pos.x - ray - 5, pos.y + 1],
  279. content: "axe d'intensité",
  280. fontSize: fontsize,
  281. fontFamily: fontFamily,
  282. justification: 'right',
  283. fillColor: '#000',
  284. }))
  285. children.push(new paper.PointText({
  286. point: [pos.x + ray + 5, pos.y - 3],
  287. content: "situation future\n\u2195\nsituation actuelle",
  288. fontSize: fontsize,
  289. fontFamily: fontFamily,
  290. justification: 'left',
  291. fillColor: '#000',
  292. }))
  293. let t1 = new paper.PointText({
  294. point: [pos.x - ray/8*2.3, pos.y - ray/8*2.3],
  295. content: "avec prise",
  296. fontSize: fontsize,
  297. fontFamily: fontFamily,
  298. justification: 'center',
  299. fillColor: '#000',
  300. })
  301. t1.rotate(-45)
  302. children.push(t1)
  303. let t2 = new paper.PointText({
  304. point: [pos.x - ray/8*2.95, pos.y - ray/8*2.95],
  305. content: "sans prise",
  306. fontSize: fontsize,
  307. fontFamily: fontFamily,
  308. justification: 'center',
  309. fillColor: '#000',
  310. })
  311. t2.rotate(-45)
  312. children.push(t2)
  313. return new paper.Group({
  314. children: children,
  315. pivot: new paper.Point(pos),
  316. name: 'boussole_bg',
  317. // locked: true,
  318. });
  319. },
  320. setPaperPuissanceagirBGSymbol(){
  321. let children = [];
  322. let ray = this.map_item_ray;
  323. let pos = {x:0,y:0};
  324. // cercles interieur
  325. for (let i = 1; i < 6; i++) {
  326. children.push(new paper.Path.Circle({
  327. center: [pos.x, pos.y],
  328. radius: (ray/5)*i,
  329. strokeWidth: 0.25
  330. }));
  331. }
  332. // rayons
  333. for (let j = 0; j < 16; j++) {
  334. let a = (360 / 16) * j;
  335. let ext_x = Math.cos(a*(Math.PI/180)) * ray;
  336. let ext_y = Math.sin(a*(Math.PI/180)) * ray;
  337. let int_x = Math.cos(a*(Math.PI/180)) * 2;
  338. let int_y = Math.sin(a*(Math.PI/180)) * 2;
  339. children.push(new paper.Path.Line({
  340. from: [pos.x + ext_x, pos.y + ext_y],
  341. to: [pos.x + int_x, pos.y + int_y],
  342. strokeWidth: 0.25,
  343. dashArray: [0.5,1]
  344. }))
  345. }
  346. // cercle exterieur
  347. children.push(new paper.Path.Circle({
  348. center: [pos.x, pos.y],
  349. radius: ray,
  350. strokeWidth: 0.5,
  351. fillColor: `rgba(255,255,255,0.6)`
  352. }));
  353. return new paper.Group({
  354. children: children,
  355. pivot: new paper.Point(pos),
  356. name: 'puissanceagir_bg',
  357. // locked: true,
  358. style: {
  359. strokeColor: '#fff'
  360. }
  361. });
  362. },
  363. setPaperPuissanceagirICONSymbol(){
  364. let children = [];
  365. let svgIcon = paper.project.importSVG(iconPuissanceagir);
  366. children.push(svgIcon);
  367. svgIcon.position = this.pos;
  368. return new paper.Group({
  369. children: children,
  370. pivot: new paper.Point(this.pos),
  371. name: 'puissanceagir_icon',
  372. locked: true,
  373. style: {
  374. strokeColor: '#000',
  375. strokeWidth: 0.75,
  376. fillColor: null
  377. }
  378. });
  379. },
  380. setPaperDoleanceBGSymbol(){
  381. let ray = this.map_item_ray;
  382. let pos = {x:0,y:0};
  383. var r = ray * 0.8; // ray
  384. var dr = r/2; // demi ray
  385. var pcr = 2; // petits cercle rayon
  386. // https://fr.wikipedia.org/wiki/Trigonom%C3%A9trie#/media/Fichier:Unit_circle_angles_color.svg
  387. // https://fr.wikipedia.org/wiki/Identit%C3%A9_trigonom%C3%A9trique_pythagoricienne#Preuve_utilisant_le_cercle_unit%C3%A9
  388. // radians = degrees * (pi/180)
  389. // degrees = radians * (180/pi)
  390. // Points for 45° axes
  391. let m = Math.sin(45*(Math.PI/180)) * r; // x = y for rayon
  392. let n = Math.sin(45*(Math.PI/180)) * r/2; // x = y for demi rayon
  393. // console.log('m', m);
  394. // points for legende arcs
  395. var lar = r*1.1; // legendes arcs rayon
  396. let o = Math.cos(22.5*(Math.PI/180)) * lar; // x @ 22.5° for legende arc rayon
  397. let p = Math.sin(22.5*(Math.PI/180)) * lar; // y @ 22.5° for legende arc rayon
  398. let q = Math.sin(45*(Math.PI/180)) * lar; // x = y @ 45° for legende arc rayon
  399. var ltr = lar + 4; // legendes texts rayon
  400. let o_t = Math.cos(22.5*(Math.PI/180)) * ltr; // x @ 22.5° for legende text rayon
  401. let p_t = Math.sin(22.5*(Math.PI/180)) * ltr; // y @ 22.5° for legende text rayon
  402. let q_t = Math.sin(45*(Math.PI/180)) * ltr; // x = y @ 45° for legende text rayon
  403. let style = {strokeColor: '#fff', strokeWidth: 0.25}
  404. let felchesstyle = {strokeColor: '#fff', strokeWidth: 0.5}
  405. let legende_style = {strokeColor: '#000', strokeWidth: 0.25}
  406. let fontsize = 4;
  407. let fontFamily = "public_sans";
  408. let children = [
  409. // big global exterior circle to keep center aligned
  410. new paper.Path.Circle({
  411. center: [0, 0],
  412. radius: r*2,
  413. style: {
  414. strokeColor: 'rgba(255,255,255,0)',
  415. strokeWidth: 0.5
  416. }
  417. }),
  418. //
  419. // ARCS EXTERIEURS
  420. // haut gauche
  421. new paper.Path.Arc({
  422. from: [- r, -pcr],
  423. through: [- m, -m],
  424. to: [ -pcr, -r],
  425. style: style
  426. }),
  427. // haut droite
  428. new paper.Path.Arc({
  429. from: [pcr, -r],
  430. through: [m, -m],
  431. to: [r, -pcr],
  432. style: style
  433. }),
  434. // bas droite
  435. new paper.Path.Arc({
  436. from: [r, pcr],
  437. through: [m, m],
  438. to: [pcr, r],
  439. style: style
  440. }),
  441. // bas gauche
  442. new paper.Path.Arc({
  443. from: [-pcr, r],
  444. through: [-m, m],
  445. to: [-r, pcr],
  446. style: style
  447. }),
  448. //
  449. // cercle interieur
  450. new paper.Path.Circle({
  451. center: [0, 0],
  452. radius: dr,
  453. style: style
  454. }),
  455. //
  456. // petit cercles
  457. new paper.Path.Circle({
  458. center: [0, -r],
  459. radius: pcr,
  460. style: style
  461. }),
  462. new paper.Path.Circle({
  463. center: [0, r],
  464. radius: pcr,
  465. style: style
  466. }),
  467. new paper.Path.Circle({
  468. center: [r, 0],
  469. radius: pcr,
  470. style: style
  471. }),
  472. new paper.Path.Circle({
  473. center: [-r, 0],
  474. radius: pcr,
  475. style: style
  476. }),
  477. //
  478. // AXES
  479. // vertical haut
  480. new paper.Path.Line({
  481. from: [0, -r + pcr],
  482. to: [0, -dr],
  483. style: style
  484. }),
  485. // vertical bas
  486. new paper.Path.Line({
  487. from: [0, r - pcr],
  488. to: [0, dr],
  489. style: style
  490. }),
  491. // horizontal gauche
  492. new paper.Path.Line({
  493. from: [-r + pcr, 0],
  494. to: [-dr, 0],
  495. style: style
  496. }),
  497. // horizontal droite
  498. new paper.Path.Line({
  499. from: [r - pcr, 0],
  500. to: [dr, 0],
  501. style: style
  502. }),
  503. //
  504. // DIAGONALES
  505. // bas droite
  506. new paper.Path.Line({
  507. from: [m, m],
  508. to: [n, n],
  509. style: style
  510. }),
  511. // bas gauche
  512. new paper.Path.Line({
  513. from: [-m, m],
  514. to: [-n, n],
  515. style: style
  516. }),
  517. // fleches
  518. // haut
  519. new paper.Path({
  520. segments: [
  521. [-2, -dr*1.5 - 2],
  522. [0, -dr*1.5],
  523. [-2, -dr*1.5 + 2]
  524. ],
  525. style: felchesstyle
  526. }),
  527. // bas
  528. new paper.Path({
  529. segments: [
  530. [2, dr*1.5 - 2],
  531. [0, dr*1.5],
  532. [2, dr*1.5 + 2]
  533. ],
  534. style: felchesstyle
  535. }),
  536. // gauche
  537. new paper.Path({
  538. segments: [
  539. [-dr*1.5 - 2, 2],
  540. [-dr*1.5, 0],
  541. [-dr*1.5 + 2, 2]
  542. ],
  543. style: felchesstyle
  544. }),
  545. // droite
  546. new paper.Path({
  547. segments: [
  548. [dr*1.5 - 2, -2],
  549. [dr*1.5, 0],
  550. [dr*1.5 + 2, -2]
  551. ],
  552. style: felchesstyle
  553. }),
  554. //
  555. // LEGENDES
  556. //
  557. // arc bas gauche 1
  558. new paper.Path.Arc({
  559. from: [-pcr, lar],
  560. through: [-p, o],
  561. to: [-q + pcr/2, q + pcr/2],
  562. style: legende_style
  563. }),
  564. // tiret
  565. new paper.Path.Line({
  566. from: [-p, o],
  567. to: [-p_t, o_t],
  568. style: legende_style
  569. }),
  570. //text
  571. new paper.PointText({
  572. point: [-p_t - 1, o_t],
  573. content: "Enquête menée\nsur le terrain de vie",
  574. fontSize: fontsize,
  575. fontFamily: fontFamily,
  576. justification: 'right'
  577. }),
  578. // arc bas gauche 2
  579. new paper.Path.Arc({
  580. from: [-q - pcr/2, q - pcr/2],
  581. through: [-o, p],
  582. to: [-lar, pcr],
  583. style: legende_style
  584. }),
  585. // tiret
  586. new paper.Path.Line({
  587. from: [-o, p],
  588. to: [-o_t, p_t],
  589. style: legende_style
  590. }),
  591. // texte
  592. new paper.PointText({
  593. point: [-o_t - 1, p_t],
  594. content: "Construction de groupes d'intérets\navec qui composer la doléance",
  595. fontSize: fontsize,
  596. fontFamily: fontFamily,
  597. justification: 'right'
  598. }),
  599. // arc haut gauche
  600. new paper.Path.Arc({
  601. from: [-lar, -pcr],
  602. through: [-q, -q],
  603. to: [-pcr, -lar],
  604. style: legende_style
  605. }),
  606. // tiret
  607. new paper.Path.Line({
  608. from: [-q, -q],
  609. to: [-q_t, -q_t],
  610. style: legende_style
  611. }),
  612. // texte
  613. new paper.PointText({
  614. point: [-q_t - 1, -q_t],
  615. content: "Réception et traitement\nde la doléance",
  616. fontSize: fontsize,
  617. fontFamily: fontFamily,
  618. justification: 'right'
  619. }),
  620. // arc haut droite
  621. new paper.Path.Arc({
  622. from: [pcr, -lar],
  623. through: [q, -q],
  624. to: [lar, -pcr],
  625. style: legende_style
  626. }),
  627. // tiret
  628. new paper.Path.Line({
  629. from: [q, -q],
  630. to: [q_t, -q_t],
  631. style: legende_style
  632. }),
  633. // texte
  634. new paper.PointText({
  635. point: [q_t + 1, -q_t],
  636. content: "Mise-en-œuvre\nde la décision",
  637. fontSize: fontsize,
  638. fontFamily: fontFamily,
  639. justification: 'left'
  640. }),
  641. // arc bas droite 1
  642. new paper.Path.Arc({
  643. from: [lar, pcr],
  644. through: [o, p],
  645. to: [q + pcr/2, q - pcr/2],
  646. style: legende_style
  647. }),
  648. // tiret
  649. new paper.Path.Line({
  650. from: [o, p],
  651. to: [o_t, p_t],
  652. style: legende_style
  653. }),
  654. // texte
  655. new paper.PointText({
  656. point: [o_t + 1, p_t],
  657. content: "Réception et application\nde la décision",
  658. fontSize: fontsize,
  659. fontFamily: fontFamily,
  660. justification: 'left'
  661. }),
  662. // arc bas droite 2
  663. new paper.Path.Arc({
  664. from: [q - pcr/2, q + pcr/2],
  665. through: [p, o],
  666. to: [pcr, lar],
  667. style: legende_style
  668. }),
  669. // tiret
  670. new paper.Path.Line({
  671. from: [p, o],
  672. to: [p_t, o_t],
  673. style: legende_style
  674. }),
  675. // texte
  676. new paper.PointText({
  677. point: [p_t + 1, o_t],
  678. content: "Réussite / échec / reprise\ndu cercle politique",
  679. fontSize: fontsize,
  680. fontFamily: fontFamily,
  681. justification: 'left'
  682. }),
  683. //
  684. // Points Cardinaux
  685. //
  686. // haut
  687. new paper.Path.Circle({
  688. center: [0, -r],
  689. radius: 0.5,
  690. style: {
  691. fillColor: '#000'
  692. }
  693. }),
  694. new paper.Path.Line({
  695. from: [0, -r],
  696. to: [0, -r - 9],
  697. style: legende_style
  698. }),
  699. new paper.PointText({
  700. point: [0, -r - 11],
  701. content: "Décision",
  702. fontSize: fontsize,
  703. fontFamily: fontFamily,
  704. justification: 'center'
  705. }),
  706. // bas
  707. new paper.Path.Circle({
  708. center: [0, r],
  709. radius: 0.5,
  710. style: {
  711. fillColor: '#000'
  712. }
  713. }),
  714. new paper.Path.Line({
  715. from: [0, r],
  716. to: [0, r + 9],
  717. style: legende_style
  718. }),
  719. new paper.PointText({
  720. point: [0, r + 14],
  721. content: "Début du cercle\nLe problème\n(injustice, indignation, plainte...)",
  722. fontSize: fontsize,
  723. fontFamily: fontFamily,
  724. justification: 'center'
  725. }),
  726. // droite
  727. new paper.Path.Circle({
  728. center: [r, 0],
  729. radius: 0.5,
  730. style: {
  731. fillColor: '#000'
  732. }
  733. }),
  734. new paper.Path.Line({
  735. from: [r, 0],
  736. to: [r + 8, 0],
  737. style: legende_style
  738. }),
  739. new paper.PointText({
  740. point: [r + 10, -0.5],
  741. content: "Adresse de la décision\nà appliquer",
  742. fontSize: fontsize,
  743. fontFamily: fontFamily,
  744. justification: 'left'
  745. }),
  746. // gauche
  747. new paper.Path.Circle({
  748. center: [-r, 0],
  749. radius: 0.5,
  750. style: {
  751. fillColor: '#000'
  752. }
  753. }),
  754. new paper.Path.Line({
  755. from: [-r, 0],
  756. to: [-r - 8, 0],
  757. style: legende_style
  758. }),
  759. new paper.PointText({
  760. point: [-r - 10, 0.4],
  761. content: "Adresse de la doléance",
  762. fontSize: fontsize,
  763. fontFamily: fontFamily,
  764. justification: 'right'
  765. }),
  766. ];
  767. return new paper.Group({
  768. children: children,
  769. pivot: new paper.Point(pos),
  770. name: 'doleance_bg',
  771. // locked: true
  772. });
  773. },
  774. setPaperDoleanceICONSymbol(){
  775. let children = [];
  776. let svgIcon = paper.project.importSVG(iconDoleancer);
  777. children.push(svgIcon);
  778. svgIcon.position = this.pos;
  779. return new paper.Group({
  780. children: children,
  781. pivot: new paper.Point(this.pos),
  782. name: 'doleance_icon',
  783. locked: true,
  784. style: {
  785. strokeColor: '#000',
  786. strokeWidth: 0.75,
  787. fillColor: null
  788. }
  789. });
  790. },
  791. setPaperEntiteSymbol(){
  792. return new paper.Path.Circle({
  793. pivot: new paper.Point({x:0,y:0}),
  794. center: [0,0],
  795. radius: 0.5, //0.3
  796. fillColor: '#000',
  797. strokeColor: 'rgba(255,255,255,0.05)',
  798. strokeWidth:2
  799. })
  800. },
  801. setPaperEntiteHoverSymbol(){
  802. return new paper.Path.Circle({
  803. pivot: new paper.Point({x:0,y:0}),
  804. center: [0,0],
  805. radius: 0.5,
  806. fillColor: '#01ffe2',
  807. strokeColor: 'rgba(255,255,255,0.05)',
  808. strokeWidth:2
  809. })
  810. },
  811. setPaperBesoinSymbol(){
  812. return new paper.Path({
  813. pivot: new paper.Point(this.pos),
  814. segments: [[0, -1],[1, 0],[0, 1],[-1, 0],[0, -1]],
  815. fillColor: '#000'
  816. })
  817. },
  818. setPaperBesoinHoverSymbol(){
  819. return new paper.Path({
  820. pivot: new paper.Point(this.pos),
  821. segments: [[0, -1],[1, 0],[0, 1],[-1, 0],[0, -1]],
  822. fillColor: '#01ffe2'
  823. })
  824. },
  825. setPaperReponseSymbol(){
  826. return new paper.Path({
  827. pivot: new paper.Point(this.pos),
  828. segments: [[0, -1],[1, 0],[0, 1],[-1, 0],[0, -1]],
  829. fillColor: '#eee',
  830. strokeColor: "#000",
  831. strokeWidth: 0.25,
  832. })
  833. },
  834. setPaperReponseHoverSymbol(){
  835. return new paper.Path({
  836. pivot: new paper.Point(this.pos),
  837. segments: [[0, -1],[1, 0],[0, 1],[-1, 0],[0, -1]],
  838. fillColor: '#eee',
  839. strokeColor: "#01ffe2",
  840. strokeWidth: 0.25,
  841. })
  842. }
  843. },
  844. beforeUpdate () {
  845. },
  846. components: {
  847. MapBackground,
  848. ConcernementMapPopup
  849. }
  850. }
  851. </script>
  852. <template>
  853. <div id="map-backgrounds">
  854. <MapBackground />
  855. </div>
  856. <div id="map-matter">
  857. <canvas ref="canvas-engine"></canvas>
  858. </div>
  859. <div id="map-concernements">
  860. <canvas ref="canvas-map"></canvas>
  861. <slot></slot>
  862. </div>
  863. <nav id="map-nav">
  864. <ul>
  865. <li>
  866. <a
  867. href="#terraindevie" @click="setMapMode('terraindevie')"
  868. >
  869. <span class="icon terraindevie"></span> terrain de vie
  870. </a>
  871. </li>
  872. <li>
  873. <a
  874. href="#proximite" @click="setMapMode('proximite')"
  875. :class="{ disabled: opened_concernement && !opened_concernement.has_proximite }"
  876. >
  877. <span class="icon proximite"></span> proximité
  878. </a>
  879. </li>
  880. <li>
  881. <a
  882. href="#superposition" @click="setMapMode('superposition')"
  883. :class="{ disabled: opened_concernement && !opened_concernement.has_superposition }"
  884. >
  885. <span class="icon superposition"></span> superposition
  886. </a>
  887. </li>
  888. <li>
  889. <a
  890. href="#puissancedagir" @click="setMapMode('puissancedagir')"
  891. :class="{ disabled: opened_concernement && !opened_concernement.has_puissancedagir }"
  892. >
  893. <span class="icon puissancedagir"></span> puissance d'agir
  894. </a>
  895. </li>
  896. <li>
  897. <a
  898. href="#action" @click="setMapMode('action')"
  899. :class="{ disabled: opened_concernement && !opened_concernement.has_agissantes }"
  900. >
  901. <span class="icon action"></span> action
  902. </a>
  903. </li>
  904. <li>
  905. <a
  906. href="#doleancer" @click="setMapMode('doleancer')"
  907. :class="{ disabled: opened_concernement && !opened_concernement.has_doleance }"
  908. >
  909. <span class="icon doleancer"></span> cercle politique
  910. </a>
  911. </li>
  912. </ul>
  913. </nav>
  914. <ConcernementMapPopup
  915. v-if="hover_elmt && hover_elmt.type !== 'doleance_step'"
  916. :infos="hover_elmt"
  917. />
  918. </template>
  919. <style lang="css" scoped>
  920. </style>