Как интегрировать фоновую анимацию JS в мое приложение реакции? - PullRequest
0 голосов
/ 26 октября 2019

Я пытаюсь добавить анимацию светлячка в компонент в реагировать (и код, который я пытаюсь использовать, находится здесь https://codepen.io/celli/pen/xZgpvN). Если бы у меня была простая настройка HTML / CSS / Javascript, я бы зналчто делать, но я запутался в том, как интегрировать эту анимацию в контекст React и в область действия одного компонента. Где разместить код ниже? Как мне ссылаться на него внутри компонента?


var total=40,
    container=document.getElementById('container'),
    w=window.innerWidth,
    h=window.innerHeight,
    Tweens=[],
    SPs=1;



for (var i=total;i--;){ 
    var Div=document.createElement('div');
    TweenLite.set(Div,{attr:{class:'dot'},x:R(w),y:R(h),opacity:0});
    container.appendChild(Div); Anim(Div);  Tweens.push(Div);
};

function Anim(elm){ 
    elm.Tween=TweenLite.to(elm,R(20)+10,{bezier:{values:[{x:R(w),y:R(h)},{x:R(w),y:R(h)}]},opacity:R(1),scale:R(1)+0.5,delay:R(2),onComplete:Anim,onCompleteParams:[elm]})
};

for(var i=total;i--;){
  Tweens[i].Tween.play()};


function R(max){return Math.random()*max};

Во-вторых, куда мне поместить код CSS ниже?

body{
  background-color: #222222;
  overflow:hidden;
}

.dot{
  width:4px;
  height:4px;
  position:absolute;
  background-color:#ff00cc;
  box-shadow:0px 0px 10px 2px #ff00cc;
  border-radius: 20px;
  z-index:2;
}

#container {
width:100%; 
height:100%;
}

1 Ответ

1 голос
/ 27 октября 2019

React's page на Интеграция с другими библиотеками , вероятно, было бы наилучшим началом для начала.

Во-первых, вот пример, который можно запустить непосредственно в StackOverflow.

const {
  useRef,
  useLayoutEffect,
} = React
// import React, { useRef, useLayoutEffect } from 'react';

function R(max) {
  return Math.random() * max
};

function Background(props) {
  const {
    total = 40
  } = props
  const ref = useRef()

  useLayoutEffect(() => {
    const contanier = ref.current
    const w = window.innerWidth
    const h = window.innerHeight
    const dots = []

    function addAnimation(elm) {
      return TweenLite.to(elm, R(20) + 10, {
        bezier: {
          values: [{
            x: R(w),
            y: R(h)
          }, {
            x: R(w),
            y: R(h)
          }]
        },
        opacity: R(1),
        scale: R(1) + 0.5,
        delay: R(2),
        onComplete: addAnimation,
        onCompleteParams: [elm]
      })
    }

    for (let i = 0; i < total; i++) {
      const div = document.createElement('div')
      TweenLite.set(div, {
        attr: {
          class: 'dot'
        },
        x: R(w),
        y: R(h),
        opacity: 0
      })
      container.appendChild(div);
      const dot = addAnimation(div)
      dot.play()
      dots.push(dot)
    }
    
    return () => {
      // Clear animations and whatever here
      dots.forEach(dot=>dot.kill())
      container.innerHTML = ''
    }
  }, [total])
  return <div className="fireflies" ref={ref} />
}

function App() {
  return <Background total={25} / >
}

ReactDOM.render( <App / > , document.querySelector("#container"))
body {
  background-color: #222222;
  overflow: hidden;
}

.dot {
  width: 4px;
  height: 4px;
  position: absolute;
  background-color: #ff00cc;
  box-shadow: 0px 0px 10px 2px #ff00cc;
  border-radius: 20px;
  z-index: 2;
}

.fireflies {
  width: 100%;
  height: 100%;
}
<div id="container" />

<!-- React -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<!-- TweenMax -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.15.0/TweenMax.min.js"></script>

Теперь объяснение.

Небольшое примечание: на ранее упомянутой странице Интеграция с другими библиотеками сейчас используется класскомпоненты, но мне нравится использовать функциональные компоненты, потому что зацепки ₜₕₑ fᵤₜᵤᵣₑ. Я также преобразовал часть кода из старого es5 в новый современный es6, потому что современный js - это «f».

Основная идея заключается в том, что когда ваш компонент монтируется в первый раз, вы запускаете все начальные настройки внутри useLayoutEffect хука. По сути, это сводится к тому, что большинство ваших текущих js будут выбрасываться внутри этого хука.

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

Преимущество здесьв том, что с реакцией вы получаете возможность управлять аспектами вашей анимации с помощью реквизита - это продемонстрировано в примере, когда переменная total передается как опора.

Кроме того, поскольку React предоставляет способ получитьссылка на dom-узел через хук useRef, вы можете использовать его вместо document.querySelector('#contanier').

Куда поместить CSS

Лучшее место на самом деле зависит от того, как вы настроили свое реагирующее приложение.

Если у вас где-то есть шаблон HTML, вы можете просто добавить туда тег стиля или ссылку, как и в любом другом проекте. .

Если вы использовали create-реакции-приложение или у вас есть аналогичные настройки, вы можете просто импортировать их в свой компонент, импортировав таблицу стилей , используя css modules или по модеЛетающий src/index.css.

Другой вариант - использовать решения css-in-js, такие как emotion или styled-components, но к ним, вероятно, потребуется немного привыкнуть.

...