12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979 |
- <script>
- // https://brm.io/matter-js/docs/classes/Engine.html
- // import {
- // // Engine,
- // // Render,
- // // World,
- // Bodies,
- // Body,
- // Events,
- // Composite,
- // // Composites,
- // // Constraint,
- // // Vertices,
- // // Mouse,
- // // MouseConstraint,
- // // Query,
- // // Common
- // } from "matter-js";
- import Matter from "matter-js";
- import MatterAttractors from "matter-attractors";
- // Matter.use(MatterAttractors);
- // import polydecomp from "poly-decomp";
- import paper from 'paper';
- // import { easeInOutQuad, easeInOutQuart } from 'easing-utils';
- import Tween from "@tweenjs/tween.js";
- import { mapState, mapActions } from 'pinia'
- import { ConcernementsStore } from '@/stores/concernements'
- import { CommonStore } from '@/stores/common'
- import iconAction from "@/assets/icons/action.svg"
- import iconDoleancer from "@/assets/icons/doleancer.svg"
- import iconProximite from "@/assets/icons/proximite.svg"
- import iconPuissanceagir from "@/assets/icons/puissancedagir.svg"
- import iconSuperposition from "@/assets/icons/superposition.svg"
- import iconTerraindevie from "@/assets/icons/terraindevie.svg"
- export default {
- inject: ['canvasMap', 'matterEngine'],
- data() {
- return {
- id: null,
- entities: null,
- canvas: null,
- ctx: null,
- pos : {
- x: 0,
- y: 0
- },
- ray: 100,
- time: 0,
- salientPoints: [],
- scale: 1,
- prev_scale: 1,
- opacity: 0,
- tween: null,
- body: null,
- body_parts: [],
- constraint: null,
- is_hover: false,
- //
- paper_objects: {}
- }
- },
- props: ['concernement', 'is_opened'],
- computed: {
- ...mapState(ConcernementsStore,['map_mode']),
- ...mapState(ConcernementsStore,['concernementsByID']),
- ...mapState(ConcernementsStore,['opened']),
- ...mapState(ConcernementsStore,['opened_entite_id']),
- ...mapState(CommonStore,['hover_elmt'])
- },
- created () {
- // console.log(`ConcernementsMapItem ${this.concernement.id} created`, this.canvasMap, this.matterEngine);
- this.id = this.concernement.id
- this.entites = this.concernement.entites
- this.entites_byid = this.concernement.entites_byid
- // console.log(`ConcernementsMapItem ${this.concernement.id} $route`, this.id, this.$route);
- // if (this.$route.name === 'concernement'
- // && parseInt(this.$route.params.id) === this.id
- // && typeof this.$route.params.eid !== "undefined") {
- // // console.log("we have an entity");
- // this.opened_entite_id = parseInt(this.$route.params.eid);
- // }
-
- // disable concernement if less than 3 entite
- if(this.entites.length < 3){
- this.hideShowConcernement(this.concernement.id, false);
- } else{
- this.parsePoints()
- // this.getSalientPoints()
- this.getJarvisEnvelopeConvexe()
- if (this.canvasMap) {
- this.initCanvasMap()
- }
- }
- // if (this.salientPoints.length > 3) { // do not build item if it doesn't get enougth salient points
- // } else {
- // this.hideShowConcernement(this.concernement.id, false);
- // }
- },
- // mounted() {
- // console.log(`ConcernementsMapItem ${this.concernement.id} mounted`, this.canvasMap.canvas);
-
- // },
- watch: {
- // canvasMap (n, o) {
- // console.log("concernementItem watch canvasMap", o, n);
- // }
- canvasMap: {
- handler (n, o){
- // console.log("concernementItem watch canvasMap.ctx", typeof this.canvas, o, n);
- if (!this.canvas) {
- this.initCanvasMap()
- }
- },
- deep: true
- },
- is_opened: {
- handler (n, o) {
- if(n){ // opened
- this.openClose(true);
- }else{ // closed
- this.openClose(false)
- }
- },
- deep: true
- },
- map_mode: {
- handler (n, o) {
- console.log('watch map_mode', o, n);
- if (n === 'terraindevie' && !this.opened) {
- this.applyShuffleForces(); // apply a little force to check the map when returning to terrain de vie
- }
- },
- deep: true
- },
- hover_elmt: {
- handler (n, o) {
- // console.log(`watch hover_elmt ${this.id}`, o, n);
- if (n && n.type === 'concernement' && n.id === this.id) {
- this.is_hover = true;
- } else {
- this.is_hover = false;
- }
- },
- deep: true
- }
- },
- methods: {
- ...mapActions(CommonStore,['setHoverElmt']),
- ...mapActions(ConcernementsStore,['openCloseConcernements']),
- ...mapActions(ConcernementsStore,['hideShowConcernement']),
- parsePoints (){
- // converts data (menace/maintien, actuel/future, prise) into atcual position x,y
- for (let i = 0; i < this.entites.length; i++) {
- let entite = this.entites[i]
- // console.log('entite', entite);
-
- this.entites[i].display = {
- alpha: null,
- ray: null
- }
- // RAYON
- // https://stackoverflow.com/questions/5731863/mapping-a-numeric-range-onto-another
- // 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 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
- if (entite.actuelfuture) {
- // future en haut : 180 <= a <= 360
- // from -90 -> 90 to range 180 -> 360
- this.entites[i].display.alpha = entite.menacemaintien + 270
- } else {
- // actuel: en bas : O <= a <= 180
- // from -90 -> 90 to range 180 -> 0
- this.entites[i].display.alpha = -1 * entite.menacemaintien + 90
- }
- // POSITION X Y (par rapport au centre du concernement)
- this.entites[i].display.pos = {
- 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_OLD() {
- // debugger
- // console.log(this.entites);
- let arc = 360/30;
- // loop through arcs
- // for (let i = 360/arc; i >= 0 ; i--) {
- for (let i = 0; i <= 360/arc ; i++) {
- // loop through entities to find the farest on the arc
- let max_r = 0;
- let farest = null;
- for (let j = 0; j < this.entites.length; j++) {
- let entite = this.entites[j];
- if(arc*i <= entite.display.alpha && entite.display.alpha <= arc*i+arc) { // if entity is in arc
- if (entite.display.ray > max_r) { // && entite.display.ray > this.ray/2 // and farest from minimu
- // if entity is farest from precedent one
- max_r = entite.display.ray;
- // recalcul x & y to get a little padding between entite and contour by increasing ray
- farest = {
- alpha: entite.display.alpha,
- ray: entite.display.ray,
- pos: {
- x: (entite.display.ray + 3) * Math.cos(entite.display.alpha * (Math.PI/180)),
- y: (entite.display.ray + 3) * Math.sin(entite.display.alpha * (Math.PI/180))
- }
- };
- }
- }
- }
- if (farest) {
- this.salientPoints.push(farest)
- }
- }
- // console.log(`this.salientPoints ${this.concernement.id}`, this.salientPoints);
- },
- getJarvisEnvelopeConvexe(){
- console.log(`getJarvisEnvelopeConvexe ${this.id}`, this.entites.length);
- // https://www.geeksforgeeks.org/convex-hull-using-jarvis-algorithm-or-wrapping/
- // the most left point
- let l, min_x = null;
- for (let i = 0; i < this.entites.length; i++) {
- let entite = this.entites[i];
- let x = entite.display.ray * Math.cos(entite.display.alpha * (Math.PI/180));
- if(!min_x || min_x > x){
- l = i;
- min_x = x;
- }
- }
- let p = l, q;
- do {
- console.log(`do while ${this.id}`, p);
- // Add current point to result
- let entite = this.entites[p];
- let farest = {
- alpha: entite.display.alpha,
- ray: entite.display.ray,
- pos: {
- x: (entite.display.ray) * Math.cos(entite.display.alpha * (Math.PI/180)),
- y: (entite.display.ray) * Math.sin(entite.display.alpha * (Math.PI/180))
- }
- };
- this.salientPoints.push(farest);
- // Search for a point 'q' such that
- // orientation(p, q, x) is counterclockwise
- // for all points 'x'. The idea is to keep
- // track of last visited most counterclock-
- // wise point in q. If any point 'i' is more
- // counterclock-wise than q, then update q.
- q = (p + 1) % this.entites.length;
- for (let i = 0; i < this.entites.length; i++) {
- let p_x = (this.entites[p].display.ray + 3) * Math.cos(this.entites[p].display.alpha * (Math.PI/180));
- let p_y = (this.entites[p].display.ray + 3) * Math.sin(this.entites[p].display.alpha * (Math.PI/180));
- let i_x = (this.entites[i].display.ray + 3) * Math.cos(this.entites[i].display.alpha * (Math.PI/180));
- let i_y = (this.entites[i].display.ray + 3) * Math.sin(this.entites[i].display.alpha * (Math.PI/180));
- let q_x = (this.entites[q].display.ray + 3) * Math.cos(this.entites[q].display.alpha * (Math.PI/180));
- let q_y = (this.entites[q].display.ray + 3) * Math.sin(this.entites[q].display.alpha * (Math.PI/180));
-
- let val = (i_y - p_y) * (q_x - i_x) - (i_x - p_x) * (q_y - i_y);
-
- // If i is more counterclockwise than current q, then update q
- if (val > 0){
- q = i;
- }
- }
- // Now q is the most counterclockwise with
- // respect to p. Set p as q for next iteration,
- // so that q is added to result 'hull'
- p = q;
- } while (p != l);
- },
- initCanvasMap (){
- // console.log(`ConcernementsMapItem ${this.concernement.id} initCanvasMap`);
- // record canvas and ctx for rendering (drawing)
- this.canvas = this.canvasMap.canvas
- this.ctx = this.canvasMap.ctx
- // this.paper = this.canvasMap.paper
- // define init position of the item
- this.pos = this.getRandomPos();
- //
- this.initMatterBody()
- //
- this.initPaperObjects()
- },
- getRandomPos(){
- let pad = 200;
- return {
- x: pad + this.ray/2 + Math.random()*(this.canvas.width - this.ray - pad),
- y: pad + this.ray/2 + Math.random()*(this.canvas.height - this.ray - pad)
- };
- },
- initMatterBody (){
-
- // MATTER
- // create the matter body and add it to the engine
- if (!this.body) {
- // console.log('concernementItem creating body');
- // https://github.com/liabru/matter-attractors/issues/8
- // https://github.com/liabru/matter-attractors/blob/master/index.js
- // MatterAttractors.Attractors.gravityConstant = -5;
-
- // Create parts of the body : main big circle & entities
- this.body_parts = [
- Matter.Bodies.circle(0, 0, this.ray, {
- item_type: 'concernement',
- id: this.concernement.id,
- })
- ];
- // Create parts of the body : entities
- 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
- // }))
- this.body_parts.push(Matter.Bodies.circle(this.entites[i].display.pos.x, this.entites[i].display.pos.y, 0.8, {
- item_type: 'entite',
- id: this.entites[i].entite.id,
- cid: this.concernement.id,
- agissante: this.entites[i].entite.agissante,
- isSensor: true
- }))
- }
-
- // Create parts of the body : besoins and responses
- this.createBesoinsBodyParts();
-
- // create the body
- this.body = Matter.Body.create({
- parts: this.body_parts,
- item_type: 'concernement',
- id: this.concernement.id,
- frictionAir: 0,
- // mass: Math.pow(3, this.entites.length),
- mass: 10,
- restitution: 0.15,
- 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
- ]
- }
- });
- Matter.Body.setPosition(this.body, this.pos);
- // add init velocity
- this.setInitBodyVelocity()
- // 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);
- }
- },
- setInitBodyVelocity(){
- let delta = 10;
- Matter.Body.setVelocity(this.body, {
- x: -delta + Math.random()*delta*2,
- y: -delta + Math.random()*delta*2
- });
- },
- createBesoinsBodyParts(){
- let res_fields = ['qui','quoi','ou','avec'];
- let arc = (360 / 16); // unit arc
- let r = (this.ray * this.scale)/5; // unit ray
- let br = r - r/3; // besoin ray
- for (let i = 0; i < this.concernement.besoins.length; i++) {
- let start_a = arc * i; // angle depart (for reponses)
- let center_a = start_a + arc/2; // angle central
- let x = Math.cos(center_a*(Math.PI/180)) * br;
- let y = Math.sin(center_a*(Math.PI/180)) * br;
- this.body_parts.push(Matter.Bodies.circle(x, y, 0.8, {
- item_type: 'besoin',
- id: this.concernement.besoins[i].id,
- cid: this.concernement.id,
- isSensor: true
- }));
- let res_arc = arc / (1 + this.concernement.besoins[i].reponses.length); // unit arc for responses depending responses number
- for (let j = 0; j < this.concernement.besoins[i].reponses.length; j++) {
- let res_a = start_a + res_arc * (j+1); // angle for response line
- for (let f = 0; f < res_fields.length; f++) { // loop through all 4 fields, keep only the last one filled
- if( this.concernement.besoins[i].reponses[j][res_fields[f]] // if field filled
- && (f === res_fields.length -1 || !this.concernement.besoins[i].reponses[j][res_fields[f+1]]) // and is last field or last field filled
- ){
- let rr = this.ray * this.scale - r*f - r/2; // reponse field ray
- let rx = Math.cos(res_a*(Math.PI/180)) * rr;
- let ry = Math.sin(res_a*(Math.PI/180)) * rr;
-
- this.body_parts.push(Matter.Bodies.circle(rx, ry, 0.8, {
- item_type: 'reponse',
- // field: res_fields[f],
- id: this.concernement.besoins[i].reponses[j].id,
- bid: this.concernement.besoins[i].id,
- cid: this.concernement.id,
- isSensor: true
- }));
- }
- }
- }
- }
- },
- // PAPER OBJECTS
- initPaperObjects(){
- this.paper_objects = new paper.Group({
- pivot: new paper.Point(this.pos),
- cid: this.id
- });
- this.paper_objects.addChild(this.setPaperBoussoleBG());
- this.paper_objects.addChild(this.setPaperContour());
- this.paper_objects.addChild(this.setPaperEntites());
- if (this.concernement.has_puissancedagir) {
- this.paper_objects.addChild(this.setPaperPuissanceagirBG());
- this.paper_objects.addChild(this.setPaperPuissanceagirICON());
- this.paper_objects.addChild(this.setPaperPuissanceagirBesoins());
- }
- if (this.concernement.has_agissantes) {
- this.paper_objects.addChild(this.setPaperAgissantes());
- }
- if (this.concernement.has_doleance) {
- this.paper_objects.addChild(this.setPaperDoleanceBG());
- this.paper_objects.addChild(this.setPaperDoleanceICON());
- this.paper_objects.addChild(this.setPaperDoleanceSteps());
- }
- console.log(`initPaperObjects ${this.id}`, this.paper_objects);
- this.initPaperEvents()
- },
- setPaperBoussoleBG(){
- // BOUSSOLE
- let children = [];
- let ray = this.ray*0.92*this.scale;
- // // // exterieur circle
- // children.push(new paper.Path.Circle({
- // center: [this.pos.x, this.pos.y],
- // radius: ray,
- // strokeWidth: 2
- // }));
- // // interieur circle
- // children.push(new paper.Path.Circle({
- // center: [this.pos.x, this.pos.y],
- // radius: this.ray/2*this.scale,
- // strokeWidth: 2
- // }));
- // cercles pointillés
- for (let i = 1; i < 9; i++) {
- let sw = i === 4 || i === 8 ? 2 : 1;
- let da = i === 4 || i === 8 ? null : [5,5];
- children.push(new paper.Path.Circle({
- center: [this.pos.x, this.pos.y],
- radius: ray/8*i,
- strokeColor: '#fff',
- strokeWidth: sw,
- dashArray: da
- }));
-
- }
- // axes
- // vertical
- children.push(new paper.Path.Line({
- from: [this.pos.x, this.pos.y - ray],
- to: [this.pos.x, this.pos.y + ray],
- strokeColor: '#fff',
- strokeWidth: 2
- }));
- // horizontal
- children.push(new paper.Path.Line({
- from: [this.pos.x - ray, this.pos.y],
- to: [this.pos.x + ray, this.pos.y],
- strokeColor: '#fff',
- strokeWidth: 2
- }))
-
- // fleches
- // haute
- children.push(new paper.Path({
- segments: [
- [this.pos.x - (8*this.scale), this.pos.y - ray + (8*this.scale)],
- [this.pos.x, this.pos.y - ray],
- [this.pos.x + (8*this.scale), this.pos.y - ray + (8*this.scale)],
- ],
- strokeWidth: 2,
- strokeColor: '#fff',
- }));
- // milieu
- children.push(new paper.Path({
- segments: [
- [this.pos.x - (8*this.scale), this.pos.y + (8*this.scale)],
- [this.pos.x, this.pos.y],
- [this.pos.x + (8*this.scale), this.pos.y + (8*this.scale)],
- ],
- strokeWidth: 2,
- strokeColor: '#fff',
- }));
- // MOINS - PLUS
- // PLUS
- // horizontal
- children.push(new paper.Path.Line({
- from: [this.pos.x + ray - (5 * this.scale), this.pos.y - ray],
- to: [this.pos.x + ray + (5 * this.scale), this.pos.y - ray],
- strokeWidth: 8,
- strokeColor: '#fff',
- }))
- // vertical
- children.push(new paper.Path.Line({
- from: [this.pos.x + ray, this.pos.y - ray - (5 * this.scale)],
- to: [this.pos.x + ray, this.pos.y - ray + (5 * this.scale)],
- strokeWidth: 8,
- strokeColor: '#fff',
- }))
-
- // MOINS
- // horizontal
- children.push(new paper.Path.Line({
- from: [this.pos.x - ray - (5 * this.scale), this.pos.y - ray],
- to: [this.pos.x - ray + (5 * this.scale), this.pos.y - ray],
- strokeWidth: 8,
- strokeColor: '#fff',
- }))
- let fontsize = 4;
-
- children.push(new paper.PointText({
- point: [this.pos.x + 4.5, this.pos.y - ray - 5],
- content: `entités qui menacent \u2194 entités qui maintiennent`,
- fontSize: fontsize,
- justification: 'center',
- fillColor: '#000',
- }))
- children.push(new paper.PointText({
- point: [this.pos.x - ray - 5, this.pos.y + 1],
- content: "axe d'intensité",
- fontSize: fontsize,
- justification: 'right',
- fillColor: '#000',
- }))
- children.push(new paper.PointText({
- point: [this.pos.x + ray + 5, this.pos.y - 4],
- content: "situation future",
- fontSize: fontsize,
- justification: 'left',
- fillColor: '#000',
- }))
- children.push(new paper.PointText({
- point: [this.pos.x + ray + 5, this.pos.y + 6],
- content: "situation actuelle",
- fontSize: fontsize,
- justification: 'left',
- fillColor: '#000',
- }))
- let t1 = new paper.PointText({
- point: [this.pos.x - ray/8*2.3, this.pos.y - ray/8*2.3],
- content: "avec prise",
- fontSize: fontsize,
- justification: 'center',
- fillColor: '#000',
- })
- t1.rotate(-45)
- children.push(t1)
- let t2 = new paper.PointText({
- point: [this.pos.x - ray/8*2.95, this.pos.y - ray/8*2.95],
- content: "sans prise",
- fontSize: fontsize,
- justification: 'center',
- fillColor: '#000',
- })
- t2.rotate(-45)
- children.push(t2)
- return new paper.Group({
- children: children,
- pivot: new paper.Point(this.pos),
- name: 'boussole_bg',
- locked: true,
- });
- },
- setPaperContour(){
- let getPaddedRoundedSegments = (b,a,c) => {
- const ac = { x: c.x - a.x, y: c.y - a.y } // get ac vecteur
- const lac = Math.sqrt(Math.pow(ac.x, 2) + Math.pow(ac.y, 2)); // get ac longueur ac
- const ab = { x: b.x - a.x, y: b.y - a.y } // get ab vecteur
- const lab = Math.sqrt(Math.pow(ab.x, 2) + Math.pow(ab.y, 2)); // get ab longeur
- const vab = { x: ab.x/lab, y: ab.y/lab } // get unit vecteur ab
- const an = { x: vab.x*lac, y: vab.y*lac } // get an vecteur
- const n = { x: a.x + an.x, y: a.y+an.y } // get n point
- const m = { x: (c.x + n.x)/2, y: (c.y + n.y)/2 } // get nc midle point
- const ma = { x:a.x - m.x, y: a.y - m.y } // get ma vecteur
- const lma = Math.sqrt(Math.pow(ma.x, 2)+Math.pow(ma.y, 2)) // get longeur m->a
- const vma = { x: ma.x/lma, y: ma.y / lma } // get ma vecteur unitaire
- const pad = 4; // exterior padding
- // the final padded point
- const pa = [
- this.pos.x+(a.x+vma.x*pad)*this.scale,
- this.pos.y+(a.y+vma.y*pad)*this.scale
- ]
-
- // handles
- const delta = 0.25;
- // handle IN
- const hli = Math.abs(lab)*delta; // handle longeur
- const vnai = { x: -vma.y, y: vma.x } // get the ma normal unit vector IN
- const hai = [ vnai.x*hli, vnai.y*hli ]; // get the handleIn point
- // handle OUT
- const hlo = Math.abs(lac)*delta; // handle longeur
- const vnao = { x: vma.y, y: -vma.x } // get the ma normal vector Out
- const hao = [ vnao.x*hlo, vnao.y*hlo ]; // get the handleOut point
- return new paper.Segment({
- point: pa,
- // handleIn: hai,
- // handleOut: hao
- })
- }
- const first_point = getPaddedRoundedSegments(
- this.salientPoints[this.salientPoints.length-1].pos,
- this.salientPoints[0].pos,
- this.salientPoints[1].pos
- );
- let segments = [first_point];
- for (let j = 1; j < this.salientPoints.length-1; j++) {
- // segments.push([this.pos.x+this.salientPoints[j].pos.x*this.scale*gap, this.pos.y+this.salientPoints[j].pos.y*this.scale*gap])
- segments.push(getPaddedRoundedSegments(
- this.salientPoints[j-1].pos,
- this.salientPoints[j].pos,
- this.salientPoints[j+1].pos,
- ))
- }
- const last_point = getPaddedRoundedSegments(
- this.salientPoints[this.salientPoints.length-2].pos,
- this.salientPoints[this.salientPoints.length-1].pos,
- this.salientPoints[0].pos
- );
- segments.push(last_point)
- segments.push(first_point)
-
- const contrs = new paper.Path({
- name: 'contours',
- segments: segments,
- fillColor: 'rgba(255,255,255,0.4)',
- // selected: true,
- strokeColor: '#fff',
- strokeWidth: 1,
- pivot: new paper.Point(this.pos),
- cid: this.id
- });
- // contrs.segments[0].selected = true;
- // contrs.segments[1].selected = true;
- return contrs;
- },
- setPaperEntites(){
- let g = new paper.Group({
- pivot: new paper.Point(this.pos),
- name: 'entites'
- });
- for (let i = 0; i < this.body.parts.length; i++) {
- if (this.body.parts[i].item_type === 'entite') {
- let part = this.body.parts[i];
- g.addChild(new paper.Path.Circle({
- center: [part.position.x, part.position.y],
- radius: 0.5, //0.3
- fillColor: '#000',
- item_id: part.id,
- item_type: 'entite'
- }))
- }
- }
- return g;
- },
- setPaperPuissanceagirBG(){
- let children = [];
- for (let i = 1; i < 6; i++) {
- children.push(new paper.Path.Circle({
- center: [this.pos.x, this.pos.y],
- radius: ((this.ray*this.scale)/5)*i,
- strokeWidth: 0.5
- }));
- }
- for (let j = 0; j < 4; j++) {
- let a = (90 / 4) * j;
- // diagonale
- // https://fr.wikipedia.org/wiki/Trigonom%C3%A9trie#/media/Fichier:Unit_circle_angles_color.svg
- // https://fr.wikipedia.org/wiki/Identit%C3%A9_trigonom%C3%A9trique_pythagoricienne#Preuve_utilisant_le_cercle_unit%C3%A9
- // radians = degrees * (pi/180)
- // degrees = radians * (180/pi)
- let x = Math.cos(a*(Math.PI/180)) * this.ray * this.scale;
- let y = Math.sin(a*(Math.PI/180)) * this.ray * this.scale;
-
- children.push(new paper.Path.Line({
- from: [this.pos.x + x, this.pos.y + y],
- to: [this.pos.x - x, this.pos.y - y],
- strokeWidth: 1,
- dashArray: [5,5]
- }))
- children.push(new paper.Path.Line({
- from: [this.pos.x - y, this.pos.y + x],
- to: [this.pos.x + y, this.pos.y - x],
- strokeWidth: 1,
- dashArray: [5,5]
- }))
- }
-
- children.push(new paper.Path.Circle({
- center: [this.pos.x, this.pos.y],
- radius: this.ray*this.scale,
- strokeWidth: 2,
- fillColor: `rgba(255,255,255,0.6)`
- }));
- return new paper.Group({
- children: children,
- pivot: new paper.Point(this.pos),
- name: 'puissanceagir_bg',
- // locked: true,
- style: {
- strokeColor: '#fff'
- }
- });
- },
- setPaperPuissanceagirICON(){
- let children = [];
- let svgIcon = paper.project.importSVG(iconPuissanceagir);
- children.push(svgIcon);
- svgIcon.position = this.pos;
-
- return new paper.Group({
- children: children,
- pivot: new paper.Point(this.pos),
- name: 'puissanceagir_icon',
- locked: true,
- style: {
- strokeColor: '#000',
- strokeWidth: 1,
- fillColor: null
- }
- });
- },
- setPaperPuissanceagirBesoins(){
- let g = new paper.Group({
- pivot: new paper.Point(this.pos),
- name: 'puissanceagir_besoins'
- });
- for (let i = 0; i < this.body.parts.length; i++) {
- if (this.body.parts[i].item_type === 'besoin' || this.body.parts[i].item_type === 'reponse') {
- let part = this.body.parts[i];
-
- switch (part.item_type) {
- case 'besoin':
- g.addChild(
- new paper.Path({
- segments: this.getDiamondSegments(part.position.x, part.position.y, 1),
- fillColor: '#000',
- pivot: new paper.Point(this.pos),
- item_id: part.id,
- item_type: 'besoin'
- })
- )
- break;
- case 'reponse':
- g.addChild(
- new paper.Path({
- segments: this.getDiamondSegments(part.position.x, part.position.y, 1),
- fillColor: '#eee',
- strokeColor: "#000",
- strokeWidth: 1,
- pivot: new paper.Point(this.pos),
- item_id: part.id,
- item_bid: part.bid,
- item_cid: part.cid,
- item_type: 'reponse'
- })
- )
- break;
- }
- }
- }
- return g;
- },
- getDiamondSegments(x,y,r){
- return [
- [x, y - r],
- [x + r, y],
- [x, y + r],
- [x - r, y],
- [x, y - r]
- ];
- },
- setPaperAgissantes(){
- let g = new paper.Group({
- pivot: new paper.Point(this.pos),
- name: 'agissantes'
- });
- for (let i = 0; i < this.body.parts.length; i++) {
- if (this.body.parts[i].item_type === 'entite' && this.body.parts[i].agissante) {
- let part = this.body.parts[i];
- g.addChild(new paper.Path.Circle({
- center: [part.position.x, part.position.y],
- radius: 0.3, //0.3
- fillColor: '#000',
- strokeColor: '#000',
- strokeWidth: 3,
- item_id: part.id,
- item_type: 'entite'
- }))
- }
- }
- return g;
- },
- setPaperDoleanceBG(){
- var r = this.ray * this.scale * 0.8; // ray
- var dr = r/2; // demi ray
- var pcr = 2*this.scale; // petits cercle rayon
- // https://fr.wikipedia.org/wiki/Trigonom%C3%A9trie#/media/Fichier:Unit_circle_angles_color.svg
- // https://fr.wikipedia.org/wiki/Identit%C3%A9_trigonom%C3%A9trique_pythagoricienne#Preuve_utilisant_le_cercle_unit%C3%A9
- // radians = degrees * (pi/180)
- // degrees = radians * (180/pi)
- // Points for 45° axes
- let m = Math.sin(45*(Math.PI/180)) * r; // x = y for rayon
- let n = Math.sin(45*(Math.PI/180)) * r/2; // x = y for demi rayon
- // console.log('m', m);
- // points for legende arcs
- var lar = r*1.1; // legendes arcs rayon
- let o = Math.cos(22.5*(Math.PI/180)) * lar; // x @ 22.5° for legende arc rayon
- let p = Math.sin(22.5*(Math.PI/180)) * lar; // y @ 22.5° for legende arc rayon
- let q = Math.sin(45*(Math.PI/180)) * lar; // x = y @ 45° for legende arc rayon
- var ltr = lar + 4; // legendes texts rayon
- let o_t = Math.cos(22.5*(Math.PI/180)) * ltr; // x @ 22.5° for legende text rayon
- let p_t = Math.sin(22.5*(Math.PI/180)) * ltr; // y @ 22.5° for legende text rayon
- let q_t = Math.sin(45*(Math.PI/180)) * ltr; // x = y @ 45° for legende text rayon
- let style = {
- strokeColor: '#fff',
- strokeWidth: 1
- }
- let felchesstyle = {
- strokeColor: '#fff',
- strokeWidth: 2
- }
- let legende_style = {
- strokeColor: '#000',
- strokeWidth: 1
- }
- let fontsize = 4;
- let children = [
- // ARCS EXTERIEURS
- // haut gauche
- new paper.Path.Arc({
- from: [this.pos.x - r, this.pos.y - pcr],
- through: [this.pos.x - m, this.pos.y - m],
- to: [this.pos.x - pcr, this.pos.y - r],
- style: style
- }),
- // haut droite
- new paper.Path.Arc({
- from: [this.pos.x + pcr, this.pos.y - r],
- through: [this.pos.x + m, this.pos.y - m],
- to: [this.pos.x + r, this.pos.y - pcr],
- style: style
- }),
- // bas droite
- new paper.Path.Arc({
- from: [this.pos.x + r, this.pos.y + pcr],
- through: [this.pos.x + m, this.pos.y + m],
- to: [this.pos.x + pcr, this.pos.y + r],
- style: style
- }),
- // bas gauche
- new paper.Path.Arc({
- from: [this.pos.x - pcr, this.pos.y + r],
- through: [this.pos.x - m, this.pos.y + m],
- to: [this.pos.x - r, this.pos.y + pcr],
- style: style
- }),
- //
- // cercle interieur
- new paper.Path.Circle({
- center: [this.pos.x, this.pos.y],
- radius: dr,
- style: style
- }),
- //
- // petit cercles
- new paper.Path.Circle({
- center: [this.pos.x, this.pos.y -r],
- radius: pcr,
- style: style
- }),
- new paper.Path.Circle({
- center: [this.pos.x, this.pos.y + r],
- radius: pcr,
- style: style
- }),
- new paper.Path.Circle({
- center: [this.pos.x + r, this.pos.y],
- radius: pcr,
- style: style
- }),
- new paper.Path.Circle({
- center: [this.pos.x -r, this.pos.y],
- radius: pcr,
- style: style
- }),
- //
- // AXES
- // vertical haut
- new paper.Path.Line({
- from: [this.pos.x, this.pos.y - r + pcr],
- to: [this.pos.x , this.pos.y - dr],
- style: style
- }),
- // vertical bas
- new paper.Path.Line({
- from: [this.pos.x, this.pos.y + r - pcr],
- to: [this.pos.x , this.pos.y + dr],
- style: style
- }),
- // horizontal gauche
- new paper.Path.Line({
- from: [this.pos.x - r + pcr, this.pos.y],
- to: [this.pos.x - dr, this.pos.y],
- style: style
- }),
- // horizontal droite
- new paper.Path.Line({
- from: [this.pos.x + r - pcr, this.pos.y],
- to: [this.pos.x + dr, this.pos.y],
- style: style
- }),
- //
- // DIAGONALES
- // bas droite
- new paper.Path.Line({
- from: [this.pos.x + m, this.pos.y + m],
- to: [this.pos.x + n, this.pos.y + n],
- style: style
- }),
- // bas gauche
- new paper.Path.Line({
- from: [this.pos.x - m, this.pos.y + m],
- to: [this.pos.x - n, this.pos.y + n],
- style: style
- }),
- // // haut droite
- // new paper.Path.Line({
- // from: [this.pos.x + m, this.pos.y - m],
- // to: [this.pos.x + n, this.pos.y - n],
- // style: style
- // }),
- // // haut gauche
- // new paper.Path.Line({
- // from: [this.pos.x - m, this.pos.y - m],
- // to: [this.pos.x - n, this.pos.y - n],
- // style: style
- // }),
- // fleches
- // haut
- new paper.Path({
- segments: [
- [this.pos.x - 2, this.pos.y - dr*1.5 - 2],
- [this.pos.x, this.pos.y - dr*1.5],
- [this.pos.x - 2, this.pos.y - dr*1.5 + 2]
- ],
- style: felchesstyle
- }),
- // bas
- new paper.Path({
- segments: [
- [this.pos.x + 2, this.pos.y + dr*1.5 - 2],
- [this.pos.x, this.pos.y + dr*1.5],
- [this.pos.x + 2, this.pos.y + dr*1.5 + 2]
- ],
- style: felchesstyle
- }),
- // gauche
- new paper.Path({
- segments: [
- [this.pos.x - dr*1.5 - 2, this.pos.y + 2],
- [this.pos.x - dr*1.5, this.pos.y],
- [this.pos.x - dr*1.5 + 2, this.pos.y + 2]
- ],
- style: felchesstyle
- }),
- // droite
- new paper.Path({
- segments: [
- [this.pos.x + dr*1.5 - 2, this.pos.y - 2],
- [this.pos.x + dr*1.5, this.pos.y],
- [this.pos.x + dr*1.5 + 2, this.pos.y - 2]
- ],
- style: felchesstyle
- }),
- //
- // LEGENDES
- //
- // arc bas gauche 1
- new paper.Path.Arc({
- from: [this.pos.x - pcr, this.pos.y + lar],
- through: [this.pos.x - p, this.pos.y + o],
- to: [this.pos.x - q + pcr/2, this.pos.y + q + pcr/2],
- style: legende_style
- }),
- // tiret
- new paper.Path.Line({
- from: [this.pos.x - p, this.pos.y + o],
- to: [this.pos.x - p_t, this.pos.y + o_t],
- style: legende_style
- }),
- //text
- new paper.PointText({
- point: [this.pos.x - p_t - 1, this.pos.y + o_t],
- content: "Enquête menée\nsur le terrain de vie",
- fontSize: fontsize,
- justification: 'right'
- }),
- // arc bas gauche 2
- new paper.Path.Arc({
- from: [this.pos.x - q - pcr/2, this.pos.y + q - pcr/2],
- through: [this.pos.x - o, this.pos.y + p],
- to: [this.pos.x - lar, this.pos.y + pcr],
- style: legende_style
- }),
- // tiret
- new paper.Path.Line({
- from: [this.pos.x - o, this.pos.y + p],
- to: [this.pos.x - o_t, this.pos.y + p_t],
- style: legende_style
- }),
- // texte
- new paper.PointText({
- point: [this.pos.x - o_t - 1, this.pos.y + p_t],
- content: "Construction de groupes d'intérets\navec qui composer la doléance",
- fontSize: fontsize,
- justification: 'right'
- }),
- // arc haut gauche
- new paper.Path.Arc({
- from: [this.pos.x - lar, this.pos.y - pcr],
- through: [this.pos.x - q, this.pos.y - q],
- to: [this.pos.x - pcr, this.pos.y - lar],
- style: legende_style
- }),
- // tiret
- new paper.Path.Line({
- from: [this.pos.x - q, this.pos.y - q],
- to: [this.pos.x - q_t, this.pos.y - q_t],
- style: legende_style
- }),
- // texte
- new paper.PointText({
- point: [this.pos.x - q_t - 1, this.pos.y - q_t],
- content: "Réception et traitement\nde la doléance",
- fontSize: fontsize,
- justification: 'right'
- }),
- // arc haut droite
- new paper.Path.Arc({
- from: [this.pos.x + pcr, this.pos.y - lar],
- through: [this.pos.x + q, this.pos.y - q],
- to: [this.pos.x + lar, this.pos.y - pcr],
- style: legende_style
- }),
- // tiret
- new paper.Path.Line({
- from: [this.pos.x + q, this.pos.y - q],
- to: [this.pos.x + q_t, this.pos.y - q_t],
- style: legende_style
- }),
- // texte
- new paper.PointText({
- point: [this.pos.x + q_t + 1, this.pos.y - q_t],
- content: "Mise-en-œuvre\nde la décision",
- fontSize: fontsize,
- justification: 'left'
- }),
- // arc bas droite 1
- new paper.Path.Arc({
- from: [this.pos.x + lar, this.pos.y + pcr],
- through: [this.pos.x + o, this.pos.y + p],
- to: [this.pos.x + q + pcr/2, this.pos.y + q - pcr/2],
- style: legende_style
- }),
- // tiret
- new paper.Path.Line({
- from: [this.pos.x + o, this.pos.y + p],
- to: [this.pos.x + o_t, this.pos.y + p_t],
- style: legende_style
- }),
- // texte
- new paper.PointText({
- point: [this.pos.x + o_t + 1, this.pos.y + p_t],
- content: "Réception et application\nde la décision",
- fontSize: fontsize,
- justification: 'left'
- }),
- // arc bas droite 2
- new paper.Path.Arc({
- from: [this.pos.x + q - pcr/2, this.pos.y + q + pcr/2],
- through: [this.pos.x + p, this.pos.y + o],
- to: [this.pos.x + pcr, this.pos.y + lar],
- style: legende_style
- }),
- // tiret
- new paper.Path.Line({
- from: [this.pos.x + p, this.pos.y + o],
- to: [this.pos.x + p_t, this.pos.y + o_t],
- style: legende_style
- }),
- // texte
- new paper.PointText({
- point: [this.pos.x + p_t + 1, this.pos.y + o_t],
- content: "Réussite / échec / reprise\ndu cercle politique",
- fontSize: fontsize,
- justification: 'left'
- }),
- //
- // Points Cardinaux
- //
- // haut
- new paper.Path.Circle({
- center: [this.pos.x, this.pos.y -r],
- radius: 0.5,
- style: {
- fillColor: '#000'
- }
- }),
- new paper.Path.Line({
- from: [this.pos.x, this.pos.y -r],
- to: [this.pos.x, this.pos.y - r - 8],
- style: legende_style
- }),
- new paper.PointText({
- point: [this.pos.x, this.pos.y - r - 9],
- content: "Décision",
- fontSize: fontsize,
- justification: 'center'
- }),
- // bas
- // new paper.Path.Circle({
- // center: [this.pos.x, this.pos.y + r],
- // radius: 0.5,
- // style: {
- // fillColor: '#000'
- // }
- // }),
- // new paper.Path.Line({
- // from: [this.pos.x, this.pos.y + r],
- // to: [this.pos.x, this.pos.y + r + 8],
- // style: legende_style
- // }),
- // new paper.PointText({
- // point: [this.pos.x, this.pos.y + r + 10],
- // content: "Début du cercle\nLe problème\n(injustice, indignation, plainte...)",
- // fontSize: fontsize,
- // justification: 'center'
- // }),
- // droite
- new paper.Path.Circle({
- center: [this.pos.x + r, this.pos.y],
- radius: 0.5,
- style: {
- fillColor: '#000'
- }
- }),
- new paper.Path.Line({
- from: [this.pos.x + r, this.pos.y],
- to: [this.pos.x + r + 8, this.pos.y],
- style: legende_style
- }),
- new paper.PointText({
- point: [this.pos.x + r + 9, this.pos.y - 0.5],
- content: "Adresse de la décision\nà appliquer",
- fontSize: fontsize,
- justification: 'left'
- }),
- // gauche
- new paper.Path.Circle({
- center: [this.pos.x -r, this.pos.y],
- radius: 0.5,
- style: {
- fillColor: '#000'
- }
- }),
- new paper.Path.Line({
- from: [this.pos.x - r, this.pos.y],
- to: [this.pos.x - r - 8, this.pos.y],
- style: legende_style
- }),
- new paper.PointText({
- point: [this.pos.x - r - 9, this.pos.y + 0.4],
- content: "Adresse de la doléance",
- fontSize: fontsize,
- justification: 'right'
- }),
- ];
- return new paper.Group({
- children: children,
- pivot: new paper.Point(this.pos),
- name: 'doleance_bg',
- locked: true
- });
- },
- setPaperDoleanceICON(){
- let children = [];
- let svgIcon = paper.project.importSVG(iconDoleancer);
- children.push(svgIcon);
- svgIcon.position = this.pos;
- return new paper.Group({
- children: children,
- pivot: new paper.Point(this.pos),
- name: 'doleance_icon',
- locked: true,
- style: {
- strokeColor: '#000',
- strokeWidth: 1,
- fillColor: null
- }
- });
- },
- setPaperDoleanceSteps(){
- let g = new paper.Group({
- pivot: new paper.Point(this.pos),
- name: 'doleance_steps'
- });
- let doleance = this.concernement.doleances[0];
- let all_fields = [
- [
- 'leprobleme',
- 'lenquete',
- {
- fieldname: 'groupesinterets',
- fields: [
- 'groupe_interets',
- 'accorder_interets',
- 'formuler',
- ]
- }
- ],
- [
- 'entite_addresse_doleance',
- 'comment_ennonce_doleance',
- 'aqui_addresse_doleance',
- {
- fieldname: 'reception_traitement',
- fields: [
- 'entite_adressee',
- 'doleance_formulee',
- 'traite_doleance',
- 'entite_recoit_doleance',
- ]
- }
- ],
- [
- 'entites_decisionnaires',
- 'decision_formule',
- {
- fieldname: 'mise_en_oeuvre_decision',
- fields: [
- 'entite_adresse_decision',
- 'formule_decision',
- 'entite_metenoeuvre_decisio',
- ]
- }
- ],
- [
- 'entite_adresse_application',
- 'aqui_adresse_decision',
- 'comment_formule_decision',
- {
- fieldname: 'receptions_et_applications',
- fields: [
- 'applique_decision',
- 'formule_decision_applic',
- 'entite_recoit_decision',
- ]
- },
- 'probleme_initial_resolu',
- 'oui_nouvelle_situation',
- 'non_adresse_doleance',
- ]
- ];
-
- var r = this.ray * this.scale * 0.8; // ray
- var dr = r/2; // demi ray
- var pcr = 2*this.scale; // petits cercle rayon
- // https://fr.wikipedia.org/wiki/Trigonom%C3%A9trie#/media/Fichier:Unit_circle_angles_color.svg
- // https://fr.wikipedia.org/wiki/Identit%C3%A9_trigonom%C3%A9trique_pythagoricienne#Preuve_utilisant_le_cercle_unit%C3%A9
- // radians = degrees * (pi/180)
- // degrees = radians * (180/pi)
- // Points for 45° axes
- let m = Math.sin(45*(Math.PI/180)) * r; // x = y for rayon
- let n = Math.sin(45*(Math.PI/180)) * r/2; // x = y for demi rayon
- let o = Math.cos(22.5*(Math.PI/180)) * r; // x @ 22.5° for rayon
- let p = Math.sin(22.5*(Math.PI/180)) * r; // y @ 22.5° for rayon
- let o_d = Math.cos(22.5*(Math.PI/180)) * r/2; // x @ 22.5° for demi rayon
- let p_d = Math.sin(22.5*(Math.PI/180)) * r/2; // y @ 22.5° for demi rayon
- let fontsize = 2.1;
-
- //
- // POINTS CARDINAUX
- //
- // le problème
- //
- g.addChild(new paper.Path.Circle({
- center: [this.pos.x, this.pos.y + r],
- radius: 0.5,
- style: {
- fillColor: '#fff'
- }
- }));
- g.addChild(new paper.Path.Line({
- from: [this.pos.x, this.pos.y + r],
- to: [this.pos.x, this.pos.y + r + 8],
- strokeColor: '#fff'
- }));
- g.addChild(new paper.PointText({
- point: [this.pos.x, this.pos.y + r + 10],
- content: "Début du cercle\nLe problème (injustice, indignation, plainte...)",
- fontSize: fontsize,
- fillColor: '#000',
- justification: 'center'
- }));
- g.addChild(new paper.PointText({
- point: [this.pos.x, this.pos.y + r + 16],
- content: doleance['leprobleme'],
- fontSize: 2.3,
- fillColor: '#fff',
- justification: 'center'
- }));
-
- //
- // CAMENBERT STATIQUES
- //
- // l'enquete
- //
- // camenbert
- let cam = new paper.Path({
- strokeColor: '#fff',
- strokeWidth: 2,
- fillColor: "rgba(255, 255, 255, 0.4)",
- item_type: 'doleance_step',
- item_id: 'lenquete'
- });
- cam.add({x: this.pos.x , y: this.pos.y + dr});
- cam.lineTo({x: this.pos.x, y: this.pos.y + r});
- cam.arcTo({x: this.pos.x - p, y: this.pos.y + o}, {x: this.pos.x - m, y: this.pos.y + m});
- cam.lineTo({x: this.pos.x - n, y: this.pos.y + n});
- cam.arcTo({x: this.pos.x - p_d, y: this.pos.y + o_d}, {x: this.pos.x , y: this.pos.y + dr});
- // texte
- // enquete.addChild(new paper.PointText({
- // point: {
- // x:this.pos.x + Math.sin(22.5*(Math.PI/180)) * r*0.75,
- // y:this.pos.y + Math.cos(22.5*(Math.PI/180)) * r*0.75
- // },
- // content: doleance['lenquete'],
- // fontSize: fontsize,
- // fillColor: '#fff',
- // justification: 'center',
- // locked: true
- // }));
- g.addChild(cam);
-
- //
- // probleme_initial_resolu
- //
- // camenbert
- let rescam = new paper.Path({
- strokeColor: '#fff',
- strokeWidth: 2,
- fillColor: "rgba(255, 255, 255, 0.4)",
- closed: true,
- item_type: 'doleance_step',
- item_id: 'probleme_initial_resolu',
- });
- rescam.add({x: this.pos.x + n, y: this.pos.y + n});
- rescam.lineTo({x: this.pos.x + m , y: this.pos.y + m});
- rescam.arcTo({x: this.pos.x + p, y: this.pos.y + o}, {x: this.pos.x, y: this.pos.y + r});
- rescam.lineTo({x: this.pos.x, y: this.pos.y + dr});
- rescam.arcTo({x: this.pos.x + p_d, y: this.pos.y + o_d}, {x: this.pos.x + n, y: this.pos.y + n});
- // texte
- // resolution.addChild(new paper.PointText({
- // point: {
- // x:this.pos.x - Math.sin(22.5*(Math.PI/180)) * r*0.75,
- // y:this.pos.y + Math.cos(22.5*(Math.PI/180)) * r*0.75
- // },
- // content: doleance['probleme_initial_resolu'] ? doleance['oui_nouvelle_situation'] : doleance['non_adresse_doleance'],
- // fontSize: fontsize,
- // fillColor: '#fff',
- // justification: 'center'
- // }));
- g.addChild(rescam)
-
- //
- // MULTIPLE FIELDS
- //
- let multiple_fields = [
- { field_name: 'groupesinterets', arc: 45, decalage: -45 },
- { field_name: 'reception_traitement', arc: 90, decalage: -90 },
- { field_name: 'mise_en_oeuvre_decision', arc: 90, decalage: -180 },
- { field_name: 'receptions_et_applications', arc: 45, decalage: 90 }
- ]
- multiple_fields.forEach((mf, j) => {
- for (let i = 0, l = doleance[mf.field_name].length, a = mf.arc/l; i < l; i++) {
- // let gi = new paper.Group({
- // item_type: 'doleance_step',
- // item_id: 'lenquete',
- // item_field: mf.field_name,
- // item_index: i
- // });
- //camenbert
- let x1= this.pos.x + Math.sin((mf.decalage- a*i)*(Math.PI/180)) * dr,
- y1= this.pos.y + Math.cos((mf.decalage- a*i)*(Math.PI/180)) * dr;
- let x2= this.pos.x + Math.sin((mf.decalage- a*i)*(Math.PI/180)) * r,
- y2= this.pos.y + Math.cos((mf.decalage- a*i)*(Math.PI/180)) * r;
- let x3= this.pos.x + Math.sin((mf.decalage- a*(i+1))*(Math.PI/180)) * r,
- y3= this.pos.y + Math.cos((mf.decalage- a*(i+1))*(Math.PI/180)) * r;
- let x3t= this.pos.x + Math.sin((mf.decalage- a*(i+0.5))*(Math.PI/180)) * r,
- y3t= this.pos.y + Math.cos((mf.decalage- a*(i+0.5))*(Math.PI/180)) * r;
- let x4= this.pos.x + Math.sin((mf.decalage- a*(i+1))*(Math.PI/180)) * dr,
- y4= this.pos.y + Math.cos((mf.decalage- a*(i+1))*(Math.PI/180)) * dr;
- let x4t= this.pos.x + Math.sin((mf.decalage- a*(i+0.5))*(Math.PI/180)) * dr,
- y4t= this.pos.y + Math.cos((mf.decalage- a*(i+0.5))*(Math.PI/180)) * dr;
- let x5= this.pos.x + Math.sin((mf.decalage- a*(i+0.5))*(Math.PI/180)) * r*0.75,
- y5= this.pos.y + Math.cos((mf.decalage- a*(i+0.5))*(Math.PI/180)) * r*0.75;
- let p = new paper.Path({
- strokeColor: '#fff',
- strokeWidth: 2,
- fillColor: "rgba(255, 255, 255, 0.4)",
- item_type: 'doleance_step',
- item_id: `${mf.field_name}-${i}`,
- item_field: mf.field_name
- });
- p.add([x1,y1]);
- p.lineTo([x2,y2]);
- p.arcTo([x3t,y3t], [x3,y3]);
- p.lineTo([x4,y4]);
- p.arcTo([x4t,y4t], [x1,y1]);
- g.addChild(p);
- // gi.addChild(p);
- // // text
- // gi.addChild(new paper.PointText({
- // point: {x:x5,y:y5},
- // content: `${j}-${i}`,
- // fontSize: fontsize,
- // fillColor: '#fff',
- // justification: 'center'
- // }))
- // g.addChild(gi)
- }
- });
- return g;
- },
- // PAPER EVENTS
- initPaperEvents(){
- this.paper_objects.onMouseEnter = function(event){
- if (!this.opened && this.isFocused()) { // only if no concernement is opened and is this focused
- this.setHoverElmt({
- type: 'concernement',
- id: this.id
- });
- document.body.style.cursor = "pointer";
- }
- }.bind(this);
-
- this.paper_objects.onMouseLeave = function(event){
- if (!this.opened && this.isFocused()) { // only if no concernement is opened
- this.resetHoverElmt();
- document.body.style.cursor = "auto";
- }
- }.bind(this);
- this.paper_objects.onMouseMove = function(event){
- // console.log(`onmousemove ${this.id}`);
- // TODO besoins & actions & doleances
- if (this.is_opened) {
-
- // lets define some options regarding the map_mode
- let paper_group_tohit;
- switch (this.map_mode) {
- case "terraindevie":
- paper_group_tohit = 'entites';
- break;
- case "action":
- paper_group_tohit = 'agissantes';
- break;
- case "puissancedagir":
- paper_group_tohit = 'puissanceagir_besoins';
- break;
- case "doleancer":
- paper_group_tohit = 'doleance_steps';
- break;
- }
- let result = this.paper_objects.children[paper_group_tohit].hitTest(event.point);
- // console.log('move result', result);
- if (result && result.item.item_id) {
- // console.log('move has result', result);
- let new_hover_elmt = {
- paper_id: result.item.id,
- type: result.item.item_type,
- id: result.item.item_id
- };
- switch (result.item.item_type) {
- case "reponse":
- new_hover_elmt.bid = result.item.item_bid;
- new_hover_elmt.cid = result.item.item_cid;
- break;
- }
- if (!this.hover_elmt || new_hover_elmt.paper_id !== this.hover_elmt.paper_id) {
- // console.log(`before setHoverElmt ${this.id}`);
- this.setHoverElmt(new_hover_elmt);
- }
- document.body.style.cursor = "pointer";
- } else {
- // console.log('move no result');
- this.resetHoverElmt();
- document.body.style.cursor = "auto";
- }
- }
- }.bind(this);
-
- this.paper_objects.onClick = function(event){
- console.log('paper concernement onClick');
- if (!this.is_opened) {
- if (!this.opened) {
- console.log(`Open me ${this.id}`);
- // open/close all concernements
- this.openCloseConcernements(this.id)
- // push route (keep the hash for map_mode)
- this.$router.push({
- name: 'concernement',
- hash: `#${this.map_mode}`,
- params: {id: this.id}
- });
- // reset the mousehover
- this.resetHoverElmt();
- }
- } else {
- // lets define some options regarding the map_mode
- // debugger;
- let op = {pg: null};
- switch (this.map_mode) {
- case "terraindevie":
- op = {
- pg: 'entites', // paper group to hittest
- }
- break;
- case "action":
- op = {
- pg: 'agissantes', // paper group to hittest
- }
- break;
- }
- if (op.pg) {
- let result = this.paper_objects.children[op.pg].hitTest(event.point);
- // console.log('click result', result);
- if (result) {
- // we have clicked on an entite
- this.$router.push({
- name: 'concernement',
- hash: `#${this.map_mode}`,
- params: {id: this.opened.id, eid: result.item.item_id}
- });
- } else {
- // otherwise we close the entite and come back to the concernement
- this.$router.push({
- name: 'concernement',
- hash: `#${this.map_mode}`,
- params: {id: this.id}
- });
- // reset the mousehover
- this.resetHoverElmt();
- }
- }
- }
- }.bind(this);
- },
- resetHoverElmt(){
- // console.log('resetHoverElmt');
- setTimeout(()=>{
- this.setHoverElmt(null);
- }, 100);
- },
- openClose(open) {
- // console.log(`ConcernementsMapItem ${this.concernement.id} openClose: ${open}`);
- if (this.tween) {
- this.tween.stop();
- }
- if (open) {
- // paper bring to front
- this.paper_objects.bringToFront();
- // calcul opened size regarding window size
- // let ch = this.canvas.height;
- let s = this.canvas.height / (this.ray*2.8)
- // debugger;
- // opening tweening
- this.tween = new Tween.Tween({s: this.scale, x: this.pos.x, y: this.pos.y, o: 0})
- .to({
- s: s,
- x: (this.canvas.width - 450) / 2,
- y: this.canvas.height / 2,
- o: 0.8
- }, 800)
- .onUpdate((obj) => {
- // 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.paper_objects.scale(1 / this.scale);
- // then scale again to new scale
- Matter.Body.scale(this.body, obj.s, obj.s)
- this.paper_objects.scale(obj.s);
- // record new scale
- this.prev_scale = this.scale;
- this.scale = obj.s;
- this.opacity = obj.o;
-
- Matter.Body.setPosition(this.body, {x:obj.x, y:obj.y});
- this.pos = {x:obj.x, y:obj.y};
- })
- .onComplete((obj) => {
- this.constraint = Matter.Constraint.create({
- pointA: this.pos,
- bodyB: this.body,
- stiffness: 1,
- damping: 0,
- length: 0
- });
- Matter.Composite.add(this.matterEngine.world, [this.body, this.constraint]);
- this.prev_scale = this.scale;
- });
- // recreate the matter engine event to get it a the end of the events stack
- Matter.Events.off(this.matterEngine, "afterUpdate", this.onAfterEngineUpdate);
- Matter.Events.on(this.matterEngine, "afterUpdate", this.onAfterEngineUpdate);
- } else {
- // closing
- if(this.constraint){
- Matter.Composite.remove(this.matterEngine.world, this.constraint);
- }
- this.tween = new Tween.Tween({s: this.scale, o: 1})
- .to({s: 1, o: 0}, 500)
- .onUpdate((obj) => {
- // 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.paper_objects.scale(1 / this.scale);
- // then scale again to new scale
- Matter.Body.scale(this.body, obj.s, obj.s)
- this.paper_objects.scale(obj.s);
-
- // record new scale
- this.prev_scale = this.scale;
- this.scale = obj.s;
- this.opacity = obj.o;
- })
- .onComplete((obj) => {
- this.prev_scale = this.scale = 1;
- });
- }
- this.tween.easing(Tween.Easing.Quadratic.InOut).start();
- },
- // ENGINE UPDATE
- onBeforeEngineUpdate (event) {
- // update the opening/closing tweening
- if (this.tween) {
- this.tween.update();
- }
- if (this.opened) {
- if (this.opened.id !== this.id) {
- this.pushAside()
- }
- } else {
- // apply focus forces : move unfocused on the sides and focused on the center
- if (this.map_mode === 'action'
- || this.map_mode === 'puissancedagir'
- || this.map_mode === 'doleancer'){
- this.applyFocusForces(); //
- }
- }
-
- // reset all matter rotation forces otherwise items will spin when colide
- Matter.Body.setAngle(this.body, 0);
- Matter.Body.setAngularSpeed(this.body, 0);
- },
- applyFocusForces(){
- if(!this.isFocused()) {
- this.pushAside()
- }else{
- this.bringToCenter()
- }
- },
- pushAside(){
- // apply a force in direction of one side or an other depending of the start position
- // the force is exponentialy proportional to the distance from the side
- let dir = this.pos.x > this.canvas.width/2 ? 1 : -1; // get the direction to the closest side
- let dist = (dir < 0 ? this.pos.x : this.canvas.width - this.pos.x); // get the distance from the side
- let ori_pos = {x:this.canvas.width/2, y:this.body.position.y};
- let x_force = Math.pow(dist/700,10) * dir;
-
- Matter.Body.applyForce(
- this.body,
- ori_pos,
- {
- x: x_force,
- y: 0
- }
- );
- },
- bringToCenter(){
- // bring to the centre
- let dir = this.pos.x > this.canvas.width/2 ? -1 : 1; // get the direction to the centre
- let dist = (dir < 0 ? this.pos.x - this.canvas.width/2 : this.canvas.width/2 - this.pos.x); // get the distance from the side
- let ori_pos = dir < 0 ? {x:this.canvas.width, y:this.body.position.y} : {x:0, y:this.body.position.y}
- let x_force = Math.pow(dist/800,10) * dir;
-
- this.body.frictionAir = 0.05;
- Matter.Body.applyForce(
- this.body,
- ori_pos,
- {
- x: x_force,
- y: 0
- }
- );
- },
- applyShuffleForces() {
- var dist, dir, x_velocity;
- dir = this.pos.x > this.canvas.width/2 ? -1 : 1; // get the direction to the centre
- dist = (dir < 0 ? this.pos.x - this.canvas.width/2 : this.canvas.width/2 - this.pos.x); // get the distance from the side
- x_velocity = Math.pow(dist/650,10) * dir;
- Matter.Body.setVelocity(this.body, {x: x_velocity, y: 0});
- },
- onAfterEngineUpdate (event) {
- // respawn element if outside screen
- // if(this.pos.x < 0
- // || this.pos.x > this.canvas.width
- // || this.pos.y < 0
- // || this.pos.y > this.canvas.height){
- // this.pos = this.getRandomPos()
- // Matter.Body.setPosition(this.body, {x:this.pos.x, y:this.pos.y});
- // this.setInitBodyVelocity();
- // }
-
- this.paper_objects.position = this.pos = this.body.position;
- // this.draw()
- this.handlePaperVisibility()
- },
- // PAPER VISIBILITY
- handlePaperVisibility(){
- // contours focused
- if (!this.isFocused()){
- this.paper_objects.children['contours'].fillColor = "rgba(255,255,255,0.1)";
- }else{
- this.paper_objects.children['contours'].fillColor = "rgba(255,255,255,0.4)";
- if (this.is_hover) {
- this.paper_objects.children['contours'].strokeColor = "#01ffe2";
- this.paper_objects.children['contours'].strokeWidth = 2;
- }else{
- this.paper_objects.children['contours'].strokeColor = "#fff";
- this.paper_objects.children['contours'].strokeWidth = 1;
- }
- }
- // contours visibility
- if (!this.is_opened
- || (this.is_opened && this.map_mode !== "puissancedagir" && this.map_mode !== "doleancer")) {
- this.paper_objects.children['contours'].visible = true;
- } else {
- this.paper_objects.children['contours'].visible = false;
- }
- // backgrounds
- if (this.is_opened) {
- // hide all bgs
- this.paper_objects.children.boussole_bg.visible = false;
- if (this.concernement.has_puissancedagir) {
- this.paper_objects.children.puissanceagir_bg.visible = false;
- }
- if (this.concernement.has_doleance) {
- this.paper_objects.children.doleance_bg.visible = false;
- }
- // choose wich one to show, if one
- switch (this.map_mode) {
- case 'terraindevie':
- this.paper_objects.children.boussole_bg.visible = true;
- break;
- case 'puissancedagir':
- if (this.concernement.has_puissancedagir) {
- this.paper_objects.children.puissanceagir_bg.visible = true;
- }
- break;
- case 'doleancer':
- if (this.concernement.has_doleance) {
- this.paper_objects.children.doleance_bg.visible = true;
- }
- break;
- }
- }else{
- this.paper_objects.children.boussole_bg.visible = false;
- if (this.concernement.has_puissancedagir) {
- this.paper_objects.children.puissanceagir_bg.visible = false;
- }
- if (this.concernement.has_doleance) {
- this.paper_objects.children.doleance_bg.visible = false;
- }
- }
- // entites
- if (this.is_opened
- && this.map_mode !== 'puissancedagir'
- && this.map_mode !== 'doleancer'
- && this.map_mode !== 'action' ) {
- this.paper_objects.children.entites.visible = true;
- // if (this.opened_entite_id) {
- // // console.log('this.paper_objects.children.entites', this.paper_objects.children.entites);
- // this.paper_objects.children.entites.children.forEach((entite) => {
- // // console.log('entite', entite);
- // if (entite.item_id === this.opened_entite_id) {
- // entite.style.fillColor = '#01ffe2';
- // } else {
- // entite.style.fillColor = '#000';
- // }
- // });
- // } else {
- // this.paper_objects.children.entites.children.forEach((entite) => {
- // entite.style.fillColor = '#000';
- // })
- // }
- } else {
- this.paper_objects.children.entites.visible = false;
- }
- // puissance d'agir
- if (this.concernement.has_puissancedagir) {
- if (this.map_mode === "puissancedagir") {
- if (!this.is_opened) {
- this.paper_objects.children.puissanceagir_icon.visible = true; // if not opened and has_puissancedagir draw the puissance d'agir icone
- this.paper_objects.children.puissanceagir_besoins.visible = false;
- } else {
- this.paper_objects.children.puissanceagir_icon.visible = false;
- this.paper_objects.children.puissanceagir_besoins.visible = true;
- // this.drawBesoins();
- }
- } else {
- this.paper_objects.children.puissanceagir_icon.visible = false;
- this.paper_objects.children.puissanceagir_besoins.visible = false;
- }
- }
- // agissantes
- // console.log('this.concernement.has_agissantes', this.concernement.has_agissantes);
- if (this.concernement.has_agissantes) {
- if (this.map_mode === "action") {
- this.paper_objects.children.agissantes.visible = true;
- } else {
- this.paper_objects.children.agissantes.visible = false;
- }
- }
-
- // doleance
- if (this.concernement.has_doleance) {
- if (this.map_mode === "doleancer") {
- if (!this.is_opened) {
- this.paper_objects.children.doleance_icon.visible = true;
- this.paper_objects.children.doleance_steps.visible = false;
- } else {
- this.paper_objects.children.doleance_icon.visible = false;
- this.paper_objects.children.doleance_steps.visible = true;
- }
- } else {
- this.paper_objects.children.doleance_icon.visible = false;
- this.paper_objects.children.doleance_steps.visible = false;
- }
- }
-
- },
- isFocused(){
- return this.map_mode === 'terraindevie'
- || (this.map_mode === 'action' && this.concernement.has_agissantes)
- || (this.map_mode === 'puissancedagir' && this.concernement.has_puissancedagir)
- || (this.map_mode === 'doleancer' && this.concernement.has_doleance);
- },
- },
- render() {
- // console.log('render()', this.ctx);
- },
- }
- </script>
|