svg.draggable.js
Advanced tools
Comparing version 1.0.0 to 2.0.0
@@ -1,2 +0,2 @@ | ||
/*! svg.draggable.js - v1.0.0 - 2015-06-12 | ||
/*! svg.draggable.js - v2.0.0 - 2015-06-21 | ||
* https://github.com/wout/svg.draggable.js | ||
@@ -6,182 +6,169 @@ * Copyright (c) 2015 Wout Fierens; Licensed MIT */ | ||
SVG.extend(SVG.Element, { | ||
// Make element draggable | ||
// Constraint might be a object (as described in readme.md) or a function in the form "function (x, y)" that gets called before every move. | ||
// The function can return a boolean or a object of the form {x, y}, to which the element will be moved. "False" skips moving, true moves to raw x, y. | ||
draggable: function(value, constraint, undefined) { | ||
var start, drag, end, element = this, | ||
parent = this.parent(SVG.Nested) || this.parent(SVG.Doc), | ||
parameter = {} | ||
// creates handler, saves it | ||
function DragHandler(el){ | ||
el.remember('_draggable', this) | ||
this.el = el | ||
} | ||
/* Check the parameters and reassign if needed */ | ||
if (typeof value == 'function' || typeof value == 'object') { | ||
constraint = value | ||
value = true | ||
} | ||
/* When no parameter is given, our value is true */ | ||
value = value === undefined ? true : value | ||
constraint = constraint || {} | ||
// Sets new parameter, starts dragging | ||
DragHandler.prototype.init = function(constraint, val){ | ||
var _this = this | ||
this.constraint = constraint | ||
this.value = val | ||
this.el.on('mousedown.drag', function(e){ _this.start(e) }) | ||
} | ||
if(element.remember('_draggable')){ | ||
element.remember('_draggable', constraint) | ||
return; | ||
} | ||
/* Remember the constraints on the element because they would be overwritten by the next draggable-call otherwise */ | ||
element.remember('_draggable', constraint) | ||
// transforms one point from screen to user coords | ||
DragHandler.prototype.transformPoint = function(x, y){ | ||
/* start dragging */ | ||
start = function(event) { | ||
this.p.x = x | ||
this.p.y = y | ||
/* invoke any callbacks */ | ||
element.fire('beforedrag', { | ||
event: event | ||
}) | ||
return this.p.matrixTransform(this.m); | ||
/* get element bounding box */ | ||
var box = element.bbox() | ||
} | ||
// gets elements bounding box with specian handling of groups, nested and use | ||
DragHandler.prototype.getBBox = function(){ | ||
if (element instanceof SVG.G) { | ||
box.x = element.x() | ||
box.y = element.y() | ||
var box = this.el.bbox() | ||
} else if (element instanceof SVG.Nested) { | ||
box = element.rbox() | ||
/*box = { | ||
x: element.x(), | ||
y: element.y(), | ||
width: element.width(), | ||
height: element.height() | ||
}*/ | ||
} | ||
if(this.el instanceof SVG.Nested) box = this.el.rbox() | ||
if (this.el instanceof SVG.G || this.el instanceof SVG.Use || this.el instanceof SVG.Nested) { | ||
box.x = this.el.x() | ||
box.y = this.el.y() | ||
} | ||
/* store event and start position */ | ||
parameter = { | ||
event: event, | ||
position: { | ||
x: box.x, | ||
y: box.y, | ||
width: box.width, | ||
height: box.height, | ||
zoom: parent.viewbox().zoom, | ||
rotation: element.transform().rotation * Math.PI / 180 | ||
} | ||
} | ||
return box | ||
} | ||
/* add while and end events to window */ | ||
SVG.on(window, 'mousemove.drag', drag) | ||
SVG.on(window, 'mouseup.drag', end) | ||
// start dragging | ||
DragHandler.prototype.start = function(e){ | ||
/* invoke any callbacks */ | ||
element.fire('dragstart', parameter) | ||
// check for left button | ||
if((e.which || e.buttons) != 1){ | ||
return | ||
} | ||
var _this = this | ||
/* prevent selection dragging */ | ||
event.preventDefault() | ||
} | ||
// fire beforedrag event | ||
this.el.fire('beforedrag', { event: e, handler: this }) | ||
/* while dragging */ | ||
drag = function(event) { | ||
// search for parent on the fly to make sure we can call | ||
// draggable() even when element is not in the dom currently | ||
this.parent = this.parent || this.el.parent(SVG.Nested) || this.el.parent(SVG.Doc) | ||
this.p = this.parent.node.createSVGPoint() | ||
var x, y, constraint = element.remember('_draggable'), | ||
rotation = parameter.position.rotation, | ||
width = parameter.position.width, | ||
height = parameter.position.height, | ||
delta = { | ||
x: event.pageX - parameter.event.pageX, | ||
y: event.pageY - parameter.event.pageY, | ||
zoom: parameter.position.zoom | ||
} | ||
element.fire('dragmove', { | ||
delta: delta, | ||
event: event | ||
}) | ||
// save current transformation matrix | ||
this.m = this.el.node.getScreenCTM().inverse() | ||
/* caculate new position [with rotation correction] */ | ||
x = parameter.position.x + (delta.x * Math.cos(rotation) + delta.y * Math.sin(rotation)) / parameter.position.zoom | ||
y = parameter.position.y + (delta.y * Math.cos(rotation) + delta.x * Math.sin(-rotation)) / parameter.position.zoom | ||
var box = this.getBBox() | ||
this.startPoints = { | ||
// We take absolute coordinates since we are just using a delta here | ||
mouse: this.transformPoint(e.pageX, e.pageY), | ||
box: box | ||
} | ||
// add drag and end events to window | ||
SVG.on(window, 'mousemove.drag', function(e){ _this.drag(e) }) | ||
SVG.on(window, 'mouseup.drag', function(e){ _this.end(e) }) | ||
/* move the element to its new position, if possible by constraint */ | ||
if (typeof constraint == 'function') { | ||
// fire dragstart event | ||
this.el.fire('dragstart', {event: e, p: this.p, m: this.m, handler: this}) | ||
var coord = constraint.call(element, x, y) | ||
// prevent browser drag behavior | ||
e.preventDefault() | ||
} | ||
/* bool just show us if movement is allowed or not */ | ||
if (typeof coord == 'boolean') { | ||
coord = { | ||
x: coord, | ||
y: coord | ||
} | ||
} | ||
// while dragging | ||
DragHandler.prototype.drag = function(e){ | ||
/* if true, we just move. If !false its a number and we move it there */ | ||
if (coord.x === true) { | ||
element.x(x) | ||
} else if (coord.x !== false) { | ||
element.x(coords.x) | ||
} | ||
var box = this.getBBox() | ||
, p = this.transformPoint(e.pageX, e.pageY) | ||
, x = this.startPoints.box.x + p.x - this.startPoints.mouse.x | ||
, y = this.startPoints.box.y + p.y - this.startPoints.mouse.y | ||
, c = this.constraint | ||
if (coord.y === true) { | ||
element.y(y) | ||
} else if (coord.y !== false) { | ||
element.y(coords.y) | ||
} | ||
this.el.fire('dragmove', { event: e, p: this.p, m: this.m, handler: this }) | ||
} else if (typeof constraint == 'object') { | ||
// move the element to its new position, if possible by constraint | ||
if (typeof c == 'function') { | ||
/* keep element within constrained box */ | ||
if (constraint.minX != null && x < constraint.minX) | ||
x = constraint.minX | ||
else if (constraint.maxX != null && x > constraint.maxX - width) | ||
x = constraint.maxX - width | ||
var coord = c.call(this.el, x, y, this.m) | ||
if (constraint.minY != null && y < constraint.minY) | ||
y = constraint.minY | ||
else if (constraint.maxY != null && y > constraint.maxY - height) | ||
y = constraint.maxY - height | ||
element.move(x, y) | ||
// bool, just show us if movement is allowed or not | ||
if (typeof coord == 'boolean') { | ||
coord = { | ||
x: coord, | ||
y: coord | ||
} | ||
} | ||
// if true, we just move. If !false its a number and we move it there | ||
if (coord.x === true) { | ||
this.el.x(x) | ||
} else if (coord.x !== false) { | ||
this.el.x(coord.x) | ||
} | ||
if (coord.y === true) { | ||
this.el.y(y) | ||
} else if (coord.y !== false) { | ||
this.el.y(coord.y) | ||
} | ||
/* when dragging ends */ | ||
end = function(event) { | ||
} else if (typeof c == 'object') { | ||
/* calculate move position */ | ||
var delta = { | ||
x: event.pageX - parameter.event.pageX, | ||
y: event.pageY - parameter.event.pageY, | ||
zoom: parameter.position.zoom | ||
} | ||
// keep element within constrained box | ||
if (c.minX != null && x < c.minX) | ||
x = c.minX | ||
else if (c.maxX != null && x > c.maxX - box.width){ | ||
x = c.maxX - box.width | ||
}if (c.minY != null && y < c.minY) | ||
y = c.minY | ||
else if (c.maxY != null && y > c.maxY - box.height) | ||
y = c.maxY - box.height | ||
/* remove while and end events to window */ | ||
SVG.off(window, 'mousemove.drag', drag) | ||
SVG.off(window, 'mouseup.drag', end) | ||
this.el.move(x, y) | ||
} | ||
} | ||
/* invoke any callbacks */ | ||
element.fire('dragend', { | ||
delta: delta, | ||
event: event | ||
}) | ||
} | ||
DragHandler.prototype.end = function(e){ | ||
if (!value) { | ||
element.off('mousedown.drag') | ||
SVG.off(window, 'mousemove.drag') | ||
SVG.off(window, 'mouseup.drag') | ||
// final drag | ||
this.drag(e); | ||
start = drag = end = null | ||
element.forget('_draggable') | ||
return this | ||
// fire dragend event | ||
this.el.fire('dragend', { event: e, p: this.p, m: this.m, handler: this }) | ||
// unbind events | ||
SVG.off(window, 'mousemove.drag') | ||
SVG.off(window, 'mouseup.drag') | ||
} | ||
SVG.extend(SVG.Element, { | ||
// Make element draggable | ||
// Constraint might be a object (as described in readme.md) or a function in the form "function (x, y)" that gets called before every move. | ||
// The function can return a boolean or a object of the form {x, y}, to which the element will be moved. "False" skips moving, true moves to raw x, y. | ||
draggable: function(value, constraint) { | ||
// Check the parameters and reassign if needed | ||
if (typeof value == 'function' || typeof value == 'object') { | ||
constraint = value | ||
value = true | ||
} | ||
/* bind mousedown event */ | ||
element.on('mousedown.drag', start) | ||
var dragHandler = this.remember('_draggable') || new DragHandler(this) | ||
// When no parameter is given, value is true | ||
value = typeof value === 'undefined' ? true : value | ||
if(value) dragHandler.init(constraint || {}, value) | ||
else this.off('mousedown.drag') | ||
return this | ||
@@ -188,0 +175,0 @@ } |
@@ -1,4 +0,4 @@ | ||
/*! svg.draggable.js - v1.0.0 - 2015-06-12 | ||
/*! svg.draggable.js - v2.0.0 - 2015-06-21 | ||
* https://github.com/wout/svg.draggable.js | ||
* Copyright (c) 2015 Wout Fierens; Licensed MIT */ | ||
(function(){SVG.extend(SVG.Element,{draggable:function(a,b,c){var d,e,f,g=this,h=this.parent(SVG.Nested)||this.parent(SVG.Doc),i={};return("function"==typeof a||"object"==typeof a)&&(b=a,a=!0),a=a===c?!0:a,b=b||{},g.remember("_draggable")?void g.remember("_draggable",b):(g.remember("_draggable",b),d=function(a){g.fire("beforedrag",{event:a});var b=g.bbox();g instanceof SVG.G?(b.x=g.x(),b.y=g.y()):g instanceof SVG.Nested&&(b=g.rbox()),i={event:a,position:{x:b.x,y:b.y,width:b.width,height:b.height,zoom:h.viewbox().zoom,rotation:g.transform().rotation*Math.PI/180}},SVG.on(window,"mousemove.drag",e),SVG.on(window,"mouseup.drag",f),g.fire("dragstart",i),a.preventDefault()},e=function(a){var b,c,d=g.remember("_draggable"),e=i.position.rotation,f=i.position.width,h=i.position.height,j={x:a.pageX-i.event.pageX,y:a.pageY-i.event.pageY,zoom:i.position.zoom};if(g.fire("dragmove",{delta:j,event:a}),b=i.position.x+(j.x*Math.cos(e)+j.y*Math.sin(e))/i.position.zoom,c=i.position.y+(j.y*Math.cos(e)+j.x*Math.sin(-e))/i.position.zoom,"function"==typeof d){var k=d.call(g,b,c);"boolean"==typeof k&&(k={x:k,y:k}),k.x===!0?g.x(b):k.x!==!1&&g.x(coords.x),k.y===!0?g.y(c):k.y!==!1&&g.y(coords.y)}else"object"==typeof d&&(null!=d.minX&&b<d.minX?b=d.minX:null!=d.maxX&&b>d.maxX-f&&(b=d.maxX-f),null!=d.minY&&c<d.minY?c=d.minY:null!=d.maxY&&c>d.maxY-h&&(c=d.maxY-h),g.move(b,c))},f=function(a){var b={x:a.pageX-i.event.pageX,y:a.pageY-i.event.pageY,zoom:i.position.zoom};SVG.off(window,"mousemove.drag",e),SVG.off(window,"mouseup.drag",f),g.fire("dragend",{delta:b,event:a})},a?(g.on("mousedown.drag",d),this):(g.off("mousedown.drag"),SVG.off(window,"mousemove.drag"),SVG.off(window,"mouseup.drag"),d=e=f=null,g.forget("_draggable"),this))}})}).call(this); | ||
(function(){function a(a){a.remember("_draggable",this),this.el=a}a.prototype.init=function(a,b){var c=this;this.constraint=a,this.value=b,this.el.on("mousedown.drag",function(a){c.start(a)})},a.prototype.transformPoint=function(a,b){return this.p.x=a,this.p.y=b,this.p.matrixTransform(this.m)},a.prototype.getBBox=function(){var a=this.el.bbox();return this.el instanceof SVG.Nested&&(a=this.el.rbox()),(this.el instanceof SVG.G||this.el instanceof SVG.Use||this.el instanceof SVG.Nested)&&(a.x=this.el.x(),a.y=this.el.y()),a},a.prototype.start=function(a){if(1==(a.which||a.buttons)){var b=this;this.el.fire("beforedrag",{event:a,handler:this}),this.parent=this.parent||this.el.parent(SVG.Nested)||this.el.parent(SVG.Doc),this.p=this.parent.node.createSVGPoint(),this.m=this.el.node.getScreenCTM().inverse();var c=this.getBBox();this.startPoints={mouse:this.transformPoint(a.pageX,a.pageY),box:c},SVG.on(window,"mousemove.drag",function(a){b.drag(a)}),SVG.on(window,"mouseup.drag",function(a){b.end(a)}),this.el.fire("dragstart",{event:a,p:this.p,m:this.m,handler:this}),a.preventDefault()}},a.prototype.drag=function(a){var b=this.getBBox(),c=this.transformPoint(a.pageX,a.pageY),d=this.startPoints.box.x+c.x-this.startPoints.mouse.x,e=this.startPoints.box.y+c.y-this.startPoints.mouse.y,f=this.constraint;if(this.el.fire("dragmove",{event:a,p:this.p,m:this.m,handler:this}),"function"==typeof f){var g=f.call(this.el,d,e,this.m);"boolean"==typeof g&&(g={x:g,y:g}),g.x===!0?this.el.x(d):g.x!==!1&&this.el.x(g.x),g.y===!0?this.el.y(e):g.y!==!1&&this.el.y(g.y)}else"object"==typeof f&&(null!=f.minX&&d<f.minX?d=f.minX:null!=f.maxX&&d>f.maxX-b.width&&(d=f.maxX-b.width),null!=f.minY&&e<f.minY?e=f.minY:null!=f.maxY&&e>f.maxY-b.height&&(e=f.maxY-b.height),this.el.move(d,e))},a.prototype.end=function(a){this.drag(a),this.el.fire("dragend",{event:a,p:this.p,m:this.m,handler:this}),SVG.off(window,"mousemove.drag"),SVG.off(window,"mouseup.drag")},SVG.extend(SVG.Element,{draggable:function(b,c){("function"==typeof b||"object"==typeof b)&&(c=b,b=!0);var d=this.remember("_draggable")||new a(this);return b="undefined"==typeof b?!0:b,b?d.init(c||{},b):this.off("mousedown.drag"),this}})}).call(this); |
{ | ||
"name": "svg.draggable.js", | ||
"version": "1.0.0", | ||
"description": "An extension for svn.js which allows to drag elements with your mouse", | ||
"version": "2.0.0", | ||
"description": "An extension for svg.js which allows to drag elements with your mouse", | ||
"main": "dist/svg.draggable.js", | ||
"keywords": [ | ||
@@ -40,4 +41,4 @@ "svg.js", | ||
"dependencies": { | ||
"svg.js":"2.x.x" | ||
"svg.js":"^2.0.1" | ||
} | ||
} |
@@ -45,6 +45,3 @@ # svg.draggable.js | ||
// event.detail.event hold the mouseevent | ||
// dragmove and dragend also serves the current delta values (event.detail.delta.x, y, zoom) | ||
// do stuff | ||
// event.detail.event hold the given data explained below | ||
@@ -57,2 +54,11 @@ }) | ||
### event.detail | ||
`beforedrag`, `dragstart`, `dragmove` and `dragend` gives you the `event` and the `handler` which calculates the drag. | ||
Except for `beforedrag` the events also give you: | ||
- `detail.m` transformation matrix to calculate screen coords to coords in the elements userspace | ||
- `detail.p` pageX and pageY transformed into the elements userspace | ||
## Constraint | ||
@@ -78,2 +84,3 @@ The drag functionality can be limited within a given box. You can pass the the constraint values as an object: | ||
**Note** that every constraint given is evaluated in the elements coordinate system and not in the screen-space | ||
@@ -84,3 +91,3 @@ ## Remove | ||
```javascript | ||
rect.draggable(true) | ||
rect.draggable(false) | ||
``` | ||
@@ -93,7 +100,13 @@ | ||
```javascript | ||
var draw = SVG('paper').attr('viewBox', '0 0 150 100').size(600, 400) | ||
var draw = SVG('paper').viewbox(0, 0, 150, 100).size(600, 400) | ||
``` | ||
## Restrictions | ||
- If your root-svg is transformed this plugin won't work properly (Viewbox is possible) | ||
- Furthermore it is not possible to move a rotated or flipped group properly. However transformed nested SVGs are possible and should be used instead. | ||
## Dependencies | ||
This module requires svg.js v2.0 | ||
This module requires svg.js >= v2.0.1 |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
12425
107
133
1
Updatedsvg.js@^2.0.1