scaling body on click with easing

This commit is contained in:
Bachir Soussi Chiadmi 2023-03-29 21:49:45 +02:00
parent 4727333dd6
commit a74fe1d9b5
5 changed files with 79 additions and 23 deletions

11
package-lock.json generated
View File

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

View File

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

View File

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

View File

@ -19,10 +19,10 @@
// } from "matter-js"; // } from "matter-js";
import Matter from "matter-js"; import Matter from "matter-js";
import MatterAttractors from "matter-attractors"; import MatterAttractors from "matter-attractors";
// Matter.use(MatterAttractors); // Matter.use(MatterAttractors);
import { easeInOutQuad, easeInOutQuart } from 'easing-utils';
import { mapState, mapActions } from 'pinia' import { mapState, mapActions } from 'pinia'
import { ConcernementsStore } from '@/stores/concernements' import { ConcernementsStore } from '@/stores/concernements'
@ -42,12 +42,12 @@ export default {
time: 0, time: 0,
salientPoints: [], salientPoints: [],
scale: 1, scale: 1,
oldScale: 1, anim: null,
// matter // matter
body: null body: null
} }
}, },
props: ['concernement'], props: ['concernement', 'opened'],
computed: { computed: {
...mapState(ConcernementsStore,['concernementsByID']) ...mapState(ConcernementsStore,['concernementsByID'])
}, },
@ -75,6 +75,29 @@ export default {
} }
}, },
deep: true 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: { methods: {
@ -117,12 +140,13 @@ export default {
}); });
// console.log('concernementItem mass', this.body.mass); // console.log('concernementItem mass', this.body.mass);
Matter.Composite.add(this.matterEngine.world, this.body); Matter.Composite.add(this.matterEngine.world, this.body);
console.log('concernement body', this.body);
} }
// // listen for animate event dispatched from parent // // listen for animate event dispatched from parent
// this.canvas.addEventListener('animate', this.animate) // this.canvas.addEventListener('animate', this.animate)
// listen for afterUpdate event from Matter.Engine object // 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 (){ parsePoints (){
// converts data (menace/maintien, actuel/future, prise) into atcual position x,y // converts data (menace/maintien, actuel/future, prise) into atcual position x,y
@ -187,10 +211,39 @@ export default {
} }
// console.log(`this.salientPoints ${this.concernement.id}`, this.salientPoints); // console.log(`this.salientPoints ${this.concernement.id}`, this.salientPoints);
}, },
animate (event) { scaleBody(scale){
if (this.ctx) { // scale vertices
this.pos = this.body.position; 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() { render() {
@ -198,17 +251,7 @@ export default {
if (!this.ctx) return; if (!this.ctx) return;
this.scale = this.concernement.opened ? 5 : 1; this.pos = this.body.position;
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)
}
// exterieur circle // exterieur circle
this.ctx.beginPath(); this.ctx.beginPath();
@ -257,7 +300,7 @@ export default {
this.ctx.fillText(this.concernement.id, this.pos.x, this.pos.y) this.ctx.fillText(this.concernement.id, this.pos.x, this.pos.y)
this.ctx.fill(); this.ctx.fill();
this.oldScale = this.scale;
}, },
} }

View File

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