问题
I'm trying to add a firefly animation into a component within react (and the code I'm trying to use is here https://codepen.io/celli/pen/xZgpvN). If I had a simple HTML / CSS / Javascript setup I'd know what to do, but I'm confused on how to integration this animation in the context of React and in the scope of a single component. Where do I put the code below? How do I reference it within the component?
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};
Secondly, where do I put the CSS code below?
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:
React's page on Integrating With Other Libraries would probably be the best place to start.
Firstly, here's an example that can be run directly on 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>
Now the explanation.
A quick side note: the previously mentioned Integrating With Other Libraries page as of right now uses class components, but I like to use functional components because hooks are ₜₕₑ fᵤₜᵤᵣₑ. I also converted some of the code from old es5 to new modern es6 because modern js is ₜₕₑ fᵤₜᵤᵣₑ.
The basic idea is that when your component is first mounted, you run all the initial setup inside of a useLayoutEffect hook. That essentially boils down to throwing most of your current js inside of that hook.
The only thing the component needs to render is the div that will contain all of the dots.
The advantage here is that with react, you get to control aspects of your animation with props--demonstrated in the example by allowing the total
variable to be passed as a prop.
Also, since React provides a way to get a reference to a dom node via the useRef hook, you can use that instead of document.querySelector('#contanier')
.
Where do I put the CSS
The best place really depends on how you set up your react application.
If you have an HTML template somewhere, you can just throw a style tag or a link tag in there as you would any other project.
If you used create-react-app or have a similar setup then you might just import them into your component by importing the stylesheet, by using css modules, or by modifying src/index.css
.
Another option is to use css-in-js solutions such as emotion
or styled-components
but those will probably take a little getting used to.
来源:https://stackoverflow.com/questions/58574393/how-do-i-integrate-a-background-js-animation-into-my-react-app