webgl+canvas实现炫酷柔和多彩背景动画效果代码
代码语言:html
所属分类:动画
代码描述:webgl+canvas实现炫酷柔和多彩背景动画效果代码
代码标签: webgl canvas 炫酷 柔和 多彩 背景 动画
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
* {
margin: 0;
padding: 0;
}
body {
height: 100vh;
width: 100%;
display: grid;
place-items: stretch;
}
#gradient-canvas {
height: 100vh;
width: 100%;
background: lightgrey;
}
</style>
</head>
<body>
<!-- partial:index.partial.html -->
<canvas style="--gradient-color-1:#ef008f;--gradient-color-2:#6ec3f4;--gradient-color-3:#7038ff;--gradient-color-4:#e2e2e2;" id="gradient-canvas" data-transition-in></canvas>
<script>
window.addEventListener('DOMContentLoaded', (e) => {
var gradient = new Gradient;
gradient.initGradient("#gradient-canvas");
});
</script>
<!-- partial -->
<script>
// https://kevinhufnagl.com/wp-content/themes/lightisol/dist/js/min/lightisol-gradient.min.js?ver=1.0
//
function normalizeColor(hexCode) {
return [
((hexCode >> 16) & 255) / 255,
((hexCode >> 8) & 255) / 255,
(255 & hexCode) / 255
];
}
["SCREEN", "LINEAR_LIGHT"].reduce(
(hexCode, t, n) => Object.assign(hexCode, { [t]: n }),
{}
);
class MiniGl {
constructor(canvas, width, height, debug = !1) {
const _miniGl = this,
debug_output =
-1 !== document.location.search.toLowerCase().indexOf("debug=webgl");
(_miniGl.canvas = canvas),
(_miniGl.gl = _miniGl.canvas.getContext("webgl", { antialias: !0 })),
(_miniGl.meshes = []);
const context = _miniGl.gl;
width && height && this.setSize(width, height),
_miniGl.lastDebugMsg,
(_miniGl.debug =
debug && debug_output
? function (e) {
const t = new Date();
t - _miniGl.lastDebugMsg > 1e3 && console.log("---"),
console.log(
t.toLocaleTimeString() +
Array(Math.max(0, 32 - e.length)).join(" ") +
e +
": ",
...Array.from(arguments).slice(1)
),
(_miniGl.lastDebugMsg = t);
}
: () => {}),
Object.defineProperties(_miniGl, {
Material: {
enumerable: !1,
value: class {
constructor(vertexShaders, fragments, uniforms = {}) {
const material = this;
function getShaderByType(type, source) {
const shader = context.createShader(type);
return (
context.shaderSource(shader, source),
context.compileShader(shader),
context.getShaderParameter(shader, context.COMPILE_STATUS) ||
console.error(context.getShaderInfoLog(shader)),
_miniGl.debug("Material.compileShaderSource", { source: source }),
shader
);
}
function getUniformVariableDeclarations(uniforms, type) {
return Object.entries(uniforms)
.map(([uniform, value]) => value.getDeclaration(uniform, type))
.join("\n");
}
(this.uniforms = uniforms), (this.uniformInstances = []);
const prefix = "\n precision highp float;\n ";
(this.vertexSource = `\n ${prefix}\n attribute vec4 position;\n attribute vec2 uv;\n attribute vec2 uvNorm;\n ${getUniformVariableDeclarations(
_miniGl.commonUniforms,
"vertex"
)}\n ${getUniformVariableDeclarations(
uniforms,
"vertex"
)}\n ${vertexShaders}\n `),
(this.Source = `\n ${prefix}\n ${getUniformVariableDeclarations(
_miniGl.commonUniforms,
"fragment"
)}\n ${getUniformVariableDeclarations(
uniforms,
"fragment"
)}\n ${fragments}\n `),
(this.vertexShader = getShaderByType(
context.VERTEX_SHADER,
this.vertexSource
)),
(this.fragmentShader = getShaderByType(
context.FRAGMENT_SHADER,
this.Source
)),
(this.program = context.createProgram()),
context.attachShader(this.program, this.vertexShader),
context.attachShader(this.program, this.fragmentShader),
context.linkProgram(this.program),
context.getProgramParameter(this.program, context.LINK_STATUS) ||
console.error(context.getProgramInfoLog(this.program)),
context.useProgram(this.program),
this.attachUniforms(void 0, _miniGl.commonUniforms),
this.attachUniforms(void 0, this.uniforms);
}
attachUniforms(name, uniforms) {
const material = this;
void 0 === name
? Object.entries(uniforms).forEach(([name, uniform]) => {
material.attachUniforms(name, uniform);
})
: "array" == uniforms.type
? uniforms.value.forEach((uniform, i) =>
material.attachUniforms(`${name}[${i}]`, uniform)
)
: "struct" == uniforms.type
? Object.entries(uniforms.value).forEach(([uniform, i]) =>
material.attachUniforms(`${name}.${uniform}`, i)
)
: (_miniGl.debug("Material.attachUniforms", {
name: name,
uniform: uniforms
}),
material.uniformInstances.push({
uniform: uniforms,
location: context.getUniformLocation(material.program, name)
}));
}
}
},
Uniform: {
enumerable: !1,
value: class {
constructor(e) {
(this.type = "float"),
Object.assign(this, e),
(this.typeFn =
{
float: "1f",
int: "1i",
vec2: "2fv",
vec3: "3fv",
vec4: "4fv",
mat4: "Matrix4fv"
}[this.type] || "1f"),
this.update();
}
update(value) {
void 0 !== this.value &&
context[`uniform${this.typeFn}`](
value,
0 === this.typeFn.indexOf("Matrix") ? this.transpose : this.value,
0 === this.typeFn.indexOf("Matrix") ? this.value : null
);
}
getDeclaration(name, type, length) {
const uniform = this;
if (uniform.excludeFrom !== type) {
if ("array" === uniform.type)
return (
uniform.value[0].getDeclaration(name, type, uniform.value.length) +
`\nconst int ${name}_length = ${uniform.value.length};`
);
if ("struct" === uniform.type) {
let name_no_prefix = name.replace("u_", "");
return (
(name_no_prefix =
name_no_prefix.charAt(0).toUpperCase() + name_no_prefix.slice(1)),
`uniform struct ${name_no_prefix} \n {\n` +
Object.entries(uniform.value)
.map(([name, uniform]) =>
uniform.getDeclaration(name, type).replace(/^uniform/, "")
)
.join("") +
`\n} ${name}${length > 0 ? `[${length}]` : ""};`
);
}
return `uniform ${uniform.type} ${name}${
length > 0 ? `[${length}]` : ""
};`;
}
}
}
},
PlaneGeometry: {
enumerable: !1,
value: class {
constructor(width, height, n, i, orientation) {
context.createBuffer(),
(this.attributes = {
position: new _miniGl.Attribute({
target: context.ARRAY_BUFFER,
size: 3
}),
uv: new _miniGl.Attribute({ target: context.ARRAY_BUFFER, size: 2 }),
uvNorm: new _miniGl.Attribute({
target: context.ARRAY_BUFFER,
size: 2
}),
index: new _miniGl.Attribute({
target: context.ELEMENT_ARRAY_BUFFER,
size: 3,
type: context.UNSIGNED_SHORT
})
}),
this.setTopology(n, i),
this.setSize(width, height, orientation);
}
setTopology(e = 1, t = 1) {
const n = this;
(n.xSegCount = e),
(n.ySegCount = t),
(n.vertexCount = (n.xSegCount + 1) * (n.ySegCount + 1)),
(n.quadCount = n.xSegCount * n.ySegCount * 2),
(n.attributes.uv.values = new Float32Array(2 * n.vertexCount)),
(n.attributes.uvNorm.values = new Float32Array(2 * n.vertexCount)),
(n.attributes.index.values = new Uint16Array(3 * n.quadCount));
for (let e = 0; e <= n.ySegCount; e++)
for (let t = 0; t <= n.xSegCount; t++) {
const i = e * (n.xSegCount + 1) + t;
if (
((n.attributes.uv.values[2 * i] = t / n.xSegCount),
(n.attributes.uv.values[2 * i + 1] = 1 - e / n.ySegCount),
(n.attributes.uvNorm.values[2 * i] = (t / n.xSegCount) * 2 - 1),
(n.attributes.uvNorm.values[2 * i + 1] = 1 - (e / n.ySegCount) * 2),
t < n.xSegCount && e < n.ySegCount)
) {
const s = e * n.xSegCount + t;
(n.attributes.index.values[6 * s] = i),
(n.attributes.index.values[6 * s + 1] = i + 1 + n.xSegCount),
(n.attributes.index.values[6 * s + 2] = i + 1),
(n.attributes.index.values[6 * s + 3] = i + 1),
(n.attributes.index.values[6 * s + 4] = i + 1 + n.xSegCount),
(n.attributes.index.values[6 * s + 5] = i + 2 + n.xSegCount);
}
}
n.attributes.uv.update(),
n.attributes.uvNorm.update(),
n.attributes.index.update(),
_miniGl.debug("Geometry.setTopology", {
uv: n.attributes.uv,
uvNorm: n.attributes.uvNorm,
index: n.attributes.index
});
}
setSize(width = 1, height = 1, orientation = "xz") {
const geometry = this;
(geometry.width = width),
(geometry.height = height),
(geometry.orientation = orientation),
(geometry.attributes.position.values &&
geometry.attributes.position.values.length ===
3 * geometry.vertexCount) ||
(geometry.attributes.position.values = new Float32Array(
3 * geometry.vertexCount
));
const o = width / -2,
r = height / -2,
segment_width = width / geometry.xSegCount,
segment_height = height / geometry.ySegCount;
for (let yIndex = 0; yIndex <= geometry.ySegCount; yIndex++) {
const t = r + yIndex * segment_height;
for (let xIndex = 0; xIndex <= geometry.xSegCount; xIndex++) {
const r = o + xIndex * segment_width,
l = yIndex * (geometry.xSegCount + 1) + xIndex;
(geometry.attributes.position.values[
3 * l + "xyz".indexOf(orientation[0])
] = r),
(geometry.attributes.position.values[
3 * l + "xyz".indexOf(orientation[1])
] = -t);
}
}
geometry.attributes.position.update(),
_miniGl.debug("Geometry.setSize", {
position: geometry.attributes.position
});
}
}
},
Mesh: {
enumerable: !1,
value: class {
constructor(geometry, material) {
const mesh = this;
(mesh.geometry = geometry),
(mesh.material = material),
(mesh.wireframe = !1),
(mesh.attributeInstances = []),
Object.entries(mesh.geometry.attributes)..........完整代码请登录后点击上方下载按钮下载查看
网友评论0