UNPKG

zoomla

Version:

16年专业研发|中文alexa排名第一的CMS品牌-基于dotNET core、功能强大,集成站群、微信开发、小程序与ERP及OA办公系统,支持国际语言和多民族语言,世界五百强与大型门户专用高端网站内核CMS系统

274 lines (266 loc) 11.6 kB
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="/dist/css/bootstrap.min.css" /> <link rel="stylesheet" type="text/css" href="/dist/css/font-awesome.min.css"/> <style type="text/css"> *{box-sizing:content-box;-webkit-box-sizing:initial;} .tool .color {float:left; margin:5px; width:30px;} .tool .color div{width:24px; height:24px; border:solid 2px #aaa; margin-bottom:5px; opacity:0.5;} .tool .color div:hover{opacity:1; cursor:pointer;} .tool .color .active{opacity:1; border:solid 2px #000;} .tool .size {float:left; margin:5px; width:30px; margin-left:0;} .tool .size div{width:30px; height:30px; border:solid 2px #aaa; margin-bottom:5px; opacity:0.5;} .tool .size div:hover{opacity:1; cursor:pointer;} .tool .size .active{opacity:1; border:solid 2px #000;} .tool .size span{display:block; margin:3px auto; height:24px; background-color:black;} .tool .btn{width:70%;margin-bottom:10px;} </style> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script> <![endif]--> <script src="/js/jquery.min.js"></script> <script src="/js/Plugs/canvas2svg.js"></script> <title>在线写字</title> </head> <body> <div class="panel panel-default tool" style="width:120px;position:fixed;left:50px;"> <div class="panel-heading"><i class="fa fa-cog"></i> 控制板</div> <div class="panel-body"> <div class="color"> <div style="background: #000;" data-color="#000"></div> <div style="background: #f00;" data-color="#f00"></div> <div style="background: #0f0;" data-color="#0f0"></div> <div style="background: #00f;" data-color="#00f"></div> <div style="background: #ff0;" data-color="#ff0"></div> <div style="background: #0ff;" data-color="#0ff"></div> <div style="background: #f0f;" data-color="#f0f"></div> <div style="background: #fff;" data-color="#fff"></div> </div> <div class="size"> <div data-size="3"><span style="width: 3px;"></span></div> <div data-size="6" class="active"><span style="width: 6px;"></span></div> <div data-size="9" class=""><span style="width: 9px;"></span></div> <div data-size="12" class=""><span style="width: 12px;"></span></div> <div data-size="15" class=""><span style="width: 15px;"></span></div> <div data-size="20"><span style="width: 20px;"></span></div> <div data-size="25" class=""><span style="width: 25px;"></span></div> </div> <input type="button" value="撤消上笔" onclick="hwrite.pen.cancel();" class="btn btn-info" /> <input type="button" value="保存图片" onclick="hwrite.help.downimg();" class="btn btn-info" /> <input type="button" value="存为SVG" onclick="saveToSvg();" class="btn btn-info" /> <input type="button" value="清空画板" onclick="hwrite.help.clear();" class="btn btn-danger" /> </div> </div> <div id="canvas_container" class="container" style="position:relative;margin-top:50px;"> <canvas id="canvas_main" style="cursor:none;"></canvas> </div> <script> //ispress:是否按下开始绘制,pen:画笔相关配置,data:绘图数据,用于重绘时调用 var hwrite = { help: {}, canvas: null, ctx: null, pen: { size: 6, color: "#000" }, cfg: { bgcolor: "#fff" }, ispress: false, pos: { x: 0, y: 0 }, data: [] }; hwrite.newData = function (d) { return { "sx": hwrite.pos.x, "sy": hwrite.pos.y, "endx": d.x, "endy": d.y, "strokeStyle": hwrite.pen.color, "lineWidth": hwrite.pen.size }; } hwrite.pen.brush = function (pos) { var d = hwrite.help.getpos(pos.x, pos.y); var model = hwrite.newData(d); hwrite.pen.brushByModel(hwrite.ctx,model); hwrite.pos = d; hwrite.data.push(model); } hwrite.pen.brushByModel=function(ctx,model) { ctx.save(); ctx.beginPath(); ctx.moveTo(model.sx, model.sy); ctx.lineTo(model.endx, model.endy); ctx.strokeStyle = model.strokeStyle; ctx.lineWidth = model.lineWidth; ctx.lineCap = "round";//设置或返回线条的结束端点样式 ctx.lineJoin = "round";//设置或返回两条线相交时,所创建的拐角类型 ctx.stroke(); ctx.closePath(); ctx.restore(); } //撤消上一笔操作 hwrite.pen.cancel = function () { for (var i = (hwrite.data.length - 1) ; i > 0; i--) { var model = hwrite.data.pop(); if (model.type == "start") { break; } } hwrite.pen.refresh(); } hwrite.pen.refresh = function (conf) { if (!conf) { conf = { panel: true }; } hwrite.ctx.clearRect(0, 0, hwrite.canvas.width, hwrite.canvas.height); if (conf.panel == true) { hwrite.help.drawPanel(); } for (var i = 0; i < hwrite.data.length; i++) { var model = hwrite.data[i]; if (model.type && model.type == "start") { continue; } hwrite.pen.brushByModel(hwrite.ctx, hwrite.data[i]); } } hwrite.help.downimg = function () { hwrite.pen.refresh({ panel: false }); var MIME_TYPE = "image/png"; var imgURL = hwrite.canvas.toDataURL(MIME_TYPE);//base64 var dlLink = document.createElement('a'); dlLink.download = "预览"; dlLink.href = imgURL; dlLink.dataset.downloadurl = [MIME_TYPE, dlLink.download, dlLink.href].join(':'); document.body.appendChild(dlLink); dlLink.click(); document.body.removeChild(dlLink); hwrite.pen.refresh(); } //初始化画板,可根据需要自修改 hwrite.help.drawPanel = function () { var ctx = hwrite.ctx; ctx.save(); var canvasWidth = hwrite.canvas.width; var canvasHeight = hwrite.canvas.height; ctx.fillStyle = hwrite.cfg.bgcolor; ctx.strokeStyle = hwrite.cfg.bgcolor; ctx.beginPath(); ctx.rect(0, 0, canvasWidth, canvasHeight); ctx.stroke(); ctx.fill(); //--------------------- ctx.strokeStyle = "red"; ctx.beginPath(); ctx.moveTo(3, 3); ctx.lineTo(canvasWidth - 3, 3); ctx.lineTo(canvasWidth - 3, canvasHeight - 3); ctx.lineTo(3, canvasHeight - 3); ctx.closePath(); ctx.lineWidth = 6; ctx.stroke(); ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(canvasWidth, canvasHeight); ctx.moveTo(canvasWidth, 0); ctx.lineTo(0, canvasHeight); ctx.moveTo(canvasWidth / 2, 0); ctx.lineTo(canvasWidth / 2, canvasHeight); ctx.moveTo(0, canvasHeight / 2); ctx.lineTo(canvasWidth, canvasHeight / 2); ctx.lineWidth = 1; ctx.stroke(); ctx.restore(); } hwrite.help.clear = function () { hwrite.ctx.clearRect(0, 0, hwrite.canvas.width, hwrite.canvas.height); hwrite.data = []; hwrite.help.drawPanel(); } hwrite.help.getpos = function (a,c) {//x,y var b = hwrite.canvas.getBoundingClientRect();//用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置 return { x: Math.round(a - b.left), y: Math.round(c - b.top) }; } //----------------------------------page $(function () { hwrite.canvas = document.getElementById("canvas_main"); hwrite.ctx = hwrite.canvas.getContext("2d"); hwrite.canvas.height = hwrite.canvas.width = Math.min(600, $(window).width() - 60); hwrite.help.drawPanel(); //-------------------------- hwrite.canvas.onmousedown = function (e) { e.preventDefault(); beginStroke({ x: e.clientX, y: e.clientY }); }; hwrite.canvas.onmouseup = function (e) { e.preventDefault(); endStroke(); }; hwrite.canvas.onmouseout = function (e) { e.preventDefault(); hwrite.pen.refresh(); endStroke(); }; hwrite.canvas.onmousemove = function (e) { e.preventDefault(); if (hwrite.ispress) { hwrite.pen.brush({ x: e.clientX, y: e.clientY }); } else { hwrite.pen.refresh(); var d = hwrite.help.getpos(e.clientX, e.clientY); var ctx = hwrite.ctx; ctx.save(); ctx.beginPath(); //ctx.shadowBlur = 20;//很吃性能,取消 //ctx.shadowColor = "black"; ctx.fillStyle = hwrite.pen.color; ctx.arc(d.x, d.y, (hwrite.pen.size / 2), 0, Math.PI * 2, true); ctx.fill(); ctx.closePath(); ctx.restore(); } }; //移动兼容 hwrite.canvas.addEventListener("touchstart", function (e) { e.preventDefault(); touch = e.touches[0]; beginStroke({ x: touch.pageX, y: touch.pageY }); }); hwrite.canvas.addEventListener("touchmove", function (a) { a.preventDefault(); if (hwrite.ispress) { touch = a.touches[0]; hwrite.pen.brush({ x: touch.pageX, y: touch.pageY }); } }); hwrite.canvas.addEventListener("touchend", function (a) { a.preventDefault(); endStroke(); }); //----------------------------- $(".size div").click(function () { $(".size div").removeClass("active"); hwrite.pen.size = $(this).data("size"); $(this).addClass("active"); }); $(".color div").click(function () { $(".color div").removeClass("active"); hwrite.pen.color = $(this).data("color"); $(this).addClass("active"); }); }) //---------------------------------- function beginStroke(a) { hwrite.ispress = true; hwrite.pos = hwrite.help.getpos(a.x, a.y); hwrite.data.push({ type: "start" }); } function endStroke() { hwrite.ispress = false; } function saveToSvg() { var ctx = C2S(hwrite.canvas.height, hwrite.canvas.width); for (var i = 0; i < hwrite.data.length; i++) { var model = hwrite.data[i]; if (model.type && model.type == "start") { continue; } hwrite.pen.brushByModel(ctx, hwrite.data[i]); } var svg = ctx.getSerializedSvg(); //true here, if you need to convert named to numbered entities. console.log(svg); //<div id="svg"></div> //var svg = ctx.getSvg(); //$("#svg").append(svg); } </script> </body> </html>