Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JSXGraph-多边形缓慢和粗糙的动画_Javascript_Animation_Jsxgraph - Fatal编程技术网

Javascript JSXGraph-多边形缓慢和粗糙的动画

Javascript JSXGraph-多边形缓慢和粗糙的动画,javascript,animation,jsxgraph,Javascript,Animation,Jsxgraph,在JSXGraph中,我用4个力(箭头)画了一个板(多边形)。我打算将代码用于可变数量的力(这就是为什么它比仅4个力更通用) 可以显示和隐藏力组件。当拖动力箭头(不通过轴点)时,“拖动”事件会触发动画: 1:显示力及其臂,等待2秒 第二:沿力分量的方向旋转多边形(顺时针或逆时针) 问题1:动画速度慢且粗糙。我尝试使用“suspendUpdate”和“unsuspendUpdate”,但这会让事情变得更糟。也许,我没有在正确的地方使用它 问题2:(可能相关)我没有找到一个好方法来克隆动画中的多边形

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

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

1:显示力及其臂,等待2秒 第二:沿力分量的方向旋转多边形(顺时针或逆时针)

问题1:动画速度慢且粗糙。我尝试使用“suspendUpdate”和“unsuspendUpdate”,但这会让事情变得更糟。也许,我没有在正确的地方使用它

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

我的完整代码如下:

您可以找到从第244行开始为动画调用的函数:
函数动画(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
}