canvas雨滴绘制总结(三)

1. 首先规划程序逻辑

##1.1 设置canvas款到与浏览器相同
1.1.1: 获取canvas元素
1.1.2: 获取浏览器宽高
1.1.3: 为canvas元素设置宽高
1.1.4:当窗口大小变化时,自动调整canvas大小

1.2. 如何用canvas绘制图形

1.2.1 绘制矩形
1.2.2 绘制圆形
1.2.3 绘制雨滴
1.2.4绘制落地后的水花

1.3 怎么实现动画

1.4 雨滴绘制的原理

1.4.1 使用原型定义雨滴对象

1.4.2 视觉原理,动画实现雨滴下落的绘制

1.5 绘制雨滴N个,不能同时下落

问题一 Canvas宽高设置出现白边

原因:canvas是内联元素,默认display:inline; 白边为行间距。
解决方案:display:block;

问题二 Canvas具有默认大小 300px*150px

问题三 Canvas自适应页面大小如何实现?

参考链接
方案一:CSS设置100%

body{margin:0;}
html,body{
    width:100%;
    height:100%;
}
#rain{
    display:block;
    background-color:black;
    width:100%;
    height:100%;
    margin:0;
        }

结果:使用也可以实现自适应大小,但是改变页面大小时,雨滴的大小形状会变形。
原因:
将canvas按img理解,canvas样式宽高改变了,但是canvas自身的宽高却不变。当两者的宽高比例不同时,出现内容拉伸。

自适应是指元素的dispaly size缩放,是CSS布局维度(css layout dimension)自适应。而canvas的width/height属性对应的是画布内的coordinate space,不属于css负责.canvas的显示大小可以由css规则指定,但是其内部元素的像素不对应CSS像素或屏幕物理像素进行缩放显示。
方案二:使用JS获取window宽高,为canvas设置
原理:使用样式的宽高比重新设置画布的宽高比。发生重绘。

//1.1 获取canvas元素,只能用id
    var can=document.getElementById("rain");
//1.2 浏览器的宽高存放在windows的全局变量
    var w=window.innerWidth;
    var h=window.innerHeight;
//1.3 设置canvas宽高
    can.width=w;
    can.height=h;
//1.4 当窗口大小变化时,自动调整canvas大小
    //监控浏览器宽高变化
    window.onresize=function(){
    w=window.innerWidth;
    h=window.innerHeight;
    //1.3 设置canvas宽高
    can.width=w;
    can.height=h;
    }

问题四 雨滴绘制原理

视觉原理:同样大小的矩形,从远处看,亮的(偏白)看起来比暗的更大。
绘制:
方案一:绘制不同透明度的矩形进行拼接。
方案二:对于一种rgb的矩形,覆盖层数不等的一种rgba整体页面。
方案二更加便于实现。

问题五 setInterval(moveRain,1000/60);

1. satInterval不写函数本体,
2. 函数体内不能写setInterval
3. 16ms所有的
4. 在第0秒就执行moveRain,隔16ms再执行一次,
5. 然而此时rainArray还没有内容,因为创建雨滴是相隔200ms创建一次
6. 进而移动函数mobeRain中无操作对象
7. 尽量不用setInterval
8. JS发现此语句,插入到栈中,间隔执行,无论其他函数怎样运行
9. 缺点:(1)丢帧 ,当callback函数运行时间太长超过setInterval间隔时(2)运行主体 window this指向问题

问题六 一个函数在没有指定调用主体前,它的this永远指向window。

/*封装框架时,this的指向,上下文,作用域
    var obj={
        num:1,
        add:function(){
                this.num++;
                console.log(this.num);
                /*
                function(){
                    console.log(this.num);//此处thiswindow
                })();//运行obj.add()输出为UNDEFINED)
                */
                (function(){
                    console.log(this.num);
                }.bind(this))();//运行obj.add()输出为UNDEFINED ;bind(this)之后输出为2),THIS指向
        }
    }
    obj.add();

function aaa(){console.log("a"+this);}
function bbb(cb){
        cb&&cb();
        console.log("b"+this);
}
bbb.call(obj,aaa);
*/


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以为你提供一个基本的实现思路: 1. 首先创建一个 canvas 元素,并获取其上下文对象。 2. 定义一个 raindrop 类,包括下落速度、位置、大小等属性,以及绘制自己的方法。 3. 创建一个数组来存储多个 raindrop 实例,可以在页面加载时初始化一些 raindrop 对象。 4. 使用 setInterval 或 requestAnimationFrame 循环调用一个函数,用于更新 raindrop 实例的位置,并重新绘制整个画布。 5. 在每次更新 raindrop 实例位置时,可以根据一定的概率来生成新的 raindrop 实例,从而实现下雨的效果。 下面是一个简单的示例代码,你可以参考一下: ```html <canvas id="canvas"></canvas> ``` ```javascript const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); // 雨滴类 class Raindrop { constructor() { this.x = Math.random() * canvas.width; // 随机位置 this.y = -Math.random() * canvas.height; // 从屏幕顶部开始下落 this.speed = Math.random() * 5 + 5; // 下落速度 this.size = Math.random() * 2 + 1; // 大小 } // 绘制雨滴 draw() { ctx.beginPath(); ctx.strokeStyle = '#fff'; ctx.lineWidth = this.size; ctx.moveTo(this.x, this.y); ctx.lineTo(this.x, this.y + this.size * 10); ctx.stroke(); } // 更新雨滴位置 update() { this.y += this.speed; if (this.y > canvas.height) { // 超出屏幕则重新开始下落 this.y = -Math.random() * canvas.height; } } } const raindrops = []; // 初始化一些雨滴 for (let i = 0; i < 100; i++) { raindrops.push(new Raindrop()); } function draw() { // 清空画布 ctx.clearRect(0, 0, canvas.width, canvas.height); // 更新并绘制所有雨滴 raindrops.forEach((raindrop) => { raindrop.update(); raindrop.draw(); }); // 根据一定概率生成新雨滴 if (Math.random() < 0.1) { raindrops.push(new Raindrop()); } } // 循环调用 draw 函数 setInterval(draw, 30); ``` 这个示例代码可能还有一些不足的地方,你可以根据自己的需求进行改进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

picoasis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值