resizing window is working

This commit is contained in:
Bachir Soussi Chiadmi 2024-01-30 16:51:40 +01:00
parent 7607fc0e23
commit 40dbbb2384
5 changed files with 360 additions and 79 deletions

View File

@ -15,7 +15,8 @@ body{
}
#app{
min-width: 1280px;
min-height: 800px;
}
#app>header#header{

View File

@ -127,6 +127,8 @@ export default {
// this.setConcernementMapItem(this.cid, this);
// this.setConcernementScale(this.cid, this.scale);
this.mapitem.scale = this.scale;
// window.addEventListener('resize', this.onWindowResize.bind(this));
},
// mounted() {
// console.log(`ConcernementsMapItem ${this.concernement.id} mounted`, this.canvasMap.canvas);
@ -255,6 +257,16 @@ export default {
// }
},
deep: true
},
// window as been resized
map_item_ray: {
handler (n, o) {
console.log(`map_item_ray updated o: ${o}, n: ${n}`);
this.ray = n;
this.updateMatterBodyRay();
this.updatePaperObjectSize(n,o);
},
deep: true
}
},
methods: {
@ -465,25 +477,19 @@ export default {
let entite_range = [3, 100];
let ray_range = [this.ray*0.8,this.ray*1.2];
let ray = ray_range[0] + (this.entites.length - entite_range[0]) * (ray_range[1] - ray_range[0]) / (entite_range[1] - entite_range[0]);
this.body_parts = [
Matter.Bodies.circle(0, 0, ray, {
// item_type: 'concernement',
// id: this.concernement.id,
})
];
// this.body_parts = [
// Matter.Bodies.circle(0, 0, ray)
// ];
// INFO map a range of numbers to another range of numbers https://stackoverflow.com/a/46462321
let mass_range = [5,15];
let mass = mass_range[0] + (this.entites.length - entite_range[0]) * (mass_range[1] - mass_range[0]) / (entite_range[1] - entite_range[0]);
// create the body
this.body = Matter.Body.create({
parts: this.body_parts,
this.body = Matter.Bodies.circle(0, 0, ray, {
item_type: 'concernement',
id: this.id,
frictionAir: 0,
// mass: Math.pow(3, this.entites.length),
// mass: 10,
mass: mass,
restitution: 0.06,
collisionFilter: {
@ -520,7 +526,51 @@ export default {
// }
]
}
});
})
// this.body = Matter.Body.create({
// parts: this.body_parts,
// item_type: 'concernement',
// id: this.id,
// frictionAir: 0,
// // mass: Math.pow(3, this.entites.length),
// // mass: 10,
// mass: mass,
// restitution: 0.06,
// collisionFilter: {
// group: -1
// },
// plugin: {
// attractors: [
// // // there is a built in helper function for Newtonian gravity!
// // // you can find out how it works in index.js
// MatterAttractors.Attractors.gravity
// // function(bodyA, bodyB) {
// // var force = {
// // x: (bodyA.position.x - bodyB.position.x) * 1e-6,
// // y: (bodyA.position.y - bodyB.position.y) * 1e-6
// // }
// // // apply force to both bodies
// // Matter.Body.applyForce(bodyA, bodyA.position, force);
// // Matter.Body.applyForce(bodyB, bodyB.position, Matter.Vector.neg(force));
// // }
// // INFO https://github.com/liabru/matter-attractors/blob/master/build/matter-attractors.js#L192
// // function (bodyA, bodyB){
// // // use Newton's law of gravitation
// // var bToA = Matter.Vector.sub(bodyB.position, bodyA.position),
// // distanceSq = Matter.Vector.magnitudeSquared(bToA) || 0.0001,
// // normal = Matter.Vector.normalise(bToA),
// // magnitude = -MatterAttractors.Attractors.gravityConstant * (bodyA.mass * bodyB.mass / distanceSq),
// // force = Matter.Vector.mult(normal, magnitude);
// // // to apply forces to both bodies
// // Matter.Body.applyForce(bodyA, bodyA.position, Matter.Vector.neg(force));
// // Matter.Body.applyForce(bodyB, bodyB.position, force);
// // }
// ]
// }
// });
Matter.Body.setPosition(this.body, this.pos);
// add init velocity
@ -543,6 +593,17 @@ export default {
y: -delta + Math.random()*delta*2
});
},
updateMatterBodyRay(){
console.log('updateMatterBodyRay',this.ray, this.body);
let entite_range = [3, 100];
let ray_range = [this.ray*0.8,this.ray*1.2];
let new_ray = ray_range[0] + (this.entites.length - entite_range[0]) * (ray_range[1] - ray_range[0]) / (entite_range[1] - entite_range[0]);
let old_ray = this.body.circleRadius;
let scale = new_ray/old_ray;
Matter.Body.scale(this.body, scale, scale);
// Matter.Body.set(this.body, 'circleRadius', ray);
console.log(`this.body circleRadius ${this.body.circleRadius}`);
},
// PAPER OBJECTS
initPaperObjects(){
@ -580,8 +641,51 @@ export default {
// this.addNewPaperSymbolInstance('doleance_icon', false, 0.7);
// }
this.initPaperEvents()
},
async updatePaperObjectSize(n,o){
await nextTick();
// INFO we redraw the points with the new ray AND sacle the backgrounds ... would it be simplier to only resize the whole mapitem ???
// window has been resized
// if open
if (this.is_open) {
// move to the new position
// INFO we need to change position first for the contours to be redraw in the right place
this.pos = this.paper_main_object.position = {
x: (this.canvas.width - this.cartouch_width) / 2,
y: this.canvas.height / 2
};
this.constraint.pointA = this.pos;
Matter.Body.setPosition(this.body, this.pos);
// reset the paper contents with paper symbols redrew by MapConcernements.vue
this.setPaperContents();
// scale
// let s = this.getOpeningAvailableScale();
// this.paper_main_object.scale(1 / this.scale);
// this.paper_main_object.scale(s);
}
// in any case
// delet the old contours
let clearables = ['contours'];
clearables.forEach(child_name => {
if (this.paper_main_object.children[child_name]) {
this.paper_main_object.children[child_name].remove();
}
});
// rebuild the contours with the new ray
this.parseEntityPointsValues()
this.sailentEntites = this.concernement.sailentEntites = this.getJarvisEnvelopeConvexeEntites(this.entites)
// redraw the contours
this.paper_main_object.addChild(this.setPaperContour());
},
/*
* called by openClose() function
*/
@ -650,7 +754,6 @@ export default {
addNewPaperSymbolInstance(name, back, scale){
let instance = new paper.SymbolItem(this.paper_symbol_definitions[name]); // , {x:0,y:0}
instance.name = name;
// instance.pivot = new paper.Point({x:0,y:0});
instance.position = this.pos;
let s = scale ? this.scale * scale : this.scale;
instance.scale(s);
@ -2003,6 +2106,16 @@ export default {
}, 100);
},
// OPEN / CLOSE (with tween)
getOpeningAvailableScale(){
// calcul opened size regarding window size and surounding contents
let header = document.querySelector('header#header');
let header_height = header.clientHeight;
let map_nav = document.querySelector('nav#map-nav');
let map_nav_height = map_nav.clientHeight;
let s_h = (this.canvas.height - header_height - map_nav_height) / (this.ray*2*1.15);
let s_w = (this.canvas.width - this.cartouch_width) / (this.ray*2*1.7);
return Math.min(s_h, s_w)
},
openClose(open) { // async
// await nextTick(); // not working
console.log(`ConcernementsMapItem ${this.id} openClose: ${open}`);
@ -2015,14 +2128,7 @@ export default {
this.setPaperContents();
this.handlePaperVisibilityOnBeforeOpen();
// calcul opened size regarding window size and surounding contents
let header = document.querySelector('header#header');
let header_height = header.clientHeight;
let map_nav = document.querySelector('nav#map-nav');
let map_nav_height = map_nav.clientHeight;
let s_h = (this.canvas.height - header_height - map_nav_height) / (this.ray*2*1.15);
let s_w = (this.canvas.width - this.cartouch_width) / (this.ray*2*1.7);
let s = Math.min(s_h, s_w)
let s = this.getOpeningAvailableScale();
// create once the opening tweening
this.tween = new Tween.Tween({s: this.scale, x: this.pos.x, y: this.pos.y, o: 0})
@ -2074,8 +2180,7 @@ export default {
// record new scale
this.prev_scale = this.scale;
this.scale = obj.s;
this.mapitem.scale = this.scale;
this.scale = this.mapitem.scale = obj.s;
this.opacity = obj.o;
// console.log('tween update obj.s', obj.s);
this.pos = {x:obj.x, y:obj.y};
@ -2448,7 +2553,10 @@ export default {
// apply a force in direction of one side or an other depending of the start position
// the force is exponentialy inversed proportional to the distance from the side
// INFO logarithmic force : https://stackoverflow.com/questions/846221/logarithmic-slider/846249#846249
// TODO cartouch width should change regarding actual cartouch is opened or not (and how many cartouch are opened)
// cartouch width should change regarding actual cartouch is opened or not (and how many cartouch are opened)
// TODO force is proportional to window size
// X
let pseudo_center_x = this.opened_concernement
? (this.canvas.width - this.cartouch_width) / 2
@ -2545,15 +2653,17 @@ export default {
}
},
respawn() {
checkOverflow() {
// respawn element if outside screen
let respanw = false;
if(this.pos.x <= 0){ this.pos.x = 50; respanw=true;}
if(this.pos.x >= this.canvas.width){ this.pos.x = this.canvas.width - 50; respanw=true;}
if(this.pos.y <= 0){ this.pos.y = 50; respanw=true;}
if(this.pos.y >= this.canvas.height){ this.pos.y = this.canvas.height - 50; respanw=true;}
if (respanw) {
// this.pos = respanw_pos;
let pad = 1;
let circleray = this.body.circleRadius+pad*1.1;
let respawn = false;
if(this.pos.x <= pad){ this.pos.x = circleray; respawn=true;}
if(this.pos.x >= this.canvas.width-pad){ this.pos.x = this.canvas.width - circleray; respawn=true;}
if(this.pos.y <= pad){ this.pos.y = circleray; respawn=true;}
if(this.pos.y >= this.canvas.height-pad){ this.pos.y = this.canvas.height - circleray; respawn=true;}
if (respawn) {
// this.pos = respawn_pos;
Matter.Body.setPosition(this.body, {x:this.pos.x, y:this.pos.y});
// this.setInitBodyVelocity();
Matter.Body.setVelocity(this.body, {x:0,y:0});
@ -2561,7 +2671,7 @@ export default {
},
onAfterEngineUpdate (event) {
this.respawn();
this.checkOverflow();
this.paper_main_object.position = this.pos = this.body.position;
@ -2576,7 +2686,32 @@ export default {
this.handlePaperVisibilityOnAfterEnginUpdate()
// DEBUG
// this.debugDrawMatterBodyCircle();
// END DEBUG
},
// onWindowResize(event){
// // console.log('mapitem onWindowResize', event, this);
// },
debugDrawMatterBodyCircle(){
if (this.paper_main_object.children['debug_circle']) {
this.paper_main_object.children['debug_circle'].remove();
}
let debugcircle = new paper.Path.Circle({
center: this.pos,
// radius: this.ray,
radius: this.body.circleRadius,
strokeColor: '#f00',
strokeWidth: 1,
name: 'debug_circle'
})
this.paper_main_object.addChild(debugcircle)
}
},
render() {
// console.log('render()', this.ctx);

View File

@ -12,6 +12,7 @@ export default {
mounted() {
this.initGradients()
this.initTrame()
window.addEventListener("resize", this.onWindowResize.bind(this));
},
// computed: {
// },
@ -116,6 +117,8 @@ export default {
canvasBackgroundTrame.height = canvasBackgroundTrame.parentElement.clientHeight;
let ctx = canvasBackgroundTrame.getContext('2d');
ctx.clearRect(0,0, canvasBackgroundTrame.width, canvasBackgroundTrame.height);
let step = 1;
for (let i = 0; i < parseInt(canvasBackgroundTrame.width); i+=step) {
for (let j = 0; j < parseInt(canvasBackgroundTrame.height); j+=step) {
@ -130,6 +133,9 @@ export default {
}
},
onWindowResize () {
this.initTrame()
}
}
}

View File

@ -39,6 +39,7 @@ export default {
// MATTER
engine: null,
world: null,
walls: null,
// PAPERJS
paper: null,
//
@ -129,22 +130,14 @@ export default {
}.bind(this);
// MATTER
let wall_w = 1000;
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
]);
this.buildMatterWalls();
// add mouse control
// https://github.com/liabru/matter-js/issues/491#issuecomment-331329404
// this.mouse = Matter.Mouse.create(this.canvasMap.canvas);
window.addEventListener("resize", this.onWindowResize.bind(this));
this.animate()
},
watch: {
@ -275,30 +268,128 @@ export default {
...mapActions(ConcernementsStore,['setMapMode',
'resetConcernementOpened']),
...mapActions(CommonStore,['addPaperSymbolDefinition',
'setHoverElmt']),
'setHoverElmt',
'updateMapItemRay']),
animate () {
// if (document.hasFocus()) {
Matter.Engine.update(this.engine, 1);
// }
window.requestAnimationFrame(this.animate);
},
initPaperSymbols(){
buildMatterWalls(){
console.log('buildMatterWalls');
// remove old walls if exists
let oldWallsBody = Matter.Composite.get(this.world, 'walls', 'body');
if (oldWallsBody) {
console.log('buildMatterWalls oldWallsBody', oldWallsBody);
Matter.Composite.remove(this.world, oldWallsBody);
}
console.log('buildMatterWalls oldWallsBody after remove', Matter.Composite.get(this.world, 'walls', 'body'));
// create walls
let canvas_w = this.canvasMap.canvas.width;
let canvas_h = this.canvasMap.canvas.height;
console.log(`buildMatterWalls canvas_w: ${canvas_w}, canvas_h: ${canvas_h}`);
let length = 10000; // set a length long enought that we don't have to redimmension it when window resize
let thickness = 1000;
let pad = 1;
let wallsParts = [
// walls
// Matter.Bodies.rectangle(x, y, width, height, [options])
Matter.Bodies.rectangle(canvas_w/2, -thickness/2 +pad, length, thickness, { label: 'top_wall'}), // top
Matter.Bodies.rectangle(canvas_w/2, canvas_h+thickness/2 -pad, length, thickness, { label: 'bottom_wall'}), // bottom
Matter.Bodies.rectangle(-thickness/2 +pad, canvas_h/2, thickness, length, { label: 'left_wall'}), // left
Matter.Bodies.rectangle(canvas_w+thickness/2 -pad, canvas_h/2, thickness, length, { label: 'right_wall'}), // right
// make the items never goes under menus
// Matter.Bodies.rectangle(500, 25, 1000, 50, { label: 'menutop_wall'}), // menu top
// Matter.Bodies.rectangle(500, canvas_h-15, 1000, 30, { label: 'menubottom_wall'}) // menu bottom
];
this.walls = Matter.Body.create({
parts: wallsParts,
id: 'walls',
isStatic: true
});
Matter.Composite.add(this.world, this.walls);
console.log('buildMatterWalls this.walls', this.walls);
},
updateMatterWalls(){
let canvas_w = this.canvasMap.canvas.width;
let canvas_h = this.canvasMap.canvas.height;
console.log(`buildMatterWalls canvas_w: ${canvas_w}, canvas_h: ${canvas_h}`);
let thickness = 1000;
let pad = 10;
this.walls.parts.forEach((p, i) =>{
// console.log('p.label', p.label);
let pos = false;
switch (p.label) {
case 'top_wall':
pos = Matter.Vector.create(canvas_w/2, -thickness/2 +pad)
break;
case 'bottom_wall':
pos = Matter.Vector.create(canvas_w/2, canvas_h+thickness/2 -pad)
break;
case 'left_wall':
pos = Matter.Vector.create(-thickness/2 +pad, canvas_h/2)
break;
case 'right_wall':
pos = Matter.Vector.create(canvas_w+thickness/2 -pad, canvas_h/2)
break;
case 'menutop_wall':
pos = Matter.Vector.create(500, 25)
break;
case 'menubottom_wall':
pos = Matter.Vector.create(500, canvas_h-15)
break;
}
if(pos){
Matter.Body.setPosition(p, pos);
}
})
},
onWindowResize(e){
// console.log('onWindowResize', e);
// get the new size
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}`);
// apply to paper env
// paper.view.viewSize.width = canvas_w;
// paper.view.viewSize.height = canvas_h;
this.paper.view.viewSize = new paper.Size(canvas_w, canvas_h);
// apply to matter env
// this.buildMatterWalls();
this.updateMatterWalls();
// resize the base item ray, this will trigger all the map_items to resize in nextTick()
this.updateMapItemRay();
// rebuild all the paper symbols with new ray
this.initPaperSymbols(true)
},
initPaperSymbols(update){
this.addPaperSymbolDefinition('boussole_bg', this.setPaperBoussoleBGSymbol());
this.addPaperSymbolDefinition('puissanceagir_bg', this.setPaperPuissanceagirBGSymbol());
// this.addPaperSymbolDefinition('puissanceagir_icon', this.setPaperPuissanceagirICONSymbol());
this.addPaperSymbolDefinition('doleance_bg', this.setPaperDoleanceBGSymbol());
// this.addPaperSymbolDefinition('doleance_icon', this.setPaperDoleanceICONSymbol());
//
this.addPaperSymbolDefinition('entite', this.setPaperEntiteSymbol());
this.addPaperSymbolDefinition('entite_hidden', this.setPaperHiddenEntiteSymbol());
this.addPaperSymbolDefinition('entite_hover', this.setPaperEntiteHoverSymbol());
this.addPaperSymbolDefinition('entite_action_icon', this.setPaperEntiteActionIconSymbol());
this.addPaperSymbolDefinition('entite_action', this.setPaperEntiteActionSymbol());
this.addPaperSymbolDefinition('entite_action_hover', this.setPaperEntiteActionHoverSymbol());
this.addPaperSymbolDefinition('besoin', this.setPaperBesoinSymbol());
this.addPaperSymbolDefinition('besoin_hover', this.setPaperBesoinHoverSymbol());
this.addPaperSymbolDefinition('reponse', this.setPaperReponseSymbol());
this.addPaperSymbolDefinition('reponse_hover', this.setPaperReponseHoverSymbol());
if (!update) {
this.addPaperSymbolDefinition('entite', this.setPaperEntiteSymbol());
this.addPaperSymbolDefinition('entite_hidden', this.setPaperHiddenEntiteSymbol());
this.addPaperSymbolDefinition('entite_hover', this.setPaperEntiteHoverSymbol());
this.addPaperSymbolDefinition('entite_action_icon', this.setPaperEntiteActionIconSymbol());
this.addPaperSymbolDefinition('entite_action', this.setPaperEntiteActionSymbol());
this.addPaperSymbolDefinition('entite_action_hover', this.setPaperEntiteActionHoverSymbol());
this.addPaperSymbolDefinition('besoin', this.setPaperBesoinSymbol());
this.addPaperSymbolDefinition('besoin_hover', this.setPaperBesoinHoverSymbol());
this.addPaperSymbolDefinition('reponse', this.setPaperReponseSymbol());
this.addPaperSymbolDefinition('reponse_hover', this.setPaperReponseHoverSymbol());
}
},
setPaperBoussoleBGSymbol(){
// BOUSSOLE
@ -317,32 +408,48 @@ export default {
}));
// cercles
for (let i = 1; i < 9; i++) {
let sw = i === 4 || i === 8 ? 0.25 : 0.1; // width
let da = i === 4 || i === 8 ? null : [5,5]; // dash array
if (!da) { // draw only 2 main non-dashed circles
children.push(new paper.Path.Circle({
center: [pos.x, pos.y],
radius: ray/8*i,
strokeColor: '#fff',
strokeWidth: sw,
dashArray: da
}));
}
}
// for (let i = 1; i < 9; i++) {
// let sw = i === 4 || i === 8 ? 0.25 : 0.1; // width
// let da = i === 4 || i === 8 ? null : [5,5]; // dash array
// if (!da) { // draw only 2 main non-dashed circles
// children.push(new paper.Path.Circle({
// center: [pos.x, pos.y],
// radius: ray/8*i,
// strokeColor: '#fff',
// strokeWidth: sw,
// dashArray: da
// }));
// }
// }
// cercle exterieur
let ext_circle_factor = 0.915;
children.push(new paper.Path.Circle({
center: [pos.x, pos.y],
radius: ray*ext_circle_factor,
strokeColor: '#fff',
strokeWidth: 0.25
}));
// cercle interieur
children.push(new paper.Path.Circle({
center: [pos.x, pos.y],
radius: ray*0.51,
strokeColor: '#fff',
strokeWidth: 0.25
}));
// axes
// vertical
children.push(new paper.Path.Line({
from: [pos.x, pos.y - ray],
to: [pos.x, pos.y + ray],
from: [pos.x, pos.y - ray*ext_circle_factor],
to: [pos.x, pos.y + ray*ext_circle_factor],
strokeColor: '#fff',
strokeWidth: 0.25
}));
// horizontal
children.push(new paper.Path.Line({
from: [pos.x - ray, pos.y],
to: [pos.x + ray, pos.y],
from: [pos.x - ray*ext_circle_factor, pos.y],
to: [pos.x + ray*ext_circle_factor, pos.y],
strokeColor: '#fff',
strokeWidth: 0.25
}))
@ -351,9 +458,9 @@ export default {
// haute
children.push(new paper.Path({
segments: [
[pos.x - 8, pos.y - ray + 8],
[pos.x, pos.y - ray],
[pos.x + 8, pos.y - ray + 8],
[pos.x - 8, pos.y - ray*ext_circle_factor + 8],
[pos.x, pos.y - ray*ext_circle_factor],
[pos.x + 8, pos.y - ray*ext_circle_factor + 8],
],
strokeWidth: 0.25,
strokeColor: '#fff',
@ -1284,6 +1391,7 @@ export default {
onAfterEngineUpdate(){
// // START OF DEBUGGING
// this.debugDrawConstraints()
// this.debugDrawWalls()
// // END OF DEBUGGING
},
debugDrawConstraints(){
@ -1312,6 +1420,34 @@ export default {
}));
}
constraints_lines.addChildren(children);
},
debugDrawWalls(){
let wall_rects = this.paper.project.getItem({name: 'wall_rects', class: paper.Group});
if (wall_rects) {
wall_rects.removeChildren();
}else{
wall_rects = new paper.Group({
pivot: new paper.Point({x:0,y:0}),
name: 'wall_rects',
});
}
let wallsbody = Matter.Composite.get(this.world, 'walls', 'body');
if (wallsbody) {
// console.log('wallsbody', wallsbody.parts);
let children = [];
wallsbody.parts.forEach((part, i) => {
if(i > 0){
// console.log('part', part.label, part.bounds.min);
children.push(new paper.Path.Rectangle({
from: part.bounds.min,
to: part.bounds.max,
strokeColor: '#00f',
strokeWidth: 2
}));
}
});
wall_rects.addChildren(children);
}
}
},
beforeUpdate () {

View File

@ -33,7 +33,10 @@ export const CommonStore = defineStore({
// console.log(`addPaperSymbolDefinition ${name}`, path);
// mode can be : terraindevie, proximite, superposition, puissancedagir, action, doleancer
this.paper_symbol_definitions[name] = new paper.SymbolDefinition(path);
},
updateMapItemRay(){
console.log('Common Store updateMapItemRay');
this.map_item_ray = Math.min(window.innerWidth, window.innerHeight) * 0.08;
}
}
})