基于zrender实现在canvas中绘制基本图形
demo1
var type = "pen";//当前画图的类型
//用于保存所有画出的图形,包括图片
var objs = [];
var canvas;
var zr;
//设置类型
function setType(t){
type=t;
//界面展示当前操作名称
var operate = document.getElementById("operate");
switch(t){
case "img":
operate.innerText="导入图片";
break;
case "pen":
operate.innerText="铅笔";
break;
case "line":
operate.innerText="直线";
break;
case "circle":
operate.innerText="圆";
break;
case "rect":
operate.innerText="矩形";
break;
case "isogon":
operate.innerText="正多边形";
break;
case "":
operate.innerText="移动";
break;
}
//类型为空代表移动,其他时候设置图形不可移动防止画新图形时改变原有图形的位置
objs = zr.storage._displayList;
if(type == ""){
for (let index = 0; index < objs.length; index++) {
var tmpobj = objs[index];
objs[index].attr({"draggable":true})
}
} else{
for (let index = 0; index < objs.length; index++) {
var tmpobj = objs[index];
objs[index].attr({"draggable":false})
}
}
zr.refresh();
}
window.onload = function() {
var btn1 = document.getElementById("btn1");
var saveAndClear = document.getElementById("saveAndClear");
var clear = document.getElementById("clear");
var load = document.getElementById("load");
var undo = document.getElementById("undo");
canvas = document.getElementById('mycv');
zr = zrender.init(canvas);
var obj;//当前画图的对象
var penline=[];
var objParam =[];//保存已画图形的关键元素
var s;//将当前对象序列化后的内容
//保存历史记录,用于撤销绘图
var objsHistory=[];
//清除画布但保留已画对象
saveAndClear.onclick = function(){
objs = zr.storage._displayList;//获取当前画布上的所有内容
for (let index = 0; index < objs.length; index++) {
var elementParam = [];
var element = objs[index];
var elementType = element.__proto__.type;//类型
var transform = element.transform;//平移
elementParam.push(elementType);
switch(elementType){
case "polyline"://曲线
var elementPoints = element.shape.points;
var elementSmooth = element.shape.smooth;
var elementStroke = element.style.stroke;
var elementLineWidth = element.style.lineWidth;
var opts = {
rectHover:true,
shape: {
points:elementPoints,
smooth:elementSmooth
},
style:{
stroke:elementStroke,
lineWidth:elementLineWidth
},
position:[transform == null ? 0 : transform[4], transform == null ? 0 : transform[5]]
}
elementParam.push(opts);
break;
case "line":
var x1 = element.shape.x1;
var x2 = element.shape.x2;
var y1 = element.shape.y1;
var y2 = element.shape.y2;
var elementStroke = element.style.stroke;
var elementLineWidth = element.style.lineWidth;
var opts = {
rectHover:true,
shape: {
x1: x1,
y1: y1,
x2: x2,
y2: y2,
percent:1
},
style:{
stroke:elementStroke,
lineWidth:elementLineWidth
},
position:[transform == null ? 0 : transform[4], transform == null ? 0 : transform[5]]
}
elementParam.push(opts);
break;
case "circle":
var cx = element.shape.cx;
var cy = element.shape.cy;
var r = element.shape.r;
var elementStroke = element.style.stroke;
var elementLineWidth = element.style.lineWidth;
var opts = {
rectHover:true,
shape: {
cx: cx,
cy: cy,
r: r,
},
style:{
fill:"rgba(255,255,255,0",
stroke:elementStroke,
lineWidth:elementLineWidth
},
position:[transform == null ? 0 : transform[4], transform == null ? 0 : transform[5]]
}
elementParam.push(opts);
break;
case "rect":
var x = element.shape.x;
var y = element.shape.y;
var width = element.shape.width;
var height = element.shape.height;
var elementStroke = element.style.stroke;
var elementLineWidth = element.style.lineWidth;
var opts = {
rectHover:true,
shape: {
x: x,
y: y,
width:width,
height:height
},
style:{
fill:"rgba(255,255,255,0",
stroke:elementStroke,
lineWidth:elementLineWidth
},
position:[transform == null ? 0 : transform[4], transform == null ? 0 : transform[5]]
}
elementParam.push(opts);
break;
case "isogon":
var x = element.shape.x;
var y = element.shape.y;
var r = element.shape.r;
var n = element.shape.n;
var elementStroke = element.style.stroke;
var elementLineWidth = element.style.lineWidth;
var opts = {
rectHover:true,
shape: {
x:x,
y:y,
r:r,
n:n
},
style:{
fill:"rgba(255,255,255,0",
stroke:elementStroke,
lineWidth:elementLineWidth
},
position:[transform == null ? 0 : transform[4], transform == null ? 0 : transform[5]]
}
elementParam.push(opts);
break;
case "image":
var x = element.style.x;
var y = element.style.y;
var width = element.style.width;
var height = element.style.height;
var image = element.style.image;
var opts = {
style: {
image:image,
x:100,
y:100,
width:200,
height:200
},
position:[transform == null ? 0 : transform[4], transform == null ? 0 : transform[5]]
}
elementParam.push(opts);
break;
}
objParam.push(elementParam);
}
s = JSON.stringify(objParam)
console.log(s);
zr.clear();
objs=[];
}
//清除画布,不保留已画对象
clear.onclick = function(){
zr.clear();
objs = [];
objsHistory=[];
}
//加载最后一次绘画
load.onclick = function(){
zr = zrender.init(canvas);
objParam = eval('('+s+')');
for (let index = 0; index < objParam.length; index++) {
var element = objParam[index];
var elementType = element[0];
var elementParam = element[1];
switch(elementType){
case "polyline":
obj = new zrender.Polyline(elementParam);
zr.add(obj);
break;
case "line":
obj = new zrender.Line(elementParam);
zr.add(obj);
break;
case "circle":
obj = new zrender.Circle(elementParam);
zr.add(obj);
break;
case "rect":
obj = new zrender.Rect(elementParam);
zr.add(obj);
break;
case "isogon":
obj = new zrender.Isogon(elementParam);
zr.add(obj);
break;
case "image":
obj = new zrender.Image(elementParam);
obj.on("mousewheel", function(params){
var shape = params.target;
var event = params.event;
var delta = event.wheelDelta;
if(delta>0){
img.attr("height",shape.style.height += 10);
img.attr("width",shape.style.width += 10);
} else{
img.attr("height",shape.style.height -= 10);
img.attr("width",shape.style.width -= 10);
}
zr.refresh();
});
zr.add(obj);
break;
}
//添加鼠标双击事件,修改线的宽及颜色
obj.on("dblclick",function(){
var lineWidth = document.getElementById("input2").value;
var color = document.getElementById("input3").value;
this.attr({
style:{
stroke:color,
lineWidth:lineWidth
}
});
});
}
objParam=[]
}
//撤销
undo.onclick = function(){
zr.clear();
objsHistory.pop();
objs = objsHistory[objsHistory.length-1];
if(objs != undefined){
zr = zrender.init(canvas);
for (let index = 0; index < objs.length; index++) {
zr.add(objs[index]);
}
}else{
objs=[];
}
}
//导入图片
btn1.onclick = function(){
type="image";
let reader = new FileReader();
reader.readAsDataURL(document.querySelector("#file").files[0]);
reader.onload = function (e) {
let result = e.target.result; // base64格式图片地址
var img = new zrender.Image({
style: {
image:result,
x:100,
y:100,
width:200,
height:200
}
});
//圖片支持縮放
img.on("mousewheel", function(params){
var shape = params.target;
var event = params.event;
var delta = event.wheelDelta;
if(delta>0){
img.attr("height",shape.style.height += 10);
img.attr("width",shape.style.width += 10);
} else{
img.attr("height",shape.style.height -= 10);
img.attr("width",shape.style.width -= 10);
}
zr.refresh();
});
zr.add(img);
//历史记录中保存当前所有元素的集合,用于撤销操作
objs = zr.storage._displayList;
objsHistory.push(new Array().concat(objs));
};
}
//繪製圖形
canvas.onmousedown = function(e){
var x0, y0;
x0 = e.offsetX;
y0 = e.offsetY;
var lineWidth = document.getElementById("input2").value;
var color = document.getElementById("input3").value;
//圆
if(type == "circle"){
var r=10;
obj = new zrender.Circle({
shape: {
cx: x0,
cy: y0,
r: r
},
style:{
fill:"rgba(255,255,255,0",
stroke:color,
lineWidth:lineWidth
}
});
zr.add(obj);
}
//矩形
if(type == "rect"){
obj = new zrender.Rect({
shape: {
x: x0,
y: y0,
width: 10,
height:10
},
style:{
fill:"rgba(255,255,255,0",
stroke:color,
lineWidth:lineWidth
}
});
zr.add(obj);
}
//正多边形
if(type == "isogon"){
var n = document.getElementById("input1").value;
obj = new zrender.Isogon({
shape: {
x: x0,
y: y0,
r: 10,
n: n
},
style:{
fill:"rgba(255,255,255,0",
stroke:color,
lineWidth:lineWidth
}
});
zr.add(obj);
}
//直线
if(type == "line"){
obj = new zrender.Line({
rectHover:true,
shape: {
x1: x0,
y1: y0,
x2: x0,
y2: y0,
percent:1
},
style:{
stroke:color,
lineWidth:lineWidth
}
});
zr.add(obj);
}
//曲线
if(type == "pen"){
penline.push([x0,y0]);
obj = new zrender.Polyline({
rectHover:true,
shape: {
points:penline,
smooth:0.5
},
style:{
stroke:color,
lineWidth:lineWidth
}
});
zr.add(obj);
}
//定义鼠标移动事件,用于画图
canvas.onmousemove = function(e){
x1 = e.offsetX;
y1 = e.offsetY;
//移动鼠标修改圆的半径
if(type == "circle"){
zr.remove(obj);
var r=Math.sqrt(Math.pow(x0-x1,2)+Math.pow(y0-y1,2));
obj = new zrender.Circle({
shape: {
cx: x0,
cy: y0,
r: r
},
style:{
fill:"rgba(255,255,255,0)",
stroke:color,
lineWidth:lineWidth
}
});
zr.add(obj);
}
//移动鼠标修改矩形长宽
if(type == "rect"){
zr.remove(obj);
obj = new zrender.Rect({
shape: {
x: x0,
y: y0,
width: x1-x0,
height:y1-y0
},
style:{
fill:"rgba(255,255,255,0",
stroke:color,
lineWidth:lineWidth
}
});
zr.add(obj);
}
//修改正多边形大小
if(type == "isogon"){
zr.remove(obj);
var n = document.getElementById("input1").value;
var r=Math.sqrt(Math.pow(x0-x1,2)+Math.pow(y0-y1,2));
obj = new zrender.Isogon({
shape: {
x: x0,
y: y0,
r: r,
n: n
},
style:{
fill:"rgba(255,255,255,0",
stroke:color,
lineWidth:lineWidth
}
});
zr.add(obj);
}
//修改直线的长度及方向
if(type == "line"){
zr.remove(obj);
obj = new zrender.Line({
rectHover:true,
shape: {
x1: x0,
y1: y0,
x2: x1,
y2: y1,
percent:1
},
style:{
stroke:color,
lineWidth:lineWidth
}
});
zr.add(obj);
}
//画曲线
if(type == "pen"){
zr.remove(obj);
penline.push([x1,y1]);
obj = new zrender.Polyline({
rectHover:true,
shape: {
points:penline,
smooth:0.5
},
style:{
stroke:color,
lineWidth:lineWidth
}
});
zr.add(obj);
}
}
//鼠标松开后为元素添加双击事件,历史记录中保存数据方便撤销
canvas.onmouseup = function(e){
canvas.onmousemove = null;
//保存绘画的对象
if(obj != undefined){
//支持修改线宽度
obj.on("dblclick",function(){
var lineWidth = document.getElementById("input2").value;
var color = document.getElementById("input3").value;
this.attr({
style:{
stroke:color,
lineWidth:lineWidth
}
});
});
objs = zr.storage._displayList;
//历史记录中保存当前所有元素的集合,用于撤销操作
objsHistory.push(new Array().concat(objs));
}
//清空铅笔画线的点集
penline=[];
obj = null;
}
}
}