прослушиватель событий для перетаскивания групп - PullRequest
3 голосов
/ 19 марта 2019

Я пытаюсь воспроизвести выбор управления тканью

. Для этого я создаю «приложение рисования», в котором мы можем нарисовать линию, нарисовать прямоугольник и перетащить. Цель состоит в том, чтобы перетащить вселиния, которая находится внутри прямоугольника с самим прямоугольником при щелчке на вводе при перетаскивании

Я сохраняю координаты линий в storeLines. В mousedown:

Я получаю текущую позицию мыши, установив флаг isDragging налюбая фигура, находящаяся под мышью

, сохраните текущую позицию мыши и сделайте цикл через сохраненные строки, чтобы увидеть все линии, находящиеся внутри прямоугольника

if(that.type == "drag"){
      dragok=false;
      for(var i=0;i<storedLines.length;i++){
          var r=storedLines[i];
          if(r.x1>startX && r.x2<(mouseX + startX) && r.y1>startY &&  r.y2<(mouseY + startY)){
              // if yes, set that rects isDragging=true
              dragok=true;
              r.isDragging=true;
              ctx.strokeStyle = "blue";
          }
      }
   }

В перемещении мыши:

Я получаю текущую позицию мыши

рассчитываю, как далеко мышь переместилась (distance = newMousePosition-oldMousePosition)

добавляет расстояние к позиции любой фигуры, которая является Dragbing

сохранить текущую позицию мыши

перерисовать сцену с фигурами в их новых позициях

но проблема в том, что я не могу сделатьэто перетаскивание, потому что даже когда кнопка перетаскивания нажата на мышь вниз, я продолжаю рисовать прямоугольник

var storedLines = [];
var startX = 0;
var startY = 0;
var isDown;
var type = "line"; // current type
var dragok = false;
class CanvasState{
  // **** First some setup! ****
 constructor(canvas){
  this.canvas = canvas;
  this.type = type;
  this.width = canvas.width;
  this.height = canvas.height;
  this.ctx = canvas.getContext('2d');
  var offsetX = canvas.offsetLeft;
  var offsetY = canvas.offsetTop;
  this.valid = false; // when set to false, the canvas will redraw everything
  this.shapes = [];  // the collection of things to be drawn
  this.dragging = false; // Keep track of when we are dragging
  this.selection = null;
  this.dragoffx = 0; // See mousedown and mousemove events for explanation
  this.dragoffy = 0;
  var myState = this;
  this.selectionColor = '#CC0000';
  this.selectionWidth = 2;  
  var that = this;
  

  canvas.addEventListener('selectstart', function(e) { e.preventDefault(); return false; }, false);
  // Up, down, and move are for dragging
  canvas.addEventListener('mousedown', function(e) {
    e.preventDefault();
    e.stopPropagation();

    canvas.style.cursor = "crosshair";

    var mouseX = parseInt(e.clientX - offsetX);
    var mouseY = parseInt(e.clientY - offsetY);

    isDown = true;
    startX = mouseX;
    startY = mouseY;

    // test each rect to see if lines are inside
    if(that.type == "drag"){
      dragok=false;
      for(var i=0;i<storedLines.length;i++){
          var r=storedLines[i];
          if(r.x1>startX && r.x2<(mouseX + startX) && r.y1>startY &&  r.y2<(mouseY + startY)){
              // if yes, set that rects isDragging=true
              dragok=true;
              r.isDragging=true;
              ctx.strokeStyle = "blue";
          }
      }
   }
  }, true);
  canvas.addEventListener('mousemove', function(e) {
    e.preventDefault();
    e.stopPropagation();
    var ctx = canvas.getContext('2d');
    if (!isDown) return;

    myState.redrawStoredLines();

    var mouseX = parseInt(e.clientX - offsetX);
    var mouseY = parseInt(e.clientY - offsetY);

    if(that.type == "rect"){
        ctx.beginPath();
        ctx.rect(startX, startY, mouseX - startX, mouseY - startY);
        ctx.stroke();
      }
    // if we're dragging anything...
    if (that.type == "drag"){

      // tell the browser we're handling this mouse event
      e.preventDefault();
      e.stopPropagation();

      // get the current mouse position
      var mx=parseInt(e.clientX-offsetX);
      var my=parseInt(e.clientY-offsetY);

      // calculate the distance the mouse has moved
      // since the last mousemove
      var dx=mx-startX;
      var dy=my-startY;

      // move each line that isDragging 
      // by the distance the mouse has moved
      // since the last mousemove
      myState.redrawStoredLines();
    }
    if(that.type == "line"){
        ctx.beginPath();
        ctx.moveTo(startX, startY);
        ctx.lineTo(mouseX, mouseY);
        ctx.stroke();
    }

  }, true);
  canvas.addEventListener('mouseup', function(e) {
    
      canvas.style.cursor = "default";
     
    e.preventDefault();
    e.stopPropagation();

    isDown = false;
    
    var mouseX = parseInt(e.clientX - offsetX);
    var mouseY = parseInt(e.clientY - offsetY);

    storedLines.push({
        type: that.type,
        x1: startX,
        y1: startY,
        x2: mouseX,
        y2: mouseY
    });
    console.log(storedLines);
    myState.redrawStoredLines();
  
  }, true);

canvas.addEventListener('handleMouseOut', function(e) {
    
      e.preventDefault();
    e.stopPropagation();
    
    if (!isDown) return;

    isDown = false;
    
    var mouseX = parseInt(e.clientX - offsetX);
    var mouseY = parseInt(e.clientY - offsetY);

    storedLines.push({
        type: that.type,
        x1: startX,
        y1: startY,
        x2: mouseX,
        y2: mouseY
    });

    myState.redrawStoredLines();
  

  }, true);
  
  
}
setType(newtype){
  if ( newtype === 'line' ) {
    this.type = "line";
    
   } 
   if ( newtype === 'rect' ) {
      this.type = "rect";
     console.log('settype:' + this.type);
   }  
}

 

 redrawStoredLines() {

    
    var ctx = this.canvas.getContext('2d');
    ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

    if (storedLines.length == 0) return;

    // redraw each stored line
    for (var i = 0; i < storedLines.length; i++) {
        if(storedLines[i].type === "line"){
            ctx.beginPath();
            ctx.moveTo(storedLines[i].x1, storedLines[i].y1);
            ctx.lineTo(storedLines[i].x2, storedLines[i].y2);
            ctx.stroke();
        }
        if(storedLines[i].type === "rect"){
            ctx.beginPath();
            ctx.rect(storedLines[i].x1, storedLines[i].y1, 
                storedLines[i].x2 - storedLines[i].x1, storedLines[i].y2 - storedLines[i].y1);
            ctx.stroke();
        }
        if (storedLines[i].type === "drag"){

            
            // move each line that isDragging 
            // by the distance the mouse has moved
            // since the last mousemove
          for(var i=0;i<storedLines.length;i++){
                    var r=storedLines[i];
                  if(r.x1>startX && r.x2<(mouseX + startX) && r.y1>startY &&  r.y2<(mouseY + startY)){
                      
                        if(r.isDragging){
                            r.x+=dx;
                            r.y+=dy;
                        }
                    }

              }
      }
    }
}

}

var radios = document.querySelectorAll('input[type=radio][name="shape"]');

function changeHandler(event) {
  
    console.log(event.srcElement.value);
    mycanvas.setType(event.srcElement.value);
   
  
}

Array.prototype.forEach.call(radios, function(radio) {
   radio.addEventListener('change', changeHandler);
  
});


var mycanvas =  new CanvasState(document.getElementById('mainCanvas'));
 

body{
    font-family: Arial, Helvetica, sans-serif;
    font-weight: 16px;
}

.container{
    margin: 10px;
    padding: 2px;
    border: solid 1px black;
    background-color: #505050 
}

h3{
    margin: 10px;
    padding: 2px;
}

.toolbox{
    display: inline;
    list-style-type: none;    
}

.toolbox > li{
    display: inline-block;
    margin: 0;    
    vertical-align: middle;
}

div.sliders div{
    /*margin-top: 20px;    */
    display: inline-block;
}

.in-line p{
    font-size: 14px;
    display: block;
}

.in-line input{
    margin: 5px;
    display: block;
}


#square{
    margin-top: 20px;
    margin-left: 48%;
    width: 50px;
    height: 50px;
    background-color: rgb(127, 127, 127);
}

#rgbcolor{
    font-size: 14px; 
    text-align: center;   
}

#clearbtn{
    width: 50px;
    margin-left: 48%;
    margin-top: 10px;
}

.canvas{    
    margin: 10px;
    position: relative;    
    width: 600px;
    height: 400px;
    border: solid 1px black;
    background-color: #ffffff;
    cursor: crosshair;    
}

#coords{
    text-align: center;
}
 <div class="container">
    <h3>Drawing Shapes</h3> 
    <div>
        <ul class="toolbox">
            <li id="btns">
              <div >        
                
                <input type="radio" name="shape" id="line" value="line">Line<br>
                <input type="radio" name="shape" id="drag" value="drag">Drag<br>
                <input type="radio" name="shape" id="rect" value="rect">Rectangle<br>                
              </div>
              <div class="sliders">
                <div class="in-line">
                  <p>Red</p>
                  <p>Green</p>
                  <p>Blue</p>                  
                </div>
                <div class="in-line">
                  <input type="range" min="0" max="255" value="127" name="Red" id="red" >
                  <input type="range" min="0" max="255" value="127" name="Green" id="green" >
                  <input type="range" min="0" max="255" value="127" name="Blue" id="blue" >
                </div>                                                
              </div>
              <div><p id="rgbcolor">RGB(127, 127, 127)</p><div id="square"></div></div>
                         
            </li>            
            <li id="cnvs">
              <div>
                <canvas id="mainCanvas" class="canvas" width="600" height="400"></canvas>  
                <h3 id="coords">(X, Y) : (0 , 0)</h3>
              </div> 
            </li>
          </ul>
    </div>                                                         
  </div>
...