├── .idea ├── drawingboard.iml ├── inspectionProfiles │ ├── Project_Default.xml │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── vcs.xml ├── watcherTasks.xml └── workspace.xml ├── README.md ├── css └── style.css ├── index.html └── js └── main.js /.idea/drawingboard.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/watcherTasks.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 16 | 24 | 25 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | undo 61 | eraser 62 | clear 63 | push 64 | 65 | 66 | 67 | 72 | 74 | 75 | 82 | 83 | 84 | 85 | 86 | true 87 | DEFINITION_ORDER 88 | 89 | 90 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 26 |
27 | 28 | 29 | 30 | 31 | 32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | let canvas = document.getElementById("drawing-board"); 2 | let ctx = canvas.getContext("2d"); 3 | let eraser = document.getElementById("eraser"); 4 | let brush = document.getElementById("brush"); 5 | let reSetCanvas = document.getElementById("clear"); 6 | let aColorBtn = document.getElementsByClassName("color-item"); 7 | let save = document.getElementById("save"); 8 | let undo = document.getElementById("undo"); 9 | let range = document.getElementById("range"); 10 | let clear = false; 11 | let activeColor = 'black'; 12 | let lWidth = 4; 13 | 14 | autoSetSize(canvas); 15 | 16 | setCanvasBg('white'); 17 | 18 | listenToUser(canvas); 19 | 20 | getColor(); 21 | 22 | window.onbeforeunload = function(){ 23 | return "Reload site?"; 24 | }; 25 | 26 | function autoSetSize(canvas) { 27 | canvasSetSize(); 28 | 29 | function canvasSetSize() { 30 | let pageWidth = document.documentElement.clientWidth; 31 | let pageHeight = document.documentElement.clientHeight; 32 | 33 | canvas.width = pageWidth; 34 | canvas.height = pageHeight; 35 | } 36 | 37 | window.onresize = function () { 38 | canvasSetSize(); 39 | } 40 | } 41 | 42 | function setCanvasBg(color) { 43 | ctx.fillStyle = color; 44 | ctx.fillRect(0, 0, canvas.width, canvas.height); 45 | ctx.fillStyle = "black"; 46 | } 47 | 48 | function listenToUser(canvas) { 49 | let painting = false; 50 | let lastPoint = {x: undefined, y: undefined}; 51 | 52 | if (document.body.ontouchstart !== undefined) { 53 | canvas.ontouchstart = function (e) { 54 | this.firstDot = ctx.getImageData(0, 0, canvas.width, canvas.height);//在这里储存绘图表面 55 | saveData(this.firstDot); 56 | painting = true; 57 | let x = e.touches[0].clientX; 58 | let y = e.touches[0].clientY; 59 | lastPoint = {"x": x, "y": y}; 60 | ctx.save(); 61 | drawCircle(x, y, 0); 62 | }; 63 | canvas.ontouchmove = function (e) { 64 | if (painting) { 65 | let x = e.touches[0].clientX; 66 | let y = e.touches[0].clientY; 67 | let newPoint = {"x": x, "y": y}; 68 | drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y); 69 | lastPoint = newPoint; 70 | } 71 | }; 72 | 73 | canvas.ontouchend = function () { 74 | painting = false; 75 | } 76 | } else { 77 | canvas.onmousedown = function (e) { 78 | this.firstDot = ctx.getImageData(0, 0, canvas.width, canvas.height);//在这里储存绘图表面 79 | saveData(this.firstDot); 80 | painting = true; 81 | let x = e.clientX; 82 | let y = e.clientY; 83 | lastPoint = {"x": x, "y": y}; 84 | ctx.save(); 85 | drawCircle(x, y, 0); 86 | }; 87 | canvas.onmousemove = function (e) { 88 | if (painting) { 89 | let x = e.clientX; 90 | let y = e.clientY; 91 | let newPoint = {"x": x, "y": y}; 92 | drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y,clear); 93 | lastPoint = newPoint; 94 | } 95 | }; 96 | 97 | canvas.onmouseup = function () { 98 | painting = false; 99 | }; 100 | 101 | canvas.mouseleave = function () { 102 | painting = false; 103 | } 104 | } 105 | } 106 | 107 | function drawCircle(x, y, radius) { 108 | ctx.save(); 109 | ctx.beginPath(); 110 | ctx.arc(x, y, radius, 0, Math.PI * 2); 111 | ctx.fill(); 112 | if (clear) { 113 | ctx.clip(); 114 | ctx.clearRect(0,0,canvas.width,canvas.height); 115 | ctx.restore(); 116 | } 117 | } 118 | 119 | function drawLine(x1, y1, x2, y2) { 120 | ctx.lineWidth = lWidth; 121 | ctx.lineCap = "round"; 122 | ctx.lineJoin = "round"; 123 | if (clear) { 124 | ctx.save(); 125 | ctx.globalCompositeOperation = "destination-out"; 126 | ctx.moveTo(x1, y1); 127 | ctx.lineTo(x2, y2); 128 | ctx.stroke(); 129 | ctx.closePath(); 130 | ctx.clip(); 131 | ctx.clearRect(0,0,canvas.width,canvas.height); 132 | ctx.restore(); 133 | }else{ 134 | ctx.moveTo(x1, y1); 135 | ctx.lineTo(x2, y2); 136 | ctx.stroke(); 137 | ctx.closePath(); 138 | } 139 | } 140 | 141 | range.onchange = function(){ 142 | lWidth = this.value; 143 | }; 144 | 145 | eraser.onclick = function () { 146 | clear = true; 147 | this.classList.add("active"); 148 | brush.classList.remove("active"); 149 | }; 150 | 151 | brush.onclick = function () { 152 | clear = false; 153 | this.classList.add("active"); 154 | eraser.classList.remove("active"); 155 | }; 156 | 157 | reSetCanvas.onclick = function () { 158 | ctx.clearRect(0, 0, canvas.width, canvas.height); 159 | setCanvasBg('white'); 160 | }; 161 | 162 | save.onclick = function () { 163 | let imgUrl = canvas.toDataURL("image/png"); 164 | let saveA = document.createElement("a"); 165 | document.body.appendChild(saveA); 166 | saveA.href = imgUrl; 167 | saveA.download = "zspic" + (new Date).getTime(); 168 | saveA.target = "_blank"; 169 | saveA.click(); 170 | }; 171 | 172 | function getColor(){ 173 | for (let i = 0; i < aColorBtn.length; i++) { 174 | aColorBtn[i].onclick = function () { 175 | for (let i = 0; i < aColorBtn.length; i++) { 176 | aColorBtn[i].classList.remove("active"); 177 | this.classList.add("active"); 178 | activeColor = this.style.backgroundColor; 179 | ctx.fillStyle = activeColor; 180 | ctx.strokeStyle = activeColor; 181 | } 182 | } 183 | } 184 | } 185 | 186 | let historyDeta = []; 187 | 188 | function saveData (data) { 189 | (historyDeta.length === 10) && (historyDeta.shift());// 上限为储存10步,太多了怕挂掉 190 | historyDeta.push(data); 191 | } 192 | 193 | undo.onclick = function(){ 194 | if(historyDeta.length < 1) return false; 195 | ctx.putImageData(historyDeta[historyDeta.length - 1], 0, 0); 196 | historyDeta.pop() 197 | }; --------------------------------------------------------------------------------