基於svg.js實現對圖形的拖拽、選擇和編輯操作
阿新 • • 發佈:2018-10-21
鼠標移出 strong lse 方便 jquery cap .cn sta plot
本文主要記錄如何使用 svg.js
實現對圖形的拖拽,選擇,圖像渲染及各類形狀的繪制操作。
1、關於SVG
SVG
是可縮放的矢量圖形,使用XML格式定義圖像,可以生成對應的DOM節點,便於對單個圖形進行交互操作。比CANVAS
更加靈活一點。關於SVG的基礎知識,請參考SVG學習地址。
2、SVG.js
今天要說的主角是 SVG.js
,它是對SVG本身的一個封裝庫,提供各種API使對SVG的使用更加方便,相當於JQuery對於JS,它的自我介紹是 輕量級,速度快,更具易讀性。SVG.js官網介紹的很詳細,不過這裏還是簡單的進行一些匯總。
2.1 初始化
<div id="svgDemo"></div>
this.draw = SVG("svgDemo").size("100%", "100%");
SVG(domId)
初始化dom結點。轉成svg
元素size()
是svg.js中的改變畫板大小的方法,其中參數可以是像素:size(‘100px‘, ‘100px‘)
;,也可以是百分比size(‘100%‘, ‘100%‘)
;
2.2 一些基本形狀
如圖所示,我們可以很快速的繪制出一些基本圖形。具體的API詳見對應的代碼塊。
// 畫線 let line = this.draw .line(10, 10, 10, 150) // 起點xy,終點xy .stroke({ width: 5, linecap: "round", color: "blue" }); // 線條樣式 // 畫矩形 let rect = this.draw .rect(100, 100) // 寬高 .radius(10) // 圓角 .fill("red") //填充 .move(20, 20); // 位移 // 畫圓 let circle = this.draw .circle(100) // 圓直徑 .fill("green") .move(130, 20); // 畫橢圓 let ellipse = this.draw .ellipse(150, 100) // 寬直徑,高直徑 .move(240, 20) .fill("pink"); // 折線 let polyline = this.draw .polyline(‘450, 10, 400, 100, 500, 100‘) // 點的位置,也可以使用數組替換[[450,10],[400,100],[500,100]] .fill("#f06") .stroke({ width: 1, color: "black" }); // 多邊形 let polygon = this.draw.polygon([[550,10],[600,10],[630,50],[600,100],[550,100],[520,50]]) // 點的位置 .fill("#71f5ea") .stroke({ width: 1 });
3、實現效果
介紹了簡單的使用方法,現闡述如何使用 svg.js
及對應的一些拓展插件,實現對圖片的標註操作。效果如下,我們可以對圖片進行放大、縮小、拖拽操作,也可以在圖片上繪制不同的圖形。當鼠標放在圖片上時,會出現輔助線。(圖片源於網絡)
圖片縮小效果
圖片放大效果
圖片拖拽效果
在圖片上繪制圖形效果
3.1 繪制圖像
這裏說一下,下面的代碼只是粘貼出核心的代碼。並不能直接粘貼復制實現效果。
{ //...省略代碼 let that = this; this.mainImage = this.draw .image(imgurl) .loaded(function(loader) { // 圖片加載後,設置圖片大小 this.size(loader.width, loader.height); // 繪制一個圖形組合,之後的圖形都在這個組合上操作 that.drawGroup = that.draw.group(); // 給圖形組合加邊框 let borderRect = that.drawGroup .rect(loader.width, loader.height) .stroke(DeomSet.imageBorder) // DeomSet下都是一些配置項,這裏不再羅列。 .fill("none"); // 給圖形組合加輔助線,只有鼠標移入地時候才顯示,先繪制dom that.lineX = that.drawGroup.line(0, 0, 0, 0).stroke(DeomSet.imageLine); that.lineY = that.drawGroup.line(0, 0, 0, 0).stroke(DeomSet.imageLine); // 將圖像也放入組合中 that.drawGroup.add(this).attr(DeomSet.groupId); // 使圖像組合可以放大縮小 that.groupZoom = that.drawGroup.panZoom(DeomSet.zoomOpt); // 鼠標移動事件 that.drawGroup.on("mousemove", that.mousemoveEvt, that); // 鼠標移出事件 that.drawGroup.on("mouseleave", that.mouseleaveEvt, that); // 鼠標點下 that.drawGroup.on("mousedown", that.mousedownEvt, that); // 鼠標松開 that.drawGroup.on("mouseup", that.mouseupEvt, that); }); }
代碼解釋:
image(url)
:在svg上繪制圖片loaded((loader)=>{})
:圖片加載成功後的回調事件,loader
參數返回的是圖像的信息,包括寬、高、鏈接group()
:繪制一個圖形組合panZoom()
:需引入 svg.pan-zoom.js 插件(npm install svg.pan-zoom.js -- save-dev),實現滾動鼠標,放大縮小圖形transform()
:可以獲取圖形移動和放大縮小的位置setPosition(x, y, scale)
:x,y表示位置,scale表示縮放比例
on(eventname,event,context)
事件綁定,eventname
:事件名,event
:事件,context
:上下文
3.2 繪制指示參考線
鼠標在圖片上移動的時候,會顯示提示的參考線,這樣更加方便繪制圖形。
{
//...省略代碼
// mousemove事件
// getPointer()這是獲取點的位置的方法,不是API
let { zx, zy } = this.getPointer(e);
// 獲取圖片的寬高
let w = this.mainImage.width();
let h = this.mainImage.height();
// 畫線
this.lineX.front().plot(0, zy + 1, w, zy + 1);
this.lineY.front().plot(zx + 1, 0, zx + 1, h);
}
front()
:表示在組合裏顯示置前plot()
:圖形移動繪制
3.3 繪制圖形
/**
* 繪制移動的矩形
*/
//...省略代碼
let currentDraw = this.currentDraw;
if (!currentDraw) {
this.currentDraw = this.drawGroup
.rect(0, 0)
.move(x, y) // 這裏的xy表示矩形的位置
.fill(OcrSet.rect)
.stroke(OcrSet.rectStroke)
.attr({ id: id });
} else {
let width = Math.abs(zx - x),
height = Math.abs(zy - y),
mx = Math.min(zx, x),
my = Math.min(zy, y); // zx,zy表示移動的鼠標的位置
this.currentDraw.size(width, height).move(mx, my);
}
/**
* 繪制多邊形-過程
*/
//...省略代碼
let currentDraw = this.currentDraw;
if (!currentDraw) {
points.push([zx, zy]); // points表示當前多邊形的點
this.currentDraw = this.drawGroup
.polygon(points)
.fill(OcrSet.polygo)
.stroke(OcrSet.rectStroke)
.attr({ id: id });
} else {
points = this.currentDraw.array().value.slice(0);
points.push([zx, zy]);
this.currentDraw.plot(points);
}
array()
:可以獲取到多邊形的點信息
3.4 圖形選中拖拽事件
// 圖形可拖拽
this.selectShape.draggable();
// 圖形禁止拖拽
this.selectShape.draggable(false);
// 圖形選中並可放大縮小
this.selectShape.selectize(OcrSet.selectOpt).resize();
// 圖形去除選中並禁止放大縮小
this.selectShape.selectize(false, { deepSelect: true }).resize("stop");
// 圖形位置修改後的事件
this.selectShape.on("resizedone", function() {
...
});
// 圖形拖拽後的事件
this.selectShape.off("dragend").on("dragend", function(e) {
...
});
- 圖形拖拽:需引入 svg.draggable.js 插件(
npm install svg.draggable.js -- save-dev
),實現圖形的拖拽draggable(boolean)
:支持拖拽,當boolean
是false
的時候禁止拖拽;dragend()
:拖拽後的事件
- 圖形選擇:需引入 svg.select.js 插件(
npm install svg.select.js -- save-dev
),實現圖形的選擇和放大縮小的操作selectize()
:圖形變成選中狀態resize(param)
:圖形可放大縮小,當參數param
是stop
的時候,禁止放大縮小resizedone()
:圖形放大縮小後的操作
基於svg.js實現對圖形的拖拽、選擇和編輯操作