Javascript 对象属性更改时重新绘制画布
我正在html5画布上构建用于对象管理的小型库。每个对象都有x和y属性,表示对象在画布上的位置。我想将DOM属性修改(当我执行elm.style.left='100px'时,更改会立即反映)复制到我的库中。渲染是在一个特殊的函数中管理的,所以每次修改任何对象时,我都会调用这个函数(+其他一些函数,如设置了碰撞检测,…)Javascript 对象属性更改时重新绘制画布,javascript,html,canvas,Javascript,Html,Canvas,我正在html5画布上构建用于对象管理的小型库。每个对象都有x和y属性,表示对象在画布上的位置。我想将DOM属性修改(当我执行elm.style.left='100px'时,更改会立即反映)复制到我的库中。渲染是在一个特殊的函数中管理的,所以每次修改任何对象时,我都会调用这个函数(+其他一些函数,如设置了碰撞检测,…) 编辑: 我有一个这样的物体: { x: 10, y:10, ... } var universe={ objects:[], requ
编辑: 我有一个这样的物体:
{
x: 10,
y:10,
...
}
var universe={
objects:[],
requiresRender:false,
physicsIterations=3,
};
function render(universe){
// if there's no work to do then return
if(!universe.requiresRender){ return; }
// do the required number of physics resolutions
for(var i=0;i<universe.physicsIterations;i++){
doPhysics(universe.objects);
}
// if any source changed any objects properties then redraw
if(universe.requiresRender){
ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i=0;i<universe.objects.length;i++){
// redraw object[i] now
}
universe.requiresRender=false;
}
}
当我做
obj.x=20时代码>,我需要用新的对象坐标重新绘制画布。[根据提问者的评论更改答案]
您可能会从多个来源更改对象属性:
- 从javascript代码中
- 来自用户(鼠标等)
- 从物理常规
要处理此问题,请设置一个主对象,该主对象包含对象数组和一些状态属性:
var universe={
objects:[],
requiresRender:false,
};
然后可以按如下方式组织render()函数:
{
x: 10,
y:10,
...
}
var universe={
objects:[],
requiresRender:false,
physicsIterations=3,
};
function render(universe){
// if there's no work to do then return
if(!universe.requiresRender){ return; }
// do the required number of physics resolutions
for(var i=0;i<universe.physicsIterations;i++){
doPhysics(universe.objects);
}
// if any source changed any objects properties then redraw
if(universe.requiresRender){
ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i=0;i<universe.objects.length;i++){
// redraw object[i] now
}
universe.requiresRender=false;
}
}
- 对宇宙物体进行物理学研究
- 如果物理改变了什么,那么就重新绘制一切
渲染函数示例:
function render(universe){
// if there's no work to do then return
if(!universe.requiresRender){ return; }
// do physics resolutions
doPhysics(universe.objects);
// if any source changed any objects properties then redraw
if(universe.requiresRender){
ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i=0;i<universe.objects.length;i++){
// redraw object[i] now
}
universe.requiresRender=false;
}
}
物理学的一个方面是,更改一个对象可能会对其他对象产生级联效应
例如,矩形A可能会与矩形B碰撞,因此A会从B反弹。A反弹时,它可能会进一步与矩形C碰撞
这意味着您可能必须递归调用doPhysics()来解析所有对象交互
通常没有足够的时间/资源来解决所有对象交互,因此物理引擎通常会执行固定数量的物理重复,而不是尝试完全解决所有对象交互
在除普通物理环境外的所有物理环境中,渲染函数还必须限制其解析物理的范围
因此,您的render()函数可能会如下所示:
{
x: 10,
y:10,
...
}
var universe={
objects:[],
requiresRender:false,
physicsIterations=3,
};
function render(universe){
// if there's no work to do then return
if(!universe.requiresRender){ return; }
// do the required number of physics resolutions
for(var i=0;i<universe.physicsIterations;i++){
doPhysics(universe.objects);
}
// if any source changed any objects properties then redraw
if(universe.requiresRender){
ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i=0;i<universe.objects.length;i++){
// redraw object[i] now
}
universe.requiresRender=false;
}
}
如果javascript更改了任何对象属性,请设置requiresRender标志:
universe.requiresRender=true;
universe.requiresRender=true;
通过使用requiresRender标志,您可以依靠循环定期调用render(),以正确绘制对象
这样,您就不需要每次属性更改都使用render()(每次属性更改都使用render()会降低性能)
可以使用requestAnimationFrame有效地将渲染与硬件显示的刷新周期同步。因此,requestAnimationFrame可以实现高效的渲染
此requestAnimationFrame循环每秒最多执行60次
function loop(time){
// keep the loop going
requestAnimationFrame(loop);
// use javascript to make any desired object property changes
// do a render
render();
}
同时
您可以查看物理引擎如何处理属性更新+物理+重绘
Box2d是一个很好的例子:您能详细介绍一下吗?很抱歉这么说,但您完全误解了我的问题。我已经知道你告诉我的一切。所以请向我解释你的问题:)如果你正在寻找一个浏览器事件,它会通知你画布元素位置的更改,那么DOMAttrModified适用于一些但不是所有的浏览器(你必须进行轮询才能完全跨浏览器兼容)。或者您正在寻找javascript getter/setter?不建议使用这些工具将对象更改自动转换为画布重画。这是因为更改obj.x和obj.y将导致2次重绘。更有效的方法是同时更改obj.x和obj.y,然后进行1次重画。我有render()函数,该函数以对象数组为参数,清除画布并重画所有对象。现在,当我更改这些对象的某些属性(例如高度、x、y等)时,我希望调用render()以立即在画布上显示该更改。。。所以基本上,每次我改变数组中其中一个对象的某些属性时,我都希望得到一个调用的函数。现在,我正在使用setter和getter。如果只是为了渲染,我可以独立完成,但问题是,我实现了一些简单的物理,所以我想与其他对象进行碰撞检查,…我现在更了解您的情况。我改变了我的答案,以便更深入地了解物理引擎是如何处理属性变化的。祝你的项目好运!