Логика вращения квадрата - PullRequest
       30

Логика вращения квадрата

0 голосов
/ 27 декабря 2018

Следующий код использует React.

У меня есть квадрат, расположенный под 45 градусов, который имеет четыре элемента.После нажатия на каждый элемент я хочу, чтобы квадрат повернул соответствующие градусы, чтобы элемент, по которому щелкнули, находился сверху.(На рисунке 3 выбрано в настоящее время).

Пожалуйста, смотрите примечания в коде.Я надеюсь, что это объясняет мою логику.

enter image description here

Вот код компонента:

class CentreCtrls extends React.Component {
  constructor(props) {
    super(props);
        this.state = {
            aboutUs: {
                activeCtrl: 0
            }
        }
  }

   // animate the square to rotate the relevant degrees 
   // so that the clicked element is at the top.
   // this logic is flawed and not working correctly
  componentDidUpdate() {
    const activeHeading = this.state.aboutUs.activeCtrl;
    const { centreCtrl } = this.refs;
    const style = centreCtrl.style;
    const currentDeg = parseInt(style.transform.slice(7, -4), 10);
    const position = this.getPosition(activeHeading, 0);
    const degRotation = position * 90;
    console.log('pos:', position, 'deg:', currentDeg, '-', degRotation);
    anime({
      targets: this.refs.centreCtrl,
      rotate: `-${currentDeg + degRotation}deg`,
      duration: 150,
      easing: 'linear',
    });
  }

  onClickHandler = e => 
        const ele = e.target;
    const i = ele.parentNode.getAttribute('data-i');
    this.setState({
      aboutUs: {
        activeCtrl: parseInt(i, 10),
      },
    });
  };


   // the purpose of this function is to find the current value
   // to be assigned to the 'data-i' property on element, this 'data-i'
   // is read in the above 'componentDidUpdate' function to animate
   // the square the relevant degrees so that the clicked square is at
   // top (where the purple 3 is in the image).
  getPosition = (i, activeHeading) => {
    const total = 3; // start: 0, ttl: 4
    let correctSeq = i;
    if (i === activeHeading) {
      correctSeq = 0;
     // if i == 2, then for our rotation purpose, its at position 3 in DOM
     // because of the way, DOM renders elements from left to right within
     // square
    } else if (i === 2) {
      correctSeq = 3;
    } else if (i === 3) {
      correctSeq = 2;
    }
    let pos = total - activeHeading + (correctSeq + 0);
    if (pos > 3) {
      pos = pos - 3;
    }
    return pos;
  };

  render() {
    const { data } = this.props;
    const activeHeading = this.state.aboutUs.activeCtrl;
    return (
      // using the react v15 style ref
      <div
        className="centreCtrl"
        ref="centreCtrl"
        style={{ transform: 'rotate(45deg)' }}
      >
        {data.map((entry, i) => {
          const j = this.getPosition(i, activeHeading);
          return (
            <div
              className="ctrl"
              key={i}
              data-i={j}
              id={`${entry.narrative.heading}`}
              onClick={this.onClickHandler}
            >
              <div
                className="textContainer"
                id={entry.narrative.heading}
                ref={`textRef${i}`}
              >
                {j}
              </div>
            </div>
          );
        })}
      </div>
    );
  }
}

Редактировать: Как я могузаставить логику вращения работать правильно.Более конкретно, я ищу информацию о том, что является лучшей логикой для вычисления вращения этого квадрата.Это выглядит намного проще, чем я предполагал.

1 Ответ

0 голосов
/ 28 декабря 2018

Если вы хотите повернуть по часовой стрелке, может помочь что-то вроде этого:

import React from "react";
import ReactDOM from "react-dom";
import styled from "styled-components";
import { Container, Square, Block, Top, Bottom } from './components';

const rotateRight = items => {
  const last = items.pop();
  items.unshift(last);
};

class App extends React.Component {
  state = {
    items: ["a", "b", "c", "d"],
    rotation: 0,
  };

  handleClick = i => {
    let start = i;
    let count = 0;
    let items = [...this.state.items];
    const end = items.length - 1;

    while (start <= end) {
      rotateRight(items);
      start += 1;
      count += 1;
    }

    this.setState(state => ({
      rotation: ((count * 90) % 360),
    }));
  };

  render() {
    const { items, rotation } = this.state;

    return (
      <Container>
        <Square rotation={rotation}>
          <Top>
            <Block onClick={() => this.handleClick(0)}>
              {items[0]}
            </Block>
            <Block onClick={() => this.handleClick(1)}>
              {items[1]}
            </Block>
          </Top>
          <Bottom>
            <Block onClick={() => this.handleClick(2)}>{
              items[2]}
            </Block>
            <Block onClick={() => this.handleClick(3)}>
              {items[3]}
            </Block>
          </Bottom>
        </Square>
      </Container>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Ссылка StackBlitz здесь .

...