svg_dragable
by DOK_UA
HTML
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 300 300"
onload="makeDraggable(evt)">
<circle id="rotateable" cx="150" cy="150" r="150" stroke="black" stroke-width="1" fill="url(#grad2)" />
<circle id="rotate" cx="150" cy="150" r="140" stroke="black" stroke-width="1" fill="blue" />
<circle class="draggable confine" id="joy" cx="150" cy="150" r="50" stroke="black" stroke-width="3" fill="green" />
</svg>
CSS
.static {
cursor: not-allowed;
}
.draggable {
cursor: move;
}
JavaScript
function makeDraggable(evt) {
var svg = evt.target;
svg.addEventListener('mousedown', startDrag);
svg.addEventListener('mousemove', drag);
svg.addEventListener('mouseup', endDrag);
svg.addEventListener('mouseleave', endDrag);
var selectedElement, offset, transform,
bbox, minX, maxX, minY, maxY, confined;
var boundaryX1 = 20;
var boundaryX2 = 280;
var boundaryY1 = 20;
var boundaryY2 = 280;
function getMousePosition(evt) {
var CTM = svg.getScreenCTM();
if (evt.touches) { evt = evt.touches[0]; }
return {
x: (evt.clientX - CTM.e) / CTM.a,
y: (evt.clientY - CTM.f) / CTM.d
};
}
function startDrag(evt) {
if (evt.target.classList.contains('draggable')) {
selectedElement = evt.target;
offset = getMousePosition(evt);
// Make sure the first transform on the element is a translate transform
var transforms = selectedElement.transform.baseVal;
if (transforms.length === 0 || transforms.getItem(0).type !== SVGTransform.SVG_TRANSFORM_TRANSLATE) {
// Create an transform that translates by (0, 0)
var translate = svg.createSVGTransform();
translate.setTranslate(0, 0);
selectedElement.transform.baseVal.insertItemBefore(translate, 0);
}
// Get initial translation
transform = transforms.getItem(0);
offset.x -= transform.matrix.e;
offset.y -= transform.matrix.f;
confined = evt.target.classList.contains('confine');
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;
}
...