前言

在制作Light Store的过程中发现了很多有意思的想法。
也制作了几个比较有意思的动画,虽然很多人会以为里面的动画是GIF。
所以这里就把动画原理和实现方式整理一下,顺便做个记录。

动画原理

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

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

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

    渐变原理

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

    RGB方式

    由于RGB(Red, Green, Blue)是利用的是一个三维坐标。
    RGB
    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
HSV

在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

效果

最后贴一个效果图

效果
效果

原文链接

http://www.zigma.cc/2018/08/24/%E3%80%90JSBox%E3%80%91%E5%A4%9A%E5%9B%BE%E5%B1%82%E5%88%B6%E4%BD%9C%E6%B8%90%E5%8F%98%E5%8A%A8%E7%94%BB/

8
0