【问题标题】:JSXGraph - Animation of Polygon slow and roughJSXGraph - 多边形动画缓慢而粗糙
【发布时间】:2020-11-02 12:02:42
【问题描述】:

在 JSXGraph 中,我绘制了一个板(多边形),上面有 4 个力(箭头)。我打算将代码用于可变数量的力(这就是为什么它比仅用于 4 个力更通用的原因)。

力组件可以显示和隐藏。当一个力箭头(不通过枢轴点)被拖动时,“拖动”事件触发动画:

1st:显示力及其手臂,等待2s 2nd:沿分力方向旋转多边形(顺时针或逆时针)。

问题 1:动画缓慢而粗糙。我尝试使用“suspendUpdate”和“unsuspendUpdate”,但它让事情变得更糟。可能是我没有在正确的地方使用它。

问题 2:(可能相关)我没有找到为动画克隆多边形的好方法。或者最好存储它的坐标?但如果是这样,我将如何在旋转/动画后将多边形(加力箭头)重置为其原始位置?

我的完整代码在这里:https://jsfiddle.net/bujowi/j1etgLsp/3/

从第 244 行开始,您可以找到为动画调用的函数: function animateRotation(x1, y1, x2, y2, sign)

欢迎提出任何改进意见和建议。

【问题讨论】:

    标签: javascript animation jsxgraph


    【解决方案1】:

    在 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/观看直播

    最好的祝愿, 阿尔弗雷德

    【讨论】:

    • 非常感谢。这很有帮助。我调整了我的动画,以便只对角度进行动画处理。因为在动画之后我将角度重置为零,所以我不再需要复制多边形了。所以代码变得更短更快 - 你真的在做一个了不起的支持:)
    猜你喜欢
    • 2018-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    相关资源
    最近更新 更多