wordpress顶部是什么seo优化网站优化排名
前言
canvas实现画板功能,有画笔、矩形、橡皮擦、圆形、线段粗细、画笔颜色、下载图片等功能
是对canvas的综合学习回顾
步骤
- 基本样式
<style type="text/css">*{margin: 0;padding: 0;box-sizing: border-box;}body{width: 100vw;height: 100vh;display: flex;flex-direction: column;justify-content: flex-start;}.caidan{height: 100px;width: 100vw;display: flex;border-bottom: 3px solid #ccc;justify-content: space-around;align-items: center;}#canvas{flex: 1;width: 100vw;}.btn{width: 150px;height: 50px;border: 1px solid #ccc;border-radius: 20px;text-align: center;line-height: 50px;color: #999;}.active{box-shadow: 0 0 20px deepskyblue;background-color: #f2f2f2;border: 1px solid deepskyblue;}</style><div class="caidan"><div class="btn" id="huabi">画笔</div><div class="btn" id="rect">矩形</div><div class="btn">圆形</div><div class="btn">线段粗细</div><div class="btn">画笔颜色</div></div><canvas id="canvas">你的浏览器不支持canvas</canvas>
- 画笔和矩形
思路解析:1、点击菜单项渲染阴影,触发相应的函数2、鼠标按下、弹起事件控制画板可画
<script>// 需求// 画笔功能:能够拖动鼠标在页面内绘图 能够设置画笔粗细 设置画笔颜色// 能够在任意位置绘制圆形: 拖动鼠标可以在任意位置绘制圆形并可以定制大小// 能够在任意位置绘制矩形: 拖动鼠标可以在任意位置绘制矩形并可以定制大小// 1、找到画布对象/** @type {HTMLCanvasElement} */ var canvas= document.getElementById('canvas')console.log([canvas])canvas.setAttribute("width",canvas.offsetWidth) // 设置宽度为页面全屏canvas.setAttribute("height",canvas.offsetHeight)// 2、上下文对象,画笔var ctx=canvas.getContext('2d') // 用于2d对象绘制 webgl是3d引擎// 设置一个对象 保存画笔当前的状态var huaban = {type:null,isDrow:false, // 是否处于可画状态beginX:0, // 矩形开始时起点的位置beginY:0, // 矩形开始时起点的位置imageData:null,huabiFn:(e)=>{ // 画笔执行的内容var x = e.pageX - canvas.offsetLeft; // 找到当前鼠标位置var y = e.pageY - canvas.offsetTop;ctx.beginPath()ctx.arc(x,y,3,0,2*Math.PI) // 以当前鼠标触发的位置为中心 进行画小圆,缺点是画的快无法连贯ctx.closePath()ctx.fill()},rectFn:(e)=>{ // 矩形执行的函数var x = e.pageX - canvas.offsetLeft; // 找到当前鼠标位置var y = e.pageY - canvas.offsetTop;ctx.clearRect(0,0,canvas.offsetWidth,canvas.offsetHeight) // 画矩形前清除画板if(huaban.imageData){ // 导入之前保存的画板图像ctx.putImageData(huaban.imageData,0,0,0,0,canvas.offsetWidth,canvas.offsetHeight)}ctx.beginPath()ctx.rect(huaban.beginX,huaban.beginY,x-huaban.beginX,y-huaban.beginY) // 以当前鼠标触发的位置为中心ctx.stroke()ctx.closePath()}}function btnClick(){ // 全局清除样式document.querySelectorAll('.btn').forEach((item)=>{item.classList.remove("active")}) }// 画笔按钮点击事件var huabiBtn = document.querySelector('#huabi')huabiBtn.onclick=()=>{btnClick()huabiBtn.classList.add("active")huaban.type='huabi'}// 矩形点击事件var rectBtn = document.querySelector('#rect')rectBtn.onclick=()=>{btnClick()rectBtn.classList.add("active")huaban.type='rect'}// 监听鼠标按下事件canvas.onmousedown=(e)=>{huaban.isDraw = trueif(huaban.type=="rect"){var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;huaban.beginX=xhuaban.beginY=y}}// 监听鼠标弹起事件canvas.onmouseup=()=>{// 将当前的数据对象保留huaban.imageData = ctx.getImageData(0,0,canvas.offsetWidth,canvas.offsetHeight)huaban.isDraw = false}// 鼠标移动时绘制圆形 将源图像的目标内容清除掉canvas.onmousemove=(e)=>{if(huaban.isDraw&&huaban.type){huaban[huaban.type+'Fn'](e) // 调用当前所点的按钮}}
- 画笔优化(连贯)
上述情况下,画笔是用填充小圆的方式实现,出现问题在画的速度过快的情况下无法连贯
优化:以绘制线段的方式实现
思路:移动过程中时刻改变起点位置
// 监听鼠标移动,如果当前是画笔状态,时刻更新起点位置canvas.onmousemove=(e)=>{if(huaban.isDraw&&huaban.type){huaban[huaban.type+'Fn'](e) // 调用当前所点的按钮}if(huaban.type=="huabi"){var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;huaban.beginX=xhuaban.beginY=y}}
lineWidth:6,huabiFn:(e)=>{ // 画笔执行的内容ctx.beginPath()var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;
++ ctx.moveTo(huaban.beginX,huaban.beginY)
++ ctx.lineTo(x,y)
-- // ctx.beginPath()
++ ctx.lineWidth=huaban.lineWidth
++ ctx.lineCap="round"
++ ctx.lineJoin="round"
-- // ctx.moveTo(huaban.beginX,huaban.beginY)
++ ctx.stroke()
-- // ctx.arc(x,y,3,0,2*Math.PI) // 以当前鼠标触发的位置为中心
-- // ctx.fill()ctx.closePath()},
效果图
- 圆形
和矩形书写方式类似
// huaban对象下添加
yuanFn:(e)=>{var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;ctx.clearRect(0,0,canvas.offsetWidth,canvas.offsetHeight)if(huaban.imageData){ctx.putImageData(huaban.imageData,0,0,0,0,canvas.offsetWidth,canvas.offsetHeight)}ctx.beginPath()ctx.arc(x,y,Math.abs(x-huaban.beginX),0,2*Math.PI) // 以当前鼠标触发的位置为中心 绝对值半径ctx.stroke()ctx.closePath()},
// 圆形var yuanBtn = document.querySelector('#yuan')yuanBtn.onclick=()=>{btnClick()yuanBtn.classList.add("active")huaban.type='yuan'}// 监听鼠标按下事件canvas.onmousedown=(e)=>{huaban.isDraw = true
++ if(huaban.type=="rect"||huaban.type=="yuan"){var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;huaban.beginX=xhuaban.beginY=y}}
- 线段粗细
思路:设置一个字段用来控制线段粗细
<div class="caidan"><div class="btn" id="huabi">画笔</div><div class="btn" id="rect">矩形</div><div class="btn" id="yuan">圆形</div>
++ <div class="btn1 line xi">线段细</div>++ <div class="btn1 line normal">线段</div>
++ <div class="btn1 line cu">线段粗</div>
++ <div class="btn1">画笔颜色</div></div>.btn1{width: 150px;height: 50px;border: 1px solid #ccc;border-radius: 20px;text-align: center;line-height: 50px;color: #999;}.line{display: flex;justify-content: center;align-items: center;}.xi::after{content: "";background-color: #333;width: 6px;height: 6px;display: block;border-radius: 3px;}.normal::after{content: "";background-color: #333;width: 10px;height: 10px;display: block;border-radius: 5px;}.cu::after{content: "";background-color: #333;width: 16px;height: 16px;display: block;border-radius: 8px;}
// 选中样式,清除其他 回到最开始线段粗细
function btn1Click(){huaban.lineWidth=6document.querySelectorAll('.line').forEach((item)=>{item.classList.remove("active")}) }
// 设置粗细的按钮var lineDivs=document.querySelectorAll(".line")lineDivs.forEach((item,i)=>{item.onclick=()=>{btn1Click() // 清除样式item.classList.add('active')if(i==0){huaban.lineWidth=6}else if(i==1){huaban.lineWidth=16}else{huaban.lineWidth=32}}})
- 字体颜色
和设置线段粗细类似
<div class="btn1 line cu">线段粗</div>-- <div class="btn1">画笔颜色</div>++ <div class="btn1" id="btnColor"><input type="color" id="color"></div>
// 添加color属性保存我们选中的颜色
var huaban = {type:null,isDrow:false,beginX:0,beginY:0,lineWidth:6,imageData:null,++ color:'#000',~~}
// 点击颜色组件var colorBtn = document.querySelector('#btnColor')colorBtn.onclick=()=>{colorBtn.classList.add("active")}// 监听颜色改变事件var colorInput = document.querySelector("#color")colorInput.onchange = (e)=>{huaban.color = colorInput.value}
huabiFn:(e)=>{ // 画笔执行的内容ctx.beginPath()var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;
++ ctx.lineWidth=huaban.lineWidth
++ ctx.strokeStyle=huaban.colorctx.lineCap="round"ctx.lineJoin="round"ctx.moveTo(huaban.beginX,huaban.beginY)ctx.lineTo(x,y)ctx.stroke()ctx.closePath()},rectFn:(e)=>{var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;ctx.clearRect(0,0,canvas.offsetWidth,canvas.offsetHeight)if(huaban.imageData){ctx.putImageData(huaban.imageData,0,0,0,0,canvas.offsetWidth,canvas.offsetHeight)}
++ ctx.lineWidth=huaban.lineWidth
++ ctx.strokeStyle=huaban.colorctx.beginPath()ctx.rect(huaban.beginX,huaban.beginY,x-huaban.beginX,y-huaban.beginY) // 以当前鼠标触发的位置为中心ctx.stroke()ctx.closePath()},yuanFn:(e)=>{var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;ctx.clearRect(0,0,canvas.offsetWidth,canvas.offsetHeight)if(huaban.imageData){ctx.putImageData(huaban.imageData,0,0,0,0,canvas.offsetWidth,canvas.offsetHeight)}
++ ctx.lineWidth=huaban.lineWidth
++ ctx.strokeStyle=huaban.colorctx.beginPath()ctx.arc(x,y,Math.abs(x-huaban.beginX),0,2*Math.PI) // 以当前鼠标触发的位置为中心ctx.stroke()ctx.closePath()},
- 下载图片
实现画布的下载保存功能
canvas.toDataURL() // 会把画布转化成base64格式的图片
调用a标签的下载事件实现
<div class="btn1" id="download">下载图片</div>
// 点击下载按钮var download = document.querySelector("#download")download.onclick=()=>{var url = canvas.toDataURL()// console.log(url) // 打印是base64格式图片地址var img = new Image()img.src = urllet eleLink = document.createElement('a')eleLink.download = "画布图片"eleLink.style.display = 'none';eleLink.href = urleleLink.click()eleLink.remove()}
效果图
- 橡皮擦
本质上就是:颜色为画布背景色的画笔
<div class="btn" id="xpc">橡皮擦</div>var xpcBtn = document.querySelector('#xpc')xpcBtn.onclick=()=>{btnClick()xpcBtn.classList.add("active")huaban.type='xpc'}
// 对象中添加橡皮擦函数
xpcFn:(e)=>{ctx.beginPath()var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;ctx.lineWidth=huaban.lineWidthctx.strokeStyle="#fff"ctx.lineCap="round"ctx.lineJoin="round"ctx.moveTo(huaban.beginX,huaban.beginY)ctx.lineTo(x,y)ctx.stroke()ctx.closePath()},
// 鼠标移动时绘制圆形 将源图像的目标内容清除掉canvas.onmousemove=(e)=>{if(huaban.isDraw&&huaban.type){huaban[huaban.type+'Fn'](e) // 调用当前所点的按钮}
++ if(huaban.type=="huabi"||huaban.type=="xpc"){var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;huaban.beginX=xhuaban.beginY=y}}
- 全部代码
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style type="text/css">*{margin: 0;padding: 0;box-sizing: border-box;}body{width: 100vw;height: 100vh;display: flex;flex-direction: column;justify-content: flex-start;}.caidan{height: 100px;width: 100vw;display: flex;border-bottom: 3px solid #ccc;justify-content: space-around;align-items: center;}#canvas{flex: 1;width: 100vw;}.btn{width: 150px;height: 50px;border: 1px solid #ccc;border-radius: 20px;text-align: center;line-height: 50px;color: #999;}.active{box-shadow: 0 0 20px deepskyblue;background-color: #f2f2f2;border: 1px solid deepskyblue;}.btn1{width: 150px;height: 50px;border: 1px solid #ccc;border-radius: 20px;text-align: center;line-height: 50px;color: #999;}.line{display: flex;justify-content: center;align-items: center;}.xi::after{content: "";background-color: #333;width: 6px;height: 6px;display: block;border-radius: 3px;}.normal::after{content: "";background-color: #333;width: 10px;height: 10px;display: block;border-radius: 5px;}.cu::after{content: "";background-color: #333;width: 16px;height: 16px;display: block;border-radius: 8px;}</style>
</head>
<body><div class="caidan"><div class="btn" id="huabi">画笔</div><div class="btn" id="rect">矩形</div><div class="btn" id="yuan">圆形</div><div class="btn" id="xpc">橡皮擦</div><div class="btn1" id="download">下载图片</div><div class="btn1 line xi active">线段细</div><div class="btn1 line normal">线段</div><div class="btn1 line cu">线段粗</div><div class="btn1" id="btnColor"><input type="color" id="color"></div></div><canvas id="canvas">你的浏览器不支持canvas</canvas><script>// 需求// 画笔功能:能够拖动鼠标在页面内绘图 能够设置画笔粗细 设置画笔颜色// 能够在任意位置绘制圆形: 拖动鼠标可以在任意位置绘制圆形并可以定制大小// 能够在任意位置绘制矩形: 拖动鼠标可以在任意位置绘制矩形并可以定制大小// 1、找到画布对象/** @type {HTMLCanvasElement} */ var canvas= document.getElementById('canvas')console.log([canvas])canvas.setAttribute("width",canvas.offsetWidth)canvas.setAttribute("height",canvas.offsetHeight)// 2、上下文对象,画笔var ctx=canvas.getContext('2d') // 用于2d对象绘制 webgl是3d引擎// 设置一个对象 保存画笔当前的状态var huaban = {type:null,isDrow:false,beginX:0,beginY:0,lineWidth:6,imageData:null,color:'#000',huabiFn:(e)=>{ // 画笔执行的内容ctx.beginPath()var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;ctx.lineWidth=huaban.lineWidthctx.strokeStyle=huaban.colorctx.lineCap="round"ctx.lineJoin="round"ctx.moveTo(huaban.beginX,huaban.beginY)ctx.lineTo(x,y)// ctx.beginPath()// ctx.moveTo(huaban.beginX,huaban.beginY)ctx.stroke()// ctx.arc(x,y,3,0,2*Math.PI) // 以当前鼠标触发的位置为中心// ctx.fill()ctx.closePath()},xpcFn:(e)=>{ctx.beginPath()var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;ctx.lineWidth=huaban.lineWidthctx.strokeStyle="#fff"ctx.lineCap="round"ctx.lineJoin="round"ctx.moveTo(huaban.beginX,huaban.beginY)ctx.lineTo(x,y)ctx.stroke()ctx.closePath()},rectFn:(e)=>{var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;ctx.clearRect(0,0,canvas.offsetWidth,canvas.offsetHeight)if(huaban.imageData){ctx.putImageData(huaban.imageData,0,0,0,0,canvas.offsetWidth,canvas.offsetHeight)}ctx.lineWidth=huaban.lineWidthctx.strokeStyle=huaban.colorctx.beginPath()ctx.rect(huaban.beginX,huaban.beginY,x-huaban.beginX,y-huaban.beginY) // 以当前鼠标触发的位置为中心ctx.stroke()ctx.closePath()},yuanFn:(e)=>{var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;ctx.clearRect(0,0,canvas.offsetWidth,canvas.offsetHeight)if(huaban.imageData){ctx.putImageData(huaban.imageData,0,0,0,0,canvas.offsetWidth,canvas.offsetHeight)}ctx.lineWidth=huaban.lineWidthctx.strokeStyle=huaban.colorctx.beginPath()ctx.arc(x,y,Math.abs(x-huaban.beginX),0,2*Math.PI) // 以当前鼠标触发的位置为中心ctx.stroke()ctx.closePath()},}function btnClick(){document.querySelectorAll('.btn').forEach((item)=>{item.classList.remove("active")}) }function btn1Click(){huaban.lineWidth=6document.querySelectorAll('.line').forEach((item)=>{item.classList.remove("active")}) }// 画笔按钮点击事件var huabiBtn = document.querySelector('#huabi')huabiBtn.onclick=()=>{btnClick()huabiBtn.classList.add("active")huaban.type='huabi'}var rectBtn = document.querySelector('#rect')rectBtn.onclick=()=>{btnClick()rectBtn.classList.add("active")huaban.type='rect'}// 圆形var yuanBtn = document.querySelector('#yuan')yuanBtn.onclick=()=>{btnClick()yuanBtn.classList.add("active")huaban.type='yuan'}// 橡皮擦var xpcBtn = document.querySelector('#xpc')xpcBtn.onclick=()=>{btnClick()xpcBtn.classList.add("active")huaban.type='xpc'}// 设置粗细的按钮var lineDivs=document.querySelectorAll(".line")lineDivs.forEach((item,i)=>{item.onclick=()=>{btn1Click() // 清除样式item.classList.add('active')if(i==0){huaban.lineWidth=6}else if(i==1){huaban.lineWidth=16}else{huaban.lineWidth=32}}})// 点击颜色组件var colorBtn = document.querySelector('#btnColor')colorBtn.onclick=()=>{colorBtn.classList.add("active")}// 监听颜色改变事件var colorInput = document.querySelector("#color")colorInput.onchange = (e)=>{huaban.color = colorInput.value}// 点击下载按钮var download = document.querySelector("#download")download.onclick=()=>{var url = canvas.toDataURL()// console.log(url) // 打印是base64格式图片地址var img = new Image()img.src = urllet eleLink = document.createElement('a')eleLink.download = "画布图片"eleLink.style.display = 'none';eleLink.href = urleleLink.click()eleLink.remove()}// 监听鼠标按下事件canvas.onmousedown=(e)=>{huaban.isDraw = trueif(huaban.type=="rect"||huaban.type=="yuan"){var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;huaban.beginX=xhuaban.beginY=y}}// 监听鼠标弹起事件canvas.onmouseup=()=>{// 将当前的数据对象保留huaban.imageData = ctx.getImageData(0,0,canvas.offsetWidth,canvas.offsetHeight)huaban.isDraw = false}// 鼠标移动时绘制圆形 将源图像的目标内容清除掉canvas.onmousemove=(e)=>{if(huaban.isDraw&&huaban.type){huaban[huaban.type+'Fn'](e) // 调用当前所点的按钮}if(huaban.type=="huabi"||huaban.type=="xpc"){var x = e.pageX - canvas.offsetLeft; // 找到当前位置var y = e.pageY - canvas.offsetTop;huaban.beginX=xhuaban.beginY=y}}</script>
</body>
</html>