Gilbert

Members
  • Content Count

    4
  • Joined

  • Last visited

Community Reputation

2 Newbie

About Gilbert

  • Rank
    Newbie
  1. 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
  2. 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.
  3. Rodrigo, Thanks a lot for your help. You are the BEST!!!
  4. I am experimenting with these title animations https://github.com/bigfanjs/react-titles and I want to sequence some titles. The questions that I have are: How can I pause or play the original animations? How can I sequence the animations (for each title)? - For example, play the first one, wait for .7 seconds and play the second one, etc. How can I set the initial position of each title? My code is: Here is the code I have: import React, { Component, Fragment } from "react"; import styled from "styled-components"; import * as titles from "react-titles"; import { TimelineMax, Power3 } from "gsap"; const mytitles = [ { component: "Title2", title: "This is ", subTitle: "Sweet", isOpen: false, size: 100, x: '50' }, { component: "Title6", title: "Let' see", subTitle: "if this works", isOpen: false, size: 400, x: '400' }, ] class Title extends Component { constructor(){ super(); this.renderTitle = this.renderTitle.bind(this); this.restartHandler = this.restartHandler.bind(this); this.tl = new TimelineMax({paused: true}); } state = { isOpen: false } restartHandler(){ const {tl} = this; tl.reversed( !tl.reversed() ); } componentDidMount(){ const {tl} = this; mytitles.forEach( (e,i) => { //tl.set(this.refs[e.component], {left:e.x, top:e.x}) tl.to( this.refs[e.component], 1, {x: e.size, y: e.size/3 , scale: 0.5, opacity: 0.5}, .5 * i ); }); tl.reverse(); } getComponent(e) { const ATitle = titles[e.component]; //ATitle.handleRest(); //const {t1} = this; //this.tl.set(this.refs[e.component], {left:e.x, top:e.x}) return( <div className="box" key={e.component} ref={e.component} > <ATitle size={e.size} text1={e.title} text2={e.subTitle} open="false" style={{ position: "absolute", x: " +e.x+" , y: " +e.x+", "fill": "orange" }} onComplete={this.handleComplete} /> </div> ) } renderTitle(e,i){ return( this.getComponent(e) ); } handleComplete = (status) => { /*const {selected, component} = this.state; if (!status && selected !== component) { this.setState({ component: selected, isOpen: true }); }*/ } render() { return( <div> <button onClick={this.restartHandler}>Toggle Tween</button> <div> {mytitles.map(this.renderTitle)} </div> </div> ) } } export default Title;