123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- <script>
- // import { mapActions, mapState } from 'pinia'
- import { computed } from 'vue'
- import MapBackground from '@components/MapBackground.vue'
- // https://brm.io/matter-js/docs/classes/Engine.html
- import Matter from "matter-js";
- import MatterAttractors from "matter-attractors";
- Matter.use(MatterAttractors);
- import paper from 'paper';
- import { mapState, mapActions } from 'pinia'
- import { ConcernementsStore } from '@/stores/concernements'
- import { CommonStore } from '@/stores/common'
- import ConcernementMapPopup from '@components/ConcernementMapPopup.vue';
- export default {
- data() {
- return {
- canvasMap: {
- canvas: null,
- ctx: null
- },
- animateEvent: new Event('animate'),
- granim: null,
- // MATTER
- engine: null,
- world: null,
- // PAPERJS
- paper: null,
- //
- mapPopupData: null,
- }
- },
- provide() {
- // https://www.digitalocean.com/community/tutorials/vuejs-vue-html5-canvas
- return {
- // explicitly provide a computed property
- canvasMap: computed(() => this.canvasMap),
- matterEngine: computed(() => this.engine)
- }
- },
- computed: {
- ...mapState(ConcernementsStore,['map_mode']),
- ...mapState(ConcernementsStore,['concernements']),
- ...mapState(ConcernementsStore,['concernementsByID']),
- ...mapState(ConcernementsStore,['opened']),
- ...mapState(CommonStore,['hover_elmt'])
- },
- created() {
- // MATTER
- // create an engine
- let engineOptions = {
- enableSleeping: true,
- timing: {
- //timestamp: 0.5,
- timeScale: 0.5
- }
- }
- this.engine = Matter.Engine.create(engineOptions);
- this.engine.gravity.scale = 0;
- this.world = this.engine.world;
- },
- mounted() {
- this.canvasMap.canvas = this.$refs['canvas-map'];
- this.canvasMap.ctx = this.canvasMap.canvas.getContext('2d');
- let canvas_w = this.canvasMap.canvas.width = this.canvasMap.canvas.parentElement.clientWidth;
- let canvas_h = this.canvasMap.canvas.height = this.canvasMap.canvas.parentElement.clientHeight;
- console.log(`canvas_w: ${canvas_w}, canvas_h: ${canvas_h}`);
- this.paper = paper.setup(this.canvasMap.canvas);
- // // use the paper.view click to get back if no items is clicked
- this.paper.view.onClick = function(event) {
- console.log("view onClick", this, event.target);
- if(event.target._id === "paper-view-0") {
- this.resetConcernementOpened();
- this.$router.push({
- name: 'home',
- hash: `#${this.map_mode}`
- });
- }
- }.bind(this);
- // MATTER
- let wall_w = 100;
- Matter.Composite.add(this.world, [
- // walls
- Matter.Bodies.rectangle(canvas_w/2, -wall_w/2, canvas_w, wall_w, { isStatic: true }), // top
- Matter.Bodies.rectangle(canvas_w/2, canvas_h+wall_w/2, canvas_w, wall_w, { isStatic: true }), // bottom
- Matter.Bodies.rectangle(-wall_w/2, canvas_h/2, wall_w, canvas_h, { isStatic: true }), // left
- Matter.Bodies.rectangle(canvas_w+wall_w/2, canvas_h/2, wall_w, canvas_h, { isStatic: true }), // right
- // make the items never goes under menus
- Matter.Bodies.rectangle(550, 25, 900, 50, { isStatic: true }), // menu top
- Matter.Bodies.rectangle(550, canvas_h-15, 900, 30, { isStatic: true }) // menu bottom
- ]);
- // add mouse control
- // https://github.com/liabru/matter-js/issues/491#issuecomment-331329404
- // this.mouse = Matter.Mouse.create(this.canvasMap.canvas);
- this.animate()
- },
- watch: {
- hover_elmt: {
- handler (n, o) {
- // console.log(`watch hover_elmt map`, o, n);
- // over highlight effect on paper items
- if (n && n.paper_id) {
- let nitem = paper.project.getItem({id: n.paper_id});
- nitem.bringToFront();
- if (nitem.strokeColor) {
- nitem.data.prevStrokeColor = nitem.strokeColor.toCSS(true);
- nitem.strokeColor = "#01ffe2";
- } else {
- nitem.data.prevFillColor = nitem.fillColor.toCSS(true);
- nitem.fillColor = "#01ffe2";
- }
- }
- if (o && o.paper_id) {
- let oitem = paper.project.getItem({id: o.paper_id})
- if (oitem.data.prevStrokeColor) {
- oitem.strokeColor = oitem.data.prevStrokeColor;
- } else {
- oitem.fillColor = oitem.data.prevFillColor;
- }
- }
- },
- deep: true
- }
- },
- methods: {
- ...mapActions(ConcernementsStore,['setMapMode']),
- ...mapActions(ConcernementsStore,['openCloseConcernements']),
- ...mapActions(ConcernementsStore,['resetConcernementOpened']),
- ...mapActions(CommonStore,['setHoverElmt']),
- animate () {
- Matter.Engine.update(this.engine, 1);
- window.requestAnimationFrame(this.animate);
- },
- },
- beforeUpdate () {
- },
- components: {
- MapBackground,
- ConcernementMapPopup
- }
- }
- </script>
- <template>
- <div id="map-backgrounds">
- <MapBackground />
- </div>
- <div id="map-matter">
- <canvas ref="canvas-engine"></canvas>
- </div>
- <div id="map-concernements">
- <canvas ref="canvas-map"></canvas>
- <slot></slot>
- </div>
- <nav id="map-nav">
- <ul>
- <li>
- <a href="#terraindevie" @click="setMapMode('terraindevie')"><span class="icon terraindevie"></span> terrain de vie</a>
- </li>
- <li>
- <a href="#proximite" @click="setMapMode('proximite')"><span class="icon proximite"></span> proximité</a>
- </li>
- <li>
- <a href="#superposition" @click="setMapMode('superposition')"><span class="icon superposition"></span> superposition</a>
- </li>
- <li>
- <a href="#puissancedagir" @click="setMapMode('puissancedagir')"><span class="icon puissancedagir"></span> puissance d'agir</a>
- </li>
- <li>
- <a href="#action" @click="setMapMode('action')"><span class="icon action"></span> action</a>
- </li>
- <li>
- <a href="#doleancer" @click="setMapMode('doleancer')"><span class="icon doleancer"></span> cercle politique</a>
- </li>
- </ul>
- </nav>
- <ConcernementMapPopup
- v-if="hover_elmt && hover_elmt.type !== 'doleance_step'"
- :infos="hover_elmt"
- />
- </template>
- <style lang="css" scoped>
- </style>
|