我正在使用Canvas和JavaScript创建粒子动画。在下面的示例中,粒子正在动态生成并向每个粒子施加颜色(红色和蓝色)。我想向每个粒子添加“径向渐变”颜色效果。我尝试过createRadialGradient()方法,但它会使我的浏览器窗口空白且动画无法正常工作。
我该如何实现?任何参考将非常有用。预先谢谢你。
(function() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
window.requestAnimationFrame = requestAnimationFrame;
})();
var particleArr = [],
canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
flakeCount = 700,
mouseX = -100,
mouseY = -100,
xMultiplier = 0.015
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var rate = 0.07788656582264941;
function getRandomColor() {
// Random Color Generate
const colorArr = ["rgba(215,88,69, 1)", "rgba(117, 161, 199, 1)"]; // Blue & Orange Color
const randomColor = colorArr[Math.floor(Math.random() * colorArr.length)];
return randomColor;
}
function flow() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < flakeCount; i++) {
var flake = particleArr[i],
x = mouseX,
y = mouseY,
minDist = 150,
x2 = flake.x,
y2 = flake.y;
var dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)),
dx = x2 - x,
dy = y2 - y;
if (dist < minDist) {
var force = minDist / (dist * dist),
xcomp = (x - x2) / dist,
ycomp = (y - y2) / dist,
deltaV = force / 2;
flake.velX -= deltaV * xcomp;
flake.velY -= deltaV * ycomp;
} else {
flake.velX *= .98;
if (flake.velY <= flake.speed) {
flake.velY = flake.speed
}
flake.velX += Math.cos(flake.step += .05) * flake.stepSize;
}
flake.y += flake.velY;
flake.x += flake.velX;
if (flake.y >= canvas.height || flake.y <= 0) {
reset(flake);
}
if (flake.x >= canvas.width || flake.x <= 0) {
reset(flake);
}
ctx.fillStyle = particleArr[i].color;
ctx.beginPath();
ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2);
ctx.fill();
}
requestAnimationFrame(flow);
};
function reset(flake) {
let temp = (Math.random() * 1) + 0.5;
flake.x = canvas.width;
flake.y = 50;
flake.size = 6.692053245649504;
flake.speed = (Math.random() * 7) + 0.5;
flake.velY = flake.speed;
flake.velX = -xMultiplier * canvas.width * temp;
}
function init() {
for (var i = 0; i < flakeCount; i++) {
var x = canvas.width,
y = 50,
size = 6.692053245649504,
speed = 0;
particleArr.push({
speed: speed,
velY: speed,
velX: -xMultiplier * canvas.width * speed,
x: x,
y: y,
size: size,
stepSize: (Math.random()) / 30,
step: 0,
angle: 360,
color: getRandomColor()
});
}
requestAnimationFrame(flow);
};
canvas.addEventListener("mousemove", function(e) {
mouseX = e.clientX,
mouseY = e.clientY
});
window.addEventListener( 'resize', onWindowResize, false );
function onWindowResize() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
init();
canvas{
background-color: #000000 !important;
}
body {
margin: 0;
overflow: hidden;
}
<canvas id="canvas"></canvas>
将fillStyle
设置为您创建的渐变,并且不要忘记添加色标:
let grad = ctx.createRadialGradient(flake.x, flake.y, 0, flake.x, flake.y, flake.size);
grad.addColorStop(0, 'blue');
grad.addColorStop(1, 'red');
ctx.fillStyle = grad;
ctx.beginPath();
ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2);
ctx.fill();
(function() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
window.requestAnimationFrame = requestAnimationFrame;
})();
var particleArr = [],
canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
flakeCount = 700,
mouseX = -100,
mouseY = -100,
xMultiplier = 0.015
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var rate = 0.07788656582264941;
function getRandomColor() {
// Random Color Generate
const colorArr = ["rgba(215,88,69, 1)", "rgba(117, 161, 199, 1)"]; // Blue & Orange Color
const randomColor = colorArr[Math.floor(Math.random() * colorArr.length)];
return randomColor;
}
function flow() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < flakeCount; i++) {
var flake = particleArr[i],
x = mouseX,
y = mouseY,
minDist = 150,
x2 = flake.x,
y2 = flake.y;
var dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)),
dx = x2 - x,
dy = y2 - y;
if (dist < minDist) {
var force = minDist / (dist * dist),
xcomp = (x - x2) / dist,
ycomp = (y - y2) / dist,
deltaV = force / 2;
flake.velX -= deltaV * xcomp;
flake.velY -= deltaV * ycomp;
} else {
flake.velX *= .98;
if (flake.velY <= flake.speed) {
flake.velY = flake.speed
}
flake.velX += Math.cos(flake.step += .05) * flake.stepSize;
}
flake.y += flake.velY;
flake.x += flake.velX;
if (flake.y >= canvas.height || flake.y <= 0) {
reset(flake);
}
if (flake.x >= canvas.width || flake.x <= 0) {
reset(flake);
}
let grad = ctx.createRadialGradient(flake.x, flake.y, 0, flake.x,
flake.y, flake.size);
grad.addColorStop(0, 'blue');
grad.addColorStop(1, 'red');
ctx.fillStyle = grad;
ctx.beginPath();
ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2);
ctx.fill();
}
requestAnimationFrame(flow);
};
function reset(flake) {
let temp = (Math.random() * 1) + 0.5;
flake.x = canvas.width;
flake.y = 50;
flake.size = 6.692053245649504;
flake.speed = (Math.random() * 7) + 0.5;
flake.velY = flake.speed;
flake.velX = -xMultiplier * canvas.width * temp;
}
function init() {
for (var i = 0; i < flakeCount; i++) {
var x = canvas.width,
y = 50,
size = 6.692053245649504,
speed = 0;
particleArr.push({
speed: speed,
velY: speed,
velX: -xMultiplier * canvas.width * speed,
x: x,
y: y,
size: size,
stepSize: (Math.random()) / 30,
step: 0,
angle: 360,
color: getRandomColor()
});
}
requestAnimationFrame(flow);
};
canvas.addEventListener("mousemove", function(e) {
mouseX = e.clientX,
mouseY = e.clientY
});
window.addEventListener( 'resize', onWindowResize, false );
function onWindowResize() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
init();
canvas{
background-color: #000000 !important;
}
body {
margin: 0;
overflow: hidden;
}
<canvas id="canvas"></canvas>
[请注意,即使以为每个粒子上看起来像两个圆圈(一个读数,顶部都有一个较小的蓝色圆圈),实际上都有一个渐变,并且调整可能会固定靶心外观。为了证明它可以将粒径更改为更大的值(75 +)。