Browse Source

scaling body on click with easing

bach 1 year ago
parent
commit
a74fe1d9b5
5 changed files with 79 additions and 23 deletions
  1. 11 0
      package-lock.json
  2. 1 0
      package.json
  3. 1 0
      src/App.vue
  4. 65 22
      src/components/ConcernementMapItem.vue
  5. 1 1
      src/stores/concernements.js

+ 11 - 0
package-lock.json

@@ -11,6 +11,7 @@
         "@csstools/normalize.css": "^12.0.0",
         "@material-design-icons/svg": "^0.14.2",
         "@mdi/font": "^7.1.96",
+        "easing-utils": "^1.0.0",
         "granim": "^2.0.0",
         "matter-attractors": "^0.1.6",
         "matter-js": "^0.19.0",
@@ -688,6 +689,11 @@
         "node": ">=6.0.0"
       }
     },
+    "node_modules/easing-utils": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/easing-utils/-/easing-utils-1.0.0.tgz",
+      "integrity": "sha512-9oabISTqjTJSZyu85nJMfYtlV2tT/Uwo0M3uqODrBWCxme0eyLqEXRuG2/uYpyqzc7iSHjV/KW2mEKTqhdtESA=="
+    },
     "node_modules/esbuild": {
       "version": "0.15.18",
       "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz",
@@ -3071,6 +3077,11 @@
         "esutils": "^2.0.2"
       }
     },
+    "easing-utils": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/easing-utils/-/easing-utils-1.0.0.tgz",
+      "integrity": "sha512-9oabISTqjTJSZyu85nJMfYtlV2tT/Uwo0M3uqODrBWCxme0eyLqEXRuG2/uYpyqzc7iSHjV/KW2mEKTqhdtESA=="
+    },
     "esbuild": {
       "version": "0.15.18",
       "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz",

+ 1 - 0
package.json

@@ -11,6 +11,7 @@
     "@csstools/normalize.css": "^12.0.0",
     "@material-design-icons/svg": "^0.14.2",
     "@mdi/font": "^7.1.96",
+    "easing-utils": "^1.0.0",
     "granim": "^2.0.0",
     "matter-attractors": "^0.1.6",
     "matter-js": "^0.19.0",

+ 1 - 0
src/App.vue

@@ -55,6 +55,7 @@ export default {
         v-for="(concernement,id) in concernementsByID"
         :key="id"
         :concernement="concernement"
+        :opened="concernement.opened"
       />
     </MapConcernements>
     <div id="content" class="row">

+ 65 - 22
src/components/ConcernementMapItem.vue

@@ -19,10 +19,10 @@
 // } from "matter-js";
 
 import Matter from "matter-js";
-
 import MatterAttractors from "matter-attractors";
 // Matter.use(MatterAttractors);
 
+import { easeInOutQuad, easeInOutQuart } from 'easing-utils';
 
 import { mapState, mapActions } from 'pinia'
 import { ConcernementsStore } from '@/stores/concernements'
@@ -42,12 +42,12 @@ export default {
       time: 0,
       salientPoints: [],
       scale: 1,
-      oldScale: 1,
+      anim: null,
       // matter
       body: null
     }
   },
-  props: ['concernement'],
+  props: ['concernement', 'opened'],
   computed: {
     ...mapState(ConcernementsStore,['concernementsByID'])
   },
@@ -75,6 +75,29 @@ export default {
         }
       },
       deep: true
+    },
+    opened: {
+      handler (n, o) {
+        if(n){
+          // opened
+          this.anim = {
+            init: this.scale,
+            target: 5, //target scale
+            start: Date.now(),
+            duration: 1000 // ms 
+          }
+        }else{
+          // closed
+          this.anim = {
+            init: this.scale,
+            target: 1, //target scale
+            start: Date.now(),
+            duration: 1000 // ms 
+          }
+        }
+        console.log(`watch opened ${this.concernement.id}`, n, o, this.anim);
+      },
+      deep: true
     }
   },
   methods: {
@@ -117,12 +140,13 @@ export default {
           });
         // console.log('concernementItem mass', this.body.mass);
         Matter.Composite.add(this.matterEngine.world, this.body);
+        console.log('concernement body', this.body);
       }
 
       // // listen for animate event dispatched from parent
       // this.canvas.addEventListener('animate', this.animate)
       // listen for afterUpdate event from Matter.Engine object
-      Matter.Events.on(this.matterEngine, "afterUpdate", this.animate)
+      Matter.Events.on(this.matterEngine, "afterUpdate", this.onAfterEngineUpdate)
     },
     parsePoints (){
       // converts data (menace/maintien, actuel/future, prise) into atcual position x,y
@@ -187,29 +211,48 @@ export default {
       }
       // console.log(`this.salientPoints ${this.concernement.id}`, this.salientPoints);
     },
-    animate (event) {
-      if (this.ctx) {
-        this.pos = this.body.position;
+    scaleBody(scale){
+      // scale vertices
+      Matter.Vertices.scale(this.body.parts[0].vertices, scale, scale);
+      // update properties
+      // this.body.parts[0].axes = Matter.Axes.fromVertices(this.body.parts[0].vertices);
+      // update bounds
+      // Matter.Bounds.update(this.body.parts[0].bounds, this.body.parts[0].vertices, this.body.velocity);
+      this.body.circleRadius *= scale;
+    },
+    onAfterEngineUpdate (event) {
+      
+      if (this.anim) {
+        let time = Date.now() - this.anim.start; // get time elapsed since anime start
+        if (time <= this.anim.duration) {
+          let ease = easeInOutQuart(time / this.anim.duration); // get the easing factor
+          let scale = this.anim.init < this.anim.target 
+            ? this.anim.init + this.anim.target * ease 
+            : this.anim.init + (this.anim.target - this.anim.init) * ease; // get the current eased scale
+          // // https://github.com/liabru/matter-js/issues/986#issuecomment-812488873
+          // // revert to the original size (by reverting the previous scale)
+          Matter.Body.scale(this.body, 1 / this.scale, 1 / this.scale)
+          // this.scaleBody(1 / this.scale)
+          // // then scale again to new scale
+          Matter.Body.scale(this.body, scale, scale)
+          // this.scaleBody(scale);
+          // record new scale
+          this.scale = scale;
+        }else{
+          this.anim = null;
+        }
+      
       }
+
     }
   },
   render() {
     // console.log('render()', this.ctx);
-    
+
     if (!this.ctx) return;
     
-    this.scale = this.concernement.opened ? 5 : 1;
-
-    if (this.scale !== this.oldScale) {
-      // https://github.com/liabru/matter-js/issues/986#issuecomment-812488873
-      // revert to the original size (by reverting the previous scale)
-      Matter.Body.scale(this.body, 1 / this.oldScale, 1 / this.oldScale)
-      // then scale again
-      Matter.Body.scale(this.body, this.scale, this.scale)
-    }
-
-
-
+    this.pos = this.body.position;
+      
     // exterieur circle
     this.ctx.beginPath();
     this.ctx.lineWidth = 0.5;
@@ -256,8 +299,8 @@ export default {
     this.ctx.fillStyle = "#000";
     this.ctx.fillText(this.concernement.id, this.pos.x, this.pos.y)
     this.ctx.fill();
-
-    this.oldScale = this.scale;
+    
+    
   },
 }
 

+ 1 - 1
src/stores/concernements.js

@@ -45,7 +45,7 @@ export const ConcernementsStore = defineStore({
       })
     },
     openCloseConcernement (id, state) {
-      console.log('openCloseConcernement', id, state);
+      // console.log('openCloseConcernement', id, state);
       this.concernementsByID[id].opened = state;
     }
   }