最近在公众号推介中发现一个好看的3D网页背景JS库, Vanta.js(https://www.vantajs.com/ )这个库。Vanta 可以借助 three.js (WebGL) 或 p5.js 渲染动态的3D背景效果,提供了多种预设。
效果见图
下面正式开始:
度娘查了好几个参考文章,最终简单结构包括网页主体、样式、脚本
网页主体
<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官网调整后拿过来用
云朵效果附加+效果
另外,在一个大佬的文章,看到了对云朵和光线颜色通过当前时间做了变化,这里引用一下,实现效果在后续研究
下面是调整官方界面,引出的参数内容
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 }
版权声明
本文章如果涉及侵权,请联系我。
部分文章系本人原创未经许可,不得转载。
评论列表
发表评论