这是我试图做的事情。到目前为止,我有2个画布元素,但我希望能够扩展它们(例如,添加更多)。在任何一种情况下,我目前在一个canvas元素中都能正常工作,但是,我想以迭代的方式从一个canvas元素切换到另一个(通过下面代码中的预构建的changeContext()函数)。我试图通过beginAnimation()函数触发一个动画,然后在完成之后,画布上下文被更改为下一个画布,而下一个实例化对象被推送到beginAnimation()功能。我有一种感觉,我可能必须通过嵌套setInterval和/或setTimeout函数来做到这一点,但是,我对这两种函数都不太擅长。
任何反馈,评论和/或建议肯定会受到赞赏。
window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded() { canvasApp(); }
function canvasSupport() { return Modernizr.canvas; }
function canvasApp() {
// if: no canvas support return, else declare 2D canvas
if (!canvasSupport()) { return; } else {
var theCanvas = document.getElementById('cvs-1');
var context = theCanvas.getContext('2d');
}
function changeContext(num) {
theCanvas = document.getElementById('cvs-' + num);
context = theCanvas.getContext('2d');
}
var stepStart = 0;
var stepEnd = 0.00;
// Constructor: myPercentage
var myPercentage = function(percentage) {
this.strokeStyle = '#2B5981'; // Blue
this.lineWidth = 10;
this.percentage = percentage; // Percentage
this.degrees = this.percentage * 360.0;
this.radians = this.degrees * (Math.PI / 180);
this.x = 57.5;
this.y = 57.5;
this.r = 45;
this.s = 1.5 * Math.PI;
this.drawShape = function() {
context.strokeStyle = this.strokeStyle;
context.lineWidth = this.lineWidth;
function clearCanvas(x,y,width,height) {
context.rect(x,y,width,height);
context.fillStyle = '#FCFCFC';
context.fill();
}
function circle(x,y,r,startAngle,endAngle,counterClockwise) {
context.beginPath();
context.arc(x,y,r,startAngle,endAngle,counterClockwise);
context.shadowColor = '#242424';
context.shadowBlur = 7;
context.stroke();
context.closePath();
}
function writePercentage(percentage) {
context.font = '20px Georgia';
context.fillStyle = 'black';
context.fillText(Math.round(percentage*100)+'%',40,62);
}
clearCanvas(0,0,115,115);
this.degrees = this.percentage * 360.0;
this.radians = this.degrees * (Math.PI / 180);
circle(this.x,this.y,this.r,this.s,this.radians+this.s,false);
writePercentage(this.percentage);
context.save();
};
};
function setSteps(object) {
stepStart = 0;
stepEnd = object.percentage * 100;
object.percentage = 0.00;
}
//Instantiate: new percentages
var phpPerc = new myPercentage(0.75);
var jsPerc = new myPercentage(0.25);
function beginAnimation(object) {
setSteps(object);
setInterval(function() {
if (stepStart < stepEnd) {
object.percentage += 0.01;
object.drawShape();
stepStart++;
} else {
clearInterval();
}
}, 33);
}
beginAnimation(phpPerc);
// changeContext(2);
// beginAnimation(jsPerc);
此处的演示应该可以在这里访问 - &gt; http://jsfiddle.net/justinbyrne001/TS8w7/
答案 0 :(得分:1)
制作像.getElementById这样的DOM请求相对昂贵。
最好是在应用程序开始时引用所有画布和上下文。
// get all canvas and context references once at the start of your app
var canvases=[];
canvases.push(document.getElementById('cvs-1'));
canvases.push(document.getElementById('cvs-2'));
canvases.push(document.getElementById('cvs-3'));
var contexts=[];
for(var i=0;i<canvases.length;i++){
contexts.push(canvases[i].getContext('2d');
}
然后,您可以将theCanvas
和context
变量设置为任意所需的画布&amp;上下文。
function changeContext(num) {
theCanvas = canvases[num];
context = contexts[num];
}
BTW,您可能希望使用单个画布而不是多个画布来测试代码。 Canvas可以快速有效地处理多组图纸。您可能会发现1个画布足够快,占用的资源比多个画布少。
答案 1 :(得分:0)
好的,这绝对给了我完成这个小项目所需要的洞察力,我真诚地感谢它。但是,我对使用各种(或多个)画布会产生不必要的开销的整个概念感到有些困惑和冲突。我理解,并且非常感谢你提醒我关于在整个运行时间不断使用getElementById()函数的过程,这会(很可能)在动画期间产生不必要的开销。但是,我在各篇文章中都已经阅读过该元素已经作为DOM元素进行了优化,因此在使用多个画布或多个画布层时不需要进行后期制作优化。
<强>参考文献:强>
Ranfelt,A。,(2013)。使用分层优化HTML5画布渲染。 IBM developerWorks。 取自:http://tinyurl.com/m3yx682
N.A。,(2013)。使用多个画布对象是一个好习惯吗? 游戏开发堆栈 交换。取自:http://tinyurl.com/l4dlv6a
N.A。,(2010)。单页上的HTML5多个画布。 堆栈溢出堆栈交换。 取自:http://tinyurl.com/ll3o7vv
Litten,J。(2010)。使用多个HTML5画布作为图层。未知的卡达斯。 取自:http://tinyurl.com/6yspxzu
虽然,这篇原创帖子询问如何 Nest setInterval函数成功更改画布的多个画布动画的上下文,但我能够通过改变stepStart&amp; amp; stepEnd单个变量到数组。另外,我自然也改变了我的原始构造方法(如下所示),以反映整个数组中存储(现在)的各种canvas元素,同时包括要通过主构造函数传递的其他参数,包括beginAnimation()方法;否定甚至需要一个changeContext()方法,更不用说嵌套的setInterval函数了。虽然这种方法肯定有效,但我希望解决方案不会偏离原始查询过多。无论如何,我真诚地感谢您的反馈 markE ,并感谢您的时间。下面更新的代码应按预期工作,此处还有一个更新版本(http://jsfiddle.net/justinbyrne001/TS8w7/1/),以防有人想将它用于自己的项目。
// Declare: canvases array to store multiple canvas elements
var canvases=[];
canvases.push(document.getElementById('cvs-1'));
canvases.push(document.getElementById('cvs-2'));
// Declare: contexts array to store '2d' canvas API
var contexts=[];
// Store: '2d' canvas API throughout canvases array
for(var i=0; i<canvases.length; i++ ) {
contexts.push(canvases[i].getContext('2d'));
}
// stepStart & stepEnd arrays
var stepStart=[];
var stepEnd=[];
// Constructor: myPercentage(percentage, context)
var myPercentage = function(percentage,ctx) {
this.context = ctx; // Context
this.strokeStyle = '#2B5981'; // Blue
this.lineWidth = 10;
this.percentage = percentage; // Percentage
this.degrees = this.percentage * 360.0;
this.radians = this.degrees * (Math.PI / 180);
this.x = 57.5;
this.y = 57.5;
this.r = 45;
this.s = 1.5 * Math.PI;
this.drawShape = function() {
contexts[ctx].strokeStyle = this.strokeStyle;
contexts[ctx].lineWidth = this.lineWidth;
function clearCanvas(x,y,width,height) {
contexts[ctx].rect(x,y,width,height);
contexts[ctx].fillStyle = '#FCFCFC';
contexts[ctx].fill();
}
function circle(x,y,r,startAngle,endAngle,counterClockwise) {
contexts[ctx].beginPath();
contexts[ctx].arc(x,y,r,startAngle,endAngle,counterClockwise);
contexts[ctx].shadowColor = '#242424';
contexts[ctx].shadowBlur = 7;
contexts[ctx].stroke();
contexts[ctx].closePath();
}
function writePercentage(percentage) {
contexts[ctx].font = '20px Georgia';
contexts[ctx].fillStyle = 'black';
contexts[ctx].fillText(Math.round(percentage*100)+'%',40,62);
}
clearCanvas(0,0,115,115);
this.degrees = this.percentage * 360.0;
this.radians = this.degrees * (Math.PI / 180);
circle(this.x,this.y,this.r,this.s,this.radians+this.s,false);
writePercentage(this.percentage);
contexts[ctx].save();
};
};
// Identify: number of steps to take between object's percentage
function setSteps(object) {
stepStart[object.context] = 0;
stepEnd[object.context] = object.percentage * 100;
object.percentage = 0.00;
}
//Instantiate: new percentages
var onePerc = new myPercentage(0.90,0);
var twoPerc = new myPercentage(0.80,1);
// Initialize: animation with passed object
function beginAnimation(object) {
setSteps(object);
setInterval(function() {
if (stepStart[object.context] < stepEnd[object.context]) {
object.percentage += 0.01;
object.drawShape(); // Uncaught Reference
stepStart[object.context]++;
}
}, 33);
}
// Call: animations to be executed
beginAnimation(onePerc,0);
beginAnimation(twoPerc,1);