135 lines
4.0 KiB
JavaScript
135 lines
4.0 KiB
JavaScript
|
// const UI = {}
|
||
|
|
||
|
|
||
|
// SVG.Point = ( x, y )=> Object.assign( document.documentElement.createSVGPoint(), {x,y} )
|
||
|
|
||
|
Symbol.Draggable = Symbol`Draggable`
|
||
|
|
||
|
var Draggable = obj=> {
|
||
|
|
||
|
if( Symbol.Draggable in obj ) return obj
|
||
|
obj[Symbol.Draggable] = true
|
||
|
|
||
|
obj.startDrag = e=> {
|
||
|
let mouse = new DOMPoint( e.clientX , e.clientY )//.matrixTransform( obj.getCTM().inverse() )
|
||
|
mouse.x /= obj.ownerSVGElement.currentScale
|
||
|
mouse.y /= obj.ownerSVGElement.currentScale
|
||
|
|
||
|
obj.drag.offset = new DOMPoint( mouse.x - obj.x, mouse.y - obj.y )
|
||
|
obj.setAttribute( 'dragged', true )
|
||
|
console.log(e, mouse, obj.drag.offset)
|
||
|
}
|
||
|
|
||
|
obj.drag = function(e)
|
||
|
{//debugger;
|
||
|
if(e.buttons === 1)
|
||
|
{
|
||
|
let mouse = new DOMPoint( e.clientX / obj.ownerSVGElement.currentScale, e.clientY / obj.ownerSVGElement.currentScale )//.matrixTransform( obj.getScreenCTM().inverse() )
|
||
|
, pos = new DOMPoint( mouse.x - obj.drag.offset.x, mouse.y - obj.drag.offset.y)
|
||
|
|
||
|
// pos.x /= obj.ownerSVGElement.currentScale
|
||
|
// pos.y /= obj.ownerSVGElement.currentScale
|
||
|
this.moveTo( pos )
|
||
|
this.dispatchEvent( new Event('move') )
|
||
|
}
|
||
|
}
|
||
|
|
||
|
obj.stopDrag = e=> obj.removeAttribute('dragged')
|
||
|
|
||
|
obj.on`mousedown`( obj.startDrag )
|
||
|
// ,onmousemove:e=> e.buttons === 1 && e.target.drag(e)
|
||
|
//obj.onmouseup = e=> e.currentTarget.setAttribute(' dragged', false )
|
||
|
|
||
|
return obj
|
||
|
}
|
||
|
Draggable.startGlobalDrag = e=> e.target.$$`[dragged]`.filter(el=>el.draggable).map( el=> el.drag(e) )
|
||
|
Draggable.stopGlobalDrag = e=> e.target.$$`[dragged]`.map( el=> el.removeAttribute('dragged') )
|
||
|
|
||
|
// $$`[draggable]`
|
||
|
// .map( Draggable )
|
||
|
|
||
|
// document.documentElement.on`mousemove`( e=> $$`[dragged]`.filter(el=>el.draggable).map( el=> el.drag(e) ) , true )
|
||
|
// document.documentElement.onmouseup = e=> $$`[dragged]`.map( el=> el.removeAttribute('dragged') )
|
||
|
|
||
|
|
||
|
// Makes an element in an SVG document draggable.
|
||
|
// Fires custom `dragstart`, `drag`, and `dragend` events on the
|
||
|
// element with the `detail` property of the event carrying XY
|
||
|
// coordinates for the location of the element.
|
||
|
function makeDraggable(el)
|
||
|
{
|
||
|
if (!el) return console.error('makeDraggable() needs an element')
|
||
|
|
||
|
let svg, pt, doc, root
|
||
|
//var svg = el;
|
||
|
//while (svg && svg.tagName!='svg') svg=svg.parentNode;
|
||
|
//if (!svg) return console.error(el,'must be inside an SVG wrapper');
|
||
|
//var pt=svg.createSVGPoint(), doc=svg.ownerDocument;
|
||
|
|
||
|
//var root = doc.rootElement || doc.body || svg;
|
||
|
let xlate, txStartX, txStartY, mouseStart
|
||
|
let xforms = el.transform.baseVal
|
||
|
|
||
|
el.addEventListener('mousedown', e=> e.which == 1 && startMove(e), false )
|
||
|
|
||
|
function startMove(evt)
|
||
|
{
|
||
|
svg = el.ownerSVGElement
|
||
|
pt = svg.createSVGPoint()
|
||
|
doc = svg.ownerDocument
|
||
|
root = doc.rootElement || doc.body || svg
|
||
|
|
||
|
// We listen for mousemove/up on the root-most
|
||
|
// element in case the mouse is not over el.
|
||
|
root.addEventListener('mousemove',handleMove,false)
|
||
|
root.addEventListener('mouseup', finishMove,false)
|
||
|
|
||
|
// Ensure that the first transform is a translate()
|
||
|
xlate = xforms.numberOfItems>0 && xforms.getItem(0)
|
||
|
if (!xlate || xlate.type != SVGTransform.SVG_TRANSFORM_TRANSLATE){
|
||
|
xlate = xforms.createSVGTransformFromMatrix( svg.createSVGMatrix() )
|
||
|
xforms.insertItemBefore( xlate, 0 )
|
||
|
}
|
||
|
txStartX = xlate.matrix.e
|
||
|
txStartY = xlate.matrix.f
|
||
|
mouseStart = inElementSpace(evt)
|
||
|
fireEvent('dragstart')
|
||
|
}
|
||
|
|
||
|
function handleMove(evt)
|
||
|
{
|
||
|
var point = inElementSpace(evt)
|
||
|
xlate.setTranslate(
|
||
|
txStartX + point.x - mouseStart.x,
|
||
|
txStartY + point.y - mouseStart.y
|
||
|
)
|
||
|
fireEvent('drag')
|
||
|
}
|
||
|
|
||
|
function finishMove(evt)
|
||
|
{
|
||
|
root.removeEventListener('mousemove',handleMove,false)
|
||
|
root.removeEventListener('mouseup', finishMove,false)
|
||
|
fireEvent('dragend')
|
||
|
}
|
||
|
|
||
|
function fireEvent(eventName)
|
||
|
{
|
||
|
var event = new Event(eventName)
|
||
|
event.detail = { x:xlate.matrix.e, y:xlate.matrix.f }
|
||
|
return el.dispatchEvent(event)
|
||
|
}
|
||
|
|
||
|
// Convert mouse position from screen space to coordinates of el
|
||
|
function inElementSpace(evt)
|
||
|
{
|
||
|
pt.x = evt.clientX
|
||
|
pt.y = evt.clientY
|
||
|
return pt.matrixTransform( el.parentNode.getScreenCTM().inverse() )
|
||
|
}
|
||
|
|
||
|
return el
|
||
|
}
|
||
|
|
||
|
|
||
|
export { Draggable, makeDraggable }
|