Javascript 为什么此画布在不同浏览器中的反应不同
我在codepen中找到了这个漂亮的小画布粒子效果:Javascript 为什么此画布在不同浏览器中的反应不同,javascript,html,css,canvas,Javascript,Html,Css,Canvas,我在codepen中找到了这个漂亮的小画布粒子效果: /** * Generates random particles using canvas * * @class Particles * @constructor */ function Particles(){ //particle colors this.colors = [ '255, 255, 255', '255, 99, 71', '19, 19, 19' ] //adds gr
/**
* Generates random particles using canvas
*
* @class Particles
* @constructor
*/
function Particles(){
//particle colors
this.colors = [
'255, 255, 255',
'255, 99, 71',
'19, 19, 19'
]
//adds gradient to particles on true
this.blurry = true;
//adds white border
this.border = false;
//particle radius min/max
this.minRadius = 10;
this.maxRadius = 35;
//particle opacity min/max
this.minOpacity = .005;
this.maxOpacity = .5;
//particle speed min/max
this.minSpeed = .05;
this.maxSpeed = .5;
//frames per second
this.fps = 60;
//number of particles
this.numParticles = 75;
//required canvas variables
this.canvas = document.getElementById('canvas');
this.ctx = this.canvas.getContext('2d');
}
/**
* Initializes everything
* @method init
*/
Particles.prototype.init = function(){
this.render();
this.createCircle();
}
/**
* generates random number between min and max values
* @param {number} min value
* @param {number} max malue
* @return {number} random number between min and max
* @method _rand
*/
Particles.prototype._rand = function(min, max){
return Math.random() * (max - min) + min;
}
/**
* Sets canvas size and updates values on resize
* @method render
*/
Particles.prototype.render = function(){
var self = this,
wHeight = $(window).height(),
wWidth = $(window).width();
self.canvas.width = wWidth;
self.canvas.height = wHeight;
$(window).on('resize', self.render);
}
/**
* Randomly creates particle attributes
* @method createCircle
*/
Particles.prototype.createCircle = function(){
var particle = [];
for (var i = 0; i < this.numParticles; i++) {
var self = this,
color = self.colors[~~(self._rand(0, self.colors.length))];
particle[i] = {
radius : self._rand(self.minRadius, self.maxRadius),
xPos : self._rand(0, canvas.width),
yPos : self._rand(0, canvas.height),
xVelocity : self._rand(self.minSpeed, self.maxSpeed),
yVelocity : self._rand(self.minSpeed, self.maxSpeed),
color : 'rgba(' + color + ',' + self._rand(self.minOpacity, self.maxOpacity) + ')'
}
//once values are determined, draw particle on canvas
self.draw(particle, i);
}
//...and once drawn, animate the particle
self.animate(particle);
}
/**
* Draws particles on canvas
* @param {array} Particle array from createCircle method
* @param {number} i value from createCircle method
* @method draw
*/
Particles.prototype.draw = function(particle, i){
var self = this,
ctx = self.ctx;
if (self.blurry === true ) {
//creates gradient if blurry === true
var grd = ctx.createRadialGradient(particle[i].xPos, particle[i].yPos, particle[i].radius, particle[i].xPos, particle[i].yPos, particle[i].radius/1.25);
grd.addColorStop(1.000, particle[i].color);
grd.addColorStop(0.000, 'rgba(34, 34, 34, 0)');
ctx.fillStyle = grd;
} else {
//otherwise sets to solid color w/ opacity value
ctx.fillStyle = particle[i].color;
}
if (self.border === true) {
ctx.strokeStyle = '#fff';
ctx.stroke();
}
ctx.beginPath();
ctx.arc(particle[i].xPos, particle[i].yPos, particle[i].radius, 0, 2 * Math.PI, false);
ctx.fill();
}
/**
* Animates particles
* @param {array} particle value from createCircle & draw methods
* @method animate
*/
Particles.prototype.animate = function(particle){
var self = this,
ctx = self.ctx;
setInterval(function(){
//clears canvas
self.clearCanvas();
//then redraws particles in new positions based on velocity
for (var i = 0; i < self.numParticles; i++) {
particle[i].xPos += particle[i].xVelocity;
particle[i].yPos -= particle[i].yVelocity;
//if particle goes off screen call reset method to place it offscreen to the left/bottom
if (particle[i].xPos > self.canvas.width + particle[i].radius || particle[i].yPos > self.canvas.height + particle[i].radius) {
self.resetParticle(particle, i);
} else {
self.draw(particle, i);
}
}
}, 1000/self.fps);
}
/**
* Resets position of particle when it goes off screen
* @param {array} particle value from createCircle & draw methods
* @param {number} i value from createCircle method
* @method resetParticle
*/
Particles.prototype.resetParticle = function(particle, i){
var self = this;
var random = self._rand(0, 1);
if (random > .5) {
// 50% chance particle comes from left side of window...
particle[i].xPos = -particle[i].radius;
particle[i].yPos = self._rand(0, canvas.height);
} else {
//... or bottom of window
particle[i].xPos = self._rand(0, canvas.width);
particle[i].yPos = canvas.height + particle[i].radius;
}
//redraw particle with new values
self.draw(particle, i);
}
/**
* Clears canvas between animation frames
* @method clearCanvas
*/
Particles.prototype.clearCanvas = function(){
this.ctx.clearRect(0, 0, canvas.width, canvas.height);
}
// go go go!
var particle = new Particles().init();
/**
*使用画布生成随机粒子
*
*@类粒子
*@constructor
*/
函数粒子(){
//粒子颜色
此项。颜色=[
'255, 255, 255',
'255, 99, 71',
'19, 19, 19'
]
//将渐变添加到“真”上的粒子
这个。模糊=真实;
//添加白色边框
this.border=false;
//最小/最大粒子半径
这个最小半径=10;
这个.maxRadius=35;
//粒子不透明度最小值/最大值
这是最小产能=.005;
这个.maxOpacity=.5;
//粒子速度最小/最大值
这个.min速度=0.05;
这是.maxSpeed=.5;
//每秒帧数
这是1.fps=60;
//粒子数
这个.numParticles=75;
//必需的画布变量
this.canvas=document.getElementById('canvas');
this.ctx=this.canvas.getContext('2d');
}
/**
*初始化一切
*@methodinit
*/
Particles.prototype.init=函数(){
这个。render();
这个.createCircle();
}
/**
*在最小值和最大值之间生成随机数
*@param{number}最小值
*@param{number}max-malue
*@return{number}最小值和最大值之间的随机数
*@method\u-rand
*/
粒子.原型._rand=函数(最小值,最大值){
返回Math.random()*(max-min)+min;
}
/**
*设置画布大小并在调整大小时更新值
*@methodrender
*/
Particles.prototype.render=函数(){
var self=这个,
wHeight=$(窗口).height(),
wWidth=$(窗口).width();
self.canvas.width=wWidth;
self.canvas.height=wHeight;
$(window.on('resize',self.render));
}
/**
*随机创建粒子属性
*@methodcreatecircle
*/
Particles.prototype.createCircle=函数(){
var粒子=[];
对于(var i=0;iself.canvas.width+particle[i]。半径| | particle[i]。yPos>self.canvas.height+particle[i]。半径){
自复位粒子(粒子,i);
}否则{
自绘制(粒子,i);
}
}
},1000/每平方英尺);
}
/**
*当粒子离开屏幕时重置其位置
*createCircle和draw方法中的@param{array}粒子值
*createCircle方法中的@param{number}i值
*@方法重置粒子
*/
Particles.prototype.resetParticle=函数(粒子,i){
var self=这个;
var random=自随机(0,1);
如果(随机>0.5){
//50%的几率粒子来自窗口左侧。。。
粒子[i].xPos=-particle[i].半径;
粒子[i].yPos=self.\u rand(0,canvas.height);
}否则{
//…或窗口底部
粒子[i].xPos=self.\u rand(0,canvas.width);
粒子[i]。yPos=canvas.height+particle[i]。半径;
}
//使用新值重新绘制粒子
自绘制(粒子,i);
}
/**
*清除动画帧之间的画布
*@方法clearCanvas
*/
Particles.prototype.clearCanvas=函数(){
this.ctx.clearRect(0,0,canvas.width,canvas.height);
}
//快走!
var particle=新粒子().init();
。为什么它在Chrome中工作得很好,在Firefox中没有颜色,在InternetExplorer中看起来+运行得很糟糕,有什么方法可以解决这个问题吗?我确保所有3个浏览器都运行最新的更新 在FF中,问题在于: 在模糊if中,更改以下两行:
grd.addColorStop(1.000, particle[i].color);
grd.addColorStop(0.000, 'rgba(34, 34, 34, 0)');
致:
在EDGE中,问题也在于模糊代码,如果将模糊设置为“false”,则所有动画都是流体。如果可以的话,我会尝试解决这个问题…在一个经常被称为循环的过程中,创建渐变是一个应该避免的操作。在这里,我认为这就是Edge无法成功的原因。
但是,即使在FF/Chrome中,您也可以通过只创建一次渐变然后重新使用它来获得更好的性能。
你会怎么做 1) 创建标准化的径向渐变,即中心渐变,wi
grd.addColorStop(0.000, 'rgba(34, 34, 34, 0)');
grd.addColorStop(1.000, particle[i].color);
// add this in the Particles cttor
( function() {
var gradients = [], grd = null;
var colors = this.colors, color=null;
//
for (var i=0; color=colors[i]; i++) {
var grd = ctx.createRadialGradient(0,0,1, 0,0,1/1.25);
grd.addColorStop(0.000, 'rgba(34, 34, 34, 0)');
grd.addColorStop(1.000, color);
gradients.push(grd);
}
this.colorGradients = gradients;
})();
var thisParticle = particles[i];
//
if (this.blurry) {
ctx.save();
ctx.translate(thisParticle.xPos, thisParticle.yPos);
ctx.scale(thisParticle.radius, thisParticle.radius);
ctx.beginPath();
ctx.arc(0,0,1,0, 2*Math.PI);
ctx.fillStyle = this.colorGradients[thisParticle.colorIndex];
ctx.fill();
ctx.restore();
}
ctx.strokeStyle = ...some 'rgb ' color string
var convertedColor = ctx.strokeStyle ; // converted color is '#...' color string