123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980 |
- <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.05;
- // 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,100) * 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>
|