From 453e07ec31d1aaad4923df09c977540d58389a23 Mon Sep 17 00:00:00 2001 From: bach Date: Wed, 24 May 2023 19:56:55 +0200 Subject: [PATCH] concernement on map hover effect, better mappopup --- src/assets/main.scss | 65 +++++++++++++++++++++++-- src/components/ConcernementMapItem.vue | 24 +++++++-- src/components/ConcernementMapPopup.vue | 58 ++++++++++++++++------ src/components/MapConcernements.vue | 24 +++++---- src/stores/common.js | 18 +++++++ 5 files changed, 157 insertions(+), 32 deletions(-) create mode 100644 src/stores/common.js diff --git a/src/assets/main.scss b/src/assets/main.scss index d39566a..23b21cd 100644 --- a/src/assets/main.scss +++ b/src/assets/main.scss @@ -112,13 +112,68 @@ body{ #map-popup{ position: absolute; + z-index: 10; + // outline: 1px solid red; // top:0; // left: 0; - background-color: white; - padding: 1em; - h1{ - font-size: 1em; - font-weight: 400; + + .popup-content-wrapper{ + background-color: white; + padding: 1em; + border-radius: 3px; + // min-width: 10em; + // max-width: 30em; + h1{ + font-size: 1em; + font-weight: 400; + } } + + &:before{ + content: ""; + display: block; + height: 0; + width: 2.9em; + border-top: 1px solid #01ffe2; + position: absolute; + } + + &[pos="top-right"]{ + padding: 0 0 2em 2em; + &:before{ + bottom: 0; + left: 0; + transform-origin: 0 0; + transform: rotate(-45deg); + } + } + &[pos="bottom-right"]{ + padding: 2em 0 0 2em; + &:before{ + top: 0; + left: 0; + transform-origin: 0 0; + transform: rotate(45deg); + } + } + &[pos="top-left"]{ + padding: 0 2em 2em 0; + &:before{ + bottom: 0; + right: 0; + transform-origin: right bottom; + transform: rotate(45deg); + } + } + &[pos="bottom-left"]{ + padding: 2em 2em 0 0; + &:before{ + top: 0; + right: 0; + transform-origin: right top; + transform: rotate(-45deg); + } + } + } } diff --git a/src/components/ConcernementMapItem.vue b/src/components/ConcernementMapItem.vue index c1f8a29..a4837fb 100644 --- a/src/components/ConcernementMapItem.vue +++ b/src/components/ConcernementMapItem.vue @@ -27,6 +27,7 @@ import Tween from "@tweenjs/tween.js"; import { mapState, mapActions } from 'pinia' import { ConcernementsStore } from '@/stores/concernements' +import { CommonStore } from '@/stores/common' export default { inject: ['canvasMap', 'matterEngine'], @@ -49,14 +50,16 @@ export default { tween: null, body: null, body_parts: [], - constraint: null + constraint: null, + isHover: false } }, props: ['concernement', 'opened'], computed: { ...mapState(ConcernementsStore,['map_mode']), ...mapState(ConcernementsStore,['concernementsByID']), - ...mapState(ConcernementsStore,['opened_entite_id']) + ...mapState(ConcernementsStore,['opened_entite_id']), + ...mapState(CommonStore,['hover_elmt']) }, created () { // console.log(`ConcernementsMapItem ${this.concernement.id} created`, this.canvasMap, this.matterEngine); @@ -115,6 +118,17 @@ export default { } }, deep: true + }, + hover_elmt: { + handler (n, o) { + console.log('watch hover_elmt', o, n); + if (n && n.type === 'concernement' && n.id === this.id) { + this.isHover = true; + } else { + this.isHover = false; + } + }, + deep: true } }, methods: { @@ -725,14 +739,18 @@ export default { drawContour(){ if (this.salientPoints.length > 3) { var fillStyle; + let strokeStyle = "#000"; if (!this.isFocused()){ fillStyle = "rgba(255,255,255,0.3)"; }else{ fillStyle = "rgba(255,255,255,0.8)" + if (this.isHover) { + strokeStyle = "#01ffe2"; + } } this.ctx.beginPath(); this.ctx.lineWidth = 1; - this.ctx.strokeStyle = "#000"; + this.ctx.strokeStyle = strokeStyle; this.ctx.fillStyle = fillStyle; this.ctx.moveTo(this.pos.x+this.salientPoints[0].pos.x*this.scale*1.15, this.pos.y+this.salientPoints[0].pos.y*this.scale*1.15) for (let j = 1; j < this.salientPoints.length; j++) { diff --git a/src/components/ConcernementMapPopup.vue b/src/components/ConcernementMapPopup.vue index 61d5aa5..5a0b50a 100644 --- a/src/components/ConcernementMapPopup.vue +++ b/src/components/ConcernementMapPopup.vue @@ -57,8 +57,35 @@ export default { methods: { onMousemove(e){ // 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`; + let v = "top"; + let h = "right"; + if (e.clientX + this.dom.clientWidth > document.body.clientWidth) { + h = "left"; + } else { + h = "right"; + } + if (e.clientY - this.dom.clientHeight < 0) { + v = "bottom"; + } else { + v = "top"; + } + this.dom.setAttribute("pos", `${v}-${h}`); + switch (h) { + case "right": + this.dom.style.left = `${e.clientX}px`; + break; + case "left": + this.dom.style.left = `${e.clientX - this.dom.clientWidth}px`; + break; + } + switch (v) { + case "top": + this.dom.style.top = `${e.clientY - this.dom.clientHeight}px`; + break; + case "bottom": + this.dom.style.top = `${e.clientY}px`; + break; + } } }, components: { @@ -69,18 +96,21 @@ export default { diff --git a/src/components/MapConcernements.vue b/src/components/MapConcernements.vue index 48548f1..ad20fef 100644 --- a/src/components/MapConcernements.vue +++ b/src/components/MapConcernements.vue @@ -29,6 +29,7 @@ Matter.use(MatterAttractors); import { mapState, mapActions } from 'pinia' import { ConcernementsStore } from '@/stores/concernements' +import { CommonStore } from '@/stores/common' import ConcernementMapPopup from '@components/ConcernementMapPopup.vue'; @@ -61,7 +62,8 @@ export default { ...mapState(ConcernementsStore,['map_mode']), ...mapState(ConcernementsStore,['concernements']), ...mapState(ConcernementsStore,['concernementsByID']), - ...mapState(ConcernementsStore,['opened']) + ...mapState(ConcernementsStore,['opened']), + ...mapState(CommonStore,['hover_elmt']) }, created() { // MATTER @@ -109,6 +111,7 @@ export default { ...mapActions(ConcernementsStore,['setMapMode']), ...mapActions(ConcernementsStore,['openCloseConcernements']), ...mapActions(ConcernementsStore,['resetConcernementOpened']), + ...mapActions(CommonStore,['setHoverElmt']), animate () { this.canvasMap.ctx.clearRect(0, 0, this.canvasMap.canvas.width, this.canvasMap.canvas.height) // this.canvasMap.canvas.dispatchEvent(this.animateEvent) @@ -132,7 +135,7 @@ export default { query = Matter.Query.point(this.world.bodies, this.mouse.position) } - this.mapPopupData = null; + let hover_elmt = null; if (query && query.length) { // if we have a results for (let body of query) { @@ -140,7 +143,7 @@ export default { && 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 = { + hover_elmt = { type: 'concernement', id: body.id }; @@ -148,14 +151,14 @@ export default { 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 = { + hover_elmt = { type: 'entite', id: body.id }; } if (body.item_type === "besoin" // if it is a besoin && this.opened) { // if a concernement is opened - this.mapPopupData = { + hover_elmt = { type: 'besoin', id: body.id }; @@ -163,15 +166,16 @@ export default { if (body.item_type === "reponse" // if it is a besoin && this.opened) { // if a concernement is opened - this.mapPopupData = { + hover_elmt = { type: 'reponse', id: body.id }; } } - // console.log(`this.mapPopupData type: ${this.mapPopupData.type}, id: ${this.mapPopupData.id}`); + // console.log(`hover_elmt type: ${hover_elmt.type}, id: ${hover_elmt.id}`); } - if (this.mapPopupData) { + this.setHoverElmt(hover_elmt); + if (hover_elmt) { document.body.style.cursor = "pointer"; } else { document.body.style.cursor = "auto"; @@ -293,8 +297,8 @@ export default { diff --git a/src/stores/common.js b/src/stores/common.js new file mode 100644 index 0000000..21e1633 --- /dev/null +++ b/src/stores/common.js @@ -0,0 +1,18 @@ +import { defineStore } from 'pinia' + +export const CommonStore = defineStore({ + id: 'common', + state: () => ({ + hover_elmt: null + }), + getters: { + + }, + actions: { + setHoverElmt(elmt) { + console.log(`setHoverElmt ${elmt}`); + // mode can be : terraindevie, proximite, superposition, puissancedagir, action, doleancer + this.hover_elmt = elmt; + } + } +}) \ No newline at end of file