在点击按钮时触发gsap动画



我有一个简单的GSAP动画,我想只在应用程序等待请求完成时运行。我可以让动画在默认情况下运行,但我现在遇到的问题是,当我试图在onClick函数中触发它时,动画似乎有时会启动,有时不会,我似乎无法追踪它背后的韵律或原因。我有一种预感,这与我试图播放时间轴和揭示组件的时间有关,但我不完全确定这一点,到目前为止,我在移动timeline.play()时的修修补补和尝试并没有看到太大的成功。

代码:

App.js

import React, { useState, useRef, useLayoutEffect } from 'react';
import { gsap } from 'gsap';
import './App.css';
import DataInput from './Components/data-input';
import Footer from './Components/footer';
import Header from './Components/header';
import RedBall from './Components/red-ball';
const timeline = gsap.timeline({paused: true, repeat: -1, yoyo: true});
function App() {
const [messageData, setMessageData] = useState(null);
const [zipData, setZipData] = useState(null);
const [screenShotData, setScreenshotData] = useState(null);
const [statusMessage, showStatusMessage] = useState(false);
const tl = useRef(timeline);
const app = useRef(null);
let zipBlob;
let zipDownload;
let url;
useLayoutEffect(() => {
const ctx = gsap.context(() => {
tl.current.fromTo('.red-ball', .5, {autoAlpha: 0, x: 0}, {autoAlpha: 1, x: 20});
}, app.current);
return () => ctx.revert();
}, []);
const getScreenshotData = (screenShotData) => {
setScreenshotData(screenShotData);
showStatusMessage(true);
setMessageData('');
setZipData('');
timeline.play();
fetch(`/dcsgrab?tearsheetUrl=${screenShotData}`)
.then((response) => response.json())
.then((data) => {
zipBlob = new Blob([new Uint8Array(data.zipFile.data)], {type: "octet/stream"});
url = window.URL.createObjectURL(zipBlob);
zipDownload = document.createElement("a");
setMessageData(data.message);
setZipData(zipBlob);
zipDownload.href = url;
zipDownload.download = "screenshot-download.zip";
document.body.appendChild(zipDownload);
zipDownload.click();
console.log(zipBlob);
console.log([new Uint8Array(data.zipFile.data)]);
console.log(data);
});
};
return (
<div className="App" ref={app}>
<Header />
<DataInput getScreenshotData={getScreenshotData} />
{
!statusMessage ? '' : <p>{!messageData ? 'Taking screenshots...' : messageData}</p>
}
{
!statusMessage ? '' : <div className="waiting-anim-container">{!messageData ? <RedBall /> : ''}</div>
}
<Footer />
</div>
);
}
export default App;

red-ball.js

export default function RedBall() {
return <div className="red-ball"></div>;
}

data-input.js

import React from 'react';
import { useState } from 'react';
function DataInputForm({ getScreenshotData }) {
const [tearsheetUrl, setTearsheetUrl] = useState('');
return (
<div>
<form>
<input 
id='tearsheetUrl'
name='tearsheetUrl'
placeholder='input tearsheet url'
type='text'
value={tearsheetUrl}
onChange={(event) => setTearsheetUrl(event.target.value)}
/>
</form>
<button id="submit-data" onClick={() => getScreenshotData(tearsheetUrl)}>SUBMIT</button>
</div>
);
}
export default DataInputForm;

好的,所以我能够弄清楚这个。最终,我必须将redball组件的预期动画行为与实际状态联系起来,这是有意义的,因为这是React。我一开始能够让动画在点击按钮时发挥作用,但后来在特定动作完成后,它就会消失。下面的代码通过触发css类soft-hide来处理这个问题,具体取决于hideClass的状态。

特别重要的行是:

const [hideClass, toggleHideClass] = useState(true);

let redBallContainerClasses = !hideClass ? 'waiting-anim-container' : 'waiting-anim-container soft-hide';

toggleHideClass(false);

toggleHideClass(true);

<div className={redBallContainerClasses}><RedBall /></div>

完整代码:

import React, { useState, useRef, useLayoutEffect } from 'react';
import { gsap } from 'gsap';
import './App.css';
import DataInput from './Components/data-input';
import Footer from './Components/footer';
import Header from './Components/header';
import RedBall from './Components/red-ball';
const timeline = gsap.timeline({paused: true, repeat: -1, yoyo: true});
function App() {
const [messageData, setMessageData] = useState(null);
const [statusMessage, showStatusMessage] = useState(false);
const [hideClass, toggleHideClass] = useState(true);
const tl = useRef(timeline);
const app = useRef(null);
let zipBlob;
let zipDownload;
let url;
let redBallContainerClasses = !hideClass ? 'waiting-anim-container' : 'waiting-anim-container soft-hide';
useLayoutEffect(() => {
const ctx = gsap.context(() => {
tl.current.fromTo('.red-ball', .5, {autoAlpha: 0}, {autoAlpha: 1, scale: 2});
}, app.current);
return () => ctx.revert();
}, []);
const getScreenshotData = (screenShotData) => {
showStatusMessage(true);
setMessageData('');
toggleHideClass(false);
timeline.revert();
timeline.play();
fetch(`/dcsgrab?tearsheetUrl=${screenShotData}`)
.then((response) => response.json())
.then((data) => {
zipBlob = new Blob([new Uint8Array(data.zipFile.data)], {type: "octet/stream"});
url = window.URL.createObjectURL(zipBlob);
zipDownload = document.createElement("a");
toggleHideClass(true);
timeline.revert();
setMessageData(data.message);
zipDownload.href = url;
zipDownload.download = "screenshot-download.zip";
document.body.appendChild(zipDownload);
zipDownload.click();
console.log(zipBlob);
console.log([new Uint8Array(data.zipFile.data)]);
console.log(data);
});
};
return (
<div className="App" ref={app}>
<Header />
<DataInput getScreenshotData={getScreenshotData} />
{
!statusMessage ? '' : <p>{!messageData ? 'Taking screenshots...' : messageData}</p>
}
<div className={redBallContainerClasses}><RedBall /></div>
<Footer />
</div>
);
}
export default App;

相关内容

  • 没有找到相关文章

最新更新