Прослушиватель событий для группового перетаскивания

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

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

Я храню координаты линий в storeLines В наведении мыши:

Я получаю текущую позицию мыши, устанавливаю флаг 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 )

добавить расстояние к положению любой формы, которая является перетаскиванием

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

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

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

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.info(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.info('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.info(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>

Когда нажата кнопка перетаскивания, вы хотите выбрать и перетащить линии/прямоугольники?

Durga 21.03.2019 07:53

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

sylvain 21.03.2019 10:38
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
2
106
0

Другие вопросы по теме