Share Posted September 5, 2018 I am trying to use GSAP with React. In React I am creating a component with some text animations, for which I would I would like to create several instances at runtime. The main component should look like this: import React, { Component } from 'react'; import './App.css'; import { TimelineMax, Bounce} from 'gsap'; import Title from './Title.js'; let mainTimeline; class App extends Component { componentDidMount() { setTimeout(this.animate, 1000); } componentWillUnmount() { mainTimeline.kill(); } animate = () => { mainTimeline = new TimelineMax({ id: 'Everything' }); const titleTimeLine = new TimelineMax({ id: 'Title' }); const titleTimeLine2 = new TimelineMax({ id: 'Title2' }); mainTimeline.addLabel('start'); // get external timelines titleTimeLine.add(this.title.timelineEnter); titleTimeLine2.add(this.title2.timelineEnter) mainTimeline .add(titleTimeLine, 'start') .addLabel("title2") .add(titleTimeLine2, 'title2') } render() { return ( <div className="App"> <Title text="The benefits are:" clipPathId="clipPath1" ref={(el) => { this.title = el; }}/> <Title text="This should work" clipPathId="clipPath2" ref={(el) => { this.title2 = el; }}/> </div> ); } } export default App; And the Tile component is: import React, { Component } from 'react'; import { TimelineMax, Power4, SlowMo} from 'gsap'; import './Title.css' class Title extends Component { constructor(props) { super(props); const { text, clipPathId } = this.props; } get timelineEnter() { const tl = new TimelineMax(); const duration = 1; tl.to(this.line, duration, {attr:{x1:120, x2:880}, ease:Power4.easeInOut}) .to([this.reveal, this.line], duration, {y:"+=120", ease:Power4.easeInOut}) .to(this.line, duration, {attr:{x1:500, x2:500}, ease:Power4.easeInOut}) .to(this.clipPathReveal, duration, {y: -180, scale: .3, transformOrigin:"50% 50%", ease:SlowMo.ease.config(0.7, 0.7, false)}) return tl; } render() { return ( <svg className="demo" viewBox="0 0 1000 500"> <defs> <clipPath id={this.props.clipPathId} ref={(el) => { this.theClipPath = el; }}> <rect ref={(el) => { this.reveal = el; }} x="0" y="-100" width="1000" height="250" fill="#000" /> </clipPath> </defs> <line ref={(el) => { this.line = el; }} x1="500" y1="150" x2="500" y2="150" strokeWidth="20" stroke="red"/> <g ref={(el) => { this.clipPathReveal = el; }} clipPath="url(#clipPath1)"> <text transform="translate(500 250)" fill="#3088Ef" textAnchor="middle" fontSize="80">{this.props.text}</text> </g> </svg> ); } } export default Title; The problem is that in the code: <g ref={(el) => { this.clipPathReveal = el; }} clipPath="url(#clipPath1)"> <text transform="translate(500 250)" fill="#3088Ef" textAnchor="middle" fontSize="80">{this.props.text}</text> </g> for the clipPath attribute, I need to pass a dynamic URL. Otherwise, it doesn't work correctly. Is there a way to pass a dynamic id to the URL in clipPath="url(#clipPath1)". Something like clipPath="url({dynamicURL})" or something? In the first instance of <Title>, it should produce clipPath="url(#clipPath1)", while in the second it should be clipPath="url(#clipPath2)" and so on. Link to post Share on other sites
Share Posted September 5, 2018 Hi Gilbert, I'll assume that the clipPathId passed in the components props is the url you want to add, right? If that's the case you can use template literals a feature from ES2015: <g ref={(el) => { this.clipPathReveal = el; }} clipPath={`url#${this.props.clipPathId}`}> If this is not what you're after, please let us know how the specific clip url is being passed. Happy Tweening!!! 2 Link to post Share on other sites
Author Share Posted September 5, 2018 Hi Rodrigo, Thanks. That didn't work, but this did work: <g ref={(el) => { this.clipPathReveal = el; }} clipPath={`url(#${this.props.clipPathId})`}> Your suggestion showed me the way 1 Link to post Share on other sites
Share Posted September 6, 2018 Ahh yeah the parenthesis, sorry SVG is not my thing. Unlucky you @PointC didn't answer this question , but glad to hear you were able to solve it Happy Tweening!!! 1 1 Link to post Share on other sites
Share Posted September 6, 2018 25 minutes ago, Rodrigo said: Unlucky you @PointC didn't answer this question , but glad to hear you were able to solve it My apologies. When I see React in the thread title I just assume the Rodrigo React Signal has been fired up and my services will not be necessary. 2 4 Link to post Share on other sites
Share Posted September 6, 2018 13 hours ago, PointC said: My apologies. When I see React in the thread title I just assume the Rodrigo React Signal has been fired up and my services will not be necessary. The signal is only visible at night, so it might be awhile before he actually sees it. Maybe you should fill that void. I hereby promote you to the role of Senior Daytime React Answering Manager, so you should start learning it. I think the basics are pretty easy to pickup, and being able to combine JavaScript with HTML/SVG is a joy. https://reactjs.org/ https://reactjs.org/tutorial/tutorial.html 6 Link to post Share on other sites
Share Posted September 6, 2018 19 minutes ago, OSUblake said: Maybe you should fill that void. I hereby promote you to the role of Senior Daytime React Answering Manager, so you should start learning it. Sounds good. It's officially item 1,437 on my 'to-do' list so I may not get to it until the year 2029. Unless you're gonna let me use your Blaketrix headjack so I can learn it in a few seconds. 3 3 Link to post Share on other sites
Share Posted September 7, 2018 18 hours ago, PointC said: Sounds good. It's officially item 1,437 on my 'to-do' list so I may not get to it until the year 2029. Unless you're gonna let me use your Blaketrix headjack so I can learn it in a few seconds. I feel you pain bruv! Link to post Share on other sites