SVG通过Javascript启动和编辑animateTransform

SVG通过Javascript启动和编辑animateTransform,javascript,animation,svg,Javascript,Animation,Svg,我想通过转换矩阵(这是动态决定的)在SVG画布上转换元素。我可以用JQuery SVG animate()实现,但结果一点也不平滑。所以我想使用原生SVG animateTransform,问题是: 如何在需要时启动它(可能是beginElement()),以及 如何动态设置矩阵中的参数 提前感谢:D动画可以用多种不同的方式制作 向图形/形状元素添加动画元素适用于预定义的动画。“动画元素”展示了非常简短的甜蜜解决方案,演示: 交互式动画需要更多的手动解决方案和相当多的Javascript样板

我想通过转换矩阵(这是动态决定的)在SVG画布上转换元素。我可以用JQuery SVG animate()实现,但结果一点也不平滑。所以我想使用原生SVG animateTransform,问题是:

  • 如何在需要时启动它(可能是beginElement()),以及
  • 如何动态设置矩阵中的参数

提前感谢:D

动画可以用多种不同的方式制作

向图形/形状元素添加动画元素适用于预定义的动画。“动画元素”展示了非常简短的甜蜜解决方案,演示:

交互式动画需要更多的手动解决方案和相当多的Javascript样板代码。您必须创建一个函数
render
,该函数将由
requestAnimationFrame
每秒调用60次(请参阅)。在
render
中,您可以获取“当前变换矩阵”(CTM)并基于该矩阵应用更改。这是一个非常小的概念证明:

在一个大项目中,我建议包装SVG元素,也许在不使用字符串连接的情况下制作动画,而直接使用矩阵和变换。这是一个我经常使用的示例类:

var SVG, Object2D;

SVG = document.querySelector( 'svg' );

// ...

Object2D = ( function () {
  var proto;

  function Object2D ( domElement ) {
    this.domElement = domElement;
    this.transform  = SVG.createSVGTransform();
    this.matrix     = SVG.createSVGMatrix();
    this.position   = SVG.createSVGPoint();
    this.rotation   = 0;
    this.scale      = 1;
  }


  proto = Object2D.prototype;


  proto.draw = function ( timestamp ) {
    // update scale and position, apply rotation
    var transform = this.transform,
        matrix    = this.matrix,
        position  = this.position,
        rotation  = this.rotation,
        scale     = this.scale;

    matrix.a = scale;
    matrix.d = scale;
    matrix.e = position.x;
    matrix.f = position.y;

    transform.setMatrix( matrix.multiply( rotation ) );
    this.domElement.transform.baseVal.initialize( transform ); // clear then put
  };


  return Object2D;
} )();
谢谢你的回答! 因为我想使用原生SVG动画,所以我找到了这个解决方案(仍然不能完美地工作)。这是不存在的animateTransform(attributeName=“transform”type=“matrix”)的一种版本

注意:我为group.transform中的每个元素保留svg转换,group.transform.matrix()只返回该元素的转换矩阵

我首先将这些元素添加到要设置动画的元素中:

<animateTransform id="canvTranslate" begin="indefinite" attributeName="transform" type="translate" to="" dur="1s" additive="sum" fill="freeze"/>
<animateTransform id="canvRotate" begin="indefinite" attributeName="transform" type="rotate" to="" dur="1s" additive="sum" fill="freeze"/>
<animateTransform id="canvScale" begin="indefinite" attributeName="transform" type="scale" to="" dur="1s" additive="sum" fill="freeze"/>
group.transform=转换
最后,要更新元素的transform属性,请执行以下操作:

    setTimeout(function(){ //i will change this somehow better :)

        //this is a problematic step. with it animations work on Chrome, without it they work good on firefox and opera too
        $(group).attr('transform', 'matrix('+tMatrix.a+','+tMatrix.b+','+tMatrix.c+','+tMatrix.d+','+tMatrix.e+','+tMatrix.f+')');
    }, duration+100);
这最后一步是有问题的。我不明白为什么它在Chrome中工作得很好,而在Firefox和Opera中动画的伸缩性要大得多(不调用setTimeout就可以了)

    setTimeout(function(){ //i will change this somehow better :)

        //this is a problematic step. with it animations work on Chrome, without it they work good on firefox and opera too
        $(group).attr('transform', 'matrix('+tMatrix.a+','+tMatrix.b+','+tMatrix.c+','+tMatrix.d+','+tMatrix.e+','+tMatrix.f+')');
    }, duration+100);