/* * Stripe WebGl Gradient Animation * All Credits to Stripe.com * Dither added to fragment shader to reduce color banding. * https://kevinhufnagl.com */ //Converting colors to proper format 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 = false) { const _miniGl = this, debug_output = -1 !== document.location.search.toLowerCase().indexOf("debug=webgl"); _miniGl.canvas = canvas, _miniGl.gl = _miniGl.canvas.getContext("webgl", { antialias: true }), _miniGl.meshes = []; const context = _miniGl.gl;https://cdn.prod.website-files.com/664b99d40859abbf7bb8e8c7/6a3bf38142879bf916fc31c8_gradient-2.txt 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: false, 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") } material.uniforms = uniforms, material.uniformInstances = []; const prefix = "\n precision highp float;\n "; material.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 `, material.Source = `\n ${prefix}\n ${getUniformVariableDeclarations(_miniGl.commonUniforms,"fragment")}\n ${getUniformVariableDeclarations(uniforms,"fragment")}\n ${fragments}\n `, material.vertexShader = getShaderByType(context.VERTEX_SHADER, material.vertexSource), material.fragmentShader = getShaderByType(context.FRAGMENT_SHADER, material.Source), material.program = context.createProgram(), context.attachShader(material.program, material.vertexShader), context.attachShader(material.program, material.fragmentShader), context.linkProgram(material.program), context.getProgramParameter(material.program, context.LINK_STATUS) || console.error(context.getProgramInfoLog(material.program)), context.useProgram(material.program), material.attachUniforms(void 0, _miniGl.commonUniforms), material.attachUniforms(void 0, material.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` + 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).forEach(([e, attribute]) => { mesh.attributeInstances.push({ attribute: attribute, location: attribute.attach(e, mesh.material.program) }) }), _miniGl.meshes.push(mesh), _miniGl.debug("Mesh.constructor", { mesh: mesh }) } draw() { context.useProgram(this.material.program), this.material.uniformInstances.forEach(({ uniform: e, location: t }) => e.update(t)), this.attributeInstances.forEach(({ attribute: e, location: t }) => e.use(t)), context.drawElements(this.wireframe ? context.LINES : context.TRIANGLES, this.geometry.attributes.index.values.length, context.UNSIGNED_SHORT, 0) } remove() { _miniGl.meshes = _miniGl.meshes.filter(e => e != this) } } }, Attribute: { enumerable: !1, value: class { constructor(e) { this.type = context.FLOAT, this.normalized = !1, this.buffer = context.createBuffer(), Object.assign(this, e), this.update() } update() { void 0 !== this.values && (context.bindBuffer(this.target, this.buffer), context.bufferData(this.target, this.values, context.STATIC_DRAW)) } attach(e, t) { const n = context.getAttribLocation(t, e); return this.target === context.ARRAY_BUFFER && (context.enableVertexAttribArray(n), context.vertexAttribPointer(n, this.size, this.type, this.normalized, 0, 0)), n } use(e) { context.bindBuffer(this.target, this.buffer), this.target === context.ARRAY_BUFFER && (context.enableVertexAttribArray(e), context.vertexAttribPointer(e, this.size, this.type, this.normalized, 0, 0)) } } } }); const a = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; _miniGl.commonUniforms = { projectionMatrix: new _miniGl.Uniform({ type: "mat4", value: a }), modelViewMatrix: new _miniGl.Uniform({ type: "mat4", value: a }), resolution: new _miniGl.Uniform({ type: "vec2", value: [1, 1] }), aspectRatio: new _miniGl.Uniform({ type: "float", value: 1 }) } } setSize(e = 640, t = 480) { this.width = e, this.height = t, this.canvas.width = e, this.canvas.height = t, this.gl.viewport(0, 0, e, t), this.commonUniforms.resolution.value = [e, t], this.commonUniforms.aspectRatio.value = e / t, this.debug("MiniGL.setSize", { width: e, height: t }) } setOrthographicCamera(e = 0, t = 0, n = 0, i = -2e3, s = 2e3) { this.commonUniforms.projectionMatrix.value = [2 / this.width, 0, 0, 0, 0, 2 / this.height, 0, 0, 0, 0, 2 / (i - s), 0, e, t, n, 1], this.debug("setOrthographicCamera", this.commonUniforms.projectionMatrix.value) } render() { this.gl.clearColor(0, 0, 0, 0), this.gl.clearDepth(1), this.meshes.forEach(e => e.draw()) } } function e(object, propertyName, val) { return propertyName in object ? Object.defineProperty(object, propertyName, { value: val, enumerable: !0, configurable: !0, writable: !0 }) : object[propertyName] = val, object } class Gradient { constructor(...t) { e(this, "el", void 0), e(this, "cssVarRetries", 0), e(this, "maxCssVarRetries", 200), e(this, "angle", 0), e(this, "isLoadedClass", !1), e(this, "isScrolling", !1), e(this, "scrollingTimeout", void 0), e(this, "scrollingRefreshDelay", 200), e(this, "isIntersecting", !1), e(this, "shaderFiles", void 0), e(this, "vertexShader", void 0), e(this, "sectionColors", void 0), e(this, "computedCanvasStyle", void 0), e(this, "conf", void 0), e(this, "uniforms", void 0), e(this, "t", 1253106), e(this, "last", 0), e(this, "width", void 0), e(this, "minWidth", 1111), e(this, "height", 600), e(this, "xSegCount", void 0), e(this, "ySegCount", void 0), e(this, "mesh", void 0), e(this, "material", void 0), e(this, "geometry", void 0), e(this, "minigl", void 0), e(this, "scrollObserver", void 0), e(this, "amp", 240), e(this, "seed", 7), e(this, "freqX", 16e-5), e(this, "freqY", 29e-5), e(this, "freqDelta", 1e-5), e(this, "activeColors", [1, 1, 1, 1]), e(this, "isMetaKey", !1), e(this, "isGradientLegendVisible", !1), e(this, "isMouseDown", !1), e(this, "handleScroll", () => { clearTimeout(this.scrollingTimeout), this.scrollingTimeout = setTimeout(this.handleScrollEnd, this.scrollingRefreshDelay), this.isGradientLegendVisible && this.hideGradientLegend(), this.conf.playing && (this.isScrolling = !0, this.pause()) }), e(this, "handleScrollEnd", () => { this.isScrolling = !1, this.isIntersecting && this.play() }), e(this, "resize", () => { this.width = window.innerWidth, this.minigl.setSize(this.width, this.height), this.minigl.setOrthographicCamera(), this.xSegCount = Math.ceil(this.width * this.conf.density[0]), this.ySegCount = Math.ceil(this.height * this.conf.density[1]), this.mesh.geometry.setTopology(this.xSegCount, this.ySegCount), this.mesh.geometry.setSize(this.width, this.height), this.mesh.material.uniforms.u_shadow_power.value = this.width < 600 ? 5 : 6 }), e(this, "handleMouseDown", e => { this.isGradientLegendVisible && (this.isMetaKey = e.metaKey, this.isMouseDown = !0, !1 === this.conf.playing && requestAnimationFrame(this.animate)) }), e(this, "handleMouseUp", () => { this.isMouseDown = !1 }), e(this, "animate", e => { if (!this.shouldSkipFrame(e) || this.isMouseDown) { if (this.t += Math.min(e - this.last, 1e3 / 15), this.last = e, this.isMouseDown) { let e = 160; this.isMetaKey && (e = -160), this.t += e } this.mesh.material.uniforms.u_time.value = this.t, this.minigl.render() } if (0 !== this.last && this.isStatic) return this.minigl.render(), void this.disconnect(); (this.conf.playing || this.isMouseDown) && requestAnimationFrame(this.animate) }), e(this, "addIsLoadedClass", () => { !this.isLoadedClass && (this.isLoadedClass = !0, this.el.classList.add("isLoaded"), setTimeout(() => { this.el.parentElement.classList.add("isLoaded") }, 3e3)) }), e(this, "pause", () => { this.conf.playing = false }), e(this, "play", () => { requestAnimationFrame(this.animate), this.conf.playing = true }), e(this,"initGradient", (selector) => { this.el = document.querySelector(selector); this.connect(); return this; }) } async connect() { this.shaderFiles = { vertex: "varying vec3 v_color;\n\nvoid main() {\n float time = u_time * u_global.noiseSpeed;\n\n vec2 noiseCoord = resolution * uvNorm * u_global.noiseFreq;\n\n vec2 st = 1. - uvNorm.xy;\n\n float tilt = resolution.y / 2.0 * uvNorm.y;\n\n float incline = resolution.x * uvNorm.x / 2.0 * u_vertDeform.incline;\n\n float offset = resolution.x / 2.0 * u_vertDeform.incline * mix(u_vertDeform.offsetBottom, u_vertDeform.offsetTop, uv.y);\n\n float noise = snoise(vec3(\n noiseCoord.x * u_vertDeform.noiseFreq.x + time * u_vertDeform.noiseFlow,\n noiseCoord.y * u_vertDeform.noiseFreq.y,\n time * u_vertDeform.noiseSpeed + u_vertDeform.noiseSeed\n )) * u_vertDeform.noiseAmp;\n\n noise *= 1.0 - pow(abs(uvNorm.y), 2.0);\n\n noise = max(0.0, noise);\n\n vec3 pos = vec3(\n position.x,\n position.y + tilt + incline + noise - offset,\n position.z\n );\n\n if (u_active_colors[0] == 1.) {\n v_color = u_baseColor;\n }\n\n for (int i = 0; i < u_waveLayers_length; i++) {\n if (u_active_colors[i + 1] == 1.) {\n WaveLayers layer = u_waveLayers[i];\n\n float noise = smoothstep(\n layer.noiseFloor,\n layer.noiseCeil,\n snoise(vec3(\n noiseCoord.x * layer.noiseFreq.x + time * layer.noiseFlow,\n noiseCoord.y * layer.noiseFreq.y,\n time * layer.noiseSpeed + layer.noiseSeed\n )) / 2.0 + 0.5\n );\n\n v_color = blendNormal(v_color, layer.color, pow(noise, 4.));\n }\n }\n\n gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);\n}", noise: "vec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec4 mod289(vec4 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec4 permute(vec4 x) {\n return mod289(((x*34.0)+1.0)*x);\n}\n\nvec4 taylorInvSqrt(vec4 r)\n{\n return 1.79284291400159 - 0.85373472095314 * r;\n}\n\nfloat snoise(vec3 v)\n{\n const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n vec3 i = floor(v + dot(v, C.yyy) );\n vec3 x0 = v - i + dot(i, C.xxx) ;\n\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min( g.xyz, l.zxy );\n vec3 i2 = max( g.xyz, l.zxy );\n\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy;\n vec3 x3 = x0 - D.yyy;\n\n i = mod289(i);\n vec4 p = permute( permute( permute(\n i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))\n + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\n float n_ = 0.142857142857;\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z);\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_ );\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4( x.xy, y.xy );\n vec4 b1 = vec4( x.zw, y.zw );\n\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\n vec3 p0 = vec3(a0.xy,h.x);\n vec3 p1 = vec3(a0.zw,h.y);\n vec3 p2 = vec3(a1.xy,h.z);\n vec3 p3 = vec3(a1.zw,h.w);\n\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),\n dot(p2,x2), dot(p3,x3) ) );\n}", blend: "vec3 blendNormal(vec3 base, vec3 blend) {\n\treturn blend;\n}\n\nvec3 blendNormal(vec3 base, vec3 blend, float opacity) {\n\treturn (blendNormal(base, blend) * opacity + base * (1.0 - opacity));\n}", fragment: "varying vec3 v_color;\n\n// Pseudo-random for dithering\nfloat rand(vec2 co){\n return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\nvoid main() {\n vec3 color = v_color;\n if (u_darken_top == 1.0) {\n vec2 st = gl_FragCoord.xy/resolution.xy;\n color.g -= pow(st.y + sin(-12.0) * st.x, u_shadow_power) * 0.4;\n }\n // Dither: add tiny noise to break up color banding\n float dither = (rand(gl_FragCoord.xy) - 0.5) / 255.0;\n color += vec3(dither);\n gl_FragColor = vec4(color, 1.0);\n}" }, this.conf = { presetName: "", wireframe: false, density: [.06, .16], zoom: 1, rotation: 0, playing: true }, document.querySelectorAll("canvas").length < 1 ? console.log("DID NOT LOAD HERO STRIPE CANVAS") : ( this.minigl = new MiniGl(this.el, null, null, !0), requestAnimationFrame(() => { this.el && (this.computedCanvasStyle = getComputedStyle(this.el), this.waitForCssVars()) }) ) } disconnect() { this.scrollObserver && (window.removeEventListener("scroll", this.handleScroll), window.removeEventListener("mousedown", this.handleMouseDown), window.removeEventListener("mouseup", this.handleMouseUp), window.removeEventListener("keydown", this.handleKeyDown), this.scrollObserver.disconnect()), window.removeEventListener("resize", this.resize) } initMaterial() { this.uniforms = { u_time: new this.minigl.Uniform({ value: 0 }), u_shadow_power: new this.minigl.Uniform({ value: 5 }), u_darken_top: new this.minigl.Uniform({ value: "" === this.el.dataset.jsDarkenTop ? 1 : 0 }), u_active_colors: new this.minigl.Uniform({ value: this.activeColors, type: "vec4" }), u_global: new this.minigl.Uniform({ value: { noiseFreq: new this.minigl.Uniform({ value: [this.freqX, this.freqY], type: "vec2" }), noiseSpeed: new this.minigl.Uniform({ value: 12e-6 }) }, type: "struct" }), u_vertDeform: new this.minigl.Uniform({ value: { incline: new this.minigl.Uniform({ value: Math.sin(this.angle) / Math.cos(this.angle) }), offsetTop: new this.minigl.Uniform({ value: -.5 }), offsetBottom: new this.minigl.Uniform({ value: -.5 }), noiseFreq: new this.minigl.Uniform({ value: [1, 4], type: "vec2" }), noiseAmp: new this.minigl.Uniform({ value: this.amp }), noiseSpeed: new this.minigl.Uniform({ value: 10 }), noiseFlow: new this.minigl.Uniform({ value: 3 }), noiseSeed: new this.minigl.Uniform({ value: this.seed }) }, type: "struct", excludeFrom: "fragment" }), u_baseColor: new this.minigl.Uniform({ value: this.sectionColors[0], type: "vec3", excludeFrom: "fragment" }), u_waveLayers: new this.minigl.Uniform({ value: [], excludeFrom: "fragment", type: "array" }) }; for (let e = 1; e < this.sectionColors.length; e += 1) this.uniforms.u_waveLayers.value.push(new this.minigl.Uniform({ value: { color: new this.minigl.Uniform({ value: this.sectionColors[e], type: "vec3" }), noiseFreq: new this.minigl.Uniform({ value: [2 + e / this.sectionColors.length, 3 + e / this.sectionColors.length], type: "vec2" }), noiseSpeed: new this.minigl.Uniform({ value: 11 + .3 * e }), noiseFlow: new this.minigl.Uniform({ value: 6.5 + .3 * e }), noiseSeed: new this.minigl.Uniform({ value: this.seed + 10 * e }), noiseFloor: new this.minigl.Uniform({ value: .1 }), noiseCeil: new this.minigl.Uniform({ value: .63 + .07 * e }) }, type: "struct" })); return this.vertexShader = [this.shaderFiles.noise, this.shaderFiles.blend, this.shaderFiles.vertex].join("\n\n"), new this.minigl.Material(this.vertexShader, this.shaderFiles.fragment, this.uniforms) } initMesh() { this.material = this.initMaterial(), this.geometry = new this.minigl.PlaneGeometry, this.mesh = new this.minigl.Mesh(this.geometry, this.material) } shouldSkipFrame(e) { return !!window.document.hidden || (!this.conf.playing || (parseInt(e, 10) % 2 == 0 || void 0)) } updateFrequency(e) { this.freqX += e, this.freqY += e } toggleColor(index) { this.activeColors[index] = 0 === this.activeColors[index] ? 1 : 0 } showGradientLegend() { this.width > this.minWidth && (this.isGradientLegendVisible = !0, document.body.classList.add("isGradientLegendVisible")) } hideGradientLegend() { this.isGradientLegendVisible = !1, document.body.classList.remove("isGradientLegendVisible") } init() { this.initGradientColors(), this.initMesh(), this.resize(), requestAnimationFrame(this.animate), window.addEventListener("resize", this.resize) } waitForCssVars() { if (this.computedCanvasStyle && -1 !== this.computedCanvasStyle.getPropertyValue("--gradient-color-1").indexOf("#")) this.init(), this.addIsLoadedClass(); else { if (this.cssVarRetries += 1, this.cssVarRetries > this.maxCssVarRetries) { return this.sectionColors = [16711680, 16711680, 16711935, 65280, 255],void this.init(); } requestAnimationFrame(() => this.waitForCssVars()) } } initGradientColors() { this.sectionColors = ["--gradient-color-1", "--gradient-color-2", "--gradient-color-3", "--gradient-color-4", "--gradient-color-5"].map(cssPropertyName => { let hex = this.computedCanvasStyle.getPropertyValue(cssPropertyName).trim(); if (4 === hex.length) { const hexTemp = hex.substr(1).split("").map(hexTemp => hexTemp + hexTemp).join(""); hex = `#${hexTemp}` } return hex && `0x${hex.substr(1)}` }).filter(Boolean).map(normalizeColor) } }