MapConcernements.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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 {
  7. // Engine,
  8. // // Render,
  9. // // World,
  10. // Bodies,
  11. // // Body,
  12. // // Events,
  13. // Composite,
  14. // // Composites,
  15. // // Constraint,
  16. // // Vertices,
  17. // // Mouse,
  18. // // MouseConstraint,
  19. // // Query,
  20. // // Common
  21. // } from "matter-js";
  22. import Matter from "matter-js";
  23. import MatterAttractors from "matter-attractors";
  24. Matter.use(MatterAttractors);
  25. import paper from 'paper';
  26. import { mapState, mapActions } from 'pinia'
  27. import { ConcernementsStore } from '@/stores/concernements'
  28. import { CommonStore } from '@/stores/common'
  29. import ConcernementMapPopup from '@components/ConcernementMapPopup.vue';
  30. export default {
  31. data() {
  32. return {
  33. canvasMap: {
  34. canvas: null,
  35. ctx: null
  36. },
  37. animateEvent: new Event('animate'),
  38. granim: null,
  39. // MATTER
  40. engine: null,
  41. world: null,
  42. // render: null,
  43. mouse: null,
  44. mapPopupData: null,
  45. // PAPERJS
  46. paper: null
  47. }
  48. },
  49. provide() {
  50. // https://www.digitalocean.com/community/tutorials/vuejs-vue-html5-canvas
  51. return {
  52. // explicitly provide a computed property
  53. canvasMap: computed(() => this.canvasMap),
  54. matterEngine: computed(() => this.engine)
  55. }
  56. },
  57. computed: {
  58. ...mapState(ConcernementsStore,['map_mode']),
  59. ...mapState(ConcernementsStore,['concernements']),
  60. ...mapState(ConcernementsStore,['concernementsByID']),
  61. ...mapState(ConcernementsStore,['opened']),
  62. ...mapState(CommonStore,['hover_elmt'])
  63. },
  64. created() {
  65. // MATTER
  66. // create an engine
  67. let engineOptions = {
  68. enableSleeping: true,
  69. timing: {
  70. //timestamp: 0.5,
  71. timeScale: 0.5
  72. }
  73. }
  74. this.engine = Matter.Engine.create(engineOptions);
  75. this.engine.gravity.scale = 0;
  76. this.world = this.engine.world;
  77. },
  78. mounted() {
  79. this.canvasMap.canvas = this.$refs['canvas-map'];
  80. this.canvasMap.ctx = this.canvasMap.canvas.getContext('2d');
  81. let canvas_w = this.canvasMap.canvas.width = this.canvasMap.canvas.parentElement.clientWidth;
  82. let canvas_h = this.canvasMap.canvas.height = this.canvasMap.canvas.parentElement.clientHeight;
  83. console.log(`canvas_w: ${canvas_w}, canvas_h: ${canvas_h}`);
  84. this.paper = paper.setup(this.canvasMap.canvas);
  85. // console.log('this.canvasMap.paper', this.canvasMap.paper);
  86. this.canvasMap.canvas.addEventListener('click', this.onCanvasClick);
  87. // MATTER
  88. let wall_w = 100;
  89. Matter.Composite.add(this.world, [
  90. // walls
  91. Matter.Bodies.rectangle(canvas_w/2, -wall_w/2, canvas_w, wall_w, { isStatic: true }), // top
  92. Matter.Bodies.rectangle(canvas_w/2, canvas_h+wall_w/2, canvas_w, wall_w, { isStatic: true }), // bottom
  93. Matter.Bodies.rectangle(-wall_w/2, canvas_h/2, wall_w, canvas_h, { isStatic: true }), // left
  94. Matter.Bodies.rectangle(canvas_w+wall_w/2, canvas_h/2, wall_w, canvas_h, { isStatic: true }), // right
  95. // make the items never goes under menus
  96. Matter.Bodies.rectangle(550, 25, 900, 50, { isStatic: true }), // menu top
  97. Matter.Bodies.rectangle(550, canvas_h-15, 900, 30, { isStatic: true }) // menu bottom
  98. ]);
  99. // add mouse control
  100. // https://github.com/liabru/matter-js/issues/491#issuecomment-331329404
  101. this.mouse = Matter.Mouse.create(this.canvasMap.canvas);
  102. this.animate()
  103. },
  104. methods: {
  105. ...mapActions(ConcernementsStore,['setMapMode']),
  106. ...mapActions(ConcernementsStore,['openCloseConcernements']),
  107. ...mapActions(ConcernementsStore,['resetConcernementOpened']),
  108. ...mapActions(CommonStore,['setHoverElmt']),
  109. animate () {
  110. Matter.Engine.update(this.engine, 1);
  111. window.requestAnimationFrame(this.animate);
  112. },
  113. onCanvasClick(event){
  114. // console.log('onCanvasClick');
  115. // use the canvas click to get back if no items is mousover
  116. if (!this.hover_elmt) {
  117. this.resetConcernementOpened();
  118. this.$router.push({
  119. name: 'home',
  120. hash: `#${this.map_mode}`
  121. });
  122. }
  123. }
  124. },
  125. beforeUpdate () {
  126. },
  127. components: {
  128. MapBackground,
  129. ConcernementMapPopup
  130. }
  131. }
  132. </script>
  133. <template>
  134. <div id="map-backgrounds">
  135. <MapBackground />
  136. </div>
  137. <div id="map-matter">
  138. <canvas ref="canvas-engine"></canvas>
  139. </div>
  140. <div id="map-concernements">
  141. <canvas ref="canvas-map"></canvas>
  142. <slot></slot>
  143. </div>
  144. <nav id="map-nav">
  145. <ul>
  146. <li>
  147. <a href="#terraindevie" @click="setMapMode('terraindevie')"><span class="icon terraindevie"></span> terrain de vie</a>
  148. </li>
  149. <li>
  150. <a href="#proximite" @click="setMapMode('proximite')"><span class="icon proximite"></span> proximité</a>
  151. </li>
  152. <li>
  153. <a href="#superposition" @click="setMapMode('superposition')"><span class="icon superposition"></span> superposition</a>
  154. </li>
  155. <li>
  156. <a href="#puissancedagir" @click="setMapMode('puissancedagir')"><span class="icon puissancedagir"></span> puissance d'agir</a>
  157. </li>
  158. <li>
  159. <a href="#action" @click="setMapMode('action')"><span class="icon action"></span> action</a>
  160. </li>
  161. <li>
  162. <a href="#doleancer" @click="setMapMode('doleancer')"><span class="icon doleancer"></span> doléancer</a>
  163. </li>
  164. </ul>
  165. </nav>
  166. <ConcernementMapPopup
  167. v-if="hover_elmt"
  168. :infos="hover_elmt"
  169. />
  170. </template>
  171. <style lang="css" scoped>
  172. </style>