shadowBlur (html canvas) 在 js 循环中不起作用
shadowBlur (html canvas) not working in js loop
我正在尝试改进我使用 JS 创建的天空动画中的星星。这是我发现的时候,我可以使用 shadowBlur 属性 来改变围绕我的星星创建的阴影的大小,使它们看起来像是在闪烁。现在的问题是 shadowBlur 上升但没有变回黑色。这是我使用的代码。对此的任何帮助将不胜感激:)。
祝你有愉快的一天!
// ---- Vars for star animation
let randomStars = [];
let starCollection = [];
let numberofStars = 50;
let flickeringStars = 50;
class Star{
constructor(x,y,color,radius,shadowBlur){
this._canvas = document.querySelector('canvas');
this._canvas.width = window.innerWidth;
this._canvas.height = window.innerHeight;
this._c = this._canvas.getContext('2d');
this._radius = radius;
this._x = x;
this._y = y;
this._color = color;
this._shadowBlur = 10;
this._shadowColor = 'white';
}
//drawing individual stars
draw(){
this._c.beginPath();
this._c.arc(this._x,this._y,this._radius,0,Math.PI * 2,false);
this._c.fillStyle = this._color;
this._c.strokeStyle = 'black';
this._c.shadowColor = this._shadowColor;
this._c.shadowBlur = this._shadowBlur;
this._c.stroke();
this._c.fill();
this._c.closePath();
}
//Fade in and out for stars
flicker(){
setTimeout(()=>{this._shadowBlur=10;},200);
setTimeout(()=>{this._shadowBlur=8;},400);
setTimeout(()=>{this._shadowBlur=6;},600);
setTimeout(()=>{this._shadowBlur=4;},800);
setTimeout(()=>{this._shadowBlur=2;},1000);
setTimeout(()=>{this._shadowBlur=0;},1200);
setTimeout(()=>{this._shadowBlur=2;},1400);
setTimeout(()=>{this._shadowBlur=4;},1600);
setTimeout(()=>{this._shadowBlur=6;},1800);
setTimeout(()=>{this._shadowBlur=8;},2000);
setTimeout(()=>{this._shadowBlur=10;},2200);
setTimeout(()=>{this.draw();},200);
setTimeout(()=>{this.draw();},400);
setTimeout(()=>{this.draw();},600);
setTimeout(()=>{this.draw();},800);
setTimeout(()=>{this.draw();},1000);
setTimeout(()=>{this.draw();},1200);
setTimeout(()=>{this.draw();},1400);
setTimeout(()=>{this.draw();},1600);
setTimeout(()=>{this.draw();},1800);
setTimeout(()=>{this.draw();},2000);
setTimeout(()=>{this.draw();},2200);
}
//Clears the canvas
clearstars(){
this._c.clearRect(0,0,window.innerWidth, window.innerHeight);
}
}
// ---- Functions ----
//Typing animation
const typingAnimation = ()=>{
if(textProgress < text.length){
setTimeout(()=>{requestAnimationFrame(typingAnimation)}, speed);
if(text.charAt(textProgress) === '\n')document.getElementById('animation-text').innerHTML += '</br>';
document.getElementById('animation-text').innerHTML += text.charAt(textProgress);
textProgress ++;
}else{
let event = new CustomEvent('showStars');
dispatchEvent(event);
}
}
//Store stars
const storeStars = ()=>{
starCollection = [];
for(let i=0;i<numberofStars;i++){
let x = Math.floor(Math.random()*window.innerWidth);
let y = Math.floor(Math.random()*window.innerHeight);
starCollection.push(new Star(x,y,"white",(Math.random()+1)-0.7));
}
}
//Show stars to the screen
const showStars = ()=>{
for(let i=0;i<starCollection.length;i++){
starCollection[i].draw();
}
}
//Store random stars
const generateRandomStars = ()=>{
randomStars = [];
for(let i=0;i<flickeringStars;i++){
let x = Math.floor(Math.random()*window.innerWidth);
let y = Math.floor(Math.random()*window.innerHeight);
randomStars.push(new Star(x,y,"white",(Math.random()+1)-0.7));
}
}
//Show randoms stars after clearing previous set of flickering stars
const showRandomStars = ()=>{
let id = window.setTimeout(function () { }, 0);
while (id--) {
window.clearTimeout(id);
}
let starHandler = new Star(0,0,"white",0);
starHandler.clearstars();
showStars();
flickerStars();
}
//Flickers stars and changes set of stars randomly
const flickerStars = ()=>{
for(let i=0;i<flickeringStars;i++){
setInterval(()=>{
randomStars[i].flicker();
},2200);
setInterval(()=>{
console.log("changing stars pattern");
generateRandomStars();
showRandomStars();
},12200);
}
}
// ---- Event Listeners ----
//Typing animation on load
window.addEventListener("load", ()=>{
storeStars();
generateRandomStars();
showStars();
flickerStars();
});
//Handles star animation scaling on window resize
window.addEventListener("resize", ()=>{
let id = window.setTimeout(function () { }, 0);
while (id--) {
window.clearTimeout(id);
}
let starHandler = new Star(0,0,"white",0);
starHandler.clearstars();
generateRandomStars();
storeStars();
showStars();
flickerStars();
});
body{
background-color:black;
}
<html>
<body><canvas></canvas></body>
</html>
我不知道你想要得到什么 FX。下面是一个简单的闪烁星星动画,它使用改变大小的小矩形来模拟闪烁。
降低帧率,使闪烁更加明显。
它非常高效,不需要复杂的状态更改或缓慢的渲染方法(如模糊)
var W = 0, H = 0; // hold canvas size. Set to zero so first frame sizes canvas
var count = 500; // number of stars
var frame = 0; // current frame number
const frameRate = 5; // render stars ever 5 frames
const sizeRange = 1.5; // max size of star us minSize + sizeRange + flickerSize
const minSize = 1; // minimum size of star
const flickerSize = 1; // amount of change random change to make a star brighter
const flickerRate = 0.1; // odds per rendered frame that a star flickers
const stars = [];
// Create a random set of numbers for star positions.
// Values must be larger than largest canvas you are going to use.
// This will work up to 8K display
while (count--) { stars.push(Math.random() * 1024 * 8) }
const ctx = canvas.getContext("2d");
requestAnimationFrame(mainLoop);
function mainLoop() {
var len = stars.length, i = 0, x = stars[i++], starSize;
// if the window has resized change the canvas to fit
if (W !== innerWidth || H !== innerHeight) {
W = canvas.width = innerWidth;
H = canvas.height = innerHeight;
ctx.fillStyle = "#FFF";
frame = 0;
}
if (frame++ % frameRate === 0) { // only render every frameRate frames
ctx.clearRect(0, 0, W, H);
ctx.beginPath(); // draw all stars with one path aas it is several orders
// of magnitude quicker than creating a path for each
while (i < len) {
// draws small stars to large
const starScale = (i / len); // set scale from 0 to 1
starSize = sizeRange; // set the range of sizes
if (Math.random() < flickerRate) { // on random odds of flicker
starSize += flickerSize * Math.random(); // add random flicker size
}
starSize *= starScale; // scale the star
starSize += minSize; // add min size of star
halfSize = starSize / 2; // offset to top left of star
const y = stars[i++]; // get next random number as star y pos
// add rect to path fitted to canvas width and height (W, H)
ctx.rect((x % W) - halfSize , (y % H) - halfSize , starSize , starSize );
x = y; // Use y for the next x star coordinate
}
ctx.fill(); // fill in all the stars
}
requestAnimationFrame(mainLoop);
}
canvas {
position: absolute;
top: 0px;
left: 0px;
background: #000;
}
<canvas id="canvas"></canvas>
我正在尝试改进我使用 JS 创建的天空动画中的星星。这是我发现的时候,我可以使用 shadowBlur 属性 来改变围绕我的星星创建的阴影的大小,使它们看起来像是在闪烁。现在的问题是 shadowBlur 上升但没有变回黑色。这是我使用的代码。对此的任何帮助将不胜感激:)。
祝你有愉快的一天!
// ---- Vars for star animation
let randomStars = [];
let starCollection = [];
let numberofStars = 50;
let flickeringStars = 50;
class Star{
constructor(x,y,color,radius,shadowBlur){
this._canvas = document.querySelector('canvas');
this._canvas.width = window.innerWidth;
this._canvas.height = window.innerHeight;
this._c = this._canvas.getContext('2d');
this._radius = radius;
this._x = x;
this._y = y;
this._color = color;
this._shadowBlur = 10;
this._shadowColor = 'white';
}
//drawing individual stars
draw(){
this._c.beginPath();
this._c.arc(this._x,this._y,this._radius,0,Math.PI * 2,false);
this._c.fillStyle = this._color;
this._c.strokeStyle = 'black';
this._c.shadowColor = this._shadowColor;
this._c.shadowBlur = this._shadowBlur;
this._c.stroke();
this._c.fill();
this._c.closePath();
}
//Fade in and out for stars
flicker(){
setTimeout(()=>{this._shadowBlur=10;},200);
setTimeout(()=>{this._shadowBlur=8;},400);
setTimeout(()=>{this._shadowBlur=6;},600);
setTimeout(()=>{this._shadowBlur=4;},800);
setTimeout(()=>{this._shadowBlur=2;},1000);
setTimeout(()=>{this._shadowBlur=0;},1200);
setTimeout(()=>{this._shadowBlur=2;},1400);
setTimeout(()=>{this._shadowBlur=4;},1600);
setTimeout(()=>{this._shadowBlur=6;},1800);
setTimeout(()=>{this._shadowBlur=8;},2000);
setTimeout(()=>{this._shadowBlur=10;},2200);
setTimeout(()=>{this.draw();},200);
setTimeout(()=>{this.draw();},400);
setTimeout(()=>{this.draw();},600);
setTimeout(()=>{this.draw();},800);
setTimeout(()=>{this.draw();},1000);
setTimeout(()=>{this.draw();},1200);
setTimeout(()=>{this.draw();},1400);
setTimeout(()=>{this.draw();},1600);
setTimeout(()=>{this.draw();},1800);
setTimeout(()=>{this.draw();},2000);
setTimeout(()=>{this.draw();},2200);
}
//Clears the canvas
clearstars(){
this._c.clearRect(0,0,window.innerWidth, window.innerHeight);
}
}
// ---- Functions ----
//Typing animation
const typingAnimation = ()=>{
if(textProgress < text.length){
setTimeout(()=>{requestAnimationFrame(typingAnimation)}, speed);
if(text.charAt(textProgress) === '\n')document.getElementById('animation-text').innerHTML += '</br>';
document.getElementById('animation-text').innerHTML += text.charAt(textProgress);
textProgress ++;
}else{
let event = new CustomEvent('showStars');
dispatchEvent(event);
}
}
//Store stars
const storeStars = ()=>{
starCollection = [];
for(let i=0;i<numberofStars;i++){
let x = Math.floor(Math.random()*window.innerWidth);
let y = Math.floor(Math.random()*window.innerHeight);
starCollection.push(new Star(x,y,"white",(Math.random()+1)-0.7));
}
}
//Show stars to the screen
const showStars = ()=>{
for(let i=0;i<starCollection.length;i++){
starCollection[i].draw();
}
}
//Store random stars
const generateRandomStars = ()=>{
randomStars = [];
for(let i=0;i<flickeringStars;i++){
let x = Math.floor(Math.random()*window.innerWidth);
let y = Math.floor(Math.random()*window.innerHeight);
randomStars.push(new Star(x,y,"white",(Math.random()+1)-0.7));
}
}
//Show randoms stars after clearing previous set of flickering stars
const showRandomStars = ()=>{
let id = window.setTimeout(function () { }, 0);
while (id--) {
window.clearTimeout(id);
}
let starHandler = new Star(0,0,"white",0);
starHandler.clearstars();
showStars();
flickerStars();
}
//Flickers stars and changes set of stars randomly
const flickerStars = ()=>{
for(let i=0;i<flickeringStars;i++){
setInterval(()=>{
randomStars[i].flicker();
},2200);
setInterval(()=>{
console.log("changing stars pattern");
generateRandomStars();
showRandomStars();
},12200);
}
}
// ---- Event Listeners ----
//Typing animation on load
window.addEventListener("load", ()=>{
storeStars();
generateRandomStars();
showStars();
flickerStars();
});
//Handles star animation scaling on window resize
window.addEventListener("resize", ()=>{
let id = window.setTimeout(function () { }, 0);
while (id--) {
window.clearTimeout(id);
}
let starHandler = new Star(0,0,"white",0);
starHandler.clearstars();
generateRandomStars();
storeStars();
showStars();
flickerStars();
});
body{
background-color:black;
}
<html>
<body><canvas></canvas></body>
</html>
我不知道你想要得到什么 FX。下面是一个简单的闪烁星星动画,它使用改变大小的小矩形来模拟闪烁。
降低帧率,使闪烁更加明显。
它非常高效,不需要复杂的状态更改或缓慢的渲染方法(如模糊)
var W = 0, H = 0; // hold canvas size. Set to zero so first frame sizes canvas
var count = 500; // number of stars
var frame = 0; // current frame number
const frameRate = 5; // render stars ever 5 frames
const sizeRange = 1.5; // max size of star us minSize + sizeRange + flickerSize
const minSize = 1; // minimum size of star
const flickerSize = 1; // amount of change random change to make a star brighter
const flickerRate = 0.1; // odds per rendered frame that a star flickers
const stars = [];
// Create a random set of numbers for star positions.
// Values must be larger than largest canvas you are going to use.
// This will work up to 8K display
while (count--) { stars.push(Math.random() * 1024 * 8) }
const ctx = canvas.getContext("2d");
requestAnimationFrame(mainLoop);
function mainLoop() {
var len = stars.length, i = 0, x = stars[i++], starSize;
// if the window has resized change the canvas to fit
if (W !== innerWidth || H !== innerHeight) {
W = canvas.width = innerWidth;
H = canvas.height = innerHeight;
ctx.fillStyle = "#FFF";
frame = 0;
}
if (frame++ % frameRate === 0) { // only render every frameRate frames
ctx.clearRect(0, 0, W, H);
ctx.beginPath(); // draw all stars with one path aas it is several orders
// of magnitude quicker than creating a path for each
while (i < len) {
// draws small stars to large
const starScale = (i / len); // set scale from 0 to 1
starSize = sizeRange; // set the range of sizes
if (Math.random() < flickerRate) { // on random odds of flicker
starSize += flickerSize * Math.random(); // add random flicker size
}
starSize *= starScale; // scale the star
starSize += minSize; // add min size of star
halfSize = starSize / 2; // offset to top left of star
const y = stars[i++]; // get next random number as star y pos
// add rect to path fitted to canvas width and height (W, H)
ctx.rect((x % W) - halfSize , (y % H) - halfSize , starSize , starSize );
x = y; // Use y for the next x star coordinate
}
ctx.fill(); // fill in all the stars
}
requestAnimationFrame(mainLoop);
}
canvas {
position: absolute;
top: 0px;
left: 0px;
background: #000;
}
<canvas id="canvas"></canvas>