在 jsfiddle 中,由于多次触发了拖动事件,因此动画看起来很粗糙。因此,动画会并行运行多次。在下面的代码中,这是由标志 is_animated 阻止的。如果true 不能启动新动画。
一个较小的、更类似于 JSXGraph 的问题是,在 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);
这是完整的新动画代码(最后没有旋转):
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
}
在https://jsfiddle.net/fbdzx0ht/3/观看直播
最好的祝愿,
阿尔弗雷德