소스 검색

boussole: moving entity points is ok, and it records the new values on the form, so it can be recorded

bach 2 년 전
부모
커밋
7e4e6dca11
1개의 변경된 파일133개의 추가작업 그리고 49개의 파일을 삭제
  1. 133 49
      src/web/themes/custom/ouatminimal_theme/js/boussole.js

+ 133 - 49
src/web/themes/custom/ouatminimal_theme/js/boussole.js

@@ -3,11 +3,15 @@
   Drupal.behaviors.boussole = {
     attach: function (context, settings) {
       console.log("Drupal Boussole behavior", context);
+      let $boussole_wrapper = document.querySelector('#boussole-layout');
       once('boussole-class-behaviour', '#boussole-layout', context).forEach(element => {
-        _boussole = new Boussole();
+        let tabs = 
+        // div.field-group-tabs-wrapper
+        // input.horizontal-tabs-active-tab
+        _boussole = new Boussole($boussole_wrapper);
       });
       
-      let $form = document.querySelector('#boussole-layout>.form-item');
+      let $form = $boussole_wrapper.querySelector(':scope>.form-item');
       console.log($form);
       let $tabledrag = $form.querySelector('table.field-multiple-table');
       console.log($tabledrag);
@@ -47,19 +51,74 @@
         entities[id] = e;
       });
       console.log(entities);
-      _boussole.updateEntities(entities);
+      _boussole.updateCreateEntities(entities);
     }
   };
 
   class Boussole {
-    constructor() {
+    constructor($boussole_wrapper) {
+      this.$boussole_wrapper = $boussole_wrapper;
       this.$boussole = document.querySelector('#boussole-layout>.boussole-wrapper>.boussole');
-      
       this.entities = {}
+
+      this.initTabChecking();
+      this.enableDragArea()
+    }
+
+    initTabChecking(){
+      // debugger
+      this.$field_group_tab = this.$boussole_wrapper.closest('details.field-group-tab');
+      // watch for tabs opening and closing
+      // hidden input do not triggers events
+      // so we have to use mutationObserver tomake it trigger the change event
+      this.$tabInput = this.$field_group_tab.parentElement.querySelector(':scope>input[type="hidden"]');
+      let observer = new MutationObserver(function(mutations, observer) {
+        if(mutations[0].attributeName == "value") {		
+          // console.log('mutation observed', mutations, observer);
+          let event = new Event('change');
+          mutations[0].target.dispatchEvent(event);
+        }
+      });
+      observer.observe(this.$tabInput, {attributes: true});
+      // then we listen to the event
+      this.$tabInput.addEventListener('change', event => {
+        // console.log('tab input changed', event, this);
+        this.wrapperTabChanged(event);
+      });
+      this.checkTabIsOpen();
     }
 
-    updateEntities(entities){
-      console.log('Class Boussole update entities', entities);
+    checkTabIsOpen(){
+      this.tabisopen = this.$field_group_tab.getAttribute('id') === this.$tabInput.value;
+    }
+
+    wrapperTabChanged(event){
+      this.checkTabIsOpen();
+      if(this.tabisopen){
+        this.updateEntities();
+      }
+    }
+
+    enableDragArea(){
+      this.$boussole.addEventListener("dragenter", (event) => {
+        event.preventDefault();
+      });
+      this.$boussole.addEventListener("dragover", (event) => {
+        event.preventDefault();
+      });
+      this.$boussole.addEventListener("drop", (event) => {
+        event.preventDefault();
+        let data = JSON.parse(event.dataTransfer.getData('text/plain'));
+        console.log('boussole drop', event, data);
+        data.clientX = event.clientX;
+        data.clientY = event.clientY;
+        // return on the entity class
+        this.entities[data.entity_id].dropedOnBoussole(data);
+      });
+    }
+
+    updateCreateEntities(entities){
+      // console.log('Class Boussole update entities', entities);
       for (const [id, values] of Object.entries(entities)) {
         // console.log(id, typeof this.entities[id], values);
         if (typeof this.entities[id] === 'undefined') {
@@ -69,6 +128,12 @@
         }
       }
     }
+
+    updateEntities(){
+      for (const [id, entity] of Object.entries(this.entities)) {
+        entity.update();
+      }
+    }
   }
 
   class Entity {
@@ -92,6 +157,7 @@
     createDomElemt(){
       this.$e = document.createElement('div');
       this.$e.classList.add('entity');
+      this.$e.setAttribute('id', `${this.id}-boussole-point`);
       this.$e.setAttribute('title', this.values.title.value);
       this.$container.append(this.$e);
       console.log(this.$e);
@@ -100,37 +166,60 @@
     }
 
     initDraggable(){
-      // // this is working but to slow, we loose the item
-      // this.$e.addEventListener('mousedown', function(event){
-      //   this.mousedown = true;
-      //   this.moving_x = this.$e.offsetLeft - event.clientX;
-      //   this.moving_y = this.$e.offsetTop - event.clientY;
-      // }.bind(this));
-      // this.$e.addEventListener('mouseup', function(event){
-      //   this.mousedown = false;
-      // }.bind(this));
-      // this.$e.addEventListener('mousemove', function(event){
-      //   if (this.mousedown) {
-      //     this.$e.style.left = event.clientX + this.moving_x + 'px';
-      //     this.$e.style.top = event.clientY + this.moving_y + 'px';
-      //   }
-      // }.bind(this));
       this.$e.setAttribute('draggable', true);
-      this.$e.addEventListener('dragstart', function(event){
-        event.dataTransfer.setData('text/plain', event.target.id);
-        setTimeout(() => {
-          event.target.classList.add('hide');  
-        }, 0);
-      }.bind(this));
-      this.$e.addEventListener('drag', function(event){
-        console.log('drag', event);
-      }.bind(this));
-      this.$e.addEventListener('dragend', function(event){
-        console.log('dragend', event);
-        event.target.style.top = event.clientY + 'px';
-        event.target.style.left = event.clientX + 'px';
+      this.$e.addEventListener('dragstart', event => {
+        // console.log('dragstart', event);
+        let data = {
+          entity_id : this.id,
+          dragging_start_x : event.target.offsetLeft - event.clientX,
+          dragging_start_y : event.target.offsetTop - event.clientY
+        };
+        event.dataTransfer.setData('text/plain', JSON.stringify(data));
+        // event.dataTransfer.effectAllowed = "move";
+        setTimeout(() => {event.target.classList.add('hide');}, 0);
+      });
+      this.$e.addEventListener('dragend', event => {
+        // console.log('dragend', event);
         event.target.classList.remove('hide');
-      }.bind(this))
+      });
+      // CAN'T DO THAT, EVENT IS FIRED FOR EACH ENTITIES
+      // TAKING CARE OF THE DROP IN THE BOUSSOLE CLASS
+      // this.$container.addEventListener('drop', event =>{
+      //   event.preventDefault();
+      //   console.log('drop', event);
+      // })
+    }
+
+    dropedOnBoussole(data){
+      this.$e.style.left = data.clientX + data.dragging_start_x + 'px';
+      this.$e.style.top = data.clientY + data.dragging_start_y + 'px';
+      this.updateValuesFromBoussole();
+    }
+
+    updateValuesFromBoussole(){
+      let compstyle = window.getComputedStyle(this.$e);
+      // AF
+      let top = parseInt(compstyle.top); 
+      let af = top >= this.sceneSize.h/2 ? 0 : 1;
+      this.values.af.value = af;
+      this.values.af.$dom.querySelector(`input[value="${af}"]`).checked = true;
+
+      // (x, y)
+      let x = parseInt(compstyle.left) - this.sceneSize.h/2;
+      let y = Math.abs(this.sceneSize.h/2 - top);
+      let a = parseFloat(Math.atan(x/y) * (180/Math.PI)).toFixed(2);
+      let r = Math.sqrt(Math.pow(x,2)+Math.pow(y,2));
+      
+      this.values.mm.value = this.values.mm.$dom.value = a;
+      
+      // https://stackoverflow.com/questions/5731863/mapping-a-numeric-range-onto-another
+      // from range 0 -> rayon_de_la_boussole to range 0 -> 100
+      let r_max = this.sceneSize.w/2; 
+      let r_slope = (100 - 0) / (r_max - 0);
+      this.values.p.value = this.values.p.$dom.value = parseFloat(0 + r_slope * (r - 0)).toFixed(2);
+      // this.values.p.$dom.value = this.values.p.value;
+      
+      console.log('x:', x, 'r:', r, 'a:', a, "y:", y);
     }
 
     listenToFormValue(){
@@ -149,17 +238,6 @@
           this.updatePos();
         }.bind(this, v));
       })
-      // this.values.af.$dom.addEventListener('change', function(event) {
-      //   console.log('af changed', event);
-      //   let af = event.target.parent('.fieldset-wrapper').querySelector('input:checked').value;
-      //   this.values.af.value = parseInt(af);
-      //   console.log(`new af`, this.values.af.value);
-      //   this.updatePos();
-      // }.bind(this));
-    }
-
-    updateValuesFromForm(values){
-
     }
 
     updatePos(){
@@ -170,6 +248,7 @@
       // from range 0 -> 100 to range 0 -> diagonale de la scene
       // let diagonale = Math.sqrt(Math.pow(this.sceneSize.w, 2) + Math.pow(this.sceneSize.h, 2))/2;
       // let r_max = diagonale;
+      // actualy we don't use diagonale, we stay on the circle
       let r_max = this.sceneSize.w/2; 
       let r_slope = (r_max - 0) / (100 - 0)
       let r = parseInt(0 + r_slope * (this.values.p.value - 0));
@@ -181,14 +260,19 @@
       let af = this.values.af.value;
 
       let left = this.sceneSize.w / 2 + x;
-      let top = this.sceneSize.h / 2 - (af ? -y : y);
+      let top = this.sceneSize.h / 2 - (af ? y : -y);
       // console.log('left:', left, "top:", top);
 
       this.$e.style.left = left+'px';
       this.$e.style.top = top+'px';
     }
-
     
+    update(){
+      console.log('Entity update');
+      this.updateSceneSize()
+      this.updatePos()
+    }
+
   }