React Spring - 动画列表 - 一次列表中的一项
React Spring - Animate list - one item in list at a time
给定一个列表:
li {
display: inline-block;
color: #000000;
}
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
使用 react-spring,我试图每 3 秒为列表中的每个项目(一个接一个)设置动画效果,并从头到尾循环。
例如:
- 来自 - 颜色以黑色开始
- 输入 - 颜色变为红色
- 离开 - 颜色变回黑色
我可以让单个项目显示并更新颜色然后隐藏(因为列表中只有 1 个项目正在动画),但不是整个列表来显示和改变每个项目的颜色 1 到 1 .
const ColourListTransition = (items, delay) => {
const [index, setIndex ] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setIndex((state) => ( state + 1 ) % items.length);
}, delay);
return () => clearInterval(interval);
}, []);
return useTransition(items[index], {
from: { color: '#000000' },
enter: { color: "#FF0000" },
leave: { color: "#000000" },
loop: true,
config: config.molasses
})
}
{ ColourListTransition(['item 1', 'item 2', 'item 3', 'item 4'], 3000)(({ color }, item) => (
<animated.li
key={ item }
style={ { color, display: 'inline-block', listStyleType: 'none' } }
>
{ item }
</animated.li>
)) }
我玩过 useTransition
但我就是想不通。当我改为使用 useSprings
时很容易。所以这可能不是最优雅的解决方案,但它确实有效。
我们创建了一组 spring 动画,它们对应于您列表中的项目。每个项目的颜色基于其索引是否与状态中的活动索引匹配。 enter
和 leave
在这里并没有真正发挥作用,因为数组中总是有相同的 4 个项目。我让你的 useState
和 useEffect
挂钩保持不变。
import React, { useState, useEffect } from "react";
import { animated, config, useSprings } from "@react-spring/web";
const ColourListTransition = ({delay, items, activeColor, inactiveColor}) => {
const [index, setIndex] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setIndex((state) => (state + 1) % items.length);
}, delay);
return () => clearInterval(interval);
}, []);
const [springs] = useSprings(
// count
items.length,
// properties as a function of index
(i) => ({
// determine the current color based on the index
color: i === index ? activeColor : inactiveColor,
// all items start out black
from: { color: inactiveColor },
config: config.molasses
}),
// dependency on index state
[index]
);
return (
<ul>
{springs.map(({ color }, i) => (
<animated.li
key={items[i]}
style={{ color, display: "inline-block", listStyleType: "none" }}
>
{items[i]}
</animated.li>
))}
</ul>
);
};
export default function App() {
return (
<ColourListTransition
items={["item 1", "item 2", "item 3", "item 4"]}
delay={3000}
activeColor={"#FF0000"}
inactiveColor={"#000000"}
/>
);
}
给定一个列表:
li {
display: inline-block;
color: #000000;
}
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
使用 react-spring,我试图每 3 秒为列表中的每个项目(一个接一个)设置动画效果,并从头到尾循环。
例如:
- 来自 - 颜色以黑色开始
- 输入 - 颜色变为红色
- 离开 - 颜色变回黑色
我可以让单个项目显示并更新颜色然后隐藏(因为列表中只有 1 个项目正在动画),但不是整个列表来显示和改变每个项目的颜色 1 到 1 .
const ColourListTransition = (items, delay) => {
const [index, setIndex ] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setIndex((state) => ( state + 1 ) % items.length);
}, delay);
return () => clearInterval(interval);
}, []);
return useTransition(items[index], {
from: { color: '#000000' },
enter: { color: "#FF0000" },
leave: { color: "#000000" },
loop: true,
config: config.molasses
})
}
{ ColourListTransition(['item 1', 'item 2', 'item 3', 'item 4'], 3000)(({ color }, item) => (
<animated.li
key={ item }
style={ { color, display: 'inline-block', listStyleType: 'none' } }
>
{ item }
</animated.li>
)) }
我玩过 useTransition
但我就是想不通。当我改为使用 useSprings
时很容易。所以这可能不是最优雅的解决方案,但它确实有效。
我们创建了一组 spring 动画,它们对应于您列表中的项目。每个项目的颜色基于其索引是否与状态中的活动索引匹配。 enter
和 leave
在这里并没有真正发挥作用,因为数组中总是有相同的 4 个项目。我让你的 useState
和 useEffect
挂钩保持不变。
import React, { useState, useEffect } from "react";
import { animated, config, useSprings } from "@react-spring/web";
const ColourListTransition = ({delay, items, activeColor, inactiveColor}) => {
const [index, setIndex] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setIndex((state) => (state + 1) % items.length);
}, delay);
return () => clearInterval(interval);
}, []);
const [springs] = useSprings(
// count
items.length,
// properties as a function of index
(i) => ({
// determine the current color based on the index
color: i === index ? activeColor : inactiveColor,
// all items start out black
from: { color: inactiveColor },
config: config.molasses
}),
// dependency on index state
[index]
);
return (
<ul>
{springs.map(({ color }, i) => (
<animated.li
key={items[i]}
style={{ color, display: "inline-block", listStyleType: "none" }}
>
{items[i]}
</animated.li>
))}
</ul>
);
};
export default function App() {
return (
<ColourListTransition
items={["item 1", "item 2", "item 3", "item 4"]}
delay={3000}
activeColor={"#FF0000"}
inactiveColor={"#000000"}
/>
);
}