enites as matter body and popup display on mouse over entites
This commit is contained in:
parent
a940012b6e
commit
a2ae70ef48
@ -104,7 +104,7 @@ body{
|
||||
}
|
||||
}
|
||||
|
||||
#concernement-map-popup{
|
||||
#map-popup{
|
||||
position: absolute;
|
||||
// top:0;
|
||||
// left: 0;
|
||||
|
@ -32,6 +32,7 @@ export default {
|
||||
inject: ['canvasMap', 'matterEngine'],
|
||||
data() {
|
||||
return {
|
||||
entities: null,
|
||||
// concernement: null,
|
||||
canvas: null,
|
||||
ctx: null,
|
||||
@ -58,6 +59,7 @@ export default {
|
||||
created () {
|
||||
// console.log("ConcernementsMapItem concernement", this.canvasMap, this.matterEngine);
|
||||
this.entites = this.concernement.entites
|
||||
this.entites_byid = this.concernement.entites_byid
|
||||
this.parsePoints()
|
||||
this.getSalientPoints()
|
||||
},
|
||||
@ -82,16 +84,11 @@ export default {
|
||||
},
|
||||
opened: {
|
||||
handler (n, o) {
|
||||
if(n){
|
||||
console.log('concernement item opened');
|
||||
// opened
|
||||
if(n){ // opened
|
||||
this.openClose(true);
|
||||
}else{
|
||||
console.log('concernement item closed');
|
||||
// closed
|
||||
}else{ // closed
|
||||
this.openClose(false)
|
||||
}
|
||||
console.log(`watch opened ${this.concernement.id}`, n, o, this.anim);
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
@ -105,6 +102,10 @@ export default {
|
||||
|
||||
// define init position of the item
|
||||
this.pos = this.getRandomPos();
|
||||
//
|
||||
this.initMatterBody()
|
||||
},
|
||||
initMatterBody (){
|
||||
|
||||
// MATTER
|
||||
// create the matter body and add it to the engine
|
||||
@ -114,12 +115,38 @@ export default {
|
||||
// https://github.com/liabru/matter-attractors/issues/8
|
||||
// https://github.com/liabru/matter-attractors/blob/master/index.js
|
||||
// MatterAttractors.Attractors.gravityConstant = -5;
|
||||
this.body = Matter.Bodies.circle(this.pos.x, this.pos.y, this.ray, {
|
||||
|
||||
// Create parts of the body : main big circle & entities
|
||||
var parts = [
|
||||
Matter.Bodies.circle(0, 0, this.ray, {
|
||||
item_type: 'concernement',
|
||||
id: this.concernement.id,
|
||||
})
|
||||
];
|
||||
for (let i = 0; i < this.entites.length; i++) {
|
||||
// parts.push(Matter.Bodies.circle(this.pos.x+this.entites[i].display.pos.x, this.pos.y+this.entites[i].display.pos.y, 15, {
|
||||
// item_type: 'entite',
|
||||
// id: this.entites[i].id
|
||||
// }))
|
||||
parts.push(Matter.Bodies.circle(this.entites[i].display.pos.x, this.entites[i].display.pos.y, 2, {
|
||||
item_type: 'entite',
|
||||
id: this.entites[i].entite.id,
|
||||
isSensor: true
|
||||
}))
|
||||
}
|
||||
|
||||
// create the body
|
||||
this.body = Matter.Body.create({
|
||||
parts: parts,
|
||||
item_type: 'concernement',
|
||||
id: this.concernement.id,
|
||||
frictionAir: 0,
|
||||
// mass: Math.pow(3, this.entites.length),
|
||||
mass: 10,
|
||||
restitution: 0.4,
|
||||
id: this.concernement.id,
|
||||
collisionFilter: {
|
||||
group: -1
|
||||
},
|
||||
plugin: {
|
||||
attractors: [
|
||||
// there is a built in helper function for Newtonian gravity!
|
||||
@ -128,8 +155,10 @@ export default {
|
||||
]
|
||||
}
|
||||
});
|
||||
let delta = 10;
|
||||
Matter.Body.setPosition(this.body, this.pos);
|
||||
|
||||
// add init velocity
|
||||
let delta = 10;
|
||||
Matter.Body.setVelocity(this.body, {
|
||||
x: -delta + Math.random()*delta*2,
|
||||
y: -delta + Math.random()*delta*2
|
||||
@ -137,14 +166,14 @@ 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, "beforeUpdate", this.onBeforeEngineUpdate);
|
||||
Matter.Events.on(this.matterEngine, "afterUpdate", this.onAfterEngineUpdate);
|
||||
}
|
||||
|
||||
// // 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, "beforeUpdate", this.onBeforeEngineUpdate)
|
||||
Matter.Events.on(this.matterEngine, "afterUpdate", this.onAfterEngineUpdate);
|
||||
},
|
||||
getRandomPos(){
|
||||
return {
|
||||
@ -167,8 +196,13 @@ export default {
|
||||
// slope = (output_end - output_start) / (input_end - input_start)
|
||||
// output = output_start + slope * (input - input_start)
|
||||
// from range 0 -> 100 to range 0 -> this.ray
|
||||
let slope = this.ray / 100
|
||||
this.entites[i].display.ray = slope * (100 - entite.prise);
|
||||
let init_max = 100
|
||||
let slope = this.ray / init_max
|
||||
this.entites[i].display.ray = slope * (init_max - entite.prise);
|
||||
// if (this.concernement.id === 28) {
|
||||
// console.log(`entity prise: ${entite.prise} | ray: ${this.entites[i].display.ray}`);
|
||||
// }
|
||||
|
||||
|
||||
// ANGLE
|
||||
// -90 <= mm <= 90
|
||||
@ -187,6 +221,8 @@ export default {
|
||||
x: this.entites[i].display.ray * Math.cos(this.entites[i].display.alpha * (Math.PI/180)),
|
||||
y: this.entites[i].display.ray * Math.sin(this.entites[i].display.alpha * (Math.PI/180))
|
||||
}
|
||||
|
||||
this.entites_byid[entite.entite.id].display = this.entites[i].display;
|
||||
}
|
||||
},
|
||||
getSalientPoints () {
|
||||
@ -309,7 +345,8 @@ export default {
|
||||
this.ctx.beginPath();
|
||||
this.ctx.lineWidth = 2;
|
||||
this.ctx.strokeStyle = `rgba(255,255,255,${this.opacity})`;
|
||||
this.ctx.arc(this.pos.x, this.pos.y, this.ray*this.scale, 0, 2 * Math.PI, false);
|
||||
// external circle is %8 less than max ray = (*0.92)
|
||||
this.ctx.arc(this.pos.x, this.pos.y, this.ray*this.scale*0.92, 0, 2 * Math.PI, false);
|
||||
// this.ctx.stroke();
|
||||
|
||||
// interieur circle
|
||||
@ -327,9 +364,9 @@ export default {
|
||||
|
||||
// fleches
|
||||
// haute
|
||||
this.ctx.moveTo(this.pos.x - (8*this.scale), this.pos.y - this.ray*this.scale + (8*this.scale));
|
||||
this.ctx.lineTo(this.pos.x, this.pos.y - this.ray*this.scale);
|
||||
this.ctx.lineTo(this.pos.x + (8*this.scale), this.pos.y - this.ray*this.scale + (8*this.scale));
|
||||
this.ctx.moveTo(this.pos.x - (8*this.scale), this.pos.y - this.ray*this.scale*0.92 + (8*this.scale));
|
||||
this.ctx.lineTo(this.pos.x, this.pos.y - this.ray*this.scale*0.92);
|
||||
this.ctx.lineTo(this.pos.x + (8*this.scale), this.pos.y - this.ray*this.scale*0.92 + (8*this.scale));
|
||||
// milieu
|
||||
this.ctx.moveTo(this.pos.x - (8*this.scale), this.pos.y + (8*this.scale));
|
||||
this.ctx.lineTo(this.pos.x, this.pos.y);
|
||||
@ -380,10 +417,26 @@ export default {
|
||||
let entite = this.entites[i];
|
||||
// console.log('entite', entite);
|
||||
this.ctx.beginPath();
|
||||
this.ctx.arc(this.pos.x+entite.display.pos.x*this.scale, this.pos.y+entite.display.pos.y*this.scale, 2, 0, 2 * Math.PI, false);
|
||||
this.ctx.fillStyle = "#000";
|
||||
this.ctx.fill();
|
||||
this.ctx.arc(this.pos.x+entite.display.pos.x*this.scale, this.pos.y+entite.display.pos.y*this.scale, 5, 0, 2 * Math.PI, false);
|
||||
this.ctx.strokeStyle = "#F00";
|
||||
this.ctx.stroke();
|
||||
}
|
||||
// OR
|
||||
for (let i = 0; i < this.body.parts.length; i++) {
|
||||
// let entite = this.entites[i];
|
||||
if (this.body.parts[i].item_type === 'entity') {
|
||||
let part = this.body.parts[i];
|
||||
// console.log('part', part);
|
||||
// console.log(`part pos x:${part.position.x} y:${part.position.y} || entity pos x:${this.pos.x+this.entites_byid[part.id].display.pos.x*this.scale} y:${this.pos.y+this.entites_byid[part.id].display.pos.y*this.scale}`);
|
||||
this.ctx.beginPath();
|
||||
// this.ctx.arc(this.pos.x+entite.display.pos.x*this.scale, this.pos.y+entite.display.pos.y*this.scale, 2, 0, 2 * Math.PI, false);
|
||||
this.ctx.arc(this.body.parts[i].position.x, this.body.parts[i].position.y, 2*this.scale, 0, 2 * Math.PI, false);
|
||||
this.ctx.strokeStyle = "#000";
|
||||
this.ctx.stroke();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// concernement id @center
|
||||
|
@ -7,28 +7,48 @@ import { ConcernementsStore } from '@/stores/concernements'
|
||||
|
||||
export default {
|
||||
name: 'concernementMapPopup',
|
||||
props: ['id'],
|
||||
props: ['infos'],
|
||||
data() {
|
||||
return {
|
||||
dom: null,
|
||||
concernement: null
|
||||
type: null,
|
||||
concernement: null,
|
||||
entite: null
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.concernement = this.concernementsByID[this.id];
|
||||
// console.log(`popup created type: ${this.infos.type}`);
|
||||
if (this.infos.type === 'concernement') {
|
||||
this.concernement = this.concernementsByID[this.infos.id];
|
||||
} else {
|
||||
this.entite = this.allEntitesById[this.infos.id];
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// console.log('APP onMounted')
|
||||
this.dom = this.$refs['concernement-map-popup'];
|
||||
this.dom = this.$refs['map-popup'];
|
||||
window.addEventListener('mousemove', this.onMousemove);
|
||||
},
|
||||
computed: {
|
||||
...mapState(ConcernementsStore,['concernements']),
|
||||
...mapState(ConcernementsStore,['concernementsByID'])
|
||||
...mapState(ConcernementsStore,['concernementsByID']),
|
||||
...mapState(ConcernementsStore,['allEntitesById'])
|
||||
},
|
||||
watch: {
|
||||
infos: {
|
||||
handler (n, o){
|
||||
if (n.type === 'concernement') {
|
||||
this.concernement = this.concernementsByID[n.id];
|
||||
} else {
|
||||
this.entite = this.allEntitesById[n.id];
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onMousemove(e){
|
||||
// console.log('popup mousemove', e, this.dom);
|
||||
// console.log(`popup move type: ${this.infos.type}`);
|
||||
this.dom.style.left = `${e.clientX + 5}px`;
|
||||
this.dom.style.top = `${e.clientY - this.dom.clientHeight - 5}px`;
|
||||
}
|
||||
@ -40,8 +60,13 @@ export default {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="concernement-map-popup" ref="concernement-map-popup">
|
||||
<h1>{{ concernement.title }}</h1>
|
||||
<div id="map-popup" ref="map-popup">
|
||||
<section v-if="infos.type === 'concernement'" class="concernement-map-popup">
|
||||
<h1>{{ concernement.title }}</h1>
|
||||
</section>
|
||||
<section v-if="infos.type === 'entite'" class="entite-map-popup">
|
||||
<h1>alors ? {{ entite.entite.title }}</h1>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -46,7 +46,7 @@ export default {
|
||||
world: null,
|
||||
// render: null,
|
||||
mouse: null,
|
||||
concernementpopupid: null
|
||||
mapPopupData: null,
|
||||
}
|
||||
},
|
||||
provide() {
|
||||
@ -59,7 +59,8 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
...mapState(ConcernementsStore,['concernements']),
|
||||
...mapState(ConcernementsStore,['concernementsByID'])
|
||||
...mapState(ConcernementsStore,['concernementsByID']),
|
||||
...mapState(ConcernementsStore,['opened'])
|
||||
},
|
||||
created() {
|
||||
// MATTER
|
||||
@ -105,6 +106,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
...mapActions(ConcernementsStore,['openCloseConcernement']),
|
||||
...mapActions(ConcernementsStore,['resetConcernementOpened']),
|
||||
animate () {
|
||||
this.canvasMap.ctx.clearRect(0, 0, this.canvasMap.canvas.width, this.canvasMap.canvas.height)
|
||||
// this.canvasMap.canvas.dispatchEvent(this.animateEvent)
|
||||
@ -113,16 +115,45 @@ export default {
|
||||
},
|
||||
onMouseMove (e) {
|
||||
// check concernement item mouse over
|
||||
const query = Matter.Query.point(Matter.Composite.allBodies(this.world), this.mouse.position)
|
||||
// console.log('mousemove query', query);
|
||||
if (query.length) {
|
||||
if (typeof this.concernementsByID[query[0].id] !== "undefined" && !this.concernementsByID[query[0].id].opened) {
|
||||
this.concernementpopupid = query[0].id;
|
||||
} else {
|
||||
this.concernementpopupid = null;
|
||||
// const query = Matter.Query.point(Matter.Composite.allBodies(this.world), this.mouse.position)
|
||||
let query;
|
||||
if (this.opened) {
|
||||
// if a concernement is opened we query the opened concernement's parts (aka entitées bodies)
|
||||
const bodies = Matter.Composite.allBodies(this.world);
|
||||
for (let body of bodies) {
|
||||
if (body.item_type === "concernement" && body.id === this.opened.id) {
|
||||
query = Matter.Query.point(body.parts, this.mouse.position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
this.concernementpopupid = null;
|
||||
} else {
|
||||
// if no concernement opened we query concernements
|
||||
query = Matter.Query.point(this.world.bodies, this.mouse.position)
|
||||
}
|
||||
|
||||
this.mapPopupData = null;
|
||||
if (query && query.length) {
|
||||
// if we have a results
|
||||
for (let body of query) {
|
||||
if (!this.opened // if no concernement is opened
|
||||
&& body.item_type === "concernement" // if it is a concernement
|
||||
&& typeof this.concernementsByID[body.id] !== "undefined" // if the id exists
|
||||
&& !this.concernementsByID[body.id].opened) { // if the concernement is not opened
|
||||
this.mapPopupData = {
|
||||
type: 'concernement',
|
||||
id: body.id
|
||||
};
|
||||
}
|
||||
if (body.item_type === "entite" // if it is an entite
|
||||
&& this.opened // if a concernement is opened
|
||||
&& typeof this.opened.entites_byid[body.id] !== "undefined") { // if the entity exists
|
||||
this.mapPopupData = {
|
||||
type: 'entite',
|
||||
id: body.id
|
||||
};
|
||||
}
|
||||
}
|
||||
// console.log(`this.mapPopupData type: ${this.mapPopupData.type}, id: ${this.mapPopupData.id}`);
|
||||
}
|
||||
},
|
||||
onClick (e) {
|
||||
@ -141,7 +172,9 @@ export default {
|
||||
this.openCloseConcernement(concernement.id, clickedIDs.indexOf(concernement.id) !== -1)
|
||||
});
|
||||
// if no concernement opened retrun to home (closing concernement contents opened)
|
||||
// and reset the opened state in concernement store
|
||||
if (!clickedIDs.length) {
|
||||
this.resetConcernementOpened();
|
||||
this.$router.push({name: 'home'});
|
||||
}
|
||||
}
|
||||
@ -190,8 +223,8 @@ export default {
|
||||
</ul>
|
||||
</nav>
|
||||
<ConcernementMapPopup
|
||||
v-if="concernementpopupid"
|
||||
:id="concernementpopupid"
|
||||
v-if="mapPopupData"
|
||||
:infos="mapPopupData"
|
||||
/>
|
||||
</template>
|
||||
|
||||
|
@ -18,6 +18,7 @@ export const ConcernementsStore = defineStore({
|
||||
state: () => ({
|
||||
concernements: [],
|
||||
concernementsByID: {},
|
||||
allEntitesById: {},
|
||||
opened: false,
|
||||
ct_concernement: {}
|
||||
}),
|
||||
@ -39,9 +40,17 @@ export const ConcernementsStore = defineStore({
|
||||
GQL.post('', { query: print(ast) })
|
||||
.then(({ data : { data : { allconcernements } } }) => {
|
||||
console.log('loadconcernements loaded', allconcernements)
|
||||
this.concernements = allconcernements
|
||||
|
||||
this.concernements = [];
|
||||
allconcernements.forEach(concernement => {
|
||||
this.concernementsByID[concernement.id] = concernement
|
||||
concernement.entites_byid = {};
|
||||
concernement.entites.forEach(entite => {
|
||||
concernement.entites_byid[entite.entite.id] = entite;
|
||||
// record a flat list of all entités of all concernement for map-popup
|
||||
this.allEntitesById[entite.entite.id] = entite;
|
||||
});
|
||||
this.concernements.push(concernement);
|
||||
this.concernementsByID[concernement.id] = concernement;
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
@ -81,6 +90,9 @@ export const ConcernementsStore = defineStore({
|
||||
this.opened = this.concernementsByID[id];
|
||||
this.router.push({name: 'concernement', params: {id: id}});
|
||||
}
|
||||
},
|
||||
resetConcernementOpened () {
|
||||
this.opened = null;
|
||||
}
|
||||
}
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user