Browse Source

implementação do selecionador de objetos 'selector.js ', remoção do transformador de objetos.

Victor Luiz Domingues 4 năm trước cách đây
mục cha
commit
448034421d

+ 94 - 77
app/app.js

@@ -1,130 +1,147 @@
 var app = (function() {
-  var width = $("#content").width();
-  var height =
+  let _width = $("#content").width();
+  let _height =
     $("#sidebar").height() - $("#header").height() - $("#files").height() - 2;
-  var layers = [];
-  var _layer = [];
-  var tools = [];
-  var menu = [];
-  var layer = undefined;
-  var _selectedTool = [];
-
-  var stage = new Konva.Stage({
+  let _screen = {
+    width: _width,
+    height: _height
+  };
+  let _layers = [];
+  let _currentLayers = [];
+  let _tools = [];
+  let _menu = [];
+  let _layer = undefined;
+  let _selectedTool = [];
+  let _objects = [];
+  let _stage = new Konva.Stage({
     container: "container",
-    width: width,
-    height: height
+    width: _width,
+    height: _height
   });
+  let _state = APP_STATE.NONE;
 
-  var screen = {
-    width: width,
-    height: height
-  };
-
-  function createLayer() {
-    var sequence = 0;
-    if (layers == null || layers.length == 0) {
+  function _createLayer() {
+    let sequence = 0;
+    if (_layers == null || _layers.length == 0) {
       sequence++;
     } else {
-      sequence = layers.length + 1;
+      sequence = _layers.length + 1;
     }
-    var layer = { sequence: sequence, layer: new Konva.Layer() };
-    layers.push(layer);
-    if (currentLayer() == undefined && _layer.length == 0) {
-      _layer = [];
-      _layer.push(layer);
+    let layer = { sequence: sequence, layer: new Konva.Layer() };
+    _layers.push(layer);
+    if (_currentLayer() == undefined && _currentLayers.length == 0) {
+      _currentLayers = [];
+      _currentLayers.push(layer);
     }
-    stage.add(layer.layer);
+    _stage.add(layer.layer);
     return layer;
   }
 
-  function bootstrap() {
-    createLayer();
+  function _bootstrap() {
+    _createLayer();
     configureStageEvents();
-    layer = currentLayer();
+    _layer = _currentLayer();
+    selector.bootstrap();
   }
 
-  function currentLayer() {
-    if (_layer[0] == undefined) return undefined;
-    return _layer[0].layer;
+  function _currentLayer() {
+    if (_currentLayers[0] == undefined) return undefined;
+    return _currentLayers[0].layer;
   }
 
   function configureStageEvents() {
-    stage.on("click tap", function(e) {
-      var tool = getSelectedTool();
+    _stage.on("mousedown ", function(e) {
+      if (e.target === _stage) {
+        _setState(APP_STATE.NONE);
+        return;
+      }
+      if (e.target.id != undefined) {
+        _setState(APP_STATE.OBJECT_SELECTED);
+        return;
+      }
+    });
+    _stage.on("click tap", function(e) {
+      let tool = _getSelectedTool();
       if (tool != undefined) {
         tool.draw();
         return;
       }
-
-      var transformEnabled = true;
-
-      if (
-        e.target.attrs.transformEnabled != undefined &&
-        e.target.attrs.transformEnabled == false
-      ) {
-        transformEnabled = false;
-      }
-      if (e.target === stage || !transformEnabled) {
-        stage.find("Transformer").destroy();
-        layer.draw();
+      if (e.target === _stage) {
+        _setState(APP_STATE.NONE);
         return;
       }
-
-      stage.find("Transformer").destroy();
-
-      var tr = new Konva.Transformer({
-        anchorStrokeWidth: 2
-      });
-      layer.add(tr);
-      tr.attachTo(e.target);
-      layer.draw();
     });
   }
 
-  function setSelectedTool(tool) {
-    clearSelectedTool();
+  function _setSelectedTool(tool) {
+    _clearSelectedTool();
+    _setState(APP_STATE.TOOL_SELECTED);
     if (tool.id != undefined) {
       document.getElementById("btn-" + tool.id).disabled = true;
     }
     _selectedTool.push(tool);
   }
 
-  function clearSelectedTool() {
-    var tool = getSelectedTool();
+  function _clearSelectedTool() {
+    let tool = _getSelectedTool();
     if (tool != undefined) {
       if (tool.id != undefined) {
         document.getElementById("btn-" + tool.id).disabled = false;
       }
     }
     _selectedTool = [];
-    setStatus("");
+    _setStatus("");
+    _setState(APP_STATE.NONE);
   }
 
-  function getSelectedTool() {
+  function _getSelectedTool() {
     if (_selectedTool.length > 0) return _selectedTool[0];
     return undefined;
   }
 
-  function getRelativePointerPosition() {
-    return stage.getPointerPosition();
+  function _getRelativePointerPosition() {
+    return _stage.getPointerPosition();
   }
 
-  function setStatus(status) {
+  function _setStatus(status) {
     document.getElementById("status").innerHTML = status;
   }
 
+  function _pushObject(object) {
+    _objects.push(object);
+  }
+
+  function _getObjects() {
+    return _objects;
+  }
+
+  function _setState(state) {
+    _state = state;
+  }
+  function _getState() {
+    return _state;
+  }
+  function _menuClick(e) {
+    _setState(APP_STATE.TOOL_SELECTED);
+    if (e.click());
+  }
   return {
-    stage: stage,
-    currentLayer: currentLayer,
-    createLayer: createLayer,
-    screen: screen,
-    bootstrap: bootstrap,
-    layers: layers,
-    tools: tools,
-    setSelectedTool: setSelectedTool,
-    clearSelectedTool: clearSelectedTool,
-    getSelectedTool: getSelectedTool,
-    pos: getRelativePointerPosition,
-    setStatus: setStatus
+    stage: _stage,
+    currentLayer: _currentLayer,
+    createLayer: _createLayer,
+    screen: _screen,
+    bootstrap: _bootstrap,
+    layers: _layers,
+    tools: _tools,
+    setSelectedTool: _setSelectedTool,
+    clearSelectedTool: _clearSelectedTool,
+    getSelectedTool: _getSelectedTool,
+    pos: _getRelativePointerPosition,
+    setStatus: _setStatus,
+    pushObject: _pushObject,
+    getObjects: _getObjects,
+    setState: _setState,
+    getState: _getState,
+    menuClick: _menuClick
   };
 })();

+ 48 - 54
app/components/circumference.js

@@ -1,47 +1,41 @@
 var circunference = (function() {
-  // dashed line
-
-  var tool = {};
-
-  var states = ["center", "radius"];
-
-  var state = undefined;
-
-  var coordinates = [0, 0, 0, 0];
-
-  var points = [0, 0, 0];
-
-  function draw() {
-    if (state == undefined) {
-      state = states[0];
+  let _tool = {};
+  let _states = ["center", "radius"];
+  let _state = undefined;
+  let _coordinates = [0, 0, 0, 0];
+  let _points = [0, 0, 0];
+
+  function _draw() {
+    if (_state == undefined) {
+      _state = _states[0];
       app.setStatus("Selecione o centro da Circunferência");
-    } else if (state == states[0]) {
-      var pos = app.pos();
-      coordinates[0] = pos.x;
-      coordinates[1] = pos.y;
-      state = states[1];
+    } else if (_state == _states[0]) {
+      let pos = app.pos();
+      _coordinates[0] = pos.x;
+      _coordinates[1] = pos.y;
+      _state = _states[1];
       app.setStatus("Selecione o raio da Circunferência");
-    } else if (state == states[1]) {
-      var pos = app.pos();
-      coordinates[2] = pos.x;
-      coordinates[3] = pos.y;
-      var legA = coordinates[2] - coordinates[0];
-      legB = coordinates[3] - coordinates[1];
-      var radius = Math.sqrt(Math.pow(legA, 2) + Math.pow(legB, 2));
-      points = [coordinates[0], coordinates[1], radius];
-      var p = points.slice();
-      drawCircunference(p[0], p[1], p[2]);
+    } else if (_state == _states[1]) {
+      let pos = app.pos();
+      _coordinates[2] = pos.x;
+      _coordinates[3] = pos.y;
+      let legA = _coordinates[2] - _coordinates[0];
+      legB = _coordinates[3] - _coordinates[1];
+      let radius = Math.sqrt(Math.pow(legA, 2) + Math.pow(legB, 2));
+      _points = [_coordinates[0], _coordinates[1], radius];
+      let p = _points.slice();
+      _drawCircunference(p[0], p[1], p[2]);
     }
   }
 
-  function drawCircunference(x, y, radius) {
-    var layer = app.currentLayer();
-    var group = new Konva.Group({
+  function _drawCircunference(x, y, radius) {
+    let layer = app.currentLayer();
+    let group = new Konva.Group({
       draggable: true,
       resizeEnabled: false
     });
 
-    var circle = new Konva.Circle({
+    let circle = new Konva.Circle({
       x: x,
       y: y,
       radius: radius,
@@ -53,7 +47,7 @@ var circunference = (function() {
       draggable: false
     });
 
-    var point = new Konva.Circle({
+    let point = new Konva.Circle({
       x: x,
       y: y,
       radius: 5,
@@ -72,45 +66,45 @@ var circunference = (function() {
     layer.add(group);
     app.stage.draw();
 
-    clearState();
+    _clearState();
     app.clearSelectedTool();
     app.setStatus("");
   }
 
-  function bootstrap() {
-    app.tools.push(tool);
+  function _bootstrap() {
+    app.tools.push(_tool);
   }
 
-  function click(id) {
-    if (state == states[0]) {
+  function _click(id) {
+    if (_state == _states[0]) {
       app.clearSelectedTool();
-      clearState();
+      _clearState();
       return;
     }
-    app.setSelectedTool(tool);
-    state = states[0];
+    app.setSelectedTool(_tool);
+    _state = _states[0];
     app.setStatus("Selecione o primeiro ponto no canvas");
   }
 
-  function clearState() {
-    state = undefined;
+  function _clearState() {
+    _state = undefined;
   }
 
-  tool = {
+  _tool = {
     id: "circunference",
     title: "Circunferência",
     icon: "line",
-    click: click,
-    draw: draw,
-    points: points,
-    coordinates: coordinates,
-    drawCircunference: drawCircunference
+    click: _click,
+    draw: _draw,
+    points: _points,
+    coordinates: _coordinates,
+    drawCircunference: _drawCircunference
   };
 
-  bootstrap();
+  _bootstrap();
 
   return {
-    draw: draw,
-    click: click
+    draw: _draw,
+    click: _click
   };
 })();

+ 40 - 0
app/components/label.js

@@ -0,0 +1,40 @@
+var label = (function() {
+  const _labels = [
+    "a",
+    "b",
+    "c",
+    "d",
+    "e",
+    "f",
+    "g",
+    "h",
+    "i",
+    "j",
+    "k",
+    "l",
+    "m",
+    "n",
+    "o",
+    "p",
+    "q",
+    "r",
+    "s",
+    "t",
+    "u",
+    "v",
+    "w",
+    "x",
+    "y",
+    "z"
+  ];
+  let _usedLabels = [];
+
+  function _draw() {
+    var label = _labels[_usedLabels.length];
+    _usedLabels.push(label);
+    return label.toUpperCase();
+  }
+  return {
+    draw: _draw
+  };
+})();

+ 36 - 41
app/components/line.js

@@ -1,30 +1,25 @@
 var line = (function() {
-  // dashed line
+  let _tool = {};
+  let _states = ["primeiro_ponto", "segundo_ponto"];
+  let _state = undefined;
+  let _points = [0, 0, 0, 0];
 
-  var tool = {};
-
-  var states = ["primeiro_ponto", "segundo_ponto"];
-
-  var state = undefined;
-
-  var points = [0, 0, 0, 0];
-
-  function draw() {
-    if (state == undefined) {
-      state = states[0];
+  function _draw() {
+    if (_state == undefined) {
+      _state = _states[0];
       app.setStatus("Selecione o primeiro ponto no canvas");
-    } else if (state == states[0]) {
-      var pos = app.pos();
-      points[0] = pos.x;
-      points[1] = pos.y;
-      state = states[1];
+    } else if (_state == _states[0]) {
+      let pos = app.pos();
+      _points[0] = pos.x;
+      _points[1] = pos.y;
+      _state = _states[1];
       app.setStatus("Selecione o segundo ponto no canvas");
-    } else if (state == states[1]) {
-      var pos = app.pos();
-      points[2] = pos.x;
-      points[3] = pos.y;
-      var p = points.slice();
-      var ln = new Konva.Line({
+    } else if (_state == _states[1]) {
+      let pos = app.pos();
+      _points[2] = pos.x;
+      _points[3] = pos.y;
+      let p = _points.slice();
+      let ln = new Konva.Line({
         points: p,
         stroke: "grey",
         strokeWidth: 2,
@@ -33,49 +28,49 @@ var line = (function() {
         strokeScaleEnabled: false
       });
 
-      var layer = app.currentLayer();
+      let layer = app.currentLayer();
       layer.add(ln);
 
       app.stage.draw();
 
-      clearState();
+      _clearState();
       app.clearSelectedTool();
       app.setStatus("");
     }
   }
 
-  function bootstrap() {
-    app.tools.push(tool);
+  function _bootstrap() {
+    app.tools.push(_tool);
   }
 
-  function click() {
-    if (state == states[0] || state == states[1]) {
+  function _click() {
+    if (_state == _states[0] || _state == _states[1]) {
       app.clearSelectedTool();
-      clearState();
+      _clearState();
       return;
     }
-    app.setSelectedTool(tool);
-    state = states[0];
+    app.setSelectedTool(_tool);
+    _state = _states[0];
     app.setStatus("Selecione o primeiro ponto no canvas");
   }
 
-  function clearState() {
-    state = undefined;
+  function _clearState() {
+    _state = undefined;
   }
 
-  tool = {
+  _tool = {
     id: "line",
     title: "Reta",
     icon: "line",
-    click: click,
-    draw: draw,
-    points: points
+    click: _click,
+    draw: _draw,
+    points: _points
   };
 
-  bootstrap();
+  _bootstrap();
 
   return {
-    draw: draw,
-    click: click
+    draw: _draw,
+    click: _click
   };
 })();

+ 34 - 66
app/components/point.js

@@ -1,73 +1,39 @@
 var point = (function() {
-  // dashed line
-
-  var tool = {};
-
-  var states = ["center"];
-
-  var state = undefined;
-
-  var points = [0, 0];
-
-  var labels = [
-    "a",
-    "b",
-    "c",
-    "d",
-    "e",
-    "f",
-    "g",
-    "h",
-    "i",
-    "j",
-    "k",
-    "l",
-    "m",
-    "n",
-    "o",
-    "p",
-    "q",
-    "r",
-    "s",
-    "t",
-    "u",
-    "v",
-    "w",
-    "x",
-    "y",
-    "z"
-  ];
-
-  var usedLabels = [];
+  let style = {
+    fill: "#9bc364",
+    strokeWidth: 1,
+    stroke: "#9bc364"
+  };
+  let tool = {};
+  let states = ["center"];
+  let state = undefined;
+  let points = [0, 0];
 
-  function draw() {
+  function _draw() {
     if (state == undefined) {
       state = states[0];
       app.setStatus("Selecione o centro do Ponto");
     } else if (state == states[0]) {
-      var pos = app.pos();
+      let pos = app.pos();
       points[0] = pos.x;
       points[1] = pos.y;
-      var p = points.slice();
-      var po = drawPoint(p[0], p[1], true);
+      let p = points.slice();
+      let po = _drawPoint(p[0], p[1], true);
     }
   }
 
-  function bootstrap() {
+  function _bootstrap() {
     app.tools.push(tool);
   }
 
-  function drawPoint(x, y, useLabel) {
-    var label = labels[usedLabels.length];
-    usedLabels.push(label);
-
-    var layer = app.currentLayer();
-    var group = new Konva.Group({
+  function _drawPoint(x, y, useLabel) {
+    let layer = app.currentLayer();
+    let group = new Konva.Group({
       draggable: true,
       resizeEnabled: false
     });
 
-    var circle = new Konva.Circle({
+    let circle = new Konva.Circle({
       x: x,
       y: y,
       radius: 5,
@@ -77,35 +43,37 @@ var point = (function() {
       strokeScaleEnabled: false,
       draggable: false,
       resizeEnabled: false,
-      transformEnabled: false
+      transformEnabled: false,
+      style: style
     });
-    var text = new Konva.Text({
+    let text = new Konva.Text({
       x: x + 10,
       y: y - 10,
-      text: label.toUpperCase(),
+      text: label.draw(),
       fontSize: 12,
       fontFamily: "Calibri",
       fill: "#434a45",
       draggable: false,
       resizeEnabled: false,
-      transformEnabled: false
+      transformEnabled: false,
+      selectable: false
     });
     group.add(circle);
     if (useLabel != undefined && useLabel) {
       group.add(text);
     }
     layer.add(group);
+    app.pushObject(group);
     app.stage.draw();
-
-    clearState();
+    _clearState();
     app.clearSelectedTool();
     app.setStatus("");
   }
 
-  function click(id) {
+  function _click(id) {
     if (state == states[0]) {
       app.clearSelectedTool();
-      clearState();
+      _clearState();
       return;
     }
     app.setSelectedTool(tool);
@@ -113,7 +81,7 @@ var point = (function() {
     app.setStatus("Selecione o centro da Ponto");
   }
 
-  function clearState() {
+  function _clearState() {
     state = undefined;
   }
 
@@ -121,15 +89,15 @@ var point = (function() {
     id: "point",
     title: "Ponto",
     icon: "point",
-    click: click,
-    draw: draw,
+    click: _click,
+    draw: _draw,
     points: points
   };
 
-  bootstrap();
+  _bootstrap();
 
   return {
-    draw: draw,
-    click: click
+    draw: _draw,
+    click: _click
   };
 })();

+ 138 - 0
app/core/components/selector.js

@@ -0,0 +1,138 @@
+var selector = (function() {
+  let _objects = [];
+  let _selectorPosStart;
+  let _selectorPosNow;
+  let _mode = "";
+  let _selectorRect = new Konva.Rect({
+    x: 0,
+    y: 0,
+    width: 0,
+    height: 0,
+    stroke: "#33BCFF",
+    dash: [2, 2]
+  });
+
+  function _bootstrap() {
+    _configureSelectorEvents();
+    _addToLayer();
+  }
+
+  function _addToLayer() {
+    let layer = app.currentLayer();
+    _selectorRect.listening(false);
+    layer.add(_selectorRect);
+  }
+
+  function _getSelectedObjects() {
+    return _objects;
+  }
+
+  function _configureSelectorEvents() {
+    app.stage.on("mousedown", function(e) {
+      _mode = "drawing";
+      _startDragSelector({ x: e.evt.layerX, y: e.evt.layerY });
+    });
+
+    app.stage.on("mousemove", function(e) {
+      if (_mode === "drawing") {
+        _updateDragSelector({ x: e.evt.layerX, y: e.evt.layerY });
+      }
+    });
+
+    app.stage.on("mouseup", function(e) {
+      _mode = "";
+      _selectorRect.visible(false);
+      app.stage.draw();
+    });
+  }
+
+  function _startDragSelector(posIn) {
+    _selectorPosStart = { x: posIn.x, y: posIn.y };
+    _selectorPosNow = { x: posIn.x, y: posIn.y };
+  }
+
+  function _updateDragSelector(posIn) {
+    if (app.getState() != APP_STATE.NONE) return;
+    let objects = app.getObjects();
+    let posRect = _reverse(_selectorPosStart, _selectorPosNow);
+    _selectorPosNow = { x: posIn.x, y: posIn.y };
+    _selectorRect.x(posRect.x1);
+    _selectorRect.y(posRect.y1);
+    _selectorRect.width(posRect.x2 - posRect.x1);
+    _selectorRect.height(posRect.y2 - posRect.y1);
+    _selectorRect.visible(true);
+
+    for (i = 0; i < objects.length; i = i + 1) {
+      let object = objects[i];
+      if (object.children != undefined && object.children.length > 0) {
+        for (j = 0; j < object.children.length; j++) {
+          _style(object.children[j], _selectorRect);
+        }
+      } else {
+        _style(object, _selectorRect);
+      }
+    }
+    app.stage.draw();
+  }
+
+  function _style(object, selectorRect) {
+    if (object.attrs.selectable != undefined) {
+      if (object.attrs.selectable == false) {
+        return;
+      }
+    }
+    if (_hitCheck(object, selectorRect)) {
+      object.stroke("#33BCFF");
+      object.fill("#33BCFF");
+    } else {
+      if (object.attrs.style != undefined) {
+        object.stroke(object.attrs.style.stroke);
+        object.fill(object.attrs.style.fill);
+      } else {
+        object.stroke("black");
+      }
+    }
+  }
+
+  function _hitCheck(shape1, shape2) {
+    let s1 = shape1.getClientRect();
+    let s2 = shape2.getClientRect();
+    let X = s1.x;
+    let Y = s1.y;
+    let A = s1.x + s1.width;
+    let B = s1.y + s1.height;
+    let X1 = s2.x;
+    let A1 = s2.x + s2.width;
+    let Y1 = s2.y;
+    let B1 = s2.y + s2.height;
+
+    if (A < X1 || A1 < X || B < Y1 || B1 < Y) {
+      return false;
+    } else {
+      return true;
+    }
+  }
+
+  function _reverse(r1, r2) {
+    let r1x = r1.x,
+      r1y = r1.y,
+      r2x = r2.x,
+      r2y = r2.y,
+      d;
+    if (r1x > r2x) {
+      d = Math.abs(r1x - r2x);
+      r1x = r2x;
+      r2x = r1x + d;
+    }
+    if (r1y > r2y) {
+      d = Math.abs(r1y - r2y);
+      r1y = r2y;
+      r2y = r1y + d;
+    }
+    return { x1: r1x, y1: r1y, x2: r2x, y2: r2y };
+  }
+  return {
+    selctedObjects: _getSelectedObjects(),
+    bootstrap: _bootstrap
+  };
+})();

+ 7 - 0
app/core/enums/app-state-enum.js

@@ -0,0 +1,7 @@
+var APP_STATE = (function() {
+  return {
+    NONE: 0,
+    OBJECT_SELECTED: 1,
+    TOOL_SELECTED: 2
+  };
+})();

+ 7 - 4
index.html

@@ -21,21 +21,21 @@
             <button
               id="btn-point"
               class="tool icon icon-point"
-              onclick="point.click()"
+              onclick="app.menuClick(point)"
             >
               <span> Point</span>
             </button>
             <button
               id="btn-line"
               class="tool icon icon-line"
-              onclick="line.click()"
+              onclick="app.menuClick(line)"
             >
               <span>Line</span>
             </button>
             <button
               id="btn-circunference"
               class="tool icon icon-circumference"
-              onclick="circunference.click()"
+              onclick="app.menuClick(circunference)"
             >
               <span>Circunferece</span>
             </button>
@@ -75,9 +75,12 @@
     <script src="node_modules/jquery/dist/jquery.min.js"></script>
     <script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
     <script src="node_modules/konva/konva.min.js"></script>
+    <script src="app/core/enums/app-state-enum.js"></script>
+    <script src="app/core/components/selector.js"></script>
     <script src="app/app.js"></script>
-    <script src="app/components/line.js"></script>
+    <script src="app/components/label.js"></script>
     <script src="app/components/point.js"></script>
+    <script src="app/components/line.js"></script>
     <script src="app/components/circumference.js"></script>
     <script>
       app.bootstrap();