網頁版小畫家筆記
利用 canvas 做出簡易版小畫家。
#77 主要 JavaScript 程式
一、建立 HTML
<!DOCTYPE html> <html> <head> <title>Draw</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css"> <link rel="stylesheet" href="css/draw.css"> </head> <body> <nav class="navbar navbar-default navbar-fixed-top"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li> <a href="#" class="clear"><i class="fas fa-brush"></i> 清除</a> </li> <li> <a href="#" class="save"><i class="fas fa-save"></i> 儲存</a> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">顏色 <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#" class="color" data-color="#000000"><i class="fas fa-circle" style="color: #000000;"></i></a></li> <li><a href="#" class="color" data-color="#7f7f7f"><i class="fas fa-circle" style="color: #7f7f7f;"></i></a></li> <li><a href="#" class="color" data-color="#ed1c24"><i class="fas fa-circle" style="color: #ed1c24;"></i></a></li> <li><a href="#" class="color" data-color="#ff7f27"><i class="fas fa-circle" style="color: #ff7f27;"></i></a></li> <li><a href="#" class="color" data-color="#fff200"><i class="fas fa-circle" style="color: #fff200;"></i></a></li> <li><a href="#" class="color" data-color="#22b14c"><i class="fas fa-circle" style="color: #22b14c;"></i></a></li> <li><a href="#" class="color" data-color="#00a2e8"><i class="fas fa-circle" style="color: #00a2e8;"></i></a></li> <li><a href="#" class="color" data-color="#3f48cc"><i class="fas fa-circle" style="color: #3f48cc;"></i></a></li> <li><a href="#" class="color" data-color="#a349a4"><i class="fas fa-circle" style="color: #a349a4;"></i></a></li> <li><a href="#" class="color" data-color="#ffffff"><i class="far fa-circle"></i></a></li> </ul> </li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">大小 <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#" class="size" data-size="small">小</a></li> <li><a href="#" class="size active" data-size="normal">一般</a></li> <li><a href="#" class="size" data-size="large">大</a></li> <li><a href="#" class="size" data-size="huge">特大</a></li> </ul> </li> </ul> </div> </div> </nav> <div class="container"> <div class="row margin-bottom"> <div class="col-xs-6"> <div id="current-pen"> 目前畫筆樣式: <div id="current-pen-style"></div> </div> </div> <div class="col-xs-6"> 目前儲存圖片: <div id="output-image"></div> </div> </div> <div id="canvas-div"></div> </div> <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <script type="text/javascript" src="js/draw.js"></script> </body> </html>#7~8、#75~76 搭配使用 bootstrap、fontawesome 讓畫面好看一點
#77 主要 JavaScript 程式
二、建立 CSS 程式
body { font-family: Arial,Helvetica,"source-han-sans-traditional","微軟正黑體","Microsoft JhengHei","sans-serif"; padding-top: 70px; } .margin-bottom { margin-bottom: 15px; } #current-pen { height: 50px; } #current-pen-style { background: #000000; border-radius: 50%; border: solid 2px #bbb; box-sizing: content-box; display: inline-block; height: 5px; width: 5px; } #output-image { height: 150px; position: relative; } #output-image img { bottom: 0; height : auto; left: 0; margin: auto; max-height: 100%; max-width: 100%; position: absolute; right: 0; top: 0; width: auto; } #canvas-div { border: solid 1px #ccc; box-shadow: 0 6px 12px rgba(0,0,0,.175); /*height: calc(100vh - 260px);*/ margin: 0 auto; } #canvas-div #canvas { cursor: crosshair; }
三、建立 JavaScript 程式
$(function() { $('#canvas-div').css({ 'height': window.innerHeight - 267 }); var canvas; var context; var canvasWidth = $('#canvas-div').width(); var canvasHeight = $('#canvas-div').height(); var clickX = []; var clickY = []; var clickColor = []; var clickTool = []; var clickSize = []; var clickDrag = []; var paint = false; var curColor = '#000000'; var curTool = "crayon"; var curSize = "normal"; var fileName = ''; prepareCanvas(); /** * Creates a canvas element, loads images, adds events, and draws the canvas for the first time. */ function prepareCanvas() { var canvasDiv = document.getElementById('canvas-div'); canvas = document.createElement('canvas'); canvas.setAttribute('width', canvasWidth); canvas.setAttribute('height', canvasHeight); canvas.setAttribute('id', 'canvas'); canvasDiv.appendChild(canvas); if(typeof G_vmlCanvasManager != 'undefined') { canvas = G_vmlCanvasManager.initElement(canvas); } context = canvas.getContext("2d"); $('#canvas') .mousedown(function(e){ paint = true; addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop); redraw(); }) .mousemove(function(e){ if(paint){ addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true); redraw(); } }) .mouseup(function(e){ paint = false; }) .mouseleave(function(e){ paint = false; }); $('#canvas') .on('touchstart', function (e) { paint = true; var touch = e.touches[0]; addClick(touch.pageX - this.offsetLeft, touch.pageY - this.offsetTop); redraw(); }) .on('touchmove', function (e) { e.preventDefault(); if (paint) { var touch = e.touches[0]; addClick(touch.pageX - this.offsetLeft, touch.pageY - this.offsetTop, true); redraw(); } }) .on('touchend', function (e) { paint = false; }); $('nav a').click(function () { var obj = $(this); if (obj.hasClass('clear')) { clearCanvas(); clickX = []; clickY = []; clickTool = []; clickColor = []; clickSize = []; clickDrag = []; } else if (obj.hasClass('save')) { var imageUrl = canvas.toDataURL(); $('#output-image').html(''); $('<img>').attr('src', imageUrl).addClass('img-responsive').appendTo('#output-image'); // $.ajax({ // url: 'draw.php', // method: "POST", // data: { // 'image': imageUrl, // 'fileName': fileName // } // }).done(function (result) { // fileName = result; // }); } else if (obj.hasClass('color')) { curColor = obj.data('color'); $('#current-pen-style').css('background', obj.data('color')); } else if (obj.hasClass('size')) { curSize = obj.data('size'); if(obj.data('size') == "small"){ radius = 2; }else if(obj.data('size') == "large"){ radius = 10; }else if(obj.data('size') == "huge"){ radius = 20; }else{ radius = 5; } $('#current-pen-style').css({ 'height': radius + 'px', 'width': radius + 'px' }); } else if (obj.hasClass('tool')) { curTool = obj.data('tool'); } }); $(window).on('beforeunload', function(){ // 聽說這個自訂訊息因為怕人家詐騙所以沒用了 return '你確定要離開嗎?'; }); } /** * Adds a point to the drawing array. * @param x * @param y * @param dragging */ function addClick(x, y, dragging) { clickX.push(x); clickY.push(y); clickDrag.push(dragging); clickTool.push(curTool); if(curTool == "eraser"){ clickColor.push("white"); }else{ clickColor.push(curColor); } clickSize.push(curSize); } /** * Clears the canvas. */ function clearCanvas() { context.clearRect(0, 0, canvasWidth, canvasHeight); } /** * Redraws the canvas. */ function redraw(){ clearCanvas(); context.lineJoin = "round"; for(var i=0; i < clickX.length; i++) { if(clickSize[i] == "small"){ radius = 2; }else if(clickSize[i] == "large"){ radius = 10; }else if(clickSize[i] == "huge"){ radius = 20; }else{ radius = 5; } context.beginPath(); if(clickDrag[i] && i){ context.moveTo(clickX[i-1], clickY[i-1]); }else{ context.moveTo(clickX[i]-1, clickY[i]); } context.lineTo(clickX[i], clickY[i]); context.closePath(); context.strokeStyle = clickColor[i]; context.lineWidth = radius; context.stroke(); } } });
留言
張貼留言