<head>
<title>Untitled</title>
</head>
<body onLoad=svgGLOB(50,800,800,30)>
<div style=font-family:arial>
Fifty(50) svg shapes are created and randomly located. Each shape is draggable. If the dragged shape's bounding box intersects another shape, its opacity is changed until the dragged shape moves out of intersect range.
</div>
<div id=svgDiv style='width:800px;height:800px;border:1px solid black'>
<svg id=mySVG width="800" height="800" onmousedown="startDrag(evt)" onmousemove="drag(evt)" onmouseup="endDrag()"></svg>
</div>
</body>
<script>
function intersectShape(target)
{
var r1 = target.getBoundingClientRect(); //BOUNDING BOX OF THE TARGET OBJECT
for(k=0;k<globG.childNodes.length;k++)
{
var shape=globG.childNodes.item(k)
if(shape!=target)
{
var r2=shape.getBoundingClientRect();
//CHECK IF ANY TWO BOUNDING BOXES OVERLAP
if(!(r2.left > r1.right ||
r2.right < r1.left ||
r2.top > r1.bottom ||
r2.bottom < r1.top))
shape.setAttribute("opacity",.5)
else
shape.setAttribute("opacity",1)
}
}
}
var TransformRequestObj
var TransList
var DragTarget=null;
var Dragging = false;
var OffsetX = 0;
var OffsetY = 0;
//---mouse down over element---
function startDrag(evt)
{
\t if(!Dragging) //---prevents dragging conflicts on other draggable elements---
\t {
\t \t if(evt.target.getAttribute("class")=="dragTarget")
\t \t {
\t \t \t DragTarget = evt.target;
\t \t \t DragTarget.setAttribute("style","cursor:move")
\t \t \t //---reference point to its respective viewport--
\t \t \t var pnt = DragTarget.ownerSVGElement.createSVGPoint();
\t \t \t pnt.x = evt.clientX;
\t \t \t pnt.y = evt.clientY;
\t \t \t //---elements transformed and/or in different(svg) viewports---
\t \t \t var sCTM = DragTarget.getScreenCTM();
\t \t \t var Pnt = pnt.matrixTransform(sCTM.inverse());
\t \t \t TransformRequestObj = DragTarget.ownerSVGElement.createSVGTransform()
\t \t \t //---attach new or existing transform to element, init its transform list---
\t \t \t var myTransListAnim=DragTarget.transform
\t \t \t TransList=myTransListAnim.baseVal
\t \t \t OffsetX = Pnt.x
\t \t \t OffsetY = Pnt.y
\t \t \t Dragging=true;
\t \t }
\t }
}
//---mouse move---
function drag(evt)
{
if(Dragging)
{
var pnt = DragTarget.ownerSVGElement.createSVGPoint();
pnt.x = evt.clientX;
pnt.y = evt.clientY;
//---elements in different(svg) viewports, and/or transformed ---
var sCTM = DragTarget.getScreenCTM();
var Pnt = pnt.matrixTransform(sCTM.inverse());
Pnt.x -= OffsetX;
Pnt.y -= OffsetY;
TransformRequestObj.setTranslate(Pnt.x,Pnt.y)
TransList.appendItem(TransformRequestObj)
TransList.consolidate()
intersectShape(DragTarget)
}
}
//--mouse up---
function endDrag()
{
Dragging = false;
DragTarget.setAttribute("style","cursor:default")
}
//==================add a bunch of SVG elements============
//---onload: svgGLOB(50,800,800,30)---
function svgGLOB(elems,svgWidth,svgHeight,elemSize)
{
\t /* ---fill empty inline SVG element---
\t \t <div id="svgDiv"><svg id="mySVG" /></div>
\t */
\t var NS="http://www.w3.org/2000/svg"
\t mySVG.setAttribute("width",svgWidth)
\t mySVG.setAttribute("height",svgHeight)
\t svgDiv.style.width=svgWidth+"px"
\t svgDiv.style.height=svgHeight+"px"
\t var globG=document.createElementNS(NS,"g")
\t globG.id="globG"
\t globG.setAttribute("stroke","black")
\t globG.setAttribute("stroke-width",1)
\t mySVG.appendChild(globG)
\t var points=randomPoints(elems,svgWidth,svgHeight,elemSize)
\t var n=points.length
\t var circleCnt=0
\t var ellipseCnt=0
\t var rectCnt=0
\t var polygonCnt=0
\t var RandomElems=[]
\t RandomElems[0]="circle"
\t RandomElems[1]="rect"
\t RandomElems[2]="ellipse"
\t RandomElems[3]="polygon_3"
\t RandomElems[4]="polygon_4"
\t RandomElems[5]="polygon_5"
\t RandomElems[6]="polygon_6"
\t RandomElems[7]="polygon_7"
\t RandomElems[8]="polygon_8"
\t RandomElems[9]="polygon_9"
\t RandomElems[10]="polygon_10"
\t RandomElems[11]="polygon_11"
\t RandomElems[12]="polygon_12"
\t for(var k=0;k<n;k++)
\t {
\t \t var rand=rdm(0,12)
\t \t var elemStr=RandomElems[rand]
\t \t if(!elemStr.indexOf("_"))
\t \t \t var elemSt=elemStr
\t \t else
\t \t \t var elemSt=elemStr.split("_")[0]
\t \t var elem=document.createElementNS(NS,elemSt)
\t \t if(elemSt=="circle")
\t \t {
\t \t \t elem.setAttribute("r",elemSize)
\t \t \t elem.setAttribute("fill",rcolor())
\t \t \t elem.setAttribute("cx",points[k][0])
\t \t \t elem.setAttribute("cy",points[k][1])
\t \t \t elem.id=elemSt+(circleCnt++)
\t \t }
\t \t else if(elemSt=="ellipse")
\t \t {
\t \t \t elem.setAttribute("rx",elemSize)
\t \t \t elem.setAttribute("ry",elemSize/2)
\t \t \t elem.setAttribute("fill",rcolor())
\t \t \t elem.setAttribute("cx",points[k][0])
\t \t \t elem.setAttribute("cy",points[k][1])
\t \t \t elem.id=elemSt+(ellipseCnt++)
\t \t }
\t \t else if(elemSt=="rect")
\t \t {
\t \t \t elem.setAttribute("width",elemSize)
\t \t \t elem.setAttribute("height",elemSize)
\t \t \t elem.setAttribute("fill",rcolor())
\t \t \t elem.setAttribute("x",points[k][0])
\t \t \t elem.setAttribute("y",points[k][1])
\t \t \t elem.id=elemSt+(rectCnt++)
\t \t }
\t \t else if(elemSt=="polygon")
\t \t {
\t \t \t var pgonSides=parseInt(elemStr.split("_")[1])
\t \t \t var pgonPnts=polygon(pgonSides,elemSize,points[k][0],points[k][1])
\t \t \t elem.setAttribute("fill",rcolor())
\t \t \t elem.setAttribute("points",pgonPnts.join())
\t \t \t elem.id=elemSt+(polygonCnt++)
\t \t }
elem.setAttribute("class","dragTarget")
\t \t globG.appendChild(elem)
\t }
\t //---obtain a random whole number from a thru b---
\t function rdm(a,b)
\t {
\t \t return a + Math.floor(Math.random()*(b-a+1));
\t }
\t function randomPoints(elems,svgWidth,svgHeight,elemSize)
\t {
\t \t //--return format:[ [x,y],[x,y],,, ]
\t \t //---Generate random points---
\t \t function times(n, fn)
\t \t {
\t \t \t var a = [], i;
\t \t \t for (i = 0; i < n; i++) {
\t \t \t a.push(fn(i));
\t \t \t }
\t \t \t return a;
\t \t }
\t \t var width=svgWidth-2*elemSize
\t \t var height=svgHeight-2*elemSize
\t \t return \t RandomPnts = times(elems, function() { return [Math.floor(width * Math.random()) + elemSize, Math.floor(height * Math.random()) + elemSize] });
\t }
//---random color---
\t function rcolor()
\t {
\t \t var letters = 'ABCDEF'.split('');
\t \t var color = '#';
\t \t for (var i = 0; i < 6; i++)
\t \t {
\t \t \t color += letters[Math.round(Math.random() * 15)];
\t \t }
\t \t return color;
\t }
\t function polygon(vCnt,radius,centerX,centerY)
\t {
\t \t var myPoints=[]
\t \t var polyXPts = Array(vCnt);
\t \t var polyYPts = Array(vCnt);
\t \t var vertexAngle = 360/vCnt;
\t \t //---init polygon points processor---
\t \t for(var v=0; v<vCnt; v++)
\t \t {
\t \t \t theAngle = (v*vertexAngle)*Math.PI/180;
\t \t \t polyXPts[v] = radius*Math.cos(theAngle);
\t \t \t polyYPts[v] = -radius*Math.sin(theAngle);
\t \t }
\t \t //--note points are CCW---
\t \t for(var v=0;v<vCnt; v++)
\t \t {
\t \t \t var point=[centerX+polyXPts[v],centerY+polyYPts[v]]
\t \t \t myPoints.push(point)
\t \t }
\t \t return myPoints
\t }
}
</script>
B、Cは何をしているなど、より良いコメントせずに、あなたのコード内のロジックを通して読みにくいです。 b1.y == b2.yのようなものでbboxをテストしたいのですか?彼らが等しいかどうかは分かりませんが、ブロッキングポイントを見つけるには> =または<=などであるかどうかだけをテストします。たぶん私はかなりコードを理解していないだろう。 – Ian
重複を完全に防止するためのほとんどのアプローチは、通常、動きに望ましくない「詰まり」をもたらします。衝突した要素の不透明度を変更するだけで、衝突がfalseの場合は不透明度= 1が返されます。これは、要素が衝突したときにドラッグ中の「穏やかな」ユーザフィードバックを提供します。 –
@Ian私は、rectがそれが衝突したrectrの側に "スティック"することを望んでいました。 > =または<=演算子を使用した場合、rect365の別の側と衝突した場合でも、<= or > =演算子を使用して、条件付きにテレポートする可能性があります。 –