conic+mask实现转场效果
<style>.artBox { font-size: 18px; }
.artBox > p { margin: 10px 0; line-height: 30px; }
.artBox mark { padding: 4px 6px; background: lightblue; }
.artBox h5 { font-size: 18px; margin: 6px 0; }
</style>
<div id="prevBox"></div>
<div class="artBox">
<h5>实现思路:</h5>
<p>使用元素和伪元素交换背景图像达成切换图像的设计:开始时头一个图像在元素背景上呈现,伪元素什么都不加载,从第一次切换开始,伪元素事先加载一个新图像,同时使用 <txt-red>conic-gradient</txt-red> 对其进行遮罩,并运行改变遮罩色标终止角度的动画使得伪元素上的背景渐次绕圈呈现,动画绕圈的起始角度随机,动画完成后将伪元素上的背景图象移交给主元素背景,如此往复运行。</p>
<p>为让上述思路变为现实,需要设计几个CSS变量:其一,<txt-darkred>--start</txt-darkred>,锥形渐变(基于圆的)起始角度,它将控制(在圆周上)放开遮罩的开始点,因为锥形渐变是绕中心点做顺时针圆周渐变的;其二,<txt-darkred>--bg1</txt-darkred>,存储主元素的背景图像数据;其三,<txt-darkred>--bg2</txt-darkred>,存储伪元素的背景图象信息。这些变量的控制权交给JS:每一次转场图像动画的触发和实施过程都会动态地更新这些变量值。下面是具体代码,可在线运行:</p>
<div class="codebox"data-prev="1">
<style>
#ma {
position: relative;
margin: 30px auto;
width: 400px;
height: 400px;
background: var(--bg1); <txt-green>/* 背景变量由JS控制 */</txt-green>
border-radius: 50%;
}
#ma::after {
position: absolute;
content: '';
inset: 0;
background: var(--bg2); <txt-green>/* 背景变量由JS控制 */</txt-green>
border-radius: 50%;
<txt-green>/* 锥形渐变转场 :开始角度、色标变量通过JS控制 */</txt-green>
mask: conic-gradient(from var(--start), transparent var(--deg) , var(--deg), red);
}
</style>
<div id="ma">点击转场</div>
<script>
<txt-green>// deg : 遮罩色标开始值,step : 色标值改变系数,</txt-green>
<txt-green>// currentBg : 当前背景,raf : requestAnimationFrame计数器</txt-green>
let deg = 360, step = 5, currentBg, raf;
<txt-green>// 设置随机背景色+随机遮罩角度</txt-green>
const setRadBg = (elm, val, bg = null) => {
<txt-green>// 如果调用者不提供 bg 参数则使用随机背景色</txt-green>
if (!bg) bg = `#${Math.random().toString(16).substring(2, 8)}`;
elm.style.setProperty(val, bg); <txt-green>// 设置 elm 元素的 val 背景色</txt-green>
elm.style.setProperty('--start', Math.random() * 360 + 'deg'); <txt-green>// 设置随机遮罩起始角度</txt-green>
return bg; <txt-green>// 返回 bg 值</txt-green>
};
<txt-green>/* 遮罩动画 */</txt-green>
const animate = () => {
if (deg < 0) { <txt-green>// 如果色标角度小于 0</txt-green>
cancelAnimationFrame(raf); <txt-green>// 取消 raf 计数器</txt-green>
deg = 360; <txt-green>// 色标值回到初始值</txt-green>
setRadBg(ma, '--bg1', currentBg); <txt-green>// 调用 setRadBg 函数 : 当前颜色值做主元素背景色</txt-green>
} else { <txt-green>// 否则</txt-green>
deg -= step; <txt-green>// 色标值递减</txt-green>
ma.style.setProperty('--deg', deg + 'deg'); <txt-green>// 更新元素的色标值</txt-green>
raf = requestAnimationFrame(animate); <txt-green>// 更新并存储 raf 计数器</txt-green>
}
};
currentBg = setRadBg(ma, '--bg1'); <txt-green>// 首次运行 setRadBg 函数 : 初始化界面并存储当前背景</txt-green>
<txt-green>// 元素点击事件</txt-green>
ma.onclick = () => {
currentBg = setRadBg(ma, '--bg2'); <txt-green>// 运行 setRadBg 函数并存储当前背景</txt-green>
animate();<txt-green>// 运行转场动画</txt-green>
};
</script>
</div>
<h5>【附】conic-gradient 锥形渐变简洁:</h5>
<p>锥形渐变默认以元素的圆心作为中心点,参与渐变的颜色围绕圆心从 0 度(指向正上方)开始、按顺时针做渐变,开始颜色和结束颜色在元素的上半部分的中央存在明显的硬线衔接痕迹。下面例子是元素背景图像由天蓝色和红色参与渐变,查看预览效果可以更好理解默认设置下的锥形渐变效果:</p>
<div class="codebox" data-prev="1">
<style>
.ma {
margin: 30px;
width: 200px;
height: 200px;
background: conic-gradient(skyblue, red); <txt-green>/* 锥形渐变背景 */</txt-green>
}
</style>
<div class="ma"></div>
</div>
<p>再提供几个其它例子,这些例子展示简单的个性化锥形渐变设置:</p>
<div class="codebox" data-prev="1">
<style>
.ma {
margin: 30px 0 30px 20px;
width: 200px;
height: 200px;
display: inline-block;
}
.ma:nth-of-type(1) {
<txt-green>/* 渐变从90度开始 */</txt-green>
background: conic-gradient(from 90deg, red, green, blue);
}
.ma:nth-of-type(2) {
<txt-green>/* 渐变从90的开始,中心点不在圆心 */</txt-green>
background: conic-gradient(from 90deg at 20% 60% , red, green, blue);
}
.ma:nth-of-type(3) {
<txt-green>/* 色标边界硬线衔接 :除百分比外还可以用 deg 做角度单位 */</txt-green>
background: conic-gradient(from 90deg, red 33.3%, green 33.3%, green 66.6%, blue 66.6%, blue);
}
.ma:nth-of-type(4) {
<txt-green>/* 饼状图 */</txt-green>
background: conic-gradient(red 120deg, orange 120deg, orange 240deg, yellow 240deg, yellow);
border-radius: 50%;
}
.ma:nth-of-type(5) {
<txt-green>/* 非标准的七彩虹色盘效果 */</txt-green>
background: conic-gradient(red,yellow,green,cyan,blue,magenta,red);
border-radius: 50%;
}
.ma:nth-of-type(6) {
<txt-green>/* 重复性锥形渐变 */</txt-green>
background: repeating-conic-gradient(hsla(0, 0%, 100%, 0.2) 0deg 15deg, hsla(0, 0%, 100%, 0) 0deg 30deg) tan;
border-radius: 50%;
}
</style>
<div class="ma"></div>
<div class="ma"></div>
<div class="ma"></div>
<div class="ma"></div>
<div class="ma"></div>
<div class="ma"></div>
</div>
</div>
<script type="module">
import linenumber from 'https://638183.freep.cn/638183/web/js/linenumber.js';
linenumber();
</script> 来看看这个新的教程。。
之前说除了线性遮罩应该还有别的形式,这个锥形的转场也很好看。。 第一个预览里的颜色是随机背景,可以无限转下去的感觉。可以点好久。。。{:4_170:}
第三个展示这么多种样式的锥形渐变,个个都漂亮。。。 花飞飞 发表于 2025-8-11 19:15
第一个预览里的颜色是随机背景,可以无限转下去的感觉。可以点好久。。。
第三个展示这么多种样 ...
{:4_196:} 花飞飞 发表于 2025-8-11 19:03
来看看这个新的教程。。
之前说除了线性遮罩应该还有别的形式,这个锥形的转场也很好看。。
{:4_181:} 马黑黑 发表于 2025-8-11 19:18
掐个小粉猪。。。你今天开心不呀。{:4_170:} 马黑黑 发表于 2025-8-11 19:18
太漂亮了,期待看到背景是图片的{:4_173:} 花飞飞 发表于 2025-8-11 19:46
太漂亮了,期待看到背景是图片的
自己弄去 花飞飞 发表于 2025-8-11 19:45
掐个小粉猪。。。你今天开心不呀。
我天天开森 马黑黑 发表于 2025-8-11 20:47
自己弄去
{:4_170:}好哒好哒,碰一鼻子灰,哭唧唧走了 马黑黑 发表于 2025-8-11 20:47
我天天开森
那就开森着你的开森{:4_173:} 后面那个个性化锥形渐变的例子太好了,尤其那个“渐变从90的开始,中心点不在圆心”,竟然还能设置起始角度的同时设置圆心点在哪,这个还不知道,或者是之前讲过我忘记了{:4_173:}
七彩虹色盘的记得,“重复性锥形渐变”也好漂亮啊{:4_187:} 任意角度的动态锥形渐变转场也好漂亮,这个太好了{:4_199:} 红影 发表于 2025-8-12 09:54
任意角度的动态锥形渐变转场也好漂亮,这个太好了
谢好 红影 发表于 2025-8-12 09:52
后面那个个性化锥形渐变的例子太好了,尤其那个“渐变从90的开始,中心点不在圆心”,竟然还能设置起始角度 ...
之前介绍的基本是一基本知识为主 花飞飞 发表于 2025-8-12 08:21
那就开森着你的开森
一起开 花飞飞 发表于 2025-8-12 08:20
好哒好哒,碰一鼻子灰,哭唧唧走了
像小计一样{:4_170:} 马黑黑 发表于 2025-8-12 19:10
一起开
{:4_173:}开就开,虽怕虽 马黑黑 发表于 2025-8-12 19:10
像小计一样
{:4_170:}你没事挠挠去,可好玩呢 花飞飞 发表于 2025-8-12 20:23
开就开,虽怕虽
{:4_172:}