sghall / react-move

React Move | Beautiful, data-driven animations for React
https://react-move-docs.netlify.app
MIT License
6.58k stars 168 forks source link

How to continue to move to next position #85

Open wiryonolau opened 2 years ago

wiryonolau commented 2 years ago

Hi from your example in https://react-move-docs.netlify.app/demos/simple

The first animate in that page, it's toggle the x value to either 200 or 0 when click. How do I make it run another 200 instead of revert to 0 but base on click ? If the inital position.left is 0 it become 200 on first click and 400 on second click and so on.

import React, { PureComponent } from 'react'
import { Animate } from 'react-move'
import { easeExpOut } from 'd3-ease'

const trackStyles = {
  borderRadius: 4,
  backgroundColor: 'rgba(255, 255, 255, 0.7)',
  position: 'relative',
  margin: '5px 3px 10px',
  width: 250,
  height: 50,
}

class Example extends PureComponent {
  state = {
    open: false,
  }

  handleClick = () => {
    this.setState({ open: !this.state.open })
  }

  render() {
    return (
      <div>
        <button
          onClick={this.handleClick}
        >
          Toggle
        </button>
        <Animate
          start={() => ({
            x: 0,
          })}

          update={() => ({
            x: [this.state.open ? 200 : 0],
            timing: { duration: 750, ease: easeExpOut },
          })}
        >
          {(state) => {
            const { x } = state

            return (
              <div style={trackStyles}>
                <div
                  style={{
                    position: 'absolute',
                    width: 50,
                    height: 50,
                    borderRadius: 4,
                    opacity: 0.7,
                    backgroundColor: '#ff69b4',
                    WebkitTransform: `translate3d(${x}px, 0, 0)`,
                    transform: `translate3d(${x}px, 0, 0)`,
                  }}
                />
              </div>
            )
          }}
        </Animate>
      </div>
    )
  }
}
wiryonolau commented 2 years ago

I come up with this, is this correct ?

import React from "https://cdn.skypack.dev/react@17.0.1";
import ReactDOM from  "https://cdn.skypack.dev/react-dom@17.0.1";
import { Animate } from "https://cdn.skypack.dev/react-move@6.5.0";

const Box = function (props) {
  let [style, setStyle] = React.useState({});
  let [newX, setNewX] = React.useState(0);
  React.useEffect(() => {
    console.log(props.s.x);
    setNewX((prev) => {
      if (props.direction == "forward") {
        return prev + (props.s.x - prev);
      } else {
        return props.s.x;
      }
    });

    setStyle({
        position: "absolute",
        width: 50,
        height: 50,
        borderRadius: 4,
        opacity: 0.7,
        backgroundColor: "#ff69b4",
        WebkitTransform: `translate3d(${newX}px, 0, 0)`,
        transform: `translate3d(${newX}px, 0, 0)`
    })
  }, [props.s.x, props.direction]);

  return (
    <div
      style={style}
    />
  );
};

const Component = function (props) {
  let [newX, setNewX] = React.useState(0);
  let [direction, setDirection] = React.useState("forward");

  let reverseClick = () => {
    setDirection("reverse");
    setNewX((prev) => { return (prev - 200); });     
  }

  let forwardClick = () => {
    setDirection("forward");
    setNewX((prev) => { return (prev + 200); });        
  };

  return (
    <div>
      <button onClick={reverseClick}>Reverse</button>
      <button onClick={forwardClick}>Foward</button>
      <Animate
        start={() => ({
            x: 0,
        })}
        update={() => ({
          x: [newX],
          timing: { duration: 750 }
        })}
      >
        {(s) => {
          return <Box s={s} direction={direction} />;
        }}
      </Animate>
    </div>
  );
};

ReactDOM.render(<Component />, document.getElementById("root"));