Я хочу расширить этот код: порождение и перетаскивание SVG-элементов - подход , но допускается перетаскивание только клонированных элементов внутри фона холста
Я пытался применить код из этого урока http://www.petercollingridge.co.uk/tutorials/svg/interactive/dragging/, где вы
Определите границу
var boundaryX1 = 10.5;
var boundaryX2 = 30;
var boundaryY1 = 2.2;
var boundaryY2 = 19.2;
Используйте bbBox из SVG, чтобы получить координаты предметов
if (confined) {
bbox = selectedElement.getBBox();
minX = boundaryX1 - bbox.x;
maxX = boundaryX2 - bbox.x - bbox.width;
minY = boundaryY1 - bbox.y;
maxY = boundaryY2 - bbox.y - bbox.height;
}
Затем вычислите позицию, в которую элемент перетаскивается, и убедитесь, что он не выходит за границы, прежде чем применять его
var dx = coord.x - offset.x;
var dy = coord.y - offset.y;
if (confined) {
if (dx < minX) { dx = minX; }
else if (dx > maxX) { dx = maxX; }
if (dy < minY) { dy = minY; }
else if (dy > maxY) { dy = maxY; }
}
Я понимаю это в теория, но я изо всех сил пытаюсь применить это к моему случаю использования. Кто-нибудь может дать некоторые советы / помощь? В идеале я пытаюсь использовать только ваниль javascript для этого :)
var drag = null;
var boundaryX1 = 0;
var boundaryX2 = 480;
var boundaryY1 = 0;
var boundaryY2 = 580;
function getMousePosition(e) {
var CTM = svg.getScreenCTM();
// working on mobile consideration
if (e.touches) { evt = evt.touches[0]; }
return {
x: (e.clientX - CTM.e) / CTM.a,
y: (e.clientY - CTM.f) / CTM.d
};
}
var canvas = {};
var inventory = {};
window.onload = function() {
canvas = document.getElementById("canvas");
inventory = document.getElementById("inventory");
// attach events listeners
AttachListeners();
}
function AttachListeners() {
var ttt = document.getElementsByClassName('inventory'), i;
for (i = 0; i < ttt.length; i++) {
document.getElementsByClassName("inventory")[i].onmousedown=Drag;
}
document.getElementById("svg").onmousemove=Drag;
document.getElementById("svg").onmouseup=Drag;
}
// Drag function that needs to be modified;//
function Drag(e) {
var t = e.target, id = t.id, et = e.type; m = MousePos(e);
if (!drag && (et == "mousedown")) {
if (t.classList.contains("inventory")) { //if its inventory class item, this should get cloned into draggable?
copy = t.cloneNode(true);
copy.onmousedown = Drag;
copy.removeAttribute("id");
copy._x = 0;
copy._y = 0;
canvas.appendChild(copy);
drag = copy;
dPoint = m;
}
else if (t.className.baseVal=="draggable") { //if its just draggable class - it can be dragged around
drag = t;
dPoint = m;
}
}
// drag the spawned/copied draggable element now
if (drag && (et == "mousemove")) {
drag._x += m.x - dPoint.x;
drag._y += m.y - dPoint.y;
dPoint = m;
drag.setAttribute("transform", "translate(" +drag._x+","+drag._y+")");
bbox = t.getBBox();
minX = boundaryX1 - bbox.x;
maxX = boundaryX2 - bbox.x - bbox.width;
minY = boundaryY1 - bbox.y;
maxY = boundaryY2 - bbox.y - bbox.height;
if (drag._x < minX) { drag._x= minX; }
else if (drag._x > maxX) { drag._x = maxX; }
if (drag._y < minY) { drag._y = minY; }
else if (drag._y > maxY) { drag._y = maxY; }
}
// stop drag
if (drag && (et == "mouseup")) {
drag.className.baseVal="draggable";
drag = null;
}
}
// adjust mouse position to the matrix of SVG & screen size
function MousePos(event) {
var p = svg.createSVGPoint();
p.x = event.clientX;
p.y = event.clientY;
var matrix = svg.getScreenCTM();
p = p.matrixTransform(matrix.inverse());
return {
x: p.x,
y: p.y
}
}
path
{
stroke-width: 4;
stroke: #000;
stroke-linecap: round;
}
html, body {
margin: 0;
padding: 0;
border: 0;
overflow:hidden;
background-color: #fff;
}
body {
-ms-touch-action: none;
}
#canvasBackground {
fill: lightgrey;
}
#inventoryBackground {
fill: grey;
}
.block1 {
fill: red;
}
.block2 {
fill: blue;
}
.draggable {
fill: green;
}
svg {
position: fixed;
top:0%;
left:0%;
width:100%;
height:100%;
}
<svg id="svg"
height="800"
width="480"
viewbox="0 0 480 800"
preserveAspectRatio="xMinYMin meet"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<rect id="canvasBackground" width="480" height="480" x="0" y="0"/>
<rect id="inventoryBackground" width="480" height="100" x="0" y="480"/>
<g id="inventory">
<path id="curve4" class="inventory block1" d="M60,530 A35,35 0 1,1 60,531" />
<path id="curve3" class="inventory block2" d="M150,530 A35,35 0 1,1 150,531" />
</g>
<g id="canvas">
</g>
</svg>
Codepen, если это полезно! https://codepen.io/mayagans/pen/RwPpKLN