每当 <img src={value} /> src 值改变时触发动画
trigger animation whenever the <img src={value} /> src value changes
我正在使用 React 创建一个 img
元素,该元素在特定时间后使用 setInterval
函数根据包含许多图像的数组更改其 src
属性。
所以我想在 src
属性发生变化时制作动画,我正在考虑使用 React.useEffect()
钩子来观察 src
变化并添加一些动画但是我无法在逻辑上更进一步。
我的代码:
import Canada from "../images/Canada.jpg"
import Tokyo from "../images/Tokyo.jpg"
import NewYork from "../images/NewYork.jpg"
import southKorea from "../images/southKorea.jpg"
function AboutMe() {
const imgArray = [NewYork, Tokyo, Canada, southKorea]
let i = 0;
const maxImgArray = imgArray.length -1 ;
const swap = function() {
let image = imgArray[i];
i = (i === maxImgArray) ? 0 : ++i;
const attr = document.getElementById("moving-image");
attr.src=image;
}
setInterval(swap, 5000)
return (
<section className="About-me">
<h1>About me</h1>
<div className="container">
<div className="cities-images">
<img
src={Tokyo}
alt="NewYork" id="moving-image"></img>
<label class="switch">
<input type="checkbox"/>
<span class="slider round"></span>
</label>
</div>
<div className="info">
</div>
</div>
</section>
)
}
通过在 React 中使用 useState
钩子,我们可以 re-render 具有更新值的组件。所以对于src
的改变,我们可以使用useState来更新图片的当前src。
通过使用 useEffect
钩子,我们可以在 src
状态改变后做任何事情,比如设置不同的动画。
组件状态
const [image, setImage] = useState(Usa);
const [imageIndex, setImageIndex] = useState(0);
const imgArray = [Usa, Japan, Canada, SouthKorea];
useEffect
useEffect(() => {
let interval = null;
if (i !== maxImgArray) {
interval = setInterval(() => {
let image = imgArray[imageIndex];
const attr = document.getElementById("moving-image");
attr.src = image;
// update the img index to state
setImageIndex((imageIndex) =>
imageIndex === maxImgArray ? 0 : imageIndex + 1
);
// update the src in state.
setImage(attr.src);
}, 3000);
}
// When our code runs and reruns for every render, useEffect also cleans up after itself using the cleanup function.
// Here we clear the interval to remove the effects that could happen with state change while interval.
return () => clearInterval(interval);
}, [image, imageIndex]); // when image, imageIndex gets change, useEffect will be triggered.
组件这里我用了framer-motion做动画
<section className="Country-flag">
<h1>Country Flag</h1>
<div className="container">
<motion.div
key={image}
animate={{ x: 100, opacity: 1 }}
transition={{
delay: 1,
x: { type: "spring", stiffness: 100 },
default: { duration: 2 }
}}
>
{/* when state {image} value change, this component will re-render with new src */}
<img alt="NewYork" src={image} id="moving-image"></img>
</motion.div>
<div className="info"></div>
</div>
</section>
检查此示例 sandbox 以获取生成的代码。
如果您希望每个 img 有不同的动画,则为动画添加另一个状态变量,并为每个图像状态更改 useEffect 中的值。
我正在使用 React 创建一个 img
元素,该元素在特定时间后使用 setInterval
函数根据包含许多图像的数组更改其 src
属性。
所以我想在 src
属性发生变化时制作动画,我正在考虑使用 React.useEffect()
钩子来观察 src
变化并添加一些动画但是我无法在逻辑上更进一步。
我的代码:
import Canada from "../images/Canada.jpg"
import Tokyo from "../images/Tokyo.jpg"
import NewYork from "../images/NewYork.jpg"
import southKorea from "../images/southKorea.jpg"
function AboutMe() {
const imgArray = [NewYork, Tokyo, Canada, southKorea]
let i = 0;
const maxImgArray = imgArray.length -1 ;
const swap = function() {
let image = imgArray[i];
i = (i === maxImgArray) ? 0 : ++i;
const attr = document.getElementById("moving-image");
attr.src=image;
}
setInterval(swap, 5000)
return (
<section className="About-me">
<h1>About me</h1>
<div className="container">
<div className="cities-images">
<img
src={Tokyo}
alt="NewYork" id="moving-image"></img>
<label class="switch">
<input type="checkbox"/>
<span class="slider round"></span>
</label>
</div>
<div className="info">
</div>
</div>
</section>
)
}
通过在 React 中使用 useState
钩子,我们可以 re-render 具有更新值的组件。所以对于src
的改变,我们可以使用useState来更新图片的当前src。
通过使用 useEffect
钩子,我们可以在 src
状态改变后做任何事情,比如设置不同的动画。
组件状态
const [image, setImage] = useState(Usa);
const [imageIndex, setImageIndex] = useState(0);
const imgArray = [Usa, Japan, Canada, SouthKorea];
useEffect
useEffect(() => {
let interval = null;
if (i !== maxImgArray) {
interval = setInterval(() => {
let image = imgArray[imageIndex];
const attr = document.getElementById("moving-image");
attr.src = image;
// update the img index to state
setImageIndex((imageIndex) =>
imageIndex === maxImgArray ? 0 : imageIndex + 1
);
// update the src in state.
setImage(attr.src);
}, 3000);
}
// When our code runs and reruns for every render, useEffect also cleans up after itself using the cleanup function.
// Here we clear the interval to remove the effects that could happen with state change while interval.
return () => clearInterval(interval);
}, [image, imageIndex]); // when image, imageIndex gets change, useEffect will be triggered.
组件这里我用了framer-motion做动画
<section className="Country-flag">
<h1>Country Flag</h1>
<div className="container">
<motion.div
key={image}
animate={{ x: 100, opacity: 1 }}
transition={{
delay: 1,
x: { type: "spring", stiffness: 100 },
default: { duration: 2 }
}}
>
{/* when state {image} value change, this component will re-render with new src */}
<img alt="NewYork" src={image} id="moving-image"></img>
</motion.div>
<div className="info"></div>
</div>
</section>
检查此示例 sandbox 以获取生成的代码。
如果您希望每个 img 有不同的动画,则为动画添加另一个状态变量,并为每个图像状态更改 useEffect 中的值。