<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>Document</title> <style> .container:before { content: ""; position: absolute; left: 50px; top: 0; width: 1px; height: 102px; background: #fff; } .container:after { content: ""; position: absolute; left: 0px; top: 50px; width: 102px; height: 1px; background: #fff; } .container { background: #abcdef; display: inline-block; font-size: 0; position: relative; } </style> </head> <body> <div class="container"> <canvas class="myCanvas" width="100" height="100"></canvas> </div> <script> var canvas = document.querySelector(‘.myCanvas‘); //获取canvas对应dom // var ctx = canvas.getContext(‘2d‘); //此方法较为基础 , 意为获取canvas绘画2d内容的工具(上下文) // var cw = 100; //分辨率 , 其实直接从dom上获取可能更好些 // var ch = 100; //分辨率 , 其实直接从dom上获取可能更好些 //API //保存上下文状态 (比如画笔尺寸 颜色 旋转角度) // ctx.save() //返回上次保存的上下文状态 //ctx.restore() //上下文移动到具体位置 //ctx.moveTo(x,y) //上下文以划线的形式移动到某位置 //ctx.lineTo(x,y) // 画线动作 //ctx.stroke() //上下文(画笔)按贝塞尔曲线移动(简单理解为可控的曲线即可) //ctx.quadraticCurveTo() //画圆 //ctx.arc() //开启新的画笔路径 //ctx.beginPath() //关闭当前画笔路径 //ctx.closePath() //创建canvas渐变对象 //ctx.createLinearGradient() //对闭合区域进行填充 //ctx.fill() //画笔的重叠模式 //ctx.globalCompositeOperation /** 首先是绘制黑色翻出的部分 , 图形分解为如下几部分(请根据上图脑补) 左上角向右下的半弧 ╮ 然后是竖直向下的竖线 | 然后是向右的半圆 ╰ 再然后是向右的横线 接着还是向右下的半弧 ╮ 最后是将线连接会起点 **/ var canvas = document.querySelector(‘.myCanvas‘); var ctx = canvas.getContext(‘2d‘); var cw = 100; var ch = 100; var percent = 0; var points = { x1 : 100, y1 : 0, x2 : 100, y2 : 0 } var speed = 1; var aSpeed = 0.1; ctx.moveTo(0,0); ctx.strokeStyle = ‘black‘; ctx.strokeWidth= 1; ctx.save(); var deg = Math.PI / 180; function start(type){ if(type === ‘show‘){ points = { x1 : 100, y1 : 0, x2 : 100, y2 : 0 } aSpeed = .1; speed = 1; }else{ points = { x1 : 50, y1 : 0, x2 : 100, y2 : 50 } aSpeed = -.1; speed = -1; } draw(points , type); } function draw(points , type){ var disX = Math.floor(points.x2 - points.x1); var disY = Math.floor(points.y2 - points.y1); if(disY < 0 && type == ‘hide‘){ // console.log(‘改展开动画了‘); ctx.clearRect(0,0,cw,ch); setTimeout(function(){ start(‘show‘); } , 2000) return ; }else if(disY > 50 && type == ‘show‘){ // console.log(‘改收起动画了‘); setTimeout(function(){ start(‘hide‘); } , 2000) return ; } ctx.clearRect(0,0,cw,ch); drawPageCorShow(points , disX , disY); drawPageCor(points, disX , disY); window.requestAnimationFrame(function(){ draw(points , type); }) } function drawPageCorShow(points, disX , disY){ ctx.save(); ctx.beginPath(); //闭合三角形 ctx.moveTo(points.x1 , points.y1); ctx.lineTo(points.x2 , points.y2); ctx.lineTo(points.x2 , points.y1); ctx.lineTo(points.x1 , points.y1); ctx.closePath(); ctx.strokeStyle = "#080"; ctx.stroke(); ctx.fillStyle = ‘#ff6600‘; ctx.fill(); //重叠模式 ctx.globalCompositeOperation = ‘source-atop‘; ctx.beginPath(); ctx.font = ‘14px Arial‘; ctx.textAlign = ‘center‘; ctx.translate(78 , 22); ctx.rotate(45 * deg); ctx.fillStyle = ‘#fff‘; ctx.fillText(‘NEW‘ , 0 , 0); ctx.closePath(); ctx.restore(); } function drawPageCor(points, disX , disY){ ctx.save(); ctx.beginPath(); //移動到位置 左上 ctx.moveTo(points.x1,points.y1); //画第一个曲线 ctx.quadraticCurveTo(points.x1 + (disX/10),points.y1 + disY/10 ,(points.x1 + disX/10),points.y1 + disY/2); //直线向下 ctx.lineTo(points.x1 + disX / 10 , points.y2 - (disY/5)); //半圆向右 ctx.arc(points.x1+disX/5,points.y2 - (disY/5),disY/10,deg*180 , deg*90,true); // 直线向右 ctx.lineTo(points.x2 - disX/2 , points.y2 - (disY / 10)) //曲线向右 ctx.quadraticCurveTo(points.x2 -disX/10,points.y2 - (disY/10) ,points.x2,points.y2 ); //闭合图形 ctx.lineTo(points.x1,points.y1); ctx.closePath(); var gradient = ctx.createLinearGradient(points.x1 , points.y2 , points.x1 + (disX/2) , points.y1 + disY/2); gradient.addColorStop(0 , ‘#ccc‘); gradient.addColorStop(0.7 , ‘#111‘); gradient.addColorStop(1 , ‘#000‘); ctx.fillStyle = gradient; ctx.fill(); ctx.restore(); //更新速度位置 points.x1 -= speed; points.y2 += speed; speed += aSpeed; } start(‘show‘); </script> </body> </html>
原文地址:http://web.jobbole.com/93229/