1. 程式人生 > >SVG圖形拖動功能的實現

SVG圖形拖動功能的實現

實現的功能

在介面上將有一些圖形,你可以隨意拖動這些圖形,可以把它們互相疊加在一起。一旦圖形被拖入到黃色矩形框中,就不可以移動了


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;
    }
}



相關推薦

SVG圖形功能實現

實現的功能 在介面上將有一些圖形,你可以隨意拖動這些圖形,可以把它們互相疊加在一起。一旦圖形被拖入到黃色矩形框中,就不可以移動了 HTML檔案 <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.

C#窗體屬性FormBordeStyle設定為none後,通過程式碼實現窗體滑鼠功能

備註:使用的是visual studio2013版本 1、新建C#窗體應用程式,初始化的程式預設FormBordeStyle屬性為Sizable,修改屬性FormBordeStyle為none (1)修改前 (2)修改後 2、F5除錯程式後,此時窗體沒有邊框、

JFrame實現無邊框,實現實現關閉按鈕,開啟實現儲存檔案到本地,實現頭像放大功能實現圖片瀏覽器

package SwingTest3; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.even

使用canvas和js實現多種圖形效果

<!doctype html> <html> <head>     <title> </title>     <meta http-equiv="X-UA-Compatible" content="IE=9

surfaceView實現圖片縮放功能

還是老闆牛,多向他學習請教。之前折騰了好一會兒的問題,被老闆一上午搞定。 問題:採用surface來實現多點觸控縮放,拖動顯示功能。 附上初稿程式碼,明天再好好整理下, public class MySurfaceView3 extends SurfaceView impl

用OnMouseMove()訊息可以實現滑鼠的功能

afx_msg void OnMouseMove(   UINT nFlags point   );   當滑鼠移動時呼叫此函式 。   引數:   nFlags   指示各種虛擬按鍵是否按下 ,此引數可以是任何下列值的組合:   MK_CONTROL 當CT

canvas上畫出座標集合,並標記新座標,背景支援放大縮小功能

寫在前面:專案需求,使用者上傳一個區位的平面圖片,使用者可以在圖片上新增新的相機位置,並且展示之前已繫結的相機座標位置,圖片支援放大縮小&拖動的功能。新增座標,頁面展示相對canvas定位,儲存時儲存該座標在背景圖片上的座標。原有座標集合相對背景圖片定位,(圖片放大縮小或者拖動時始終在圖片的固定位置)

JQuery 頁面實現頁面滾動

$(function(){ $('.jy-dragscroll').each(function(){ var downx; var downy; var upx; var upy;

MFC客戶區視窗實現

思路: 總共分2步 1 在OnLButtonDown中記住滑鼠點選的位置2 在OnMouseMove中處理視窗移動 程式碼: void CLoginDlg::OnLButtonDown(UINT nF

移動端語音播放以及語音條實現

移動端語音播放,包含了語音播放動態小喇叭,語音條,時間長度,支援移動端觸動拖動,不支援PC拖動。 類似於微信公眾號裡面的語音播放,效果如下: 進入頁面: 播放時: 頁面程式碼: <!DOCTYPE html> <html> <head&g

PictureBox內的圖片功能

當 PictureBox內的圖片太大,超過PictureBox邊框時可以用下面的方法來實現, 通過重繪來實現 :   Code bool wselected = false;  Point p = new Point(); private void pictureBox1

RecyclerView借助ItemTouchHelper實現和滑動刪除功能

enable all istview aslist mar -- main erl pub RecyclerView是官方推薦代替ListView的空間,怎樣實現RecyclerView列表元素的拖動呢? 官方提供了ItemTouchHelper類使用過程例如以下

正交相機下實現滾輪按鈕,滾動滾輪縮放的功能

pix spa serial ext 分享 內容 onu bject 開始 實現了一個功能,鼠標滾輪鍵按下可以拖動視野內的物體全體(其實是相機自己在移動),滾動滾輪可以縮放內容(其實是改變相機視野大小) 效果如下 代碼奉上 1 using UnityE

我的Android進階之旅------>Android自定義View來實現解析lrc歌詞並同步滾動、上下、縮放歌詞的功能

前言 最近有個專案有關於播放音樂時候,關於歌詞有以下幾個功能: 1、實現歌詞同步滾動的功能,即歌曲播放到哪句歌詞,就高亮地顯示出正在播放的這個歌詞; 2、實現上下拖動歌詞時候,可以拖動播放器的進度。即可以不停地上下拖動歌詞,

基於Metronic的Bootstrap開發框架經驗總結(13)--頁面連結收藏夾功能實現2(利用Sortable進行排序)

在上篇隨筆《基於Metronic的Bootstrap開發框架經驗總結(12)--頁面連結收藏夾功能的實現》上,我介紹了連結收藏夾功能的實現,以及對收藏記錄的排序處理。該篇隨筆主要使用功能按鈕的方式移動收藏記錄,功能雖然實現的還算不錯,不過文章出來後,有讀者同行指出可以利用直接拖動的方式實現排序更方便,因此對其

Android自定義View來實現解析lrc歌詞同步滾動、上下、縮放歌詞等功能

http://blog.csdn.net/ouyang_peng/article/details/50813419 前言 最近有個專案有關於播放音樂時候,關於歌詞有以下幾個功能:  1、實現歌詞同步滾動的功能,即歌曲播放到哪句

svg實現元素

這段時間比較忙,php的設計模式想寫工廠模式,但是比較難寫,不是一時半會兒能寫完的,先把現在正在使用的關於svg中元素的拖動,記錄一下。 藉助svg,我們可以畫出多種多樣的圖形,而且利用g標籤,還可以把多個標籤組合在一起,讓他們具有相同的行為。語法也比較簡

Android 實現音樂剪下功能 可以選擇起始點和結束點 也可以同時塊級元素

先看一下最終的效果使用者可以拖動兩邊來改變要擷取音樂的長度,也可以直接拖紅線來改變要擷取音樂的位置唯一的難點就是要計算出當前選擇了多少秒,還有拖動時候的操作,我是直接建立的佈局元素,通過onlayout()方法來改變控制元件的位置,廢話不多說,直接上部分原始碼之前上傳的程式碼

微信小程式中懸浮窗功能實現(主要探討和解決在原生元件上的

問題場景 所謂懸浮窗就是圖中微信圖示的按鈕,採用fixed定位,可拖動和點選。 這算是一個比較常見的實現場景了。 為什麼要用cover-view做懸浮窗?原生元件出來背鍋了~ 最初我做懸浮窗用的不是cover-view,而是view。 這是簡化的程式碼結構: index.wxml: <view cl

原生js實現滑塊驗證

cnblogs tcc mvt wms 網站 hnu 按鈕 itl rip 拖動滑塊驗證是現在的網站隨處可見的,各式各樣的拖動法都有。 下面實現的是某寶的拖動滑塊驗證: <!DOCTYPE html> <html lang="en"> <he