前言
在制作Light Store的过程中发现了很多有意思的想法。
也制作了几个比较有意思的动画,虽然很多人会以为里面的动画是GIF。
所以这里就把动画原理和实现方式整理一下,顺便做个记录。
动画原理
思路很简单,因为JSBox不支持字体渐变,只提供了一个矩形渐变接口,所以需要一共两层图层来完成动画。
- 上层为镂空字体层
- 下层为动画渐变层

animation
接下来就是利用JSBox将动画渐变层的渐变颜色动起来。渐变原理
JSBox之中设置颜色有HEX值和RGB值两种方式,但是归根结底HEX只不过是RGB的十六进制显示方式。RGB方式
由于RGB(Red, Green, Blue)是利用的是一个三维坐标。
RGB
如果利用RGB来动态变更颜色的话,需要平滑地显示红橙黄绿蓝靛紫红一个周期则需要运用Sin函数。
利用下面的Demo可以清楚看到颜色渐变过程,仅需改变start的值就可以改变起始颜色。
$ui.render({
layout: $layout.fill,
props: {
id: "1",
}
$ui.render({
layout: $layout.fill,
props: {
id: "1",
}
})
let start = 1
$cache.set("time", start)
$timer.schedule({
interval: 0.1,
handler: function () {
let i = $cache.get("time")
let a_ = i * 2 * 3.141592654 / 1200
let b_ = i * 2 * 3.141592654 / 1200 + 2.094395102
let c_ = i * 2 * 3.141592654 / 1200 - 2.094395102
let r = (255 * (Math.sin(c_) + 0.5)) < 0 ? 0 : ((255 * (Math.sin(c_) + 0.5)) > 255 ? 255 : (255 * (Math.sin(c_) + 0.5)))
let g = (255 * (Math.sin(b_) + 0.5)) < 0 ? 0 : ((255 * (Math.sin(b_) + 0.5)) > 255 ? 255 : (255 * (Math.sin(b_) + 0.5)))
let b = (255 * (Math.sin(a_) + 0.5)) < 0 ? 0 : ((255 * (Math.sin(a_) + 0.5)) > 255 ? 255 : (255 * (Math.sin(a_) + 0.5)))
$("1").bgcolor = $rgb(r,g,b)
console.log(r,g,b)
$cache.set("time", i + 1)
}
})
HSV方式
相对于此,利用HSV值更加直观,唯一缺点就是需要重新将输出的HSV值转换为HEX值。

在HSV
(Hue, Saturation, Lightness,即色相,饱和度,明度)里,颜色变化更为直观,我们只需要变更H值即可,完成一个周期颜色变化,而且也更为强大。同样利用一个Demo,来看一下HSV变化。改变
hh为起始颜色,改变ss则是统一饱和,vv则是统一明度。唯一缺点就是增加了HEX值封装函数,但是相对于上面的RGB方法,这里可以比较直观地控制饱和度和明度。
$ui.render({
layout: $layout.fill,
props: {
id: "1",
}
})
let hh = 0
let ss = 60
let vv = 100
$cache.set("time", hh)
var timer = $timer.schedule({
interval: 0.1,
handler: function() {
let i = $cache.get("time")
let j = i + 60
let hex = HSV2HEX(i, ss, vv)
$("1").bgcolor = $color(hex)
$cache.set("time", i > 360 ? 0 : i + 2)
}
})
function HSV2HEX(h, s, v) {
var h = h > 359 ? 0 : h
var s = s / 100
var v = v / 100
let h1 = Math.floor(h / 60) % 6
let f = h / 60 - h1
let p = v * (1 - s)
let q = v * (1 - f * s)
let t = v * (1 - (1 - f) * s)
if (h1 === 0) {
r = v
g = t
b = p
} else if (h1 === 1) {
r = q
g = v
b = p
} else if (h1 === 2) {
r = p
g = v
b = t
} else if (h1 === 3) {
r = p
g = q
b = v
} else if (h1 === 4) {
r = t
g = p
b = v
} else if (h1 === 5) {
r = v
g = p
b = q
}
let r = r * 255
let g = g * 255
let b = b * 255
let RGB = [Math.ceil(r), Math.ceil(g), Math.ceil(b)]
let HEX = "#" + RGB2HEX(r, g, b)
return HEX
}
function RGB2HEX(r, g, b) {
let r_ = Math.ceil(r).toString(16)
let g_ = Math.ceil(g).toString(16)
let b_ = Math.ceil(b).toString(16)
let h = r_.length < 2 ? "0" + r_ : r_
let e = g_.length < 2 ? "0" + g_ : g_
let x = b_.length < 2 ? "0" + b_ : b_
let HEX = (h.toUpperCase() + e.toUpperCase() + x.toUpperCase())
return HEX
}
Coding
实时计算颜色数值后,我们只需要在画布上添加一个渐变的图层gradient。
然后写入渐变层的colors。
最后再在最上面覆盖一层PS制作的镂空字体层即可。
附上测试脚本:
渐变Demo
效果
最后贴一个效果图

