ограничить SVG в Bbox - PullRequest
       7

ограничить SVG в Bbox

0 голосов
/ 26 февраля 2020

Я хочу расширить этот код: порождение и перетаскивание SVG-элементов - подход , но допускается перетаскивание только клонированных элементов внутри фона холста

enter image description here

Я пытался применить код из этого урока http://www.petercollingridge.co.uk/tutorials/svg/interactive/dragging/, где вы

  1. Определите границу

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

...