Я пытаюсь воспроизвести выбор ткани
Для этого Я создаю «приложение для рисования», в котором мы можем нарисовать прямоугольник рисования линии и перетащить Цель состоит в том, чтобы перетащить всю линию, которая находится внутри прямоугольника, с самим прямоугольником, когда щелчок мышью
Я храню координаты линий в 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>линии внутри прямоугольника. Идея состоит в том, чтобы использовать прямоугольник в качестве инструмента выбора, чтобы все линии внутри прямоугольника были выбраны, а затем, когда нажата кнопка перетаскивания, прямоугольник и вся линия внутри перетаскиваются при наведении мыши, следуйте за движением мыши и опускайтесь в положение мыши.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


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