ZiGma

【JSBox】多图层制作渐变动画

字数统计: 1,040阅读时长: 5 min
2018/08/24 Share

前言

在制作Light Store的过程中萌发了很多有意思的想法。

也制作了几个比较有意思的动画,虽然很多人会以为里面的动画是GIF。

所以这里就把动画原理和实现方式整理一下,顺便做个记录。

动画原理

思路很简单,因为JSBox不支持字体渐变,只提供了一个矩形渐变接口,所以需要一共两层图层来完成动画。

  • 上层为镂空字体层
  • 下层为动画渐变层

animation

接下来就是利用JSBox将动画渐变层的渐变颜色动起来。

渐变原理

JSBox之中设置颜色有HEX值和RGB值两种方式,但是归根结底HEX只不过是RGB的十六进制显示方式。

RGB方式

由于RGB(Red, Green, Blue)是利用的是一个三维坐标。

RGB

如果利用RGB来动态变更颜色的话,需要平滑地显示红橙黄绿蓝靛紫红一个周期则需要运用Sin函数。

利用下面的Demo可以清楚看到颜色渐变过程,仅需改变start的值就可以改变起始颜色。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$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

在HSV(Hue, Saturation, Lightness,即色相,饱和度,明度)里,颜色变化更为直观,我们只需要变更H值即可,完成一个周期颜色变化,而且也更为强大。

同样利用一个Demo,来看一下HSV变化。改变hh为起始颜色,改变ss则是统一饱和,vv则是统一明度。

唯一缺点就是增加了HEX值封装函数,但是相对于上面的RGB方法,这里可以比较直观地控制饱和度和明度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
$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

效果

最后贴一个效果图

gif

CATALOG
  1. 1. 前言
  2. 2. 动画原理
  3. 3. 渐变原理
    1. 3.1. RGB方式
    2. 3.2. HSV方式
  4. 4. Coding
  5. 5. 效果