簡單實現svg的拖拽和縮放

2021-09-25 10:25:39 字數 2094 閱讀 2499

此方法限制太多,可能

svg使用d3繪製,並且抽象出svg中所有元素的乙個參照點和縮放比例

svg元素不會太多,否則會造成卡頓。

最近有個專案需要我幫一下前端,主要是使用d3繪製svg放在頁面,其中有乙個功能就是對繪製的svg進行拖動和縮放,有點像地圖。

這裡我已經寫好了乙個方法來繪製svg

function drawtopo(svg, data, x, y, svga, radio)
其中svg是要繪製的元素,data是要繪製的資料,x,y是svg的中心座標,svga是父元素的邊長,來控制svg(正方形)剛好在父元素內,radio是縮放比例

實現方式是重繪,所以元素太多會造成卡頓。

一、拖拽

我們來分析拖拽的過程,滑鼠按下---->滑鼠移動------>鬆開滑鼠。對應的事件分別是mousedown、mousemove、mouseup,先定義兩個全域性變數

data() ,

}}

滑鼠按下事件

mousedown(e) ,

//滑鼠按下,準備拖拽,記錄當前滑鼠位置

滑鼠移動事件

mousemove(e) 

let nx = event .clientx;

let ny = event .clienty;

//計算偏移座標

let offsetx = nx - this.mousepos.x;

let offsety = ny - this.mousepos.y;

//drag方法會把svg刪除再重繪

this.drag(offsetx, offsety);

//繼續記錄滑鼠位置

this.mousepos.x = nx;

this.mousepos.y = ny;

},

最後放開滑鼠

mouseup(e) ,
乙個問題,毋庸置疑這三個事件都註冊在svg元素(或者與svg等大的父元素)上,但是當滑鼠拖到svg外面時,在svg外面放開了滑鼠,滑鼠回到svg中,圖形會隨著滑鼠移動,這樣是不應該的,所以應該把最後乙個事件mouseup註冊到最外面的元素上,那麼滑鼠在svg外放開也可以觸發。

二、縮放

縮放的實現和拖拽類似,相同的就不贅述了。

縮放是根據滑鼠滾輪的事件觸發,但是滑鼠滾輪有他的預設事件,那就是頁面滾動,這裡要阻止它。

mousewheel(e)  else 

if(newradio <= 0.1)

this.radio = newradio;

this.zoom();

},

對於縮放,我是想做對於滑鼠位置放大和縮小,這裡要獲取到滑鼠相對于父元素的座標(具體做法可以參考上篇文章),保證滑鼠放在的那一點相對于父元素的座標(後都稱絕對座標)不變,再計算中心座標的偏移量,一開始我是使用矩陣的座標變換做的,計算量很大,結果顯示並不如預期,並且當時矩陣座標變換也學的不好,我懷疑是算錯了,然後突然想到向量,發現用向量的話計算量大大降低,結果顯示還是一樣。最後還是做的關於中心座標(包括拖拽後的)的縮放。

對於沒能將圖形在滑鼠位置放大縮小的原因,我認為是做法有問題,專案中的svg圖形是以中心點開始向外發散繪製的,所以不應該是滑鼠那一點絕對座標不變,而應該是滑鼠所在的元素組的參考點絕對座標不變。但是實現起來太麻煩,另外如果滑鼠沒有在任何乙個元素組也不好處理,所以乾脆以中心座標不變吧。

另外,此方法簡單粗暴,但用處並不太大,只做對拖拽和縮放的理解使用。

最尷尬的是在寫這篇部落格的時候我看到了一篇文章,讓我知道了有transform,汗吶!!!

svg計算位置要矩陣和向量靈活使用

可以使用transform

這裡給出簡單**片段(親測可用)

let svg = document.getelementbyid('svg');

svg.style.transform = 'scale(3)';

把svg放大三倍,這裡縮放就要計算中心位置偏移量了,然後使用transform的translate進行平移,避免重繪。

SVG元素縮放的問題

在網上研究了一下,svg元素的縮放有兩種方法。參考viewbox的使用方法如下 這段svg的 svg的顯示需要400 400的空間。如果更改 如下 則可在100 100的空間裡顯示原本的全部內容,也就是說svg縮小為原來的1 4!viewbox的作用是,把原svg中從 0,0 到 400,400 區...

EyesBaby功能實現之視窗拖拽與縮放功能

winform中窗體拖拽主要由滑鼠移動事件 mousemove 滑鼠按下事件 mousedown 和滑鼠釋放事件 mouseup 完成。以下詳細 滑鼠滾動軸控制視窗大小 需要實現滑鼠滑動滾動軸事件 mousewheel 事件引數mouseeventargs.delta值分別是120和 120.如下 ...

簡單拖拽事件實現

var div document.getelementbyid div 通過id找到你的目標元素 div.ondrag function evt 主要應用到的還是ondrag事件 當然你也可以用 var drage false if ontouchstart in window else div.a...