*新闻详情页*/>
本文关键详细介绍:
1、新项目详细介绍
名字:智美术绘画板
技术性栈:HTML5,CSS3,JavaScript,挪动端
作用叙述:
2、新项目实际效果展现
新项目详细地址 预览详细地址
预览图
PC端预览图:
挪动端预览图:
看完上面的预览图和体验过 智美术绘画板 感觉还能够的,记得点个赞哦,无论你是不是10分兴奋,总之我是挺兴奋的,终究自身完成出現的新项目实际效果,挺引以为豪的,说了1堆空话,下面便可以动起手来敲编码,完成自身要想的实际效果!!!
注:下面完成新项目实际效果关键是有关JavaScript层面的,下面仅仅是出示 完成思路的编码 , 并不是所有编码 。
3、1步步完成新项目实际效果
(1)剖析网页页面
根据 测试用例图 ,大家了解客户进到大家这个网站有哪些作用?
客户能够开展的实际操作:
(2)开展HTML合理布局
我撰写html的另外,引进了css文档和js文档
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF⑻"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>智美术绘画板</title> <link rel="shortcut icon" href="./image/favicon.png" type="image/x-icon"> <link rel="stylesheet" href="./css/style.css"> </head> <body> <canvas id="canvas"></canvas> <div class="bg-btn"></div> <div class="color-group" id="bgGroup"> <h3>挑选情况色调:</h3> <ul class="clearfix"> <li class="bgcolor-item" style="background-color: blue;"></li> <li class="bgcolor-item" style="background-color: black;"></li> <li class="bgcolor-item" style="background-color: #FF3333;"></li> <li class="bgcolor-item" style="background-color: #0066FF;"></li> <li class="bgcolor-item" style="background-color: #FFFF33;"></li> <li class="bgcolor-item" style="background-color: #33CC66;"></li> <li class="bgcolor-item" style="background-color: gray;"></li> <li class="bgcolor-item" style="background-color: #F34334;"></li> <li class="bgcolor-item" style="background-color: #fff;box-shadow: 0 1px 2px 0 rgba(32,33,36,0.28);"></li> <li class="bgcolor-item" style="background-color: #9B27AC;"></li> <li class="bgcolor-item" style="background-color: #4CB050;"></li> <li class="bgcolor-item" style="background-color: #029688;"></li> </ul> <i class="closeBtn"></i> </div> <div class="tools"> <div class="container"> <button class="save" id="save" title="储存"></button> <button class="brush active" id="brush" title="画笔"></button> <button class="eraser" id="eraser" title="橡皮擦"></button> <button class="clear" id="clear" title="清屏"></button> <button class="undo" id="undo" title="撤消"></button> <button class="redo" id="redo" title="再做"></button> </div> </div> <div class="pen-detail" id="penDetail"> <i class="closeBtn"></i> <p>笔尺寸</p> <span class="circle-box"><i id="thickness"></i></span> <input type="range" id="range1" min="1" max="10" value="1"> <p>笔色调</p> <ul class="pen-color clearfix"> <li class="color-item active" style="background-color: black;"></li> <li class="color-item" style="background-color: #FF3333;"></li> <li class="color-item" style="background-color: #99CC00;"></li> <li class="color-item" style="background-color: #0066FF;"></li> <li class="color-item" style="background-color: #FFFF33;"></li> <li class="color-item" style="background-color: #33CC66;"></li> </ul> <p>不全透明度</p> <i class="showOpacity"></i> <input type="range" id="range2" min="1" max="10" value="1"> </div> <script src="./js/main.js"></script> </body> </html>
(3)用CSS清理页面
css编码能够依据本人习惯性开展清理页面,因此这里就不写css的编码了,大伙儿能够立即看 新项目编码 或从开发设计者专用工具中核查元素收看。假如有难题能够私聊我,我感觉难题不大。
(4)应用JS完成新项目的实际作用
1.提前准备工作中
最先,提前准备个器皿,也便是画板了,前面的html早已撰写好这个器皿,这里纯属是空话。
<canvas id="canvas"></canvas>
随后原始化js
let canvas = document.getElementById('canvas'); let context = canvas.getContext('2d');
我准备把画板做满足屏的,因此接下来设定1下 canvas
的宽高
let pageWidth = document.documentElement.clientWidth; let pageHeight = document.documentElement.clientHeight; canvas.width = pageWidth; canvas.height = pageHeight;
因为一部分IE不适用 canvas
,假如要适配IE,大家能够建立1个 canvas
,随后应用 excanvas
原始化,对于IE再加exCanvas.js,这里大家确立不考虑到IE。
可是我在电脑上上对访问器的对话框开展更改,画板不容易自融入的放缩。处理方法:
// 记得要实行autoSetSize这个涵数哦 function autoSetSize(){ canvasSetSize(); // 当实行这个涵数的情况下,会先设定canvas的宽高 function canvasSetSize(){ let pageWidth = document.documentElement.clientWidth; let pageHeight = document.documentElement.clientHeight; canvas.width = pageWidth; canvas.height = pageHeight; } // 在对话框尺寸更改以后,就会开启resize恶性事件,再次设定canvas的宽高 window.onresize = function(){ canvasSetSize(); } }
2.完成画画的作用
完成思路:监视电脑鼠标恶性事件, 用 drawLine()
方式把纪录的数据信息画出来。
painting = false
。mousedown
),把 painting
设为 true
,表明正在画,电脑鼠标没松开。把电脑鼠标点纪录下来。mousemove
)就 把点纪录 下来并画出来。 假如电脑鼠标挪动过快,访问器跟不上美术绘画速率,点与点之间会出現空隙,因此大家必须将画出的点用线连起来( lineTo()
)。mouseup
),把 painting
设为 false
。注: drawCircle
这个方式实际上能够无需撰写,这个只是以便让大伙儿可以了解刚开始点一下的部位在哪儿里?
function listenToUser() { // 界定1个自变量原始化画笔情况 let painting = false; // 纪录画笔最终1次的部位 let lastPoint = {x: undefined, y: undefined}; // 电脑鼠标按下恶性事件 canvas.onmousedown = function(e){ painting = true; let x = e.clientX; let y = e.clientY; lastPoint = {'x':x,'y':y}; drawCircle(x,y,5); } // 电脑鼠标挪动恶性事件 canvas.onmousemove = function(e){ if(painting){ let x = e.clientX; let y = e.clientY; let newPoint = {'x':x,'y':y}; drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y); lastPoint = newPoint; } } // 电脑鼠标松开恶性事件 canvas.onmouseup = function(){ painting = false; } } // 画点涵数 function drawCircle(x,y,radius){ // 新建1条相对路径,转化成以后,图型绘图指令被指向到相对路径上转化成相对路径。 context.beginPath(); // 画1个以(x,y)为圆心的以radius为半径的圆弧(圆), // 从startAngle刚开始到endAngle完毕,依照anticlockwise给定的方位(默认设置为顺时针)来转化成。 context.arc(x,y,radius,0,Math.PI*2); // 根据填充相对路径的內容地区转化成实心的图型 context.fill(); // 闭合相对路径以后图型绘图指令又再次指向到左右文中。 context.closePath(); } function drawLine(x1,y1,x2,y2){ // 设定线条宽度 context.lineWidth = 10; // 设定线条尾端款式。 context.lineCap = "round"; // 设置线条与线条间接性合处的款式 context.lineJoin = "round"; // moveTo(x,y)将笔触挪动到特定的座标x和y上 context.moveTo(x1,y1); // lineTo(x, y) 绘图1条从当今部位到特定x和y部位的平行线 context.lineTo(x2,y2); // 根据线条来绘图图型轮廊 context.stroke(); context.closePath(); }
3.完成橡皮擦作用
完成思路:
eraserEnabled = false
。click
恶性事件,点一下橡皮擦,更改橡皮擦情况, eraserEnabled = true
,而且切换class,完成 被激活 的实际效果。eraserEnabled
为 true
时,挪动电脑鼠标用 context.clearRect()
完成了 橡皮檫。可是我发现canvas的API中,能够消除像素的便是clearRect方式,可是clearRect方式的消除地区矩形框,终究绝大多数人的习惯性中的橡皮擦全是圆形的,因此就引进了剪辑地区这个强劲的作用,也便是clip方式。下面的编码是应用 context.clearRect()
完成了 橡皮檫。请看踩坑一部分,掌握怎样更好的完成橡皮檫。
let eraser = document.getElementById("eraser"); let eraserEnabled = false; // 记得要实行listenToUser这个涵数哦 function listenToUser() { // ... 意味着省略了以前写的编码 // ... // 电脑鼠标按下恶性事件 canvas.onmousedown = function(e){ // ... if(eraserEnabled){//要应用eraser context.clearRect(x⑸,y⑸,10,10) }else{ lastPoint = {'x':x,'y':y} } } // 电脑鼠标挪动恶性事件 canvas.onmousemove = function(e){ let x = e.clientX; let y = e.clientY; if(!painting){return} if(eraserEnabled){ context.clearRect(x⑸,y⑸,10,10); }else{ var newPoint = {'x':x,'y':y}; drawLine(lastPoint.x, lastPoint.y,newPoint.x, newPoint.y); lastPoint = newPoint; } } // ... } // 点一下橡皮檫 eraser.onclick = function(){ eraserEnabled = true; eraser.classList.add('active'); brush.classList.remove('active'); }
4.完成清屏作用
完成思路:
获得元素连接点。
点一下清空按钮清空canvas画布。
let reSetCanvas = document.getElementById("clear"); // 完成清屏 reSetCanvas.onclick = function(){ ctx.clearRect(0,0,canvas.width,canvas.height); setCanvasBg('white'); } // 再次设定canvas情况色调 function setCanvasBg(color) { ctx.fillStyle = color; ctx.fillRect(0, 0, canvas.width, canvas.height); }
5.完成储存成照片作用
完成思路:
let save = document.getElementById("save"); // 免费下载照片 save.onclick = function(){ let imgUrl = canvas.toDataURL('image/png'); let saveA = document.createElement('a'); document.body.appendChild(saveA); saveA.href = imgUrl; saveA.download = 'mypic'+(new Date).getTime(); saveA.target = '_blank'; saveA.click(); }
6.完成更改情况色调的作用
完成思路:
let selectBg = document.querySelector('.bg-btn'); let bgGroup = document.querySelector('.color-group'); let bgcolorBtn = document.querySelectorAll('.bgcolor-item'); let penDetail = document.getElementById("penDetail"); let activeBgColor = '#fff'; // 完成了切换情况色调 for (let i = 0; i < bgcolorBtn.length; i++) { bgcolorBtn[i].onclick = function (e) { // 阻拦冒泡 e.stopPropagation(); for (let i = 0; i < bgcolorBtn.length; i++) { bgcolorBtn[i].classList.remove("active"); this.classList.add("active"); activeBgColor = this.style.backgroundColor; setCanvasBg(activeBgColor); } } } document.onclick = function(){ bgGroup.classList.remove('active'); } selectBg.onclick = function(e){ bgGroup.classList.add('active'); e.stopPropagation(); }
7.完成更改画笔粗细的作用
完成思路:
let range1 = document.getElementById('range1'); let lWidth = 2; let ifPop = false; range1.onchange = function(){ console.log(range1.value); console.log(typeof range1.value) thickness.style.transform = 'scale('+ (parseInt(range1.value)) +')'; console.log(thickness.style.transform ) lWidth = parseInt(range1.value*2); } // 画线涵数 function drawLine(x1,y1,x2,y2){ // ... context.lineWidth = lWidth; // ... } // 点一下画笔 brush.onclick = function(){ eraserEnabled = false; brush.classList.add('active'); eraser.classList.remove('active'); if(!ifPop){ // 弹出框 console.log('弹1弹') penDetail.classList.add('active'); }else{ penDetail.classList.remove('active'); } ifPop = !ifPop; }
8.完成更改画笔色调的作用
完成思路跟 更改画板情况色调 的思路相近。
let aColorBtn = document.getElementsByClassName("color-item"); getColor(); function getColor(){ for (let i = 0; i < aColorBtn.length; i++) { aColorBtn[i].onclick = function () { for (let i = 0; i < aColorBtn.length; i++) { aColorBtn[i].classList.remove("active"); this.classList.add("active"); activeColor = this.style.backgroundColor; ctx.fillStyle = activeColor; ctx.strokeStyle = activeColor; } } } }
9.完成更改撤消和重做的作用
完成思路:
canvasHistory
数字能量数组(转化成快照应用 canvas 的 toDataURL()
方式,转化成的是 base64 的照片);canvasHistory
数字能量数组中对应数据库索引的快照应用 canvas 的 drawImage()
方式重绘1遍;let undo = document.getElementById("undo"); let redo = document.getElementById("redo"); // ... canvas.onmouseup = function(){ painting = false; canvasDraw(); } let canvasHistory = []; let step = ⑴; // 绘图方式 function canvasDraw(){ step++; if(step < canvasHistory.length){ canvasHistory.length = step; // 断开数字能量数组 } // 加上新的绘图到历史时间纪录 canvasHistory.push(canvas.toDataURL()); } // 撤消方式 function canvasUndo(){ if(step > 0){ step--; // ctx.clearRect(0,0,canvas.width,canvas.height); let canvasPic = new Image(); canvasPic.src = canvasHistory[step]; canvasPic.onload = function () { ctx.drawImage(canvasPic, 0, 0); } undo.classList.add('active'); }else{ undo.classList.remove('active'); alert('不可以再再次撤消了'); } } // 重做方式 function canvasRedo(){ if(step < canvasHistory.length - 1){ step++; let canvasPic = new Image(); canvasPic.src = canvasHistory[step]; canvasPic.onload = function () { // ctx.clearRect(0,0,canvas.width,canvas.height); ctx.drawImage(canvasPic, 0, 0); } redo.classList.add('active'); }else { redo.classList.remove('active') alert('早已是全新的纪录了'); } } undo.onclick = function(){ canvasUndo(); } redo.onclick = function(){ canvasRedo(); }
10.适配挪动端
完成思路:
true
,则应用 touch
恶性事件; false
,则应用 mouse
恶性事件// ... if (document.body.ontouchstart !== undefined) { // 应用touch恶性事件 anvas.ontouchstart = function (e) { // 刚开始触碰 } canvas.ontouchmove = function (e) { // 刚开始拖动 } canvas.ontouchend = function () { // 拖动完毕 } }else{ // 应用mouse恶性事件 // ... } // ...
4、踩坑
难题1:在电脑上上对访问器的对话框开展更改,画板不容易自融入
处理方法:
onresize回应恶性事件解决中,获得到的网页页面规格主要参数是变动后的主要参数 。
当对话框尺寸产生更改以后,再次设定canvas的宽高,简易来讲,便是对话框更改以后,给canvas.width和canvas.height再次取值。
// 记得要实行autoSetSize这个涵数哦 function autoSetSize(){ canvasSetSize(); // 当实行这个涵数的情况下,会先设定canvas的宽高 function canvasSetSize(){ let pageWidth = document.documentElement.clientWidth; let pageHeight = document.documentElement.clientHeight; canvas.width = pageWidth; canvas.height = pageHeight; } // 在对话框尺寸更改以后,就会开启resize恶性事件,再次设定canvas的宽高 window.onresize = function(){ canvasSetSize(); } }
难题2:当绘图线条宽度较为小的情况下还好,1旦较为粗就会出現难题
处理方法:看1下文本文档,得出方式,只必须简易改动1下 绘图线条的编码 就行
// 画线涵数 function drawLine(x1,y1,x2,y2){ context.beginPath(); context.lineWidth = lWidth; //-----添加----- // 设定线条尾端款式。 context.lineCap = "round"; // 设置线条与线条间接性合处的款式 context.lineJoin = "round"; //-----添加----- context.moveTo(x1,y1); context.lineTo(x2,y2); context.stroke(); context.closePath(); }
难题3:怎样完成圆形的橡皮檫?
处理方法:
canvas的API中,能够消除像素的便是clearRect方式,可是clearRect方式的消除地区矩形框,终究绝大多数人的习惯性中的橡皮擦全是圆形的,因此就引进了剪辑地区这个强劲的作用,也便是clip方式。用法很简易:
ctx.save() ctx.beginPath() ctx.arc(x2,y2,a,0,2*Math.PI); ctx.clip() ctx.clearRect(0,0,canvas.width,canvas.height); ctx.restore();
上面那段编码就完成了圆形地区的擦除,也便是先完成1个圆形相对路径,随后把这个相对路径做为剪辑地区,再消除像素就可以了。有个留意点便是必须先储存制图自然环境,消除完像素后要重设制图自然环境,假如不重设的话之后的制图全是会被限定在那个剪辑地区中。
难题4:怎样适配挪动端?
1.加上meta标识
由于访问器原始会将网页页面如今手机上端显示信息时开展放缩,因而大家能够在meta标识中设定meta viewport特性,告知访问器不将网页页面开展放缩,网页页面宽度=客户机器设备显示屏宽度
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no, maximum-scale=1.0,minimum-scale=1.0"/> /* 网页页面宽度=挪动宽度 :width=device-width 客户不能以放缩:user-scalable=no 放缩占比:initial-scale=1 最大放缩占比:maximum-scale=1.0 最少放缩占比:minimum-scale=1.0 */
2.在挪动端基本上应用的全是touch恶性事件,与PC端不一样
因为挪动端是触碰恶性事件,因此要用到H5的特性touchstart/touchmove/touchend,可是PC端只适用电脑鼠标恶性事件,因此要开展特点检验。
在 touch
恶性事件里,是根据 .touches[0].clientX
和 .touches[0].clientY
来获得座标的,这点要和 mouse
恶性事件差别开。
难题5:出現1个难题便是清空以后,再次画,随后出現原先的画的物品
这个嘛,难题不大,只但是是我漏写context.beginPath(); ,也花了1点時间在上面处理bug,让我想起“编码干万行,注解第1行;程序编写不标准,朋友两行泪 ”,還是依照文本文档实际操作标准实际操作好,真香!!!
以上便是本文的所有內容,期待对大伙儿的学习培训有一定的协助,也期待大伙儿多多适用脚本制作之家。
Copyright © 2002-2020 如何制作微信小程序_微信小程序源码_小程序码生成_凡科网微信小程序_微信公众号小程序 版权所有 (网站地图) 粤ICP备10235580号