canvas滑鼠繪圖【新】
阿新 • • 發佈:2018-12-11
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>canvas滑鼠繪圖</title> <link rel="stylesheet" href="colpick.css" type="text/css"/> <style type="text/css"> *{margin:0;padding: 0} .painter_win{position:absolute;top:0;bottom:0;background-color: #f2f2f2;width: 100%;font-size: 16px;} .painter_win>.setWH{padding: 40px;} canvas#box{border: 2px solid #333;box-shadow: 10px 10px 5px #9E9E9E;} .painter_win .setWH{background: #ccc;} .setWH .setCanvas{display: inline;} .setWH #canvas_width,.setWH #canvas_height{width: 50px;} .tool{overflow: hidden;display: none;} .setWH #submitSet{margin-left: 20px;text-decoration: none;padding: 4px 9px; border-radius: 7px;background: #03A9F4;color: #fff;} .tool ul{list-style: none;position: relative;left: 50%;margin-left: -284px;margin-top:20px;overflow: hidden;} .tool ul>li{float: left;width: 90px; background-color: #03A9F4;color: #fff;padding: 10px;text-align: center;margin-left: 20px;border-radius: 6px;cursor: pointer;} .tool ul>li:first-child{margin-left: 0;} .tool ul>li:hover{background-color: #607d8b;} .tool ul>li.reduceW{width:58px;} .tool .setWe{text-align: left;} .tool #penWeight,.tool #penColor{width: 17px;display: inline-block;color: #605454;} .tool #penColor{cursor: pointer;} .painter_win #content{width: 100%;} .selectStyle .clicked{background-color: #607d8b} </style> </head> <body> <div class="painter_win"> <div class="setWH"> <span>請輸入畫布大小:</span> <div class="setCanvas"> <input type="text" id="canvas_width" value="500"> x <input type="text" id="canvas_height" value="300"> </div> <button id="submitSet" onclick="createCanvas()">確定</button> </div> <div class="tool"> <ul> <li> 畫筆顏色 <input type="text" id="penColor" color-mark="#ff8800"> </li> <li id="setWe"> 畫筆粗細 <input type="text" id="penWeight" value="3" onclick="selectText()"> </li> <li class="reduceW" onclick="backStep()">撤回</li> <li class="reduceW" onclick="clearCanvas()">清空</li> <li id="downloadImage">下載圖片</li> </ul> <ul class="selectStyle"> <li onclick="beLine()">直線</li> <li onclick="beRect()">矩形</li> <li onclick="beCircle()">圓</li> <li class="clicked" onclick="bePen()" >筆</li> </ul> </div> <div id="content"></div> </div> </body> <script src="jquery-3.3.1.js"></script> <script src="colpick.js" type="text/javascript"></script> <script type="text/javascript"> var record =[]; $(function(){ //下載圖片 var downloadImage = document.getElementById('downloadImage'); bindButtonEvent(downloadImage, "click", saveAsLocalImage); //設定畫筆顏色 $("#penColor").colpick({ layout:'rgbhex', color:'ff8800', onSubmit:function(hsb,hex,rgb,el) { $(el).css('background-color', '#'+hex); $(el).colpickHide(); $(el).attr('color-mark','#'+hex); } }).css('background-color', '#ff8800'); $(".selectStyle li").click(function(){ $(this).addClass('clicked'); $(this).siblings().removeClass('clicked'); }); }); //建立canvas畫布 function createCanvas(){ if(!$("#content #box")[0]){ var width = $(".painter_win .setWH #canvas_width").val(); var height = $(".painter_win .setWH #canvas_height").val(); if(width || height){ initCanvas(width,height); $(".tool").show(); $(".setWH").hide(); }else{ alert("請輸入畫布大小"); } } } //初始化畫布,新增滑鼠事件 function initCanvas(width,height){ let txt = `<canvas id="box" width="${width}" height="${height}"></canvas>`; $("#content").append(txt); $("#box").css({ 'position' : 'relative', 'left' : '50%', 'margin-left': -width/2, 'margin-top' : '20px' }); bePen(); } //畫筆繪圖 function bePen(){ var box=document.getElementById('box'); var ctx=box.getContext('2d'); box.onmousedown=function(e){ record.push(box.toDataURL()); e=e||window.event; var penColor = $("#penColor").attr('color-mark'); var penWeight = $("#penWeight").val(); ctx.strokeStyle= penColor; ctx.lineWidth = penWeight; ctx.beginPath(); //注意這裡offset獲取到的是box相對上一個定位元素的距離,沒有則為body var ox=e.clientX-box.offsetLeft; var oy=e.clientY-box.offsetTop; ctx.moveTo(ox,oy); box.onmousemove=function(e){ var ox1=e.clientX-box.offsetLeft; var oy1=e.clientY-box.offsetTop; ctx.lineTo(ox1,oy1); ctx.stroke(); } //程式碼改進,在僅有畫筆畫圖時還是改成document.onmouseup較好。 //因為此處若為box.onmouseup則滑鼠移出canvas鬆開監聽不到導致一直處於onmousemove狀態中 //這裡是由於其他style(圓、矩形、線條)中只能定義成box.onmouseup,這裡要覆蓋掉不易出bug box.onmouseup=function(){ box.onmousemove=null; ctx.closePath(); } } } //直線繪圖 function beLine(){ var box=document.getElementById('box'); var ctx=box.getContext('2d'); box.onmousedown=function(e){ record.push(box.toDataURL()); e=e||window.event; var penColor = $("#penColor").attr('color-mark'); var penWeight = $("#penWeight").val(); ctx.strokeStyle= penColor; ctx.lineWidth = penWeight; ctx.beginPath(); //注意這裡offset獲取到的是box相對上一個定位元素的距離,沒有則為body var ox=e.clientX-box.offsetLeft; var oy=e.clientY-box.offsetTop; ctx.moveTo(ox,oy); //暫時不知道該如何做出預覽的效果 box.onmouseup=function(e){ var ox1=e.clientX-box.offsetLeft; var oy1=e.clientY-box.offsetTop; ctx.lineTo(ox1,oy1); ctx.stroke(); ctx.closePath(); } } } //矩形繪圖 function beRect(){ var box=document.getElementById('box'); var ctx=box.getContext('2d'); box.onmousedown=function(e){ record.push(box.toDataURL()); e=e||window.event; var penColor = $("#penColor").attr('color-mark'); var penWeight = $("#penWeight").val(); ctx.strokeStyle= penColor; ctx.lineWidth = penWeight; ctx.beginPath(); var ox=e.clientX-box.offsetLeft; var oy=e.clientY-box.offsetTop; box.onmouseup=function(e){ var ox1=e.clientX-box.offsetLeft; var oy1=e.clientY-box.offsetTop; //這裡也可以是填充矩形,但是style就不是strokeStyle而是fillStyle ctx.strokeRect(ox,oy,ox1-ox,oy1-oy); ctx.closePath(); } } } //圓繪圖 function beCircle(){ var box=document.getElementById('box'); var ctx=box.getContext('2d'); box.onmousedown=function(e){ record.push(box.toDataURL()); e=e||window.event; var penColor = $("#penColor").attr('color-mark'); var penWeight = $("#penWeight").val(); ctx.strokeStyle= penColor; ctx.lineWidth = penWeight; ctx.beginPath(); var ox=e.clientX-box.offsetLeft; var oy=e.clientY-box.offsetTop; box.onmouseup=function(e){ var ox1=e.clientX-box.offsetLeft; var oy1=e.clientY-box.offsetTop; ctx.arc((ox+ox1)/2,(oy+oy1)/2,(ox1-ox)/2,0,2*Math.PI); ctx.stroke(); ctx.closePath(); } } } //撤銷 function backStep(){ if(record.length>0){ //不加上下面語句會出現oc is not defined問題,暫未理解 ctx=box.getContext('2d'); var canvasPic = new Image(); resetCanvas(); canvasPic.src = record.pop(); //一定要載入完圖片再進行繪製 canvasPic.onload = function(){ ctx.drawImage(canvasPic, 0, 0); } } } // 清空canvas畫布 function resetCanvas(){ //canvas每當高度或寬度被重設時,畫布內容就會被清空 box.height = box.height; } //清空操作 把操作記錄也清空 function clearCanvas(){ resetCanvas(); record = []; } //指定線型為直線 //新增事件監聽 相容IE function bindButtonEvent(element, type, handler){ if(element.addEventListener) { element.addEventListener(type, handler, false); } else { element.attachEvent('on'+type, handler); } } //儲存本地 function saveAsLocalImage () { var box=document.getElementById('box'); var image = box.toDataURL("image/png").replace("image/png", "image/octet-stream"); window.location.href=image; } //點選自動選中input內的所有文字 function selectText(){ //原生js物件也有此方法 $("#penWeight").select(); } </script> </html>
結果如下圖: