☰
shimmer4cj 核心算法揭秘:倾斜角度三角函数计算与渐变位置推导全指南
2026/9/25 1:42:03 网站建设 项目流程

shimmer4cj 核心算法揭秘:倾斜角度三角函数计算与渐变位置推导全指南

【免费下载链接】shimmer4cj一个简单灵活的为应用视图添加闪烁效果的库,主要有由左到右倾斜,由左到右竖直,由左到右圆形,由上到下水平等闪光效果项目地址: https://gitcode.com/Cangjie-TPC/shimmer4cj

shimmer4cj 是一个用仓颉(Cangjie)语言编写的开源库,专为应用视图添加闪烁效果(Shimmer 微光动画)。它用一块 Canvas 蒙层叠加线性渐变,实现由左到右倾斜、竖直、圆形、由上到下水平等闪光效果。本文将带你快速读懂它的核心算法:倾斜角度如何用三角函数计算成渐变坐标,以及渐变位置(颜色停靠点)是如何一步步推导出来的。🔍

30 秒看懂:shimmer4cj 的闪烁效果是怎么画出来的

shimmer4cj 的思路非常直观(架构图见下方 shimmer_diagram.png):

  1. 把你需要加效果的组件包进ShimmerElement自定义组件;
  2. ShimmerElement在其上方叠一块canvas 蒙层,监听组件尺寸(通过 component_rect_util.cj 完成 px 到 vp 的换算);
  3. 每一帧用createLinearGradient(或createRadialGradient)重新计算渐变的起点、终点和四个颜色停靠点,整块fillRect填充;
  4. 定时器每约 40ms 触发一帧,渐变起点gradientValue逐帧前移,光带就"扫"了过去。✨

整个算法核心就在两个文件:渲染与三角计算在 shimmer_element.cj,参数与停靠点推导在 shimmer.cj。

倾斜角度三角函数计算:sinTilt / cosTilt / tanTilt 源码解析

setTilt(tilt)可以设置 0–360 的倾斜角度(默认 90)。角度要变成画布上的坐标,靠的是 shimmer_element.cj#L417-L427 里三个小函数:

func sinTilt(): Float64 { return sin(Float64(mShimmer.tilt)) } func cosTilt(): Float64 { return cos((Float64(90 - tilt) * Float64.PI) / 180.0) } func tanTilt(): Float64 { return tan((Float64(90 - tilt) * Float64.PI) / 180.0) }

注意这里统一把"有效角度"折算为90° − tilt:

  • tilt = 90(默认)→ 有效角 0°,tan = 0、cos = 1,渐变线水平,光带竖直——经典 Shimmer 效果;
  • tilt = 60→ 有效角 30°,tan ≈ 0.577、cos ≈ 0.866,光带倾斜 30°;
  • tilt = 30→ 有效角 60°,tan ≈ 1.732、cos ≈ 0.5,光带倾斜更明显。
倾斜角 tilt有效角 90°−tilttanTilt(斜率)cosTilt(水平投影系数)
90(默认)0°01.000
6030°0.5770.866
3060°1.7320.500

另外 titlConfirm() 会把 tilt 钳制在 0–360 区间,并对 0 / 180 / 360 这类边界角度走简化的水平渐变分支,避开 tan(90°) 的奇异点。🧮

渐变起止点推导:createLinearGradient 的两个坐标

以"由左到右"为例,createDirectionLeftToRight() 用点斜式推导渐变线的起点和终点(fixedWidth是光带宽度):

y0 = gradientValue × tanTilt() // 起点:斜率 × 起点横坐标 x1 = gradientValue + fixedWidth × cosTilt() // 终点横坐标 = 起点 + 宽度水平投影 y1 = x1 × tanTilt() // 终点纵坐标 createLinearGradient(gradientValue, y0, x1, y1)

推导逻辑一句话概括:光带是一条斜线,其水平投影长度 = 光带宽度 × cos(90°−tilt),斜率 = tan(90°−tilt)。倾斜越陡,水平投影越短、斜率越大。左右、上下四个方向(shimmer_directions.cj)各自套用同一套投影公式;圆形闪光则改用createRadialGradient以 (x, 高/2) 为圆心生成向外扩散的圆形光晕。

渐变位置推导:intensity 与 dropOffset 如何生成四个颜色停靠点

光带内部"淡入 → 高亮 → 淡出"的过渡,由 shimmer.cj 的 updatePositions() 推导。条形(LINEAR)闪光的四个停靠点关于 0.5 对称:

停靠点颜色位置公式
positions[0]底色max((1 − intensity − dropOffset) / 2, 0)
positions[1]高光色max((1 − intensity − 0.001) / 2, 0)
positions[2]高光色min((1 + intensity + 0.001) / 2, 1)
positions[3]底色min((1 + intensity + dropOffset) / 2, 1)

两个参数各管一件事:

  • intensity(强度,0–1):控制高亮区宽度,越大光带中央越"亮";
  • dropOffset(渐变程度,0–1):控制两侧透明过渡区的宽度,越大光带边缘越柔和。

取默认值 intensity = 0、dropOffset = 0.5,即得[0.25, 0.5, 0.5, 0.75]——正好一半位置开始、一半位置结束,形成教科书式的平滑光带。公式里的±0.001 是刻意保留的极小量,保证两个高光停靠点严格有序,防止高亮区塌成一条线。🎚️

圆形(RADIAL)闪光则更简单,从圆心向外推导:[0, min(intensity, 1), min(intensity + dropOffset, 1), 1](当前仅支持从左到右方向)。

匀速移动的秘密:|sin(tilt)| 修正步长与帧间隔

光带每帧走多远?看 gradientValueAddition():

单帧步长 step = 组件宽度 / animationDuration × 50 × |sin(tilt)| 帧间隔 moveDelay = animationDuration / 组件宽度 × step // ≈ 50 × |sin(tilt)| 毫秒

这里的50即常量TILT_PARAM(shimmer_element.cj#L32-L33),它定义了"参考帧间隔"。巧妙之处在于:倾斜角通过 |sin(tilt)| 同时缩放步长和帧间隔,总帧数相应增减,相乘后完整扫过一次的总时长恒等于animationDuration——无论你怎么调 tilt,动画时长都不变。当 sin 为 0 时则回退到TILT_COEFFICIENT = 0.5的兜底系数。

配合PlayMode播放模式(Normal 循环 / Reverse 折返)与repeatCount(-1 表示无限循环),四个方向的边界处理分别落在 shimmer_element.cj#L246-L380 中,细节可自行翻阅。

快速上手:5 行代码配置倾斜闪烁效果

读懂算法后,实际使用只需要几行配置:

@State var testControl: Shimmer = Shimmer() // 倾斜 50°,调强度与渐变程度 testControl.setTilt(50).setIntensity(0.1).setDropOffset(1.0) ShimmerElement(mShimmer: testControl, content: testComponent)

完整功能演示在 test_01.cj(左右/折返)、test_03.cj(倾斜方向)等页面中;全部接口说明见 feature_api.md。

小结

shimmer4cj 的算法精髓可以浓缩为三句话:

  1. 角度 → 坐标:用cos(90°−tilt)求光带宽度的水平投影、用tan(90°−tilt)求渐变线斜率,一步推出createLinearGradient的起止点;
  2. 强度 → 停靠点:intensity与dropOffset通过对称公式推导出四个颜色位置,±0.001 保证过渡平滑;
  3. 恒定时长:|sin(tilt)|同步修正单帧步长与帧间隔,让任意倾斜角度下的动画时长都等于设定值。

📖 延伸阅读:渲染主逻辑 shimmer_element.cj · 参数控制器 shimmer.cj · 尺寸换算 component_rect_util.cj · 版本记录 CHANGELOG.md

【免费下载链接】shimmer4cj一个简单灵活的为应用视图添加闪烁效果的库,主要有由左到右倾斜,由左到右竖直,由左到右圆形,由上到下水平等闪光效果项目地址: https://gitcode.com/Cangjie-TPC/shimmer4cj

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询