Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interpolate transform function lists, not just matrices. #44

Open
ccprog opened this issue Sep 12, 2017 · 2 comments
Open

Interpolate transform function lists, not just matrices. #44

ccprog opened this issue Sep 12, 2017 · 2 comments

Comments

@ccprog
Copy link

ccprog commented Sep 12, 2017

Consider this animation which interpolates using interpolateTransformSvg:

var p1 = d3.select('svg')
  .append('polygon')
  .attr('points', '100 90 100 110 10 100')
  .attr('transform', 'rotate(20, 100, 100)');

p1.transition()
  .duration(2000)
  .attr('transform', 'rotate(160, 100, 100)')
  .on('start end', function () {
    console.log(p1.node().transform.baseVal.consolidate().matrix);
  });

Codepen

It should rotate the polygon about a constant center. Instead, the rotation center moves during the transition. If you look at the logged consolidated transform matrices, this is not that suprising:

{ a: 0.9396926164627075, b: 0.3420201539993286, c: -0.3420201539993286, d: 0.9396926164627075, e: 40.23275375366211, f: -28.171276092529297 }
{ a: -0.9396926164627075, b: 0.3420201539993286, c: -0.3420201539993286, d: -0.9396926164627075, e: 228.17127990722656, f: 159.76724243164062 }

The method of blindly taking the matrix supplied by SVGTransformList.consolidate() as a basis for interpolation is clearly not appropriate in this case.

Rotating without supplying a rotation center works is as expected.

@mbostock
Copy link
Member

mbostock commented Sep 12, 2017

I’ve reproduced this here:

https://bl.ocks.org/mbostock/98edae5ce16c3400b5bcd180653a3717

The way transform interpolation currently works is that it decomposes the start and end transform into a standard matrix representation, and then uses the CSS Transforms Module Level 1 specification for interpolating 2D matrices.

However, what we should be doing is following the specification for interpolating transforms, not matrices; the latter only applies in the general case when the start and end transform have different structure. This will require looking at the transform as a series of transform functions, rather than immediately decomposing it.

@mbostock mbostock changed the title interpolateTransformSvg produces unexpected values if a rotation center is supplied Interpolate transform function lists, not just matrices. Sep 12, 2017
@Karolusrex
Copy link

Karolusrex commented Aug 24, 2018

Great care has to be taken when implementing this feature, as the transformation lists might look different at start and end, but they can still be interpolated by the default value that is implied.

For example, interpolating between rotateZ(90deg) and scale(0.5, 0.5) would then be the same as interpolating between rotateZ(90deg) scale(1, 1) and rotateZ(0deg) scale(0.5, 0.5).

The user could also specify a transformation matrix on either of side of the transition, in which case it probably makes sense to reinterpret everything as matrices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants