canvas学习canvas优点是html5提出的新标签,可用于游戏轻量级画布,可以直接使用js做处理,不需增加额外插件,性能好,不卡顿,在手机中也很流畅canvas缺点绘制图形,一旦绘制成功,便将其像素化即canvas无法在次得到这个图形,将其修改解决:canvas图形的移动,必须按照清屏 > 更新 > 渲染的逻辑进行版本兼容问题:不兼容IE6、7、8,可通过在标签里边写入提示文字,来做区分,兼容的浏览器不会显示提示文字基本使用创建画布:<canvas height="200" width="400" id="myCanvas"> 当前浏览器版本不支持,请升级浏览器</canvas>通过height和width直接设置宽高(无需单位),也可以通过css设置,但是会失真id属性用来唯一定位画布获取画布:let canvas = document.getElementById("myCanvas") // 获取画布let ctx = canvas.getContext("2d") // 设置画布环境所有的图像绘制都基于canvas.getContext("2d")进行设置,和canvas标签无关基于画布绘图: 坐标原点在左上角// 填充ctx.fillStyle='red' // 设置颜色ctx.fillRect(100,200,300,400) // 绘制图像// 绘制ctx.strokeStyle = "grend"ctx.strokeRect(left,120,100,100)// 路径ctx.beginPath() // 创建一个路径ctx.moveTo(100,200)// 设置绘制初始点ctx.lineTo(200,300)// 绘制路径ctx.lineTo(180,360)ctx.lineTo(80,380)ctx.lineTo(140,330)ctx.closePath()// 封闭路径ctx.strokeStyle = "yellow"// 对已绘制路径进行渲染颜色ctx.stroke() // 绘制出路径// 圆弧ctx.beginPath()ctx.arc(100,100,80,0,4,false)// 直线ctx.globalAlpha = 0.3 // 直线的透明的,零到一之间ctx.lineWidth = 3 // 设置线的粗细ctx.lineCap = "butt" // 设置未封闭直线两端的样式ctx.lineJoin = "miter" // 设置直线的折点处的样式ctx.setLineDash = ([1,2,3,4]) // 设置虚线的直线线段样式ctx.strokeRect(20,20,100,100) // 以上边的虚线构成矩形ctx.lineDashOffset = 2 // 向左偏移2// 绘制文本ctx.textAlign="center" // 居中对齐ctx.strokeText("你好吖", 0, 100); // 在指定位置绘制内容// 线性渐变let lnear = ctx.createLinearGradinent(0,0,100,100) // 渐变方向lnear.addColorStop(0,"red") // 设置对应比例的颜色ctx.fillStyle = lnear // 将对应颜色渲染出来// 阴影ctx.shadowOffsetX = 2 // 阴影的x方向偏移为2ctx.shadowOffsetY = 2 // 阴影的y方向偏移为2ctx.shadowBlur = 10 // 阴影的模糊度为10ctx.shadowColor = "red" // 阴影的颜色为红色// 图片let image = new Image() // 实例化图片对象image.src = "图片地址" // 给实例赋地址image.onload = function(){ // 监听图片加载事件 ctx.drawImage(image,1,2,3,4,5,6,7,8) // 从图片1,2处开始切取宽为3,高为4的切片,放在画布的5,6处,设置宽为7,高为8}填充ctx.fillStyle="color":绘制图形填充颜色ctx.fillRect(x轴,y轴,width,height):绘制填充矩形绘制ctx.strokeStyle = "color":绘制边框的颜色ctx.strokeRect(x轴,y轴,width,height):绘制空心矩形路径ctx.beginPath():创建路径表示将绘制不规则图形ctx.moveTo(x,y):创建绘制路径的起点位置ctx.lineTo(x,y):创建第二个点及所有点的坐标,按照顺序依次连接ctx.closePath():绘制完路径后,用最后一个点的位置连接起点,形成封闭图形ctx.strokeStyle = "yellow":对已绘制路径进行渲染颜色ctx.fillStyle="color":或者对已绘制路径进行填充渲染颜色ctx.stroke(): 实例化路径ctx.fill(): 实例化填充路径圆弧ctx.arc(x,y,redius,starAngle,endAngle,anticlockwise):绘制圆弧 - 填充x、y:表示圆心位置redius:表示半径startAngle:表示开始开始位置(单位为3.14即Π,一个弧度),endAngle:表示结束位置(单位也是Π)anticlockwise:表示方向(false为顺时针,true表示逆时针)直线ctx.globalAlpha = 0.3:绘制直线的透明的,范围在0-1之间ctx.lineWidth = number:设置直线的粗细,无单位,默认为一ctx.lineCap = "butt":设置线暴露端的样式,可选值("butt","round","square"),'square'两端会延长宽度的一半ctx.lineJoin = "miter":设置两线交接处的样式,可选值("rund","bevel","miter")ctx.setLineDash = ([数组]):接收一个数字数组,数组里边的数值及顺序代表虚线的长度比,数组里边至少两个参数ctx.strokeRect(x,y,width,height):构型,使用上边虚线线段ctx.lineDashOffset = 2:设置虚线起始偏移量绘制文本ctx.textAlign="center":设置文本在绘制范围内对齐方式ctx.strokeText("文本内容", x, y);:x、y:表示绘制的起点位置线性渐变let lnear = ctx.createLinearGradinent(x1,y1,x2,y2):x1、y1:表示绘制起点;x2、y2:表示绘制终点lnear.addColorStop(num,"color"):num:是0-1之间的值,多个,按比例划分各段颜色;color:对应端的颜色ctx.fillStyle = lnear :渲染对应颜色径向渐变ctx.createRadialGradient(x1,y1,r1,x2,y2,r2):x1、y1、r1:开始圆形的参数,x2、y2、r2:结束圆形的参数阴影ctx.shadowOffsetX = num :阴影方向 -- x轴ctx.shadowOffsetY = num :阴影方向 -- y轴ctx.shadowBlur = num :阴影模糊度ctx.shadowColor = "color" :阴影颜色图片let image = new Image():创建图片image.src = "图片地址":引入图片地址image.onload = function(){}:图片加载完成后立即执行ctx.drawImage(image,e,f,j,h,a,b,c,d):写于onload事件里边,可以写两个参数,四个参数,八个参数a、b:表示图片的初始位置,即x轴、y轴的位置c、d:表示图片的宽高e、f:表示切取图片的起点j、h:表示切片的宽高当只有两个或四个参数时,取a、b、c、d动画实现的基础:ctx.clearRect(0,0,canvas.width,canvas.height) // 动画会用到的属性 - 清屏ctx.clearRect(x,y,width,height):x、y代表开始清除的位置,width、height代表清除的宽度和高度设置全屏画布 canvas.width = document.documentElement.clientWidth-30 ; // 减30是为了消去滚动条,可以不减 canvas.height = document.documentElement.clientHeight -30 ;任意方向this.dx = parseInt(Math.random()*10)-5this.dy = parseInt(Math.random()*10)-5动画学习简单的动画实现 let canvas = document.getElementById("myCanvas") let ctx = canvas.getContext("2d") ctx.fillStyle='red' let left = 100 // 初始左边距离位置 setInterval(()=>{ ctx.clearRect(0,0,canvas.width,canvas.height) // 清屏 left++; // 距离左边的距离 ctx.fillRect(left,100,100,100) // 重复绘制 left>600?left = -100:left; // 对左边距离清零 })以面向对象的思想完成动画在函数原型对象上准备好各个参数function rects(x,y,w,h,color) {// 初始状态 this.x = x; this.y = y; this.w = w; this.h = h; this.color = color; } // 在原型上设置方法 // 更新 rects.prototype.updata = function () { this.x++ } // 渲染 rects.prototype.render = function () { ctx.fillStyle = this.color; ctx.fillRect(this.x,this.y,this.w,this.h); }实例化对象let r1 = new rects(100,30,50,50,"red")动画过程setInterval(()=>{ // 清屏 ctx.clearRect(0,0,canvas.width,canvas.height) r1.updata(); r1.render() },10)动画案例炫彩小球案例 const ballArr = [] ; // 创建一个存储实例的数组 function Ball(x,y,r){ this.x = x ; // 设置x轴坐标 this.y = y ; // 设置y轴左边 this.r = r ; // 设置小圆半径 this.color = getRandom() ; // 设置小圆颜色 -- 随机y this.dx = parseInt(Math.random()*10)-5 ; // 设置x轴行经方向 this.dy = parseInt(Math.random()*10)-5 ; // 设置y轴行经方向 ballArr.push(this) ; // 将生成的小球存到数组中 } // 渲染小球 -- 创建一个图形,并对其渲染 Ball.prototype.render = function () { ctx.beginPath() ctx.arc(this.x,this.y,this.r,0,Math.PI*2,false) ctx.fillStyle = this.color ctx.fill() } // 设置鼠标监听事件 -- 鼠标移动时监创建小球 canvas.addEventListener("mousemove",function (event) { new Ball(event.offsetX,event.offsetY,30) }) // 小球的移动方向及移动时的变化 -- 减小 Ball.prototype.updata = function () { this.x += this.dx; this.y += this.dy; this.r -= 0.1 if (this.r < 0 ){ // 判断半径小于零时,执行删除指令,将其在数组中删除 this.remove(); } } // 当半径小于一定程度时,执行将其删除 Ball.prototype.remove = function () { for (let i = 0 ; i < ballArr.length ; i++){ if (ballArr[i] == this){ ballArr.splice(i,1) } } } // 定时器进行动画渲染和更新 setInterval(function () { ctx.clearRect(0,0,canvas.width,canvas.height) for (let i = 0 ; i < ballArr.length; i++){ ballArr[i].updata() if (ballArr[i]){ ballArr[i].render() } } },10) // 随机生成颜色 function getRandom() { let allTypeArr = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"] let color = "#" for (let i = 0 ; i < 6 ; i++){ let random = parseInt(Math.random()*allTypeArr.length) color += allTypeArr[random] } return color }小球连线案例 let canvas = document.getElementById("myCanvas") let ctx = canvas.getContext("2d") // 设置全屏宽度 canvas.width = document.documentElement.clientWidth-30 canvas.height = document.documentElement.clientHeight -30 function Ball() { // 设置小球出现点 -- 任意 this.x = parseInt(Math.random() * canvas.width) this.y = parseInt(Math.random() * canvas.height) this.r = 10 this.color = getRandom() // 设置小球行驶方向 - 任意 this.dx = parseInt(Math.random()*10)-5 this.dy = parseInt(Math.random()*10)-5 // 存储生成的小球 ballArr.push(this) // 记录自己在数组中的值 this.index = ballArr.length-1; } // 小球行驶方向 -- 跟新 Ball.prototype.update = function () { this.x += this.dx; this.y += this.dy; if (this.x < this.r || this.x > canvas.width-this.r){ this.dx = -this.dx; } if (this.y < this.r || this.y > canvas.height-this.r){ this.dy = -this.dy; } } // 小球渲染 Ball.prototype.render = function () { ctx.beginPath() ctx.globalAlpha = 1 // 透明度 // 画小球 ctx.arc(this.x,this.y,this.r,0,Math.PI*2,false) ctx.fillStyle = this.color; ctx.fill() // 划线 for (let i = this.index ; i < ballArr.length ; i++){ if (Math.abs(ballArr[i].x-this.x)<150 && Math.abs(ballArr[i].y - this.y) < 150){ ctx.strokeStyle = getRandom(); ctx.beginPath(); ctx.globalAlpha = 10/Math.sqrt(Math.pow(ballArr[i].x-this.x ,2)+Math.pow(ballArr[i].y -this.y,2))//连线小球间的透明的问题 ctx.moveTo(this.x,this.y); ctx.lineTo(ballArr[i].x,ballArr[i].y) ctx.closePath() ctx.stroke() } } } let ballArr = [] for (let i = 0 ; i < 30 ; i++){ new Ball() } setInterval(function () { ctx.clearRect(0,0,canvas.width,canvas.height) for (let i = 0 ; i < ballArr.length ; i++){ ballArr[i].update() ballArr[i].render(); } }) function getRandom() { let allTypeArr = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"] let color = "#" for (let i = 0 ; i < 6 ; i++){ let random = parseInt(Math.random()*allTypeArr.length) color += allTypeArr[random] } return color }
