ng-cw-v12
Version:
Angular UI Component Library
279 lines (262 loc) • 11.8 kB
JavaScript
import * as i0 from '@angular/core';
import { Component, ViewChild, Input, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
class LightningBackgroundComponent {
constructor(ngZone) {
this.ngZone = ngZone;
/** 闪电的色调(度数,0到360) */
this.ncHue = 230;
/** 闪电水平偏移量(-2~2) */
this.ncXOffset = 0;
/** 闪电动画速度倍率(0.5-2) */
this.ncSpeed = 1;
/** 闪电强度(0.1-2) */
this.ncIntensity = 1;
/** 闪电密集程度(0.1-3) */
this.ncSize = 1;
this.gl = null;
this.program = null;
this.rafId = null;
this.startTime = 0;
// WebGL Uniform locations
this.locResolution = null;
this.locTime = null;
this.locHue = null;
this.locXOffset = null;
this.locSpeed = null;
this.locIntensity = null;
this.locSize = null;
this.vertexShaderSource = `
attribute vec2 aPosition;
void main() {
gl_Position = vec4(aPosition, 0.0, 1.0);
}
`;
this.fragmentShaderSource = `
precision mediump float;
uniform vec2 iResolution;
uniform float iTime;
uniform float uHue;
uniform float uXOffset;
uniform float uSpeed;
uniform float uIntensity;
uniform float uSize;
#define OCTAVE_COUNT 10
vec3 hsv2rgb(vec3 c) {
vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);
return c.z * mix(vec3(1.0), rgb, c.y);
}
float hash11(float p) {
p = fract(p * .1031);
p *= p + 33.33;
p *= p + p;
return fract(p);
}
float hash12(vec2 p) {
vec3 p3 = fract(vec3(p.xyx) * .1031);
p3 += dot(p3, p3.yzx + 33.33);
return fract((p3.x + p3.y) * p3.z);
}
mat2 rotate2d(float theta) {
float c = cos(theta);
float s = sin(theta);
return mat2(c, -s, s, c);
}
float noise(vec2 p) {
vec2 ip = floor(p);
vec2 fp = fract(p);
float a = hash12(ip);
float b = hash12(ip + vec2(1.0, 0.0));
float c = hash12(ip + vec2(0.0, 1.0));
float d = hash12(ip + vec2(1.0, 1.0));
vec2 t = smoothstep(0.0, 1.0, fp);
return mix(mix(a, b, t.x), mix(c, d, t.x), t.y);
}
float fbm(vec2 p) {
float value = 0.0;
float amplitude = 0.5;
for (int i = 0; i < OCTAVE_COUNT; ++i) {
value += amplitude * noise(p);
p *= rotate2d(0.45);
p *= 2.0;
amplitude *= 0.5;
}
return value;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
vec2 uv = fragCoord / iResolution.xy;
uv = 2.0 * uv - 1.0;
uv.x *= iResolution.x / iResolution.y;
uv.x += uXOffset;
uv += 2.0 * fbm(uv * uSize + 0.8 * iTime * uSpeed) - 1.0;
float dist = abs(uv.x);
vec3 baseColor = hsv2rgb(vec3(uHue / 360.0, 0.7, 0.8));
vec3 col = baseColor * pow(mix(0.0, 0.07, hash11(iTime * uSpeed)) / dist, 1.0) * uIntensity;
col = pow(col, vec3(1.0));
fragColor = vec4(col, 1.0);
}
void main() {
mainImage(gl_FragColor, gl_FragCoord.xy);
}
`;
this.render = () => {
if (!this.gl || !this.program)
return;
this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
this.gl.uniform2f(this.locResolution, this.canvas.width, this.canvas.height);
const currentTime = performance.now();
this.gl.uniform1f(this.locTime, (currentTime - this.startTime) / 1000.0);
this.gl.uniform1f(this.locHue, this.ncHue);
this.gl.uniform1f(this.locXOffset, this.ncXOffset);
this.gl.uniform1f(this.locSpeed, this.ncSpeed);
this.gl.uniform1f(this.locIntensity, this.ncIntensity);
this.gl.uniform1f(this.locSize, this.ncSize);
this.gl.drawArrays(this.gl.TRIANGLES, 0, 6);
this.rafId = requestAnimationFrame(this.render);
};
}
ngOnInit() {
}
ngAfterViewInit() {
this.initWebGL();
}
ngOnChanges(changes) {
// WebGL loops read parameters dynamically, no need for extra updates unless structural or texture-based changing.
}
ngOnDestroy() {
if (this.rafId !== null) {
cancelAnimationFrame(this.rafId);
}
if (this.resizeObserver) {
this.resizeObserver.disconnect();
}
if (this.gl && this.program) {
this.gl.deleteProgram(this.program);
}
}
initWebGL() {
const container = this.containerRef.nativeElement;
this.canvas = document.createElement('canvas');
this.canvas.style.width = '100%';
this.canvas.style.height = '100%';
this.canvas.style.display = 'block';
container.appendChild(this.canvas);
this.gl = this.canvas.getContext('webgl');
if (!this.gl) {
console.error('WebGL not supported');
return;
}
const vertexShader = this.compileShader(this.vertexShaderSource, this.gl.VERTEX_SHADER);
const fragmentShader = this.compileShader(this.fragmentShaderSource, this.gl.FRAGMENT_SHADER);
if (!vertexShader || !fragmentShader)
return;
this.program = this.gl.createProgram();
if (!this.program)
return;
this.gl.attachShader(this.program, vertexShader);
this.gl.attachShader(this.program, fragmentShader);
this.gl.linkProgram(this.program);
if (!this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS)) {
console.error('Program linking error:', this.gl.getProgramInfoLog(this.program));
return;
}
this.gl.useProgram(this.program);
const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);
const vertexBuffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);
const aPosition = this.gl.getAttribLocation(this.program, 'aPosition');
this.gl.enableVertexAttribArray(aPosition);
this.gl.vertexAttribPointer(aPosition, 2, this.gl.FLOAT, false, 0, 0);
this.locResolution = this.gl.getUniformLocation(this.program, 'iResolution');
this.locTime = this.gl.getUniformLocation(this.program, 'iTime');
this.locHue = this.gl.getUniformLocation(this.program, 'uHue');
this.locXOffset = this.gl.getUniformLocation(this.program, 'uXOffset');
this.locSpeed = this.gl.getUniformLocation(this.program, 'uSpeed');
this.locIntensity = this.gl.getUniformLocation(this.program, 'uIntensity');
this.locSize = this.gl.getUniformLocation(this.program, 'uSize');
this.startTime = performance.now();
this.resizeObserver = new ResizeObserver(() => {
this.resizeCanvas();
});
this.resizeObserver.observe(container);
this.resizeCanvas();
this.ngZone.runOutsideAngular(() => {
this.render();
});
}
compileShader(source, type) {
if (!this.gl)
return null;
const shader = this.gl.createShader(type);
if (!shader)
return null;
this.gl.shaderSource(shader, source);
this.gl.compileShader(shader);
if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
console.error('Shader compile error:', this.gl.getShaderInfoLog(shader));
this.gl.deleteShader(shader);
return null;
}
return shader;
}
resizeCanvas() {
if (!this.canvas)
return;
const width = this.canvas.clientWidth;
const height = this.canvas.clientHeight;
if (this.canvas.width !== width || this.canvas.height !== height) {
this.canvas.width = width;
this.canvas.height = height;
}
}
}
LightningBackgroundComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: LightningBackgroundComponent, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
LightningBackgroundComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: LightningBackgroundComponent, selector: "nc-lightning-background", inputs: { ncHue: "ncHue", ncXOffset: "ncXOffset", ncSpeed: "ncSpeed", ncIntensity: "ncIntensity", ncSize: "ncSize" }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div #container class=\"nc-lightning-canvas-container\"></div>\r\n<div class=\"nc-content-wrapper\">\r\n <ng-content></ng-content>\r\n</div>\r\n", styles: [":host{display:block;position:relative;width:100%;height:100%;overflow:hidden}.nc-lightning-canvas-container{position:absolute;inset:0;z-index:0}.nc-content-wrapper{position:relative;z-index:1;width:100%;height:100%}\n"] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: LightningBackgroundComponent, decorators: [{
type: Component,
args: [{
selector: 'nc-lightning-background',
templateUrl: './lightning-background.component.html',
styleUrls: ['./lightning-background.component.less']
}]
}], ctorParameters: function () { return [{ type: i0.NgZone }]; }, propDecorators: { containerRef: [{
type: ViewChild,
args: ['container', { static: true }]
}], ncHue: [{
type: Input
}], ncXOffset: [{
type: Input
}], ncSpeed: [{
type: Input
}], ncIntensity: [{
type: Input
}], ncSize: [{
type: Input
}] } });
class NcLightningBackgroundModule {
}
NcLightningBackgroundModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcLightningBackgroundModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
NcLightningBackgroundModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcLightningBackgroundModule, declarations: [LightningBackgroundComponent], imports: [CommonModule], exports: [LightningBackgroundComponent] });
NcLightningBackgroundModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcLightningBackgroundModule, imports: [[
CommonModule
]] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcLightningBackgroundModule, decorators: [{
type: NgModule,
args: [{
declarations: [
LightningBackgroundComponent
],
imports: [
CommonModule
],
exports: [
LightningBackgroundComponent
]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { LightningBackgroundComponent, NcLightningBackgroundModule };
//# sourceMappingURL=ng-cw-v12-lightning-background.js.map