Javascript JSXGraph-多边形缓慢和粗糙的动画
在JSXGraph中,我用4个力(箭头)画了一个板(多边形)。我打算将代码用于可变数量的力(这就是为什么它比仅4个力更通用) 可以显示和隐藏力组件。当拖动力箭头(不通过轴点)时,“拖动”事件会触发动画: 1:显示力及其臂,等待2秒 第二:沿力分量的方向旋转多边形(顺时针或逆时针) 问题1:动画速度慢且粗糙。我尝试使用“suspendUpdate”和“unsuspendUpdate”,但这会让事情变得更糟。也许,我没有在正确的地方使用它 问题2:(可能相关)我没有找到一个好方法来克隆动画中的多边形。还是最好存储其坐标?但如果是这样,我如何在旋转/动画后将多边形(加上力箭头)重置为其原始位置 我的完整代码如下: 您可以找到从第244行开始为动画调用的函数:Javascript JSXGraph-多边形缓慢和粗糙的动画,javascript,animation,jsxgraph,Javascript,Animation,Jsxgraph,在JSXGraph中,我用4个力(箭头)画了一个板(多边形)。我打算将代码用于可变数量的力(这就是为什么它比仅4个力更通用) 可以显示和隐藏力组件。当拖动力箭头(不通过轴点)时,“拖动”事件会触发动画: 1:显示力及其臂,等待2秒 第二:沿力分量的方向旋转多边形(顺时针或逆时针) 问题1:动画速度慢且粗糙。我尝试使用“suspendUpdate”和“unsuspendUpdate”,但这会让事情变得更糟。也许,我没有在正确的地方使用它 问题2:(可能相关)我没有找到一个好方法来克隆动画中的多边形
函数动画(x1、y1、x2、y2、符号)
欢迎提出任何改进意见和建议。在JSFIDLE中,由于拖动事件被多次触发,动画看起来很粗糙。因此,动画将并行运行多次。在下面的代码中,这是通过标记
已设置动画来阻止的。如果true
则无法启动新动画
JSXGraph-ish的一个小问题是,在setInterval
中的动画的每个步骤中,都会将转换添加到JSXGraph元素中。这可能会产生奇怪的效果。将转换绑定到元素一次要干净得多,但要使转换动态,例如依赖于角度变量:
var angle = 0.03;
let tRot = b1.create('transform', [function() { return sign * angle; }, pivot], { type: 'rotate' });
此外,这样可以在动画结束时将多边形旋转回零角度。因此,在setInterval
中,仅增加角度变量,并更新电路板:
let idInterval = setInterval(function() {
angle += 0.03;
b1.update();
// ...
}, refreshTime);
以下是完整的新动画代码(结尾处不向后旋转):
函数动画(x1、y1、x2、y2、符号){
如果(这是动画){
返回;
}
this.is_animated=true;
//力箭头和臂(与枢轴的距离)
设Rot1=b1.create('point',[x1,y1],{visible:false})
设Rot2=b1.create('point',[x2,y2],{visible:false})
设rotArrow=b1.create('arrow',[Rot1,Rot2],{strokeColor:'#000',strokeWidth:3,visible:true})
//多边形
让PolyCopy=[]
对于(i=0;i20){
即:is_=false;
b1.移除对象(多副本);
b1.移除对象(箭头);
展示(真实);
净空间期;
}
},刷新时间)
},1000);//显示作用线和距离的时间
}
现场观看
致以最良好的祝愿,
阿尔弗雷德非常感谢你。这很有帮助。我调整了动画,以便仅为角度设置动画。因为在动画之后,我将角度重置为零,所以我不再需要复制多边形。因此,代码变得更短、更快—您真的做了一个惊人的支持:)
function animateRotation(x1, y1, x2, y2, sign) {
if (this.is_animated) {
return;
}
this.is_animated = true;
// Force arrow and arm (distance from pivot)
let Rot1 = b1.create('point', [x1, y1], { visible: false })
let Rot2 = b1.create('point', [x2, y2], { visible: false })
let rotArrow = b1.create('arrow', [Rot1, Rot2], { strokeColor: '#000', strokeWidth: 3, visible: true })
// Polygon
let PolyCopy = []
for (i = 0; i < poly_coord.length; i++) {
PolyCopy.push(b1.create('point', [poly_coord[i][0], poly_coord[i][1]], at))
}
let polyCopy = b1.create('polygon', PolyCopy, { strokeColor: myBlue, fillColor: myBlue })
// Hide all other force arrows
showAllElements(false)
// Show line of action and distance from pivot for 1s
let lineOfAction = b1.create('line', [[x1, y1], [x2, y2]], { strokeColor: '#000', strokeWidth: 2, dash: 1 })
let perpLine = b1.create('perpendicular', [lineOfAction, Pivot], { withLabel: false, visible: false })
let isecP = b1.create('intersection', [perpLine, lineOfAction, 0], { withLabel: false, visible: false })
let dist = b1.create('segment', [Pivot, isecP], { strokeColor: '#000', strokeWidth: 4 })
var that = this; // make "this" available in the interval function
// This is the animation: rotating the polygon for how many 'frames', refreshTime in ms
setTimeout(function() {
b1.removeObject(lineOfAction)
b1.removeObject(perpLine)
b1.removeObject(isecP)
b1.removeObject(dist)
var angle = 0.03;
let tRot = b1.create('transform', [function() { return sign * angle; }, pivot], { type: 'rotate' });
tRot.bindTo(PolyCopy);
tRot.bindTo([Rot1, Rot2]);
let frames = 0;
const refreshTime = 50;
let idInterval = setInterval(function() {
angle += 0.03;
b1.update();
if (frames++ > 20) {
that.is_animated = false;
b1.removeObject(polyCopy);
b1.removeObject(rotArrow);
showAllElements(true);
clearInterval(idInterval);
}
}, refreshTime)
}, 1000); // time for showing the line of action and distance
}