效果展示
理论基础——“常见的canvas优化——模糊问题、旋转效果”

用离屏canvas画基础部分

1、封装画线函数

function drawLine(ctx,x1,y1,x2,y2,color){
ctx.save();
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
ctx.restore();
}

2、画雪花的六条线

function canvasSingleSnow(snowSize){
var singleSnow = document.createElement('canvas');
var ctxSingle = singleSnow.getContext('2d');
singleSnow.setAttribute('width', snowSize * 2);
singleSnow.setAttribute('height', snowSize * 2);
ctxSingle.translate(snowSize, snowSize);//定位原点到画布中心
for(var i = 0; i < 6; i++){//画六条线
ctxSingle.save();
ctxSingle.rotate(Math.PI*2 * i/6);
drawLine(ctxSingle, 0, 0, snowSize, 0,"#656565");
ctxSingle.restore();
}
return singleSnow;
}

首先这里用到了离屏canvas,我们通过传参的方式确定离屏canvas的尺寸,是为了尽可能避免canvas图案缩放导致的显示效果问题。

另外这里for循环中用到了canvas的旋转效果,所以我们可以很轻易的画出6条有角度的线。效果如下图所示

3、画出完整的雪花

function drawCanvasSnow(centerSnow){
var canvasSnow = document.createElement('canvas');
var ctxSnow = canvasSnow.getContext('2d');
canvasSnow.setAttribute('width', centerSnow * 2);
canvasSnow.setAttribute('height', centerSnow * 2);
//画一个大雪花
var bigSnow = canvasSingleSnow(centerSnow);
ctxSnow.drawImage(bigSnow, 0, 0, bigSnow.width, bigSnow.height,
0, 0, centerSnow * 2, centerSnow * 2);
//画六个小雪花
var smallSnow = canvasSingleSnow(centerSnow/3);
var sizeSnow = centerSnow * 3/5;//小雪花的尺寸(直径)
var rSnow = centerSnow - sizeSnow/2;//小雪花的位置(离大雪花中心的距离)
for(var i = 0; i < 6; i++){
ctxSnow.save();
ctxSnow.translate(centerSnow, centerSnow);
ctxSnow.rotate(Math.PI*2 * i/6);
ctxSnow.drawImage(smallSnow, 0, 0, smallSnow.width, smallSnow.height,
rSnow - sizeSnow/2, -sizeSnow/2, sizeSnow, sizeSnow);
ctxSnow.restore();
}
return canvasSnow;
}

上述代码中尺寸部分说明:小雪花的尺寸比大雪花小,用比例可以方便缩放;小雪花的位置则固定在大雪花六条线的端点处。效果如下图所示

将离屏canvas作为资源画到实际显示的canvas上

1、封装一个根据旋转加载离屏canvas的函数

//r为雪花图案中心距画布中心的距离
//angle为雪花图案在画布上的安放角度
//size为雪花图案的显示尺寸
function drawSnowAngle(ctx,r,angle,size){
ctx.save();
ctx.rotate(Math.PI*2 * angle);
drawLine(ctx,0,0,r,0,"#656565");
ctx.drawImage(canvasSnow, 0, 0, canvasSnow.width, canvasSnow.height,
r - size/2, -size/2, size, size);
ctx.restore();
}

2、可以将离屏canvas画的雪花图案画到实际显示的canvas上了

//center为实际显示canvas的画布中心(半径)
//rSnow为雪花图案的半径
drawSnowAngle(ctx, center - rSnow, i/snowNum, rSnow * 2);

3、加上动态旋转效果

var snowNum = 1;
var isAdd = true;
var loop = setInterval('drawCanvas()', 10);//定时器,每10ms绘制一次
function drawCanvas(){
//设置旋转效果
if(snowNum >= 18){isAdd = false;}//最大个数为18
else if(snowNum <= 1){isAdd = true;}//最小个数为1
if(isAdd){snowNum += snowNum/200;}//达到最大后开始递减
else{snowNum -= snowNum/100;}//达到最少后开始递增
//画图
var rSnow = center/2 * (snowNum - 6)/6;//设置雪花图案显示尺寸
canvasSnow = drawCanvasSnow(rSnow);//画出离屏雪花图案
ctx.clearRect(-center, -center, center * 2, center * 2);//清除画布
for(var i = 0; i < snowNum; i++){//开始画图
drawSnowAngle(ctx, center - rSnow, i/snowNum, rSnow * 2);
}
}

旋转的雪花就这样完成了。效果见文章开头的效果展示链接

canvas离屏、旋转效果实践——旋转的雪花的更多相关文章

  1. HTML 5 +CSS3 + 原生js 做(雪花全屏飘落 + 3d旋转图)

    原文:HTML 5 +CSS3 + 原生js 做(雪花全屏飘落 + 3d旋转图) 3d旋转图:主要用css3中transform属性中的rotate,translate;以及用来做舞台效果的 pers ...

  2. html5 canvas首屏自适应背景动画循环效果代码

    模板描述:html5 canvas首屏自适应背景动画循环效果代码 由于动态图太大,怕以后服务器受不了,所以现在都改为静态图了,大家点击演示地址一样的,希望大家喜欢,你们的支持就是小海的动力!! 欢迎大 ...

  3. canvas离屏技术与放大镜实现

    教程所示图片使用的是 github 仓库图片,网速过慢的朋友请移步>>> (原文)canvas 离屏技术与放大镜实现. 更多讨论或者错误提交,也请移步. 利用canvas除了可以实现 ...

  4. Canvas清屏的实现

    /** * Canvas清屏的操作 * * 參考资料: http://blog.csdn.net/lfdfhl/article/details/9076001 * */ private void cl ...

  5. 【HTML】html5 canvas全屏烟花动画特效

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  6. canvas绘图基础及基于粒子系统的雪花飘落

    canvas是html中的一个元素,可以通过js操控绘图! 可以绘制各种图形,各种填充样式! 绘制时可以进行旋转,缩放,平移,但并不是很灵活! 有一对比较好用的方法是save restore! sav ...

  7. ios手机竖屏拍照图片旋转90°问题解决方法

    手机拍照会给图片添加一个Orientaion信息(即拍照方向),如下: 用ios手机拍照,系统会给图片加上一个方向的属性, ios相机默认的拍照方向是后摄Home键在右为正,前摄Home键在左为正. ...

  8. 虚幻引擎4笔记20160821 - 使用GPU粒子做雪花旋转镜头雪花忽有忽无的问题

    在使用GPU进行雪花制作的时候,雪花总是在镜头旋转的时候,一会有,一会无的情况,后来下载别人的例子才知道,原来要给粒子加上边界,具体解决方法如下图

  9. 使用canvas实现超绚丽的旋转正方形

    自己无意中的一个小"bug",却让动画变得超绚丽= = 所以,不要害怕出bug,谁知道bug不会开出一朵绚丽的花呢? <!DOCTYPE html> <html ...

随机推荐

  1. C语言中一些知识点

    1.学编程:找代码,读代码,改代码,写代码:少看书.但少看不是不看,看一本书要限制在一天内.任务是通读书中主要的概念,明白大致是干什么用的,形成一个大概的框架:然后一周内干掉书中全部代码,代码不理解再 ...

  2. 穿透、击穿、雪崩…Redis这么多问题,如何解决?

    摘要:什么是缓存穿透?什么是缓存击穿,又什么是缓存雪崩呢?它们是如何造成的?又该如何解决呢?今天,我们就一起来探讨这些问题. 本文分享自华为云社区<[高并发]什么是缓存穿透?击穿?雪崩?如何解决 ...

  3. HarmonyOS UI组件在线预览,程序员直呼“不要太方便~”

    一.介绍 以往大家如果想查看组件的使用效果,需要打开DevEco Studio构建工程.现在为了便于大家高效开发,文档上线了JS UI组件在线预览功能,无需本地构建工程,在线即可修改组件样式等参数.一 ...

  4. 【VR游戏】封神榜传

    领悟导入SteamVR和VRTK,SteamVR要和CameraRig位置保持一致.1.可以创建多个scene,然后进行连接跳转.但是创建好之后要自己重新导回scene附:删除MainCamera,添 ...

  5. php 23种设计模型 - 享元模式

    享元模式 享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. ...

  6. CF1601C题解

    赛时一小时,赛后十分钟. 题意:给定一个序列 \(a\) 和一个集合 \(b\),问将 \(b\) 中所有元素插入 \(a\) 后逆序对最少是多少. 观察样例解释,发现 \(b\) 已经被排序过了,于 ...

  7. 『德不孤』Pytest框架 — 15、Pytest参数化

    目录 1.Pytest参数化说明 2.Pytest参数化方式 3.parametrize装饰器参数说明 4.Pytest参数化(单个参数) 5.Pytest参数化(多个参数) 6.ids参数说明 1. ...

  8. web安全常用端口

    21 FTP 22 SSH 23 Telent 25 SMTP 53 DNS 80 HTTP 135 139 443 HTTPS 445 SMB 1433 SQLSERVER 1521 ORCAL 3 ...

  9. 14FPGA综设之图像边沿检测的sobel算法

    连续学习FPGA基础课程接近一个月了,迎来第一个有难度的综合设计,图像的边沿检测算法sobel,用verilog代码实现算法功能. 一设计功能 (一设计要求) (二系统框图) 根据上面的系统,Veri ...

  10. SpringCloudAlibaba 微服务讲解(三)Nacos Discovery-服务治理

    3.1 服务治理 先来思考一个问题,通过上一章的操作,我们已经实现微服务之间的调用,但是我们把服务提供者的网络地址(ip,端口)等硬编码到了代码中,这种做法存在许多问题: 一旦服务提供者地址变化,就需 ...