推介一个3D网页背景库VantaJS

xzbxzb 工具 2024-12-06 540 0

最近在公众号推介中发现一个好看的3D网页背景JS库, Vanta.js(https://www.vantajs.com/ )这个库。Vanta 可以借助 three.js (WebGL) 或 p5.js 渲染动态的3D背景效果,提供了多种预设。

效果见图

推介一个3D网页背景库VantaJS


下面正式开始:

度娘查了好几个参考文章,最终简单结构包括网页主体、样式、脚本

网页主体

<div id="your-element-selector">  </div>

*这个id会和脚本定义元素对应,否则不能形成调用关系

样式表

div {
  width: 100%; 
  height: 360px; 
  margin-bottom: 10px;
}

*样式结构根据个人需要去调整

脚本

VANTA.CLOUDS({
  el: "#your-element-selector",
  mouseControls: true,
  touchControls: true,
  gyroControls: false,
  minHeight: 200.00,
  minWidth: 200.00,
  speed: 1.10
})

运行效果跳转查看

由于使用官方库加载速度太慢,我把库做了本地化

根据官方文档解释参数包括:

  • el:容器元素。

    • Vanta 画布将作为该元素的子元素附加,并采用该元素的宽度和高度。 (如果您想要全屏画布,请确保此容器元素是全屏的。)

    • 该容器可以有其他子容器。其他子项将作为前景内容出现在 Vanta 画布前面。

  • mouseControls:(默认为true)设置为 false 以禁用鼠标控件。仅适用于某些效果。

  • touchControls:(默认为true)设置为 false 以禁用触摸控制。仅适用于某些效果。

  • gyroControls:(默认为false)设置为 true 以允许陀螺仪模仿鼠标。仅适用于某些效果。

具体代码见官方库,效果调整界面也可以在js官网调整后拿过来用

推介一个3D网页背景库VantaJS

云朵效果附加+效果

另外,在一个大佬的文章,看到了对云朵和光线颜色通过当前时间做了变化,这里引用一下,实现效果在后续研究

下面是调整官方界面,引出的参数内容

 mouseControls: true,
  touchControls: true,
  gyroControls: false,
  minHeight: 200.00,
  minWidth: 200.00,
  skyColor: 0x68bfe0,
  cloudColor: 0xbacbe3,
  cloudShadowColor: 0x1e3e5b,
  sunColor: 0xfc981b,
  sunGlareColor: 0xff6937,
  sunlightColor: 0xf9942f,
  speed: 1.10

下面是大佬代码

// 获取 Vanta.js clouds 效果的颜色的模块
// 插值代码来自:https://www.zhihu.com/question/38869928/answer/78527903
 
// HTML颜色转RGB颜色
function parseColor(hexString: string) {
  return [
    hexString.substring(1, 3),
    hexString.substring(3, 5),
    hexString.substring(5, 7),
  ].map((s) => { return parseInt(s, 16); })
};
 
// 将一位补位到两位
function pad(s: string) {
  return (s.length === 1) ? '0' + s : s;
};
 
// 插值获得颜色
function gradientColors(startHTML: string, endHTML: string, steps: number, gamma: number) {
  let i, j, ms, me, output = [], so = [];
  gamma = gamma || 1;
  const normalize = (channel: number) => {
    return Math.pow(channel / 255, gamma);
  };
  const startRGB = parseColor(startHTML).map(normalize);
  const endRGB = parseColor(endHTML).map(normalize);
  for (i = 0; i < steps; i++) {
    ms = i / (steps - 1);
    me = 1 - ms;
    for (j = 0; j < 3; j++) {
      so[j] = pad(Math.round(Math.pow(startRGB[j] * me + endRGB[j] * ms, 1 / gamma) * 255).toString(16));
    }
    output.push('#' + so.join(''));
  }
  return output;
};
 
// 获取系统时间,从0点开始计数,以分钟为单位
function getCurrMinute(): number {
  const now = new Date()
  return now.getHours() * 60 + now.getMinutes()
}

Vanta 中 cloud 效果有多个颜色可以指定。对视觉效果影响最大的应该是天空颜色(skyColor)。使用上面的插值函数,可以得到如下的代码:

export function getSkyColor(): string {
  const black = '#121212'
  const purple = '#140248'
  const orange = '#fea443'
  const dusk = '#c88a46'
  const blue = '#58acfa'
 
  const currMinute = getCurrMinute()
  let currColor = black
 
  if (currMinute >= 0 && currMinute < 4 * 60) {
    currColor = black
  } else if (currMinute >= 4 * 60 && currMinute < 5 * 60) {
    currColor = gradientColors(black, purple, 60, 1)[currMinute - 4 * 60]
  } else if (currMinute >= 5 * 60 && currMinute < 6 * 60) {
    currColor = gradientColors(purple, orange, 60, 1)[currMinute - 5 * 60]
  } else if (currMinute >= 6 * 60 && currMinute < 9 * 60) {
    currColor = gradientColors(orange, blue, 3 * 60, 1)[currMinute - 6 * 60]
  } else if (currMinute >= 9 * 60 && currMinute < 16 * 60) {
    currColor = blue
  } else if (currMinute >= 16 * 60 && currMinute < 18 * 60) {
    currColor = gradientColors(blue, dusk, 2 * 60, 1)[currMinute - 16 * 60]
  } else if (currMinute >= 18 * 60 && currMinute < 19 * 60) {
    currColor = gradientColors(dusk, purple, 60, 1)[currMinute - 18 * 60]
  } else if (currMinute >= 19 * 60 && currMinute < 20 * 60) {
    currColor = gradientColors(purple, black, 60, 1)[currMinute - 19 * 60]
  } else if (currMinute >= 20 * 60 && currMinute < 24 * 60) {
    currColor = black
  }
  return currColor
}

实际上,不一定所有时间段都需要插值,白天的大部分时间天空颜色是可以保持不变的,深夜和凌晨同理。

白天时,云层应当呈现为白色;到了夜间,云层应该带有灰色,于是我们简单写出获取云层颜色的代码:

export function getCloudColor(): string {
  const grey = '#525252'
  const whiteblue= '#adc1de'
 
  const currMinute = getCurrMinute()
  let currColor = whiteblue
 
  if (currMinute >= 0 && currMinute < 4 * 60) {
    currColor = grey
  } else if (currMinute >= 4 * 60 && currMinute < 6 * 60) {
    currColor = gradientColors(grey, whiteblue, 2 * 60, 1)[currMinute - 4 * 60]
  } else if (currMinute >= 6 * 60 && currMinute < 17 * 60) {
    currColor = whiteblue
  } else if (currMinute >= 17 * 60 && currMinute < 19 * 60) {
    currColor = gradientColors(whiteblue, grey, 2 * 60, 1)[currMinute - 17 * 60]
  } else if (currMinute >= 19 * 60 && currMinute < 24 * 60) {
    currColor = grey
  }
 
  return currColor
}

同理,有获取太阳颜色的代码:

export function getSunColor(): string {
  const white = '#fef0c0'
  const lightorange = '#f5d0a9'
  const black = '#000000'	// 不能直接隐藏太阳,因此夜间必须将太阳设置为黑色来间接隐藏,否则夜间也会有光源,很不自然。
 
  const currMinute = getCurrMinute()
  let currColor = white
 
  if (currMinute >= 0 && currMinute < 4 * 60) {
    currColor = black
  } else if (currMinute >= 4 && currMinute < 6 * 60) {
    currColor = gradientColors(black, lightorange, 2 * 60, 1)[currMinute - 4 * 60]
  } else if (currMinute >= 6 * 60 && currMinute < 8 * 60) {
    currColor = gradientColors(lightorange, white, 2 * 60, 1)[currMinute - 6 * 60]
  } else if (currMinute >= 8 * 60 && currMinute < 16 * 60) {
    currColor = white
  } else if (currMinute >= 16 * 60 && currMinute < 18 * 60) {
    currColor = gradientColors(white, lightorange, 2 * 60, 1)[currMinute - 16 * 60]
  } else if (currMinute >= 18 * 60 && currMinute < 19 * 60) {
    currColor = gradientColors(lightorange, black, 60, 1)[currMinute - 18 * 60]
  } else if (currMinute >= 19 * 60 && currMinute < 24 * 60) {
    currColor = black
  }
 
  return currColor
}

和获取太阳光晕颜色的代码:

export function getSunGlareColor(): string {
  const white = '#fef0c0'
  const orange = '#ffa64d'
  const black = '#000000'	// 解释同上
 
  const currMinute = getCurrMinute()
  let currColor = white
 
  if (currMinute >= 0 && currMinute < 4 * 60) {
    currColor = black
  } else if (currMinute >= 4 && currMinute < 6 * 60) {
    currColor = gradientColors(black, orange, 2 * 60, 1)[currMinute - 4 * 60]
  } else if (currMinute >= 6 * 60 && currMinute < 7 * 60) {
    currColor = gradientColors(orange, white, 60, 1)[currMinute - 6 * 60]
  } else if (currMinute >= 7 * 60 && currMinute < 17 * 60) {
    currColor = white
  } else if (currMinute >= 17 * 60 && currMinute < 18 * 60) {
    currColor = gradientColors(white, orange, 60, 1)[currMinute - 17 * 60]
  } else if (currMinute >= 18 * 60 && currMinute < 19 * 60) {
    currColor = gradientColors(orange, black, 60, 1)[currMinute - 18 * 60]
  } else if (currMinute >= 19 * 60 && currMinute < 24 * 60) {
    currColor = black
  }
 
  return currColor
}

大佬文章在这里

 您阅读本篇文章共花了: 

版权声明

本文章如果涉及侵权,请联系我。
部分文章系本人原创未经许可,不得转载。

喜欢0发布评论

评论列表

发表评论

  • 昵称(必填)
  • 邮箱
  • 网址