本文介绍了JavaScript:画布中落下的五彩纸屑颗粒的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我找到了这个很棒的脚本,让它像雨一样飘落在五彩纸屑上:http://jsfiddle.net/hcxabsgh/请注意粒子是如何产生这种扭曲/旋转/倾斜效果的,以使其感觉更自然。
我一直在尝试让粒子变圆,效果也很好:http://jsfiddle.net/rqr9hb7x/2/
但我无法让粒子像矩形示例那样绕其轴扭曲/旋转/倾斜。
我认为使用ctx.setTransform()应该是可行的,因为它处理倾斜参数,但是它似乎倾斜了整个画布,而不是单个粒子。有谁知道如何正确处理这件事吗?
this.draw = function () {
ctx.beginPath();
ctx.save();
//ctx.setTransform(1, 0, 0, 1, 0, 0); // straigt
ctx.setTransform(1, .3, 0, .7, 0, 0); // skewed - to make dynamic
ctx.arc(this.x + this.tilt, this.y + this.tilt + (this.r / 4), (this.r / 2), 0, Math.PI * 2, false);
ctx.restore();
ctx.fillStyle = this.color;
return ctx.fill();
}
推荐答案
歪斜使用setTransform
您希望随时间旋转粒子的局部x轴。x轴是setTransform
的前两个参数。若要随时间旋转轴,请使用cos(angle)
和sin(angle)
设置x轴的x和y分量。
因为您希望它是粒子的局部位置,所以还需要设置粒子原点(旋转点),然后在0,0处绘制粒子。原点是setTransform
您需要的绘图函数是
draw() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.setTransform(
Math.cos(this.tiltAngle), // set the x axis to the tilt angle
Math.sin(this.tiltAngle),
0, 1,
this.x, this.y // set the origin
);
ctx.arc(0, 0, (this.r / 2), 0, Math.PI * 2, false); // draw at origin (0,0)
ctx.fill();
}
示例
看一下给定的小提琴上的代码,我不知道他们想要做什么,因为它太复杂了,所以我重写了整个代码,现在只需要三分之一的代码,而且没有jQuery。
为您想要的FX运行演示.
也许?
(function () {
requestAnimationFrame(mainLoop);
const ctx = canvas.getContext("2d");
var W,H;
var confetti = new Particles();
var droppedCount = 0;
var particlesPerFrame = 1.5;
var wind = 0;
var windSpeed = 1;
const windSpeedMax = 1;
const windChange = 0.01;
const windPosCoef = 0.002;
const maxParticlesPerFrame = 2; //max particles dropped per frame
var id = 0;
stopButton.addEventListener("click",() => particlesPerFrame = 0 );
startButton.addEventListener("click",() => particlesPerFrame = maxParticlesPerFrame);
const randI = (min, max = min + (min = 0)) => (Math.random() * (max - min) + min) | 0;
const rand = (min = 1, max = min + (min = 0)) => Math.random() * (max - min) + min;
const colors = {
options: "DodgerBlue,OliveDrab,Gold,pink,SlateBlue,lightblue,Violet,PaleGreen,SteelBlue,SandyBrown,Chocolate,Crimson".split(","),
index: 0,
step: 10,
get color() { return colors.options[((colors.index++) / colors.step | 0) % colors.options.length] }
}
function Confetti() { this.setup() }
Confetti.prototype = {
setup(){
this.x = rand(-35,W + 35);
this.y = rand(-30,-35);
this.r = rand(10, 30);
this.d = rand(150) + 10; //density;
this.color = colors.color;
this.tilt = randI(10);
this.tiltAngleIncremental = (rand(0.08) + 0.04) * (rand() < 0.5 ? -1 : 1);
this.tiltAngle = 0;
this.angle = rand(Math.PI * 2);
this.id = id++;
return this;
},
update() {
this.tiltAngle += this.tiltAngleIncremental * (Math.cos(wind + (this.d + this.x + this.y) * windPosCoef) * 0.2 + 1);
this.y += (Math.cos(this.angle + this.d) + 3 + this.r / 2) / 2;
this.x += Math.sin(this.angle);
this.x += Math.cos(wind + (this.d + this.x + this.y) * windPosCoef) * windSpeedMax;
this.y += Math.sin(wind + (this.d + this.x + this.y) * windPosCoef) * windSpeedMax;
this.tilt = (Math.sin(this.tiltAngle - (this.id / 3))) * 15;
return this.y > H; // returns true if particle is past bottom
},
draw() {
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.setTransform(
Math.cos(this.tiltAngle), // set the x axis to the tilt angle
Math.sin(this.tiltAngle),
0, 1,
this.x, this.y // set the origin
);
ctx.arc(0, 0, (this.r / 2), 0, Math.PI * 2, false);
ctx.fill();
}
}
function Particles() {
const items = [];
const pool = [];
this.update = function() {
for (var i = 0; i < items.length; i++) {
if(items[i].update() === true){ pool.push(items.splice(i--,1)[0]) }
}
}
this.draw = function() { for (var i = 0; i < items.length; i++) { items[i].draw() } }
this.add = function() {
if (pool.length > 0) { items.push(pool.pop().setup()) }
else { items.push(new Confetti()) }
}
}
function mainLoop(time) {
if (W !== innerWidth || H !== innerHeight) {
W = canvas.width = innerWidth;
H = canvas.height = innerHeight;
} else {
ctx.setTransform(1,0,0,1,0,0);
ctx.clearRect(0, 0, W, H);
}
windSpeed = Math.sin(time / 8000) * windSpeedMax;
wind += windChange;
while(droppedCount < particlesPerFrame){
droppedCount += 1;
confetti.add();
}
droppedCount -= particlesPerFrame;
confetti.update();
confetti.draw();
requestAnimationFrame(mainLoop);
}
})();
* {
margin: 0;
padding: 0;
}
body {
/*You can use any kind of background here.*/
background: transparent;
}
canvas {
display: block;
position: relative;
zindex: 1;
pointer-events: none;
}
#content {
text-align: center;
width: 500px;
height: 300px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -250px;
margin-top: -150px;
color: silver;
font-family: verdana;
font-size: 45px;
font-weight: bold;
}
.buttonContainer {
display: inline-block;
}
button {
padding: 5px 10px;
font-size: 20px;
}
<div id="content">
Confetti World
<br /> I 💙 confetti!
<br />
<div class="buttonContainer">
<button id="stopButton">Stop Confetti</button>
<button id="startButton">Drop Confetti</button>
</div>
</div>
<canvas id="canvas"></canvas>
注意此代码和内容的某些内容已从this fiddle复制。
这篇关于JavaScript:画布中落下的五彩纸屑颗粒的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!