基于svg.js实现对图形的拖拽、选择和编辑操作
本文主要记录如何使用 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实现对图形的拖拽、选择和编辑操作的更多相关文章
- JS实现漂亮的窗口拖拽效果(可改变大小、最大化、最小化、关闭)
转自<JS实现漂亮的窗口拖拽效果(可改变大小.最大化.最小化.关闭)>:http://www.jb51.net/article/73157.htm 这篇文章主要介绍了JS实现漂亮的窗口 ...
- 拖拽系列二、利用JS面向对象OOP思想实现拖拽封装
接着上一篇拖拽系列一.JavaScript实现简单的拖拽效果这一篇博客将接着对上一节实现代码利用JS面向对象(OOP)思维对上一节代码进行封装; 使其模块化.避免全局函数污染.方便后期维护和调用:写到 ...
- (Demo分享)利用JavaScript(JS)实现一个九宫格拖拽功能
利用JavaScript(JS)实现一个九宫格拖拽功能 Demo实现了对任意方格进行拖拽,可以交换位置,其中Demo-1利用了勾股定理判断距离! Demo-1整体思路: 1.首先div实现自由移动 ...
- EgLine V0.3—LVGL官方拖拽式UI编辑工具(可导出代码)
** EdgeLine ** 是LVGL官方团队退出的一款拖拽式UI编辑工具,现在还处于测试间断,目前最新版本为v0.3,已经可导出代码. 注意: 使用该软件需要注册lvgl账号,这一步可能需要代理 ...
- 基于JS的WEB会议室预订拖拽式图形界面的实现
06年的一篇blog,转到这个博客上: 很早之前写的,后来由于这个功能模块取消,最终没有上线,所以与Server交互的那部分还没有写,不过那部分方案我也已经出来了,而且现在客户端这一部分已经通过了比较 ...
- 在高德地图上用svg.js绘制简单图形
这段时间做的一个项目,需要在地图上绘制简单的图形.在学习高德地图JS API的过程中,发现高德地图提供的点.线等API并不能满足我的需求,还好它开放了自定义图层CustomLayer,官方说自定义图层 ...
- 基于SVG.js实现网页初始化线条描绘效果
前端实现看到一个网页的效果很cool(参考https://tympanus.net/Development/SVGDrawingAnimation/index2.html),决定自己去实现以下这个效果 ...
- 基于svg.js实现可编辑的图像
svg.js的git地址https://github.com/svgdotjs/svg.js 实现可以拖动,可双击编辑,可拖动改变长短,线条可旋转以及一个可点击改变大小,可更改内容的二维码. 首先引入 ...
- 【原创】js实现一个可随意拖拽排序的菜单导航栏
1.想做这个效果的原因主要是用在UC上看新闻发现他们的导航菜单很有趣.无聊的时候在哪划着玩了很久.所以就干脆自己写一个.原效果如下 2.整体效果如下,在已推荐和未添加里面每个小方块可以触摸移动位置互换 ...
随机推荐
- 使用私有git仓库备份服务器脚本和配置文件
1. 创建私有git仓库 服务器端配置: # 安装 git yum -y install git # 创建 git 用户 useradd git # 创建私有仓库数据存储目录 mkdir /git_b ...
- php 返回数组中指定多列的方法
php array_column 方法可以返回数组中指定的一列,但不能返回多列,本文将介绍array_column方法的使用,并用代码演示返回数组中指定多列的方法. 1.array_column说明 ...
- javax.jms.JMSException: Could not connect to broker URL: tcp://localhost:61616. Reason: java.net.ConnectException: Connection timed out: connect
本地测试向服务器中ActiveMQ添加队列数据,报错连接超时 解决: 查看服务器端口号是否存在,(最好是0.0.0.0格式的,虽然暂时还不知道为啥得这个格式) 通过telnet测试该端口不通(6161 ...
- jenkins配置以cygwin环境的子节点
1.为Cygwin配置上sshd服务 ⑴.双击点击如下安装文件,并一直选取下一步 ⑵.到这个步骤停止,并且在search栏里输入openssh,并下载搜出的两个程序 ⑶.下载好以后以管理员权限打开cy ...
- 基础篇:6.9)GD&T较线性尺寸公差的优缺点
本章目的:理解GD&T标注对比线性/传统/坐标尺寸公差的优势,但也不要忘记其使用限制. 1.线性尺寸公差 1.1 定义 线性尺寸公差=传统尺寸公差=坐标尺寸公差. 传统尺寸公差(Tradi ...
- POST请求出现中文乱码的问题
最近使用Java的HttpURLConnection请求rest接口时候,POST请求参数中的中文传输之后出现乱码的问题,在网上找了一个亲测有效的方法: 将 DataOutputStream out ...
- 添加ASP.NET网站资源文件夹
ASP.NET应用程序包含7个默认文件夹,分别为Bin.APP_Code.App_GlobalResources.App_LocalResources.App_WebReferences.App_Br ...
- 国内Windows系统go get语言包
这时候我们需要设置代理.代理工具我推荐用 lantern https://github.com/getlantern/lantern 需要注意的是,它的代理地址是: http://127.0.0.1: ...
- An internal error occurred during: "Initializing Java Tooling". Eclipse启动发生的错误
An internal error occurred during: “Initializing Java Tooling” 错误经常是莫名其妙的出现这种总错误,解决办法: 1.eclipse -&g ...
- java获取当前秒数输出
Date的getSeconds()已经过时了.不建议用.所以用了下面方法 Calendar c = Calendar.getInstance(); while(true) { c ...