React-spring: [v9] return array from to/interpolate breaks transform

Created on 15 Oct 2019  路  3Comments  路  Source: pmndrs/react-spring

馃悰 Bug Report

Returning an array (multiple statements) from to/interpolate results in no transform being applied to the target element.

To Reproduce

const [animatedX] = React.useState(() => new SpringValue(10));
const [animatedY] = React.useState(() => new SpringValue(10));
const [animatedScale] = React.useState(() => new SpringValue(1));

const transform = to(
  [animatedX, animatedY, animatedScale],
  (offsetX, offsetY, scale) => [
    `translate(${offsetX}px, ${offsetY}px)`,
    `scale(${scale})`
  ]
);

Neither the translate or the scale style is applied to the element.

Expected behavior

The translate and the scale style is applied to the element.

Workaround

Use a transform matrix, which can combine transform and scale (and also rotate).

Link to repro (highly encouraged)

https://codesandbox.io/s/elastic-firefly-du2uy

Environment

  • react-spring v9.0.0-canary.808.8.4a87fcb
  • react v16.8.6
bug invalid

All 3 comments

Okay, when combining the both styles like this:

const transform = to(
    [animatedX, animatedY, animatedScale],
    (offsetX, offsetY, scale) =>
      `translate(${offsetX}px, ${offsetY}px) scale(${scale})`
  );

Everything seems to work fine. I think this solves the issue.

With react-dom, you can't use an array for the transform prop. Maybe you got confused with how react-native does things?

Anyway, you can make it even easier on yourself by doing it this way:

import { useSpring, animated } from 'react-spring'

// Create the animated values
const style = useSpring({ translate: [10, 10], scale: 1 })

// Put them in the style
return <animated.div style={{ ...style, backgroundColor: 'red', width: 100, height: 100 }} />

This works, because translate and scale are specially handled by the animated.div (thanks to #782). Note: This only works with react-spring/web currently.

@aleclarson Good to know, I must have mixed things up 馃槄

This is pretty cool! I created a new Sandbox for the method you mentioned:

https://codesandbox.io/s/eloquent-pine-d1mfb


I really like using SpringValue for two-way binding tasks. I wish React had this built-in for stuff like range sliders etc.

There should definitely a section for this in the docs!


I also wanted to ask you: What is your opinion on using SpringValue as a two way data binding:

https://codesandbox.io/s/throbbing-cherry-dzb4i

This example uses either the passed in SpringValue (which makes it controllable by the parent component) or uses its own local SpringValue in case no SpringValues are passed to the component instance.

Do you classify this a feature (and valid use-case) of this library or either something that is a hack?

Was this page helpful?
0 / 5 - 0 ratings