这是一个关于在我通过javascript试验canvas元素时弹出的东西的查询。我希望有一个点阵列形成一个随时间移动的渐变,它与出现的奇怪图案(仅在第一波或更多波之后)完全不同,它也会根据列和行的数量而变化。画布(改变点的大小只会使图案变大或变小,它总是在相同的像素上。
这里有一个小小的演示,我的意思是你可以随意使用一些界面,更改模式的一个例子是如果行数改变为原始列数的0.75倍(即40列,30行)。
http://codepen.io/zephyr/pen/GpwwWB
使用Javascript:
String.prototype.hexToRGBA = function(a) {
function cutHex(h) {
return (h.charAt(0) == "#") ? h.substring(1, 7) : h
}
var r = parseInt((cutHex(this)).substring(0, 2), 16);
var g = parseInt((cutHex(this)).substring(2, 4), 16);
var b = parseInt((cutHex(this)).substring(4, 6), 16);
return 'rgba(' + r.toString() + ',' + g.toString() + ',' + b.toString() + ',' + a.toString() + ')';
}
CanvasRenderingContext2D.prototype.clearDrawRect = function(shape) {
this.clearRect(shape.position.x, shape.position.y, shape.size, shape.size);
this.fillStyle = shape.color.base;
this.fillRect(shape.position.x, shape.position.y, shape.size, shape.size);
}
CanvasRenderingContext2D.prototype.render = function(render) {
(function animate() {
requestAnimationFrame(animate);
render();
})();
}
CanvasRenderingContext2D.prototype.renderAndThrottleFpsAt = function(fps, render) {
var fpsInterval, startTime, now, then, elapsed;
fpsInterval = 1000 / fps;
then = Date.now();
startTime = then;
(function animate() {
requestAnimationFrame(animate);
now = Date.now();
elapsed = now - then;
if (elapsed > fpsInterval) {
then = now - (elapsed % fpsInterval);
render();
}
})();
}
CanvasRenderingContext2D.prototype.pool = {};
CanvasRenderingContext2D.prototype.parsePoint = function(x, y, s, c) {
return {
color: c,
position: {
x: x,
y: y
},
size: s
}
}
CanvasRenderingContext2D.prototype.fillPointsPool = function(size, cols, rows, color) {
var i = cols;
var j = rows;
while(i--){
while(j--){
var x = i * size;
var y = j * size;
var a = (i * j) / (cols * rows);
var c = {
hex: color,
alpha: a,
dir: 1
};
if (typeof this.pool.points == 'undefined') {
this.pool.points = [this.parsePoint(x, y, size, c)];
} else {
this.pool.points.push(this.parsePoint(x, y, size, c));
}
}
j = rows;
}
}
CanvasRenderingContext2D.prototype.updatePointsPool = function(size, cols, rows, color) {
this.pool.points = [];
this.clearRect(0,0,this.canvas.width,this.canvas.height);
this.fillPointsPool(size, cols, rows, color);
}
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// Populate Points
var size = document.getElementById('size');
var cols = document.getElementById('cols');
var rows = document.getElementById('rows');
var color = document.getElementById('color');
ctx.fillPointsPool(size.value, cols.value, rows.value, color.value);
size.oninput = function(){
ctx.updatePointsPool(this.value, cols.value, rows.value, color.value);
}
cols.oninput = function(){
ctx.updatePointsPool(size.value, this.value, rows.value, color.value);
}
rows.oninput = function(){
ctx.updatePointsPool(size.value, cols.value, this.value, color.value);
}
color.oninput = function(){
ctx.updatePointsPool(size.value, cols.value, rows.value, this.value);
}
ctx.renderAndThrottleFpsAt(60, function(){
var i = 0;
var len = ctx.pool.points.length;
while (i<len) {
var point = ctx.pool.points[i];
// Change alpha for wave
var delta = 0.01;
point.color.alpha = point.color.alpha + (delta * point.color.dir);
if (point.color.alpha > 1) {
point.color.dir = -1;
} else if (point.color.alpha <= 0) {
point.color.dir = 1;
}
// Calculate rgba value with new alpha
point.color.base = point.color.hex.hexToRGBA(point.color.alpha);
ctx.clearDrawRect(point);
i++;
}
});
你们中是否有人知道导致模式出现的原因,以及有关解决此问题的任何建议?
注意:我将更改updatePointsPool函数
答案 0 :(得分:1)
更改方向时,您忘记夹住Alpha值。 alpha值中的小误差会缓慢累积,从而产生您在动画进行过程中看到的不需要的伪像。
要在将delta方向添加到alpha后立即在代码中添加alpha的顶部和底部限制。
if (point.color.alpha > 1) {
point.color.alpha = 1; // clamp alpha max
point.color.dir = -1;
} else if (point.color.alpha <= 0) {
point.color.alpha = 0; // clamp alpha min
point.color.dir = 1;
}