请马上登录,朋友们都在花潮里等着你哦:)
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 马黑黑 于 2025-8-15 20:31 编辑
<style>
#ma {
position: relative;
margin: 30px auto;
width: 400px;
height: 530px;
background: var(--bg);
color: red;
/* 主元素背景使用JS图片数组中的第 1 张图片 */
--bg: url('https://638183.freep.cn/638183/t22/hl/bw1.jpg') no-repeat center/cover;
/* 伪元素背景使用JS图片数组中的第 2 张图片 */
--bg1: url('https://638183.freep.cn/638183/t22/hl/bw2.jpg') no-repeat center/cover;
--per: 0%; /* 色标边界变量 */
}
#ma::before {
position: absolute;
content: '';
inset: 0;
background: var(--bg1);
/* 遮罩设定 : 圆形遮罩(椭圆遮罩则将 circle, 删掉) */
mask: radial-gradient(circle, red var(--per), transparent var(--per) 0);
--webkit-mask: radial-gradient(circle, red var(--per), transparent var(--per) 0);
}
</style>
<div id="ma" title="点击转场"></div>
<script>
var per = 0, // 遮罩渐变色标边界
step = 1, // 色标边界变化歩幅
picIdx = 0, // 图片序号
isPlaying = false, // 遮罩动画是否运行中
raf; // 请求关键帧动画计数器
// 图片数组(多少任意)
var pics = [
'https://638183.freep.cn/638183/t22/hl/bw1.jpg',
'https://638183.freep.cn/638183/t22/hl/bw2.jpg',
'https://638183.freep.cn/638183/t22/hl/bw3.jpg',
'https://638183.freep.cn/638183/t22/hl/bw4.jpg',
'https://638183.freep.cn/638183/t22/hl/bw5.jpg',
'https://638183.freep.cn/638183/t22/hl/bw6.jpg'
];
// 更新图片(背景图片序号的计算需要做取余数处理)
const update = () => {
if (isPlaying) return; // 若请求关键帧动画正在运行中则不执行此函数
// 如果当前使用的图片序号为偶数 :
if (picIdx % 2 === 0) {;
// 主元素背景使用伪元素的背景图片
ma.style.setProperty('--bg', `url(${pics[picIdx % pics.length]}) no-repeat center/cover`);
// 伪元素背景使用下一张图片
ma.style.setProperty('--bg1', `url(${pics[(picIdx + 1) % pics.length]}) no-repeat center/cover`);
// 否则假如是奇数 :
} else {
// 伪元素背景使用当前图片序号对应的图片
ma.style.setProperty('--bg1', `url(${pics[picIdx % pics.length]}) no-repeat center/cover`);
// 主元素背景使用下一张图片
ma.style.setProperty('--bg', `url(${pics[(picIdx + 1) % pics.length]}) no-repeat center/cover`);
}
picIdx ++; // 图片序号递增
animate(); // 运行遮罩动画
};
// 遮罩动画
const animate = () => {
per += step; // 色标边界变量递增(或递减)
// 若色标变量小于 0 或 大于 100 :
if (per < 0 || per > 100) {
cancelAnimationFrame(raf); // 取消请求关键帧动画计数器
step = -step; // 歩幅正负互变
isPlaying = false; // 此时遮罩动画运行状态为假
// 否则 :
} else {
ma.style.setProperty('--per', per + '%'); // 将 per 变量传递给CSS变量 --per
raf = requestAnimationFrame(animate); // 递归运行函数自身(以持续改变色标边界)
isPlaying = true; // 此时遮罩动画运行状态为真
}
};
ma.onclick = () => update();
</script>
|