SVG图形拖动功能的实现

来源:互联网 发布:淘宝茶叶类目 编辑:程序博客网 时间:2024/06/06 11:00

实现的功能

在界面上将有一些图形,你可以随意拖动这些图形,可以把它们互相叠加在一起。一旦图形被拖入到黄色矩形框中,就不可以移动了


HTML文件

<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"><head>    <meta charset="utf-8" />    <title></title></head><body>    <svg id="s" width="100%" height="100%" viewBox="0 0 1000 1000" xmlns="http://www.w3.org/2000/svg" onload="init(evt)" onmousedown="Grab(evt)" onmousemove="Drag(evt)" onmouseup="Drop(evt)">        <rect id="BackDrop" x="-10%" y="-10%" width="110%" height="110%" fill="none" pointer-events="all" />        <circle id="Blue_Circle" cx="30" cy="30" r="25" style="fill:blue;" />        <text id="Draggable_Text" x="20" y="100" style="fill:red;font-size:18px;font-weight:bold;font-family:SimHei">可拖动文本</text>        <rect id="Green_Rectangle" x="50" y="150" width="100" height="100" style="fill:green" />        <g id="Box">            <rect id="FolderRectangle" x="300" y="100" width="200" height="150" style="fill:yellow;stroke:brown;stroke-width:3;" />        </g>        <script type="application/javascript" xlink:href="13-7.js"></script>    </svg></body></html>
JS文件

var svgDoc = null;var svgRoot = null;var trueCoords = null;//记录元素在视口中的实际坐标var grabCoords = null;//表示视图经过缩放或移动后的点在视口中的坐标var backDrop = null;var GrabPoint = null;var DragTarget = null;function init(evt) {    svgDoc = evt.target.ownerDocument;    svgRoot = evt.target;    //两个不显示的点    trueCoords = svgRoot.createSVGPoint();    GrabPoint = svgRoot.createSVGPoint();    //定义了画布,作为拖动时间的透明背景层使用,接收所有的触发事件    //这样做主要是为了避免因为拖动鼠标速度太快,而离开了被拖拽的元素,导致鼠标的onmousemove事件无法产生    //有了这个层,无论被拖拽的元素是否跟得上鼠标的脚步,在这个层都能产生鼠标onmousemove事件    backDrop = svgDoc.getElementById("BackDrop");}//获得当前元素在视口中的坐标位置的函数function GetTrueCoords(evt) {           var newScale = svgRoot.currentScale;//currentScale获得当前视图的伸缩比例    var translation = svgRoot.currentTranslate;//currentTranslate获得当前视图的平移量    trueCoords.x = (evt.clientX - translation.x) / newScale;    trueCoords.y = (evt.clientY - translation.y) / newScale;}//鼠标按下触发的事件function Grab(evt) {        var targetElement = evt.target;//取得要拖动的DOM Object    GetTrueCoords(evt);    if ("Box" == targetElement.parentNode.id) {//判断图形是否被拖入黄色框中        DragTarget = null;//后续的拖动事件取消掉        return;    }    if (backDrop != targetElement) {//不是在拖动背景        DragTarget = targetElement;    }        DragTarget.parentNode.appendChild(DragTarget);//把要拖动的元素加入到它的父节点中,类似于在绘图软件中常见的”至于最上方“的操作    DragTarget.setAttributeNS(null, "pointer-events", "none");//取消要拖动元素的鼠标接收事件    //这样可以保证当鼠标释放时所触发的事件的”主人“不是要拖动的元素本身,而是它所覆盖的元素,画布或其他元素        var Matrix = DragTarget.getCTM();//获取当前SVG的坐标转换矩阵     GrabPoint.x = trueCoords.x - Number(Matrix.e);//定义元素移动后在视图中的坐标    GrabPoint.y = trueCoords.y - Number(Matrix.f);}//拖动鼠标触发的事件function Drag(evt) {    GetTrueCoords(evt);//获取当前元素在视口的实际坐标    if (DragTarget) { //判断被拖动元素是否存在        var newX = trueCoords.x - GrabPoint.x;        var newY = trueCoords.y - GrabPoint.y;        DragTarget.setAttributeNS(null, "transform", "translate(" + newX + "," + newY + ")");//设置元素的平移变化参数 实际效果就是被拖动的元素随着鼠标不断移动    }    }function Drop(evt) {//evt不是要拖动的元素本身,而是它所覆盖的元素,画布或其他元素    if (DragTarget) {        var targetElement = evt.target;         DragTarget.setAttributeNS(null, "pointer-events", "all");//恢复要拖动元素的鼠标接收事件        if ("Box" == targetElement.parentNode.id) {            targetElement.parentNode.appendChild(DragTarget);            alert(DragTarget.id + " 已经被拖入黄色箱子中");        } else {            //alert(DragTarget.id + " 已经位于" + targetElement.id + "之上");        }        DragTarget = null;    }}



1 0
原创粉丝点击