glamorous-native icon indicating copy to clipboard operation
glamorous-native copied to clipboard

Animated components

Open atticoos opened this issue 8 years ago • 9 comments

Animated components are currently unsupported.

It's unclear if there is additional work needed for Animated component styles, or if they can simply be passed into glamorous to create a glamorousComponentFactory.


Example of the end goal:

const glamorousAnimatedViewFactory = glamorous(Animated.View)

cont AnimatedFadeView = glamorousAnimatedViewFactory(styles.fadeView)

<AnimatedFadeView opacity={this.state.opacity} />

☝️ this will have a major appeal for animated components. Everyone feels the pain of having to use inline styles:

<AnimatedView style={[styles.fadeView, {opacity: this.state.opacity}]} />

atticoos avatar May 17 '17 16:05 atticoos

Gave this a shot, and it indeed works:

const glamorousAnimatedComponentFactory = glamorous(Animated.View)
const AnimatedView = glamorousAnimatedComponentFactory({
  height: 200,
  width: 200,
  margin: 20,
  backgroundColor: 'red',
})
AnimatedView.propsAreStyleOverrides = true

class FadeView extends React.Component {
  state = {opacity: new Animated.Value(1)}

  componentDidMount() {
    Animated.timing(
      this.state.opacity,
      {toValue: 0, duration: 1000},
    ).start()
  }

  render() {
    return (
      <AnimatedView opacity={this.state.opacity} />
    )
  }
}

atticoos avatar May 18 '17 14:05 atticoos

Looks really great. Two questions.

  1. Per this discussion is the following supported?
    <glamorous.Animated.View 
        height={200} 
        width={200}
        margin={20} 
        backgroundColor={red}
        opacity ={this.state.opacity}
    />  

You'd have to bake Animated into the API right? I think that was the consensus though.

  1. What about if I want to use a glamorRule to animate? I spent some time considering this one:
const glamorousAnimatedComponentFactory = glamorous(Animated.View)
const Row = glamorousAnimatedComponentFactory(
  {
    flexDirection: "row"
  },
  (props) => {
    const {top, right, bottom, left} = props
    const isAbsolute = [top, right, bottom, left].filter(p => typeof p === "number").length > 0
    return {
      position: isAbsolute ? "absolute" : "relative",
      top,
      right,
      bottom,
      left,
    }
  }
)

Will this not result in a creation of an new StyleSheet (cache number) for every frame?

ssomnoremac avatar May 18 '17 15:05 ssomnoremac

Great timing! In #23 I added basic support for allowing animated components to be detected as known "root elements", such that it will detect supported style properties when doing something like:

const glamorousAnimatedComponentFactory = glamorous(Animated.View)
const AnimatedView = glamorousAnimatedComponentFactory()
AnimatedView.propsAreStyleOverrides = true

<AnimatedView width={500} height={500} />

This is just the starting point.

Still todo:

Convenience built-ins

Mentioned in #23, this does not include the built-in factory functions or components. I'd like to still think about naming conventions. For example

<glamorous.Animated.View />
<glamorous.AnimatedView />
glamorous.animatedView()
glamorous.animated.view()

I do lean towards keeping it 1-1 with React Native and using glamorous.Animated.View


What about if I want to use a glamorRule to animate? I spent some time considering this one:

Haven't played with this yet! But the following should technically work:

const glamorousAnimatedComponentFactory = glamorous(Animated.View)
const Component = glamorousAnimatedComponentFactory(
  props => ({opacity: props.opacity})
)

<Component opacity={this.state.opacityAnimatedValue} />

Will this not result in a creation of an new StyleSheet (cache number) for every frame?

Currently dynamic styles are uncached, and I had meant to add an issue for optimizations/caching -- feel free to open!

atticoos avatar May 18 '17 15:05 atticoos

yes, but what what about the caching of the glamorRule?

Will this not result in a creation of an new StyleSheet (cache number) for every frame?

ssomnoremac avatar May 18 '17 15:05 ssomnoremac

I snuck an edit in there after re-reading that:

Currently dynamic styles are uncached, and I had meant to add an issue for optimizations/caching -- feel free to open!

atticoos avatar May 18 '17 15:05 atticoos

👍 let's continue the discussion there.

ssomnoremac avatar May 18 '17 15:05 ssomnoremac

Hi, I'd also like to have glamorous.Animated.View available by default that would be convenient

slorber avatar Jan 09 '18 12:01 slorber

Note that I tried the code above but RN issues a lot of warnings:

YellowBox.js:82 You are setting the style { height: ... } as a prop. You should nest it in a style object. E.g. { style: { height: ... } }

Edit: it's fine I just forgot the AnimatedView.propsAreStyleOverrides = true;

slorber avatar Jan 09 '18 12:01 slorber

Just an idea but what about this syntax?

<View animated opacity={animatedValue}/>

slorber avatar Feb 02 '18 13:02 slorber