最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Canvas动画小demo(从零到一)

    正文概述 掘金(大大?)   2021-04-07   574

    前言

    因对于 canvas 画布在面试过程中有重复遇见,而自身也仅仅了解和学习过 canvas 的理论知识,那就那就整一个 demo 叭!

    对应的文件已经整理上传到自己的仓库啦(全部注释讲解了喔)

    Canvas动画小demo(从零到一) 跟随 imooc 系列课程 学习总结,如果有不清楚的地方,也建议跟我一样从零观看学习喔

    Canvas 基础

    创建 Canvas

    HTML标签

    	<canvas id="canvas" width="1024" height="768" style="border: 1px solid #aaa; display: block; margin: auto auto">
    		<!--兼容降错-->
    		当前浏览器不支持 Canvas,请更换浏览器后再试
    	</canvas>
    

    块级元素,默认 350px 宽,150px 高

    Javascript

    const canvas = document.getElementById('canvas')
    // 绘图上下文环境 2D 绘图
    const context = canvas.getContext('2d')
    

    Canvas 绘制

    绘制直线

    // 状态设置 - 以左上角为顶点(0, 0)
    context.moveTo(100, 100)	// 笔尖移动
    context.lineTo(700, 700)	// 画笔移动到这点
    
    // 常用属性
    // 笔线
    context.lineWidth = 5	// 线粗
    context.strokeStyle = '#005588'	// 线颜色
    
    context.stroke()	// 开始绘制
    

    绘制多边形

    // 三角形
    context.moveTo(100, 100)	// 笔尖移动
    context.lineTo(700, 700)	// 画笔移动到这点
    context.lineTo(100, 700)	// 画笔移动到这点
    context.lineTo(100, 100)	// 画笔移动到这点
    
    // 常用属性
    // 笔线
    context.lineWidth = 5	// 线粗
    context.strokeStyle = '#005588'	// 线颜色
    // 填充
    context.fillStyle = 'rgb(2, 100, 30)'	// 填充颜色
    context.fill()	// 填充
    
    context.stroke()	// 开始绘制
    

    绘制七巧板

    // 七巧板线条数据
    const tanGram = [
      {p: [{x: 0, y: 0}, {x: 800, y: 0}, {x: 400, y: 400}], color: '#caff67'},
      {p: [{x: 0, y: 0}, {x: 400, y: 400}, {x: 0, y: 800}], color: '#67beef'},
      {p: [{x: 800, y: 0}, {x: 800, y: 400}, {x: 600, y: 600}, {x: 600, y:200}], color: '#ef3d61'},
      {p: [{x: 600, y: 200}s, {x: 600, y: 600}, {x: 400, y: 400}], color: '#f9f51a'},
      {p: [{x: 400, y: 400}, {x: 600, y: 600}, {x: 400, y: 800}, {x: 200, y: 600}], color: '#a594c0'},
      {p: [{x: 200, y: 600}, {x: 400, y: 800}, {x: 0, y: 800}], color: '#fa8ecc'},
      {p: [{x: 800, y: 400}, {x: 800, y: 800}, {x: 400, y: 800}], color: '#f6ca29'},
    ]
    
    window.onload = function() {
      // 七巧板
      const canvas = document.getElementById('canvas')
      // 绘图上下文环境 2D 绘图
      const context = canvas.getContext('2d')
      const len = tanGram.length
      // 绘画各个多边形
      for (let i = 0; i < len; i++) {
        draw(tanGram[i], context)
      }
    }
    
    function draw(piece, cxt) {
      // 开始绘制
      cxt.beginPath();
      cxt.moveTo(piece.p[0].x, piece.p[0].y)
      const len = piece.p.length
      for (let i = 1; i < len; i++) {
        cxt.lineTo(piece.p[i].x, piece.p[i].y)
      }
      // 结束绘制
      cxt.closePath()
      cxt.fillStyle = piece.color
      cxt.fill()
    }
    

    绘制弧和圆

    方法属性

    constext.arc(
    	centerx, centery, radius,	// 圆心原点坐标以及半径的值
      startingAngle, endingAngle,	// 弧度值的范围
      anticlockwise = false	// 是否顺时针(可选)- 默认 false 以顺时针方向
    )
    

    context.lineWidth = 5
    context.strokeStyle = '#005588'
    context.arc(300, 300, 200, 0, 1.5 + Math.PI)
    context.stroke()
    

    连续弧

    context.lineWidth = 5
    context.strokeStyle = '#005588'
    
    // 不连续弧
    for (let i = 0; i < 10; i++) {
      context.beginPath()
      context.arc(50 + i*100, 60, 40, 0, 2*Math.PI*(i+1)/10)
      context.closePath()
      context.stroke()
    }
    
    // 连续弧
    for (let i = 0; i < 10; i++) {
      context.beginPath()
      context.arc(50 + i*100, 180, 40, 0, 2*Math.PI*(i+1)/10)
      context.stroke()
    }
    

    context.lineWidth = 5
    context.strokeStyle = '#005588'
    
    for (let i = 0; i < 10; i++) {
      context.beginPath()
      context.arc(50 + i*100, 60, 40, 0, 2*Math.PI*(i+1)/10)
      context.closePath()
    	context.fill()	// 填充
    }
    
    for (let i = 0; i < 10; i++) {
      context.beginPath()
      context.arc(50 + i*100, 180, 40, 0, 2*Math.PI*(i+1)/10)
    	context.fill()	// 填充
    }
    

    实现电子钟

    绘制电子钟

    目录结构

    二维点阵 - digin.js

    因为数据太多,稍微拿一个进行例子

    // 表示 0,1 表示需绘制圆
    [
      [0,0,1,1,1,0,0],
      [0,1,1,0,1,1,0],
      [1,1,0,0,0,1,1],
      [1,1,0,0,0,1,1],
      [1,1,0,0,0,1,1],
      [1,1,0,0,0,1,1],
      [1,1,0,0,0,1,1],
      [1,1,0,0,0,1,1],
      [0,1,1,0,1,1,0],
      [0,0,1,1,1,0,0]
    ]
    

    具体逻辑 - countdown.js

    初始化

    // 常量
    const WINDOW_WIDTH = 1024;
    const WINDOW_HEIGHT = 768;
    const RADIUS = 8;
    const MARGIN_TOP = 60;
    const MARGIN_LEFT = 30;
    
    window.onload = function(){
    		// 初始化画布
        const canvas = document.getElementById('canvas');
        const context = canvas.getContext("2d");
    
        canvas.width = WINDOW_WIDTH;
        canvas.height = WINDOW_HEIGHT;
    
        // 绘制方法
        render( context )
    }
    

    绘制圆点

    // 绘制圆点
    function renderDigit( x , y , num , cxt ){
        cxt.fillStyle = "rgb(0,102,153)";
    
        for(let i = 0 ; i < digit[num].length ; i ++ )
            for(let j = 0 ; j < digit[num][i].length ; j ++ )
                if( digit[num][i][j] == 1 ){
                    cxt.beginPath();
                  	// 第(i, j)个圆的圆心位置:
                  	// j*2*(R+1) => 第 j 列个的框框
                  	// x: x+j*2*(R+1)+(R+1)
                   	// y: y+i*2*(R+1)+(R+1)
                    cxt.arc( x+j*2*(RADIUS+1)+(RADIUS+1) , y+i*2*(RADIUS+1)+(RADIUS+1) , RADIUS , 0 , 2*Math.PI )
                    cxt.closePath()
    
                    cxt.fill()
                }
    }
    
    

    绘制数字圆点

    // 绘制数字的每一个圆点
    function render( cxt ){
        let hours = 12
    		let minutes = 34
    		let seconds = 56
    
        // 1
        renderDigit( MARGIN_LEFT , MARGIN_TOP , parseInt(hours/10) , cxt )
      	// 2
        renderDigit( MARGIN_LEFT + 15*(RADIUS+1) , MARGIN_TOP , parseInt(hours%10) , cxt )
      	// :
        renderDigit( MARGIN_LEFT + 30*(RADIUS + 1) , MARGIN_TOP , 10 , cxt )
      	// 3
        renderDigit( MARGIN_LEFT + 39*(RADIUS+1) , MARGIN_TOP , parseInt(minutes/10) , cxt);
      	// 4
        renderDigit( MARGIN_LEFT + 54*(RADIUS+1) , MARGIN_TOP , parseInt(minutes%10) , cxt);
      	// :
        renderDigit( MARGIN_LEFT + 69*(RADIUS+1) , MARGIN_TOP , 10 , cxt);
      	// 5
        renderDigit( MARGIN_LEFT + 78*(RADIUS+1) , MARGIN_TOP , parseInt(seconds/10) , cxt);
      	// 6
        renderDigit( MARGIN_LEFT + 93*(RADIUS+1) , MARGIN_TOP , parseInt(seconds%10) , cxt);
    }
    

    时间计算

    初始化

    // 记得动态更改你的截止日期噢
    const endTime = new Date(2021,3,7,0,0,0);
    let curShowTimeSeconds = 0
    

    绘制

    window.onload = function(){
    		// 初始化画布
        const canvas = document.getElementById('canvas');
        const context = canvas.getContext("2d");
    
        canvas.width = WINDOW_WIDTH;
        canvas.height = WINDOW_HEIGHT;
    		curShowTimeSeconds = getCurrentShowTimeSeconds()
    		render( context )
    }
    

    获取时间数字

    // 获取当前时间与截止日期
    function getCurrentShowTimeSeconds() {
    	var curTime = new Date();
    	var ret = endTime.getTime() - curTime.getTime();
    	ret = Math.round( ret/1000 )
    
    	return ret >= 0 ? ret : 0;
    }
    

    绘制数字圆点

    // 更改值
    let hours = parseInt( curShowTimeSeconds / 3600);
    let minutes = parseInt( (curShowTimeSeconds - hours * 3600)/60 )
    let seconds = curShowTimeSeconds % 60
    

    实现动画效果

    时钟数字动画

    目录结构

    定时渲染

    使用 setInterval() 来渲染动画

    // countdown.js
    
    window.onload = function(){
    		// 初始化画布
        const canvas = document.getElementById('canvas');
        const context = canvas.getContext("2d");
    
        canvas.width = WINDOW_WIDTH;
        canvas.height = WINDOW_HEIGHT;
    		curShowTimeSeconds = getCurrentShowTimeSeconds()
      	// 定时渲染
    		setInterval(() => {
          render( context );
          update()	// 更新函数
        }, 50)
    }
    

    更新时钟

    function update() {
      // 下一秒的时钟
      const nextShowTimeSeconds = getCurrentShowTimeSeconds()
      let nextHours = parseInt( nextShowTimeSeconds / 3600);
    	let nextMinutes = parseInt( (nextShowTimeSeconds - nextHours * 3600)/60 )
    	let nextSeconds = nextShowTimeSeconds % 60
      
      // 当前秒的时钟
      let curHours = parseInt( curShowTimeSeconds / 3600);
    	let curMinutes = parseInt( (curShowTimeSeconds - curHours* 3600)/60 )
    	let curSeconds = curShowTimeSeconds % 60
      
      // 更新秒钟
      if (nextShowTimeSeconds != curShowTimeSeconds) {
        curShowTimeSeconds = nextShowTimeSeconds
      }
    }
    

    更新画布

    function render( cxt ){
    
      // 对整个屏幕矩形进行刷新
    	cxt.clearRect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT)
    
    	let hours = parseInt( curShowTimeSeconds / 3600);
    	let minutes = parseInt( (curShowTimeSeconds - hours * 3600)/60 )
    	let seconds = curShowTimeSeconds % 60
    
    	renderDigit( MARGIN_LEFT , MARGIN_TOP , parseInt(hours/10) , cxt )
    	renderDigit( MARGIN_LEFT + 15*(RADIUS+1) , MARGIN_TOP , parseInt(hours%10) , cxt )
    	renderDigit( MARGIN_LEFT + 30*(RADIUS + 1) , MARGIN_TOP , 10 , cxt )
    	renderDigit( MARGIN_LEFT + 39*(RADIUS+1) , MARGIN_TOP , parseInt(minutes/10) , cxt);
    	renderDigit( MARGIN_LEFT + 54*(RADIUS+1) , MARGIN_TOP , parseInt(minutes%10) , cxt);
    	renderDigit( MARGIN_LEFT + 69*(RADIUS+1) , MARGIN_TOP , 10 , cxt);
    	renderDigit( MARGIN_LEFT + 78*(RADIUS+1) , MARGIN_TOP , parseInt(seconds/10) , cxt);
    	renderDigit( MARGIN_LEFT + 93*(RADIUS+1) , MARGIN_TOP , parseInt(seconds%10) , cxt);
    }
    

    小球动画

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Title</title>
    </head>
    <body>
    <canvas id="canvas" width="1024" height="768" style="border: 1px solid #aaa; display: block; margin: auto auto">
    	<!--兼容降错-->
    	当前浏览器不支持 Canvas,请更换浏览器后再试
    </canvas>
    
    <script>
    // 初始化小球
    const ball = { x: 512, y: 100, r: 20, g: 2, vx: -4, vy: 0, color: '#005588' }
    window.onload = function() {
    	const canvas = document.getElementById('canvas')
    	// 绘图上下文环境 2D 绘图
    	const context = canvas.getContext('2d')
    
    	// 定时器动画
    	setInterval(() => {
    		// 渲染
    		render(context)
    		// 更新
    		update()
    	}, 50)
    }
    // 动画
    function update() {
    	ball.x += ball.vx
    	ball.y += ball.vy
    	ball.vy += ball.g
    
    	// 碰撞底部
    	if (ball.y >= 768 - ball.r) {
    		ball.y = 768 - ball.r
    		ball.vy = -ball.vy*0.6	// 摩擦力
    	}
    }
    function render(ctx) {
    	// 刷新 canvas 画布
    	ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)
    	ctx.fillStyle = ball.color
    	ctx.beginPath()
    	ctx.arc(ball.x, ball.y, ball.r, 0, 2*Math.PI)
    	ctx.closePath()
    	ctx.fill()
    }
    </script>
    </body>
    </html>
    
    

    时钟小球动画

    目录结构

    初始化数据

    // 常量
    const WINDOW_WIDTH = 1024;
    const WINDOW_HEIGHT = 768;
    const RADIUS = 8;
    const MARGIN_TOP = 60;
    const MARGIN_LEFT = 30;
    
    const endTime = new Date(2021,3,7,0,0,0);
    let curShowTimeSeconds = 0
    
    // 存放小球
    const balls = [];
    // 更换颜色
    const colors = ["#33B5E5","#0099CC","#AA66CC","#9933CC","#99CC00","#669900","#FFBB33","#FF8800","#FF4444","#CC0000"]
    

    更新小球

    function update() {
    	// 下一秒的时钟
    	const nextShowTimeSeconds = getCurrentShowTimeSeconds()
    	let nextHours = parseInt(nextShowTimeSeconds / 3600);
    	let nextMinutes = parseInt((nextShowTimeSeconds - nextHours * 3600) / 60)
    	let nextSeconds = nextShowTimeSeconds % 60
    
    	// 当前秒的时钟
    	let curHours = parseInt(curShowTimeSeconds / 3600);
    	let curMinutes = parseInt((curShowTimeSeconds - curHours * 3600) / 60)
    	let curSeconds = curShowTimeSeconds % 60
    
    	// 更新秒钟
    	if (nextShowTimeSeconds != curShowTimeSeconds) {
        // 对 6 个数字一起判断更新
    		if (parseInt(curHours / 10) != parseInt(nextHours / 10)) {
          // 添加小球
    			addBalls(MARGIN_LEFT + 0, MARGIN_TOP, parseInt(curHours / 10));
    		}
    		if (parseInt(curHours % 10) != parseInt(nextHours % 10)) {
    			addBalls(MARGIN_LEFT + 15 * (RADIUS + 1), MARGIN_TOP, parseInt(curHours / 10));
    		}
    		if (parseInt(curMinutes / 10) != parseInt(nextMinutes / 10)) {
    			addBalls(MARGIN_LEFT + 39 * (RADIUS + 1), MARGIN_TOP, parseInt(curMinutes / 10));
    		}
    		if (parseInt(curMinutes % 10) != parseInt(nextMinutes % 10)) {
    			addBalls(MARGIN_LEFT + 54 * (RADIUS + 1), MARGIN_TOP, parseInt(curMinutes % 10));
    		}
    		if (parseInt(curSeconds / 10) != parseInt(nextSeconds / 10)) {
    			addBalls(MARGIN_LEFT + 78 * (RADIUS + 1), MARGIN_TOP, parseInt(curSeconds / 10));
    		}
    		if (parseInt(curSeconds % 10) != parseInt(nextSeconds % 10)) {
    			addBalls(MARGIN_LEFT + 93 * (RADIUS + 1), MARGIN_TOP, parseInt(nextSeconds % 10));
    		}
    
    		curShowTimeSeconds = nextShowTimeSeconds;
    	}
    	// 更新球
    	updateBalls();
    }
    

    添加小球

    // 添加小球
    function addBalls(x, y, num) {
    	for (let i = 0; i < digit[num].length; i++)
    		for (let j = 0; j < digit[num][i].length; j++)
    			if (digit[num][i][j] == 1) {
    				const aBall = {
              // 原点
    					x: x + j * 2 * (RADIUS + 1) + (RADIUS + 1),
    					y: y + i * 2 * (RADIUS + 1) + (RADIUS + 1),
              // 动画随机设计
    					g: 1.5 + Math.random(),
    					vx: Math.pow(-1, Math.ceil(Math.random() * 1000)) * 4,
    					vy: -5,
    					color: colors[Math.floor(Math.random() * colors.length)]
    				}
    
    				balls.push(aBall)
    			}
    }
    

    更新小球运动

    // 更新小球运动
    function updateBalls() {
    	for (let i = 0; i < balls.length; i++) {
    		balls[i].x += balls[i].vx;
    		balls[i].y += balls[i].vy;
    		balls[i].vy += balls[i].g;
    
        // 碰撞检测
    		if (balls[i].y >= WINDOW_HEIGHT - RADIUS) {
    			balls[i].y = WINDOW_HEIGHT - RADIUS;
    			balls[i].vy = -balls[i].vy * 0.75;
    		}
    	}
    }
    

    绘制小球

    // 绘制数字的每一个圆点
    function render(cxt) {
    
    	// 对整个屏幕矩形进行刷新
    	cxt.clearRect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT)
    
    	let hours = parseInt(curShowTimeSeconds / 3600);
    	let minutes = parseInt((curShowTimeSeconds - hours * 3600) / 60)
    	let seconds = curShowTimeSeconds % 60
    
    	renderDigit(MARGIN_LEFT, MARGIN_TOP, parseInt(hours / 10), cxt)
    	renderDigit(MARGIN_LEFT + 15 * (RADIUS + 1), MARGIN_TOP, parseInt(hours % 10), cxt)
    	renderDigit(MARGIN_LEFT + 30 * (RADIUS + 1), MARGIN_TOP, 10, cxt)
    	renderDigit(MARGIN_LEFT + 39 * (RADIUS + 1), MARGIN_TOP, parseInt(minutes / 10), cxt);
    	renderDigit(MARGIN_LEFT + 54 * (RADIUS + 1), MARGIN_TOP, parseInt(minutes % 10), cxt);
    	renderDigit(MARGIN_LEFT + 69 * (RADIUS + 1), MARGIN_TOP, 10, cxt);
    	renderDigit(MARGIN_LEFT + 78 * (RADIUS + 1), MARGIN_TOP, parseInt(seconds / 10), cxt);
    	renderDigit(MARGIN_LEFT + 93 * (RADIUS + 1), MARGIN_TOP, parseInt(seconds % 10), cxt);
    
      // 绘制小球
    	for (let i = 0; i < balls.length; i++) {
    		cxt.fillStyle = balls[i].color;
    
    		cxt.beginPath();
    		cxt.arc(balls[i].x, balls[i].y, RADIUS, 0, 2 * Math.PI, true);
    		cxt.closePath();
    
    		cxt.fill();
    	}
    }
    

    优化、扩展时钟

    性能优化

    目录结构

    实现

    // 更新小球运动
    function updateBalls() {
    	for (let i = 0; i < balls.length; i++) {
    		balls[i].x += balls[i].vx;
    		balls[i].y += balls[i].vy;
    		balls[i].vy += balls[i].g;
    
    		if (balls[i].y >= WINDOW_HEIGHT - RADIUS) {
    			balls[i].y = WINDOW_HEIGHT - RADIUS;
    			balls[i].vy = -balls[i].vy * 0.75;
    		}
    	}
    
      // 数量初始化为 0 => 确立还有多少个小球保留在画布中
    	let cnt = 0
    	for( let i = 0 ; i < balls.length ; i ++ )
        // 是否在画布中
    		if( balls[i].x + RADIUS > 0 && balls[i].x -RADIUS < WINDOW_WIDTH )
          // 是则添加小球
    			balls[cnt++] = balls[i]
    	// 只保留存在画布的小球
    	while( balls.length > cnt ){
    		balls.pop();
    	}
    }
    

    屏幕自适应

    让初始化的常量根据当前屏幕来自适应即可。

    <!DOCTYPE html>
    <html style="height: 100%;">
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body style="height: 100%;">
        <canvas id="canvas" style="height: 100%;">
            当前浏览器不支持Canvas,请更换浏览器后再试
        </canvas>
    
        <script src="digit.js"></script>
        <script src="countdown.js"></script>
    </body>
    </html>
    
    
    // countdown.js
    
    // 常量
    let WINDOW_WIDTH = 1024;
    let WINDOW_HEIGHT = 768;
    let RADIUS = 8;
    let MARGIN_TOP = 60;
    let MARGIN_LEFT = 30;
    
    const endTime = new Date(2021, 3, 8, 0, 0, 0);
    let curShowTimeSeconds = 0
    
    // 存放小球
    const balls = [];
    // 更换颜色
    const colors = ["#33B5E5", "#0099CC", "#AA66CC", "#9933CC", "#99CC00", "#669900", "#FFBB33", "#FF8800", "#FF4444", "#CC0000"]
    
    window.onload = function () {
      // 根据用户屏幕来自定义常量
      WINDOW_WIDTH = document.body.clientWidth;
      WINDOW_HEIGHT = document.body.clientHeight;
      MARGIN_LEFT = Math.round(WINDOW_WIDTH/10);
      // 根据 renderDigit 的 x 来进行判断
      RADIUS = Math.round(WINDOW_WIDTH * 4 / 5 / 108)-1
      MARGIN_TOP = Math.round(WINDOW_HEIGHT / 5)
      
    	// 初始化画布
    	const canvas = document.getElementById('canvas');
    	const context = canvas.getContext("2d");
    
    	canvas.width = WINDOW_WIDTH;
    	canvas.height = WINDOW_HEIGHT;
    	curShowTimeSeconds = getCurrentShowTimeSeconds()
    	// 定时渲染
    	setInterval(() => {
    		render(context);
    		update()	// 更新函数
    	}, 50)
    }
    

    归零时间更新

    // 当前时间增加一小时
    let endTime = new Date()
    endTime.setTime(endTime.getTime() + 3600 * 1000)
    

    绚丽时钟效果

    可以来做当前时钟的效果,不止是倒计时

    // 获取当前时间
    function getCurrentShowTimeSeconds() {
    	let curTime = new Date();
      // 存的是今天已经走过了多久 => 时钟
    	let ret = curTime.getHours() * 3600 + curTime.getMinutes() * 60 + curTime.getSeconds()
    
    	return ret
    }
    

    总结

    放上 canvas Api

    以下将本次学习课程中使用常见的方法和属性再次整理回顾。

    Canvas

    HTML

    JavaScript

    • const canvas = document.getElementById('canvas')	// 获取 canvas 元素
      const context = canvas.getContext('2d')	// 获取上下文来进行绘制
      
    • 常用属性

    // 当前画布的宽高
    canvas.width
    canvas.height
    
    
    • 常用方法
    // 获取当前画布的上下文
    canvas.getContext('2d')
    

    Context

    • 常用属性
    // 笔线宽
    context.lineWidth
    
    // 笔线颜色
    context.strokeStyle
    
    // 填充色
    context.fillStyle
    
    // 该上下文对应的 canvas 画布
    context.canvas
    
    
    • 常用方法
    // 移动笔尖
    context.moveTo(x, y)
    
    // 画线
    context.lineTo(x, y)
    
    // 画弧
    context.arc(cx, cy, r, sAng, eAng, anticlock = false)
    
    // 开始描绘
    context.beginPath()
    
    // 结束描绘
    context.closePath()
    
    // 绘制笔线颜色
    context.stroke()
    
    // 填充颜色
    context.fill()
    
    // 刷新矩形区域
    context.clearRect(x, y, width, height)
    

    后记

    加油~

    整理自己的前端体系架构,然后找到一个好实习!


    起源地下载网 » Canvas动画小demo(从零到一)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元