1
0

MapConcernements.vue 31 KB

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