在 React 中再次触发动画时重置动画(使用钩子)- 滑动文本
Resetting an animation when it is triggered again in React (using hooks) - Sliding Text
我正在构建一个连接到 Spotify 的简单音乐应用程序。
如果 song/artist 的名称太 long(文本溢出),animation 会制作文本的相邻副本,然后它幻灯片他们两个离开了 - 无限。
问题是,如果长文本已被另一个长文本替换,则动画不会重置,而只是从中间继续。
我尝试删除 class 然后立即添加它,但这种方法不起作用。
class 被称为“active_animation”,它是用 React 有条件地渲染的。
变量isOverflowingTitle
和isOverflowingNames
,当设置为真时,激活动画。每当有新歌更新时,useEffect
就会被触发。
这是我的代码:
import React, { useContext, useRef, useEffect, useState } from 'react';
import ArtistsLinksBySong from '../ArtistsLinksBySong';
import { PlayerSourceContext } from '../../store/PlayerSourceContext';
export default () => {
const [playerSource] = useContext(PlayerSourceContext);
const containerTagRef = useRef(null);
const songTitleTag = useRef(null);
const artistNamesTag = useRef(null);
const [isOverflowingTitle, setIsOverflowingTitle] = useState(false);
const [isOverflowingNames, setIsOverflowingNames] = useState(false);
useEffect(() => {
let mainPixelWidth = containerTagRef.current.clientWidth;
artistNamesTag.current.clientWidth > mainPixelWidth - 16
? setIsOverflowingNames(true)
: setIsOverflowingNames(false);
songTitleTag.current.clientWidth > mainPixelWidth - 16
? setIsOverflowingTitle(true)
: setIsOverflowingTitle(false);
}, [playerSource]);
const getSongArtists = () => {
if (playerSource.artists) {
return <ArtistsLinksBySong artistArrOfObj={playerSource.artists} />;
} else {
return 'Artist Name';
}
};
const getSongTitle = () => {
if (playerSource.name) {
return String(playerSource.name);
} else {
return 'Track Title';
}
};
return (
<div id='player-song-text-container' ref={containerTagRef}>
<div id='title-name-text'>
<div id='move-control'>
<div
id='move1'
ref={songTitleTag}
className={isOverflowingTitle ? 'active_animation' : ''}
>
{getSongTitle()}
</div>
{isOverflowingTitle && (
<div className='adjacent-copy'>{getSongTitle()}</div>
)}
</div>
</div>
<div id='artists-names-text'>
<div id='move-control2'>
<div
id='move2'
ref={artistNamesTag}
className={isOverflowingNames ? 'active_animation' : ''}
>
{getSongArtists()}
</div>
{isOverflowingNames && (
<div className='adjacent-copy'>{getSongArtists()}</div>
)}
</div>
</div>
<div id='left-shade'></div>
<div id='right-shade'></div>
</div>
);
};
你们会如何解决这个问题?
顺便说一句,这是回购协议:https://github.com/itayperry/react_spotify_player
这似乎是不好的做法 - 但这个 setTimeout(() => {....}, 0)
解决了问题:
useEffect(() => {
let mainPixelWidth = containerTagRef.current.clientWidth;
setTimeout(() => {
artistNamesTag.current.clientWidth > mainPixelWidth - 16
? setIsOverflowingNames(true)
: setIsOverflowingNames(false);
songTitleTag.current.clientWidth > mainPixelWidth - 16
? setIsOverflowingTitle(true)
: setIsOverflowingTitle(false);
}, 0);
return () => {
setIsOverflowingNames(false); // reset this animation
setIsOverflowingTitle(false); // reset this animation
};
}, [playerSource]);
我正在构建一个连接到 Spotify 的简单音乐应用程序。 如果 song/artist 的名称太 long(文本溢出),animation 会制作文本的相邻副本,然后它幻灯片他们两个离开了 - 无限。
问题是,如果长文本已被另一个长文本替换,则动画不会重置,而只是从中间继续。 我尝试删除 class 然后立即添加它,但这种方法不起作用。
class 被称为“active_animation”,它是用 React 有条件地渲染的。
变量isOverflowingTitle
和isOverflowingNames
,当设置为真时,激活动画。每当有新歌更新时,useEffect
就会被触发。
这是我的代码:
import React, { useContext, useRef, useEffect, useState } from 'react';
import ArtistsLinksBySong from '../ArtistsLinksBySong';
import { PlayerSourceContext } from '../../store/PlayerSourceContext';
export default () => {
const [playerSource] = useContext(PlayerSourceContext);
const containerTagRef = useRef(null);
const songTitleTag = useRef(null);
const artistNamesTag = useRef(null);
const [isOverflowingTitle, setIsOverflowingTitle] = useState(false);
const [isOverflowingNames, setIsOverflowingNames] = useState(false);
useEffect(() => {
let mainPixelWidth = containerTagRef.current.clientWidth;
artistNamesTag.current.clientWidth > mainPixelWidth - 16
? setIsOverflowingNames(true)
: setIsOverflowingNames(false);
songTitleTag.current.clientWidth > mainPixelWidth - 16
? setIsOverflowingTitle(true)
: setIsOverflowingTitle(false);
}, [playerSource]);
const getSongArtists = () => {
if (playerSource.artists) {
return <ArtistsLinksBySong artistArrOfObj={playerSource.artists} />;
} else {
return 'Artist Name';
}
};
const getSongTitle = () => {
if (playerSource.name) {
return String(playerSource.name);
} else {
return 'Track Title';
}
};
return (
<div id='player-song-text-container' ref={containerTagRef}>
<div id='title-name-text'>
<div id='move-control'>
<div
id='move1'
ref={songTitleTag}
className={isOverflowingTitle ? 'active_animation' : ''}
>
{getSongTitle()}
</div>
{isOverflowingTitle && (
<div className='adjacent-copy'>{getSongTitle()}</div>
)}
</div>
</div>
<div id='artists-names-text'>
<div id='move-control2'>
<div
id='move2'
ref={artistNamesTag}
className={isOverflowingNames ? 'active_animation' : ''}
>
{getSongArtists()}
</div>
{isOverflowingNames && (
<div className='adjacent-copy'>{getSongArtists()}</div>
)}
</div>
</div>
<div id='left-shade'></div>
<div id='right-shade'></div>
</div>
);
};
你们会如何解决这个问题?
顺便说一句,这是回购协议:https://github.com/itayperry/react_spotify_player
这似乎是不好的做法 - 但这个 setTimeout(() => {....}, 0)
解决了问题:
useEffect(() => {
let mainPixelWidth = containerTagRef.current.clientWidth;
setTimeout(() => {
artistNamesTag.current.clientWidth > mainPixelWidth - 16
? setIsOverflowingNames(true)
: setIsOverflowingNames(false);
songTitleTag.current.clientWidth > mainPixelWidth - 16
? setIsOverflowingTitle(true)
: setIsOverflowingTitle(false);
}, 0);
return () => {
setIsOverflowingNames(false); // reset this animation
setIsOverflowingTitle(false); // reset this animation
};
}, [playerSource]);