Jump to content


  • Posts

  • Joined

  • Last visited

Everything posted by Gilbert

  1. @Shrug ¯\_(ツ)_/¯ Thanks. That's what I was looking for.
  2. I would like to know whether or not there are methods in GSAP to animate perspectives. In the codepen I am using a js library call perspective transform. Is there something equivalent on GSAP that besides allowing to edit the 4 points manually allows to animate them? Or how to use this library to animate those points with GSAP
  3. @chrisgannon, thanks for the detailed explanation. I also came from Flash (Flex) and I was doing mainly visualization stuff. After Flash I learned D3 and I was doing lots of experiments with Edge Animate. Now, I am exploring what I can do to combine video with animation overlays with GSAP. (on my free time)
  4. Hi Shrug. yeah, I read the post. However, after so many years maybe others have some ideas of to achieve that with new techniques and tools, and of course, GSAP has evolved as well.
  5. Hi Zach. I agree. But he didn't say how he built it. So, I wanted to get some ideas from the forum on how to do something like that.
  6. In this video, Chris Gannon shows how he uses a motion tracker based on GSAP (this is from 2014). Any pointers on how to achieve something like this?
  7. hi @Shaun Gorneau, Thanks a lot. That works
  8. Let's say I have this animation: tl.to('.video-react-video', {left: '-=325px', duration: 1, ease: "back.out(2.5)"}, 9); How can I replace left: '-=325px' with left: '-=someVar' I tried creating a variable as const someVar = '325px'; and then use it as tl.to('.video-react-video', {left: '-=someVar', duration: 1, ease: "back.out(2.5)"}, 9); but it doesn't work. What would be the right syntax?
  9. 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
  10. 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.
  11. Rodrigo, Thanks a lot for your help. You are the BEST!!!
  12. 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;