ng-cw-v12
Version:
Angular UI Component Library
407 lines (381 loc) • 17.4 kB
JavaScript
import * as i0 from '@angular/core';
import { Component, ViewChild, Input, HostListener, NgModule } from '@angular/core';
import * as THREE from 'three';
import { CommonModule } from '@angular/common';
const vertexShader = `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = vec4(position, 1.0);
}
`;
const fragmentShader = `
precision highp float;
uniform float uTime;
uniform vec3 uResolution;
uniform float uSpeed;
uniform float uScale;
uniform float uBrightness;
uniform vec3 uColor1;
uniform vec3 uColor2;
uniform float uNoiseFreq;
uniform float uNoiseAmp;
uniform float uBandHeight;
uniform float uBandSpread;
uniform float uOctaveDecay;
uniform float uLayerOffset;
uniform float uColorSpeed;
uniform vec2 uMouse;
uniform float uMouseInfluence;
uniform bool uEnableMouse;
#define TAU 6.28318
vec3 gradientHash(vec3 p) {
p = vec3(
dot(p, vec3(127.1, 311.7, 234.6)),
dot(p, vec3(269.5, 183.3, 198.3)),
dot(p, vec3(169.5, 283.3, 156.9))
);
vec3 h = fract(sin(p) * 43758.5453123);
float phi = acos(2.0 * h.x - 1.0);
float theta = TAU * h.y;
return vec3(cos(theta) * sin(phi), sin(theta) * cos(phi), cos(phi));
}
float quinticSmooth(float t) {
float t2 = t * t;
float t3 = t * t2;
return 6.0 * t3 * t2 - 15.0 * t2 * t2 + 10.0 * t3;
}
vec3 cosineGradient(float t, vec3 a, vec3 b, vec3 c, vec3 d) {
return a + b * cos(TAU * (c * t + d));
}
float perlin3D(float amplitude, float frequency, float px, float py, float pz) {
float x = px * frequency;
float y = py * frequency;
float fx = floor(x); float fy = floor(y); float fz = floor(pz);
float cx = ceil(x); float cy = ceil(y); float cz = ceil(pz);
vec3 g000 = gradientHash(vec3(fx, fy, fz));
vec3 g100 = gradientHash(vec3(cx, fy, fz));
vec3 g010 = gradientHash(vec3(fx, cy, fz));
vec3 g110 = gradientHash(vec3(cx, cy, fz));
vec3 g001 = gradientHash(vec3(fx, fy, cz));
vec3 g101 = gradientHash(vec3(cx, fy, cz));
vec3 g011 = gradientHash(vec3(fx, cy, cz));
vec3 g111 = gradientHash(vec3(cx, cy, cz));
float d000 = dot(g000, vec3(x - fx, y - fy, pz - fz));
float d100 = dot(g100, vec3(x - cx, y - fy, pz - fz));
float d010 = dot(g010, vec3(x - fx, y - cy, pz - fz));
float d110 = dot(g110, vec3(x - cx, y - cy, pz - fz));
float d001 = dot(g001, vec3(x - fx, y - fy, pz - cz));
float d101 = dot(g101, vec3(x - cx, y - fy, pz - cz));
float d011 = dot(g011, vec3(x - fx, y - cy, pz - cz));
float d111 = dot(g111, vec3(x - cx, y - cy, pz - cz));
float sx = quinticSmooth(x - fx);
float sy = quinticSmooth(y - fy);
float sz = quinticSmooth(pz - fz);
float lx00 = mix(d000, d100, sx);
float lx10 = mix(d010, d110, sx);
float lx01 = mix(d001, d101, sx);
float lx11 = mix(d011, d111, sx);
float ly0 = mix(lx00, lx10, sy);
float ly1 = mix(lx01, lx11, sy);
return amplitude * mix(ly0, ly1, sz);
}
float auroraGlow(float t, vec2 shift) {
vec2 uv = gl_FragCoord.xy / uResolution.y;
uv += shift;
float noiseVal = 0.0;
float freq = uNoiseFreq;
float amp = uNoiseAmp;
vec2 samplePos = uv * uScale;
for (float i = 0.0; i < 3.0; i += 1.0) {
noiseVal += perlin3D(amp, freq, samplePos.x, samplePos.y, t);
amp *= uOctaveDecay;
freq *= 2.0;
}
float yBand = uv.y * 10.0 - uBandHeight * 10.0;
return 0.3 * max(exp(uBandSpread * (1.0 - 1.1 * abs(noiseVal + yBand))), 0.0);
}
void main() {
vec2 uv = gl_FragCoord.xy / uResolution.xy;
float t = uSpeed * 0.4 * uTime;
vec2 shift = vec2(0.0);
if (uEnableMouse) {
shift = (uMouse - 0.5) * uMouseInfluence;
}
vec3 col = vec3(0.0);
col += 0.99 * auroraGlow(t, shift) * cosineGradient(uv.x + uTime * uSpeed * 0.2 * uColorSpeed, vec3(0.5), vec3(0.5), vec3(1.0), vec3(0.3, 0.20, 0.20)) * uColor1;
col += 0.99 * auroraGlow(t + uLayerOffset, shift) * cosineGradient(uv.x + uTime * uSpeed * 0.1 * uColorSpeed, vec3(0.5), vec3(0.5), vec3(2.0, 1.0, 0.0), vec3(0.5, 0.20, 0.25)) * uColor2;
col *= uBrightness;
float alpha = clamp(length(col), 0.0, 1.0);
gl_FragColor = vec4(col, alpha);
}
`;
class SoftAuroraBackgroundComponent {
constructor(ngZone) {
this.ngZone = ngZone;
/** 播放速度(0.1-5) */
this.ncSpeed = 0.6;
/** 缩放比例(0.1-3) */
this.ncScale = 1.5;
/** 亮度(0.1-3) */
this.ncBrightness = 1.0;
/** 光晕颜色1 */
this.ncColor1 = '#f7f7f7';
/** 光晕颜色2 */
this.ncColor2 = '#e100ff';
/** 噪声频率(0.5-10) */
this.ncNoiseFrequency = 2.5;
/** 噪声幅度(0.5-10) */
this.ncNoiseAmplitude = 1.0;
/** 色带高度位置(0-1) */
this.ncBandHeight = 0.5;
/** 色带扩展程度(0.1-3) */
this.ncBandSpread = 1.0;
/** 噪声每层的衰减量(0.01-0.5) */
this.ncOctaveDecay = 0.1;
/** 两层极光之间的时间差(0-1) */
this.ncLayerOffset = 0;
/** 颜色渐变速度(0.1-5) */
this.ncColorSpeed = 1.0;
/** 鼠标事件的影响力(0.1-1) */
this.ncMouseInfluence = 0.25;
/** 是否启用鼠标交互 */
this._enableMouseInteraction = true;
this.animationFrameId = null;
this.targetMouse = [0.5, 0.5];
this.currentMouse = [0.5, 0.5];
this.timeOffset = 0;
this.lastTime = 0;
this.animate = () => {
this.animationFrameId = requestAnimationFrame(this.animate);
const currentTime = performance.now();
this.timeOffset += (currentTime - this.lastTime);
this.lastTime = currentTime;
if (this.material) {
this.material.uniforms['uTime'].value = this.timeOffset * 0.001;
if (this.ncEnableMouseInteraction) {
this.currentMouse[0] += 0.05 * (this.targetMouse[0] - this.currentMouse[0]);
this.currentMouse[1] += 0.05 * (this.targetMouse[1] - this.currentMouse[1]);
this.material.uniforms['uMouse'].value.set(this.currentMouse[0], this.currentMouse[1]);
}
else {
this.material.uniforms['uMouse'].value.set(0.5, 0.5);
}
this.renderer.render(this.scene, this.camera);
}
};
}
set ncEnableMouseInteraction(val) {
this._enableMouseInteraction = val !== null && val !== undefined && val !== false && val !== 'false';
}
get ncEnableMouseInteraction() {
return this._enableMouseInteraction;
}
ngOnInit() { }
ngAfterViewInit() {
this.ngZone.runOutsideAngular(() => {
this.initThreeJS();
});
}
ngOnDestroy() {
this.cleanup();
}
ngOnChanges(changes) {
if (!this.material)
return;
if (changes['ncSpeed'])
this.material.uniforms['uSpeed'].value = this.ncSpeed;
if (changes['ncScale'])
this.material.uniforms['uScale'].value = this.ncScale;
if (changes['ncBrightness'])
this.material.uniforms['uBrightness'].value = this.ncBrightness;
if (changes['ncColor1'])
this.material.uniforms['uColor1'].value.set(this.ncColor1);
if (changes['ncColor2'])
this.material.uniforms['uColor2'].value.set(this.ncColor2);
if (changes['ncNoiseFrequency'])
this.material.uniforms['uNoiseFreq'].value = this.ncNoiseFrequency;
if (changes['ncNoiseAmplitude'])
this.material.uniforms['uNoiseAmp'].value = this.ncNoiseAmplitude;
if (changes['ncBandHeight'])
this.material.uniforms['uBandHeight'].value = this.ncBandHeight;
if (changes['ncBandSpread'])
this.material.uniforms['uBandSpread'].value = this.ncBandSpread;
if (changes['ncOctaveDecay'])
this.material.uniforms['uOctaveDecay'].value = this.ncOctaveDecay;
if (changes['ncLayerOffset'])
this.material.uniforms['uLayerOffset'].value = this.ncLayerOffset;
if (changes['ncColorSpeed'])
this.material.uniforms['uColorSpeed'].value = this.ncColorSpeed;
if (changes['ncMouseInfluence'])
this.material.uniforms['uMouseInfluence'].value = this.ncMouseInfluence;
if (changes['ncEnableMouseInteraction'])
this.material.uniforms['uEnableMouse'].value = this.ncEnableMouseInteraction;
}
onMouseMove(e) {
if (!this.ncEnableMouseInteraction || !this.renderer)
return;
const canvas = this.renderer.domElement;
const rect = canvas.getBoundingClientRect();
if (rect.width === 0 || rect.height === 0)
return;
this.targetMouse = [
(e.clientX - rect.left) / rect.width,
1.0 - (e.clientY - rect.top) / rect.height
];
}
onMouseLeave() {
if (!this.ncEnableMouseInteraction)
return;
this.targetMouse = [0.5, 0.5];
}
initThreeJS() {
const container = this.containerRef.nativeElement;
this.renderer = new THREE.WebGLRenderer({ alpha: true, antialias: false, premultipliedAlpha: false });
this.renderer.setClearColor(0x000000, 0); // transparent background
this.scene = new THREE.Scene();
this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
this.material = new THREE.ShaderMaterial({
vertexShader,
fragmentShader,
transparent: true,
uniforms: {
uTime: { value: 0 },
uResolution: { value: new THREE.Vector3() },
uSpeed: { value: this.ncSpeed },
uScale: { value: this.ncScale },
uBrightness: { value: this.ncBrightness },
uColor1: { value: new THREE.Color(this.ncColor1) },
uColor2: { value: new THREE.Color(this.ncColor2) },
uNoiseFreq: { value: this.ncNoiseFrequency },
uNoiseAmp: { value: this.ncNoiseAmplitude },
uBandHeight: { value: this.ncBandHeight },
uBandSpread: { value: this.ncBandSpread },
uOctaveDecay: { value: this.ncOctaveDecay },
uLayerOffset: { value: this.ncLayerOffset },
uColorSpeed: { value: this.ncColorSpeed },
uMouse: { value: new THREE.Vector2(0.5, 0.5) },
uMouseInfluence: { value: this.ncMouseInfluence },
uEnableMouse: { value: this.ncEnableMouseInteraction }
}
});
const geometry = new THREE.PlaneGeometry(2, 2);
this.mesh = new THREE.Mesh(geometry, this.material);
this.scene.add(this.mesh);
container.appendChild(this.renderer.domElement);
this.resizeObserver = new ResizeObserver(() => this.resize());
this.resizeObserver.observe(container);
this.resize();
this.lastTime = performance.now();
this.animate();
}
resize() {
if (!this.containerRef || !this.renderer)
return;
const container = this.containerRef.nativeElement;
const width = container.offsetWidth;
const height = container.offsetHeight;
if (width === 0 || height === 0)
return;
this.renderer.setSize(width, height);
if (this.material) {
this.material.uniforms['uResolution'].value.set(width, height, width / height);
}
}
cleanup() {
if (this.animationFrameId !== null) {
cancelAnimationFrame(this.animationFrameId);
this.animationFrameId = null;
}
if (this.resizeObserver) {
this.resizeObserver.disconnect();
}
if (this.renderer && this.containerRef) {
const container = this.containerRef.nativeElement;
if (container.contains(this.renderer.domElement)) {
container.removeChild(this.renderer.domElement);
}
this.renderer.dispose();
this.renderer.forceContextLoss();
}
if (this.mesh) {
if (this.mesh.geometry)
this.mesh.geometry.dispose();
if (this.material)
this.material.dispose();
}
}
}
SoftAuroraBackgroundComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: SoftAuroraBackgroundComponent, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
SoftAuroraBackgroundComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.5", type: SoftAuroraBackgroundComponent, selector: "nc-soft-aurora-background", inputs: { ncSpeed: "ncSpeed", ncScale: "ncScale", ncBrightness: "ncBrightness", ncColor1: "ncColor1", ncColor2: "ncColor2", ncNoiseFrequency: "ncNoiseFrequency", ncNoiseAmplitude: "ncNoiseAmplitude", ncBandHeight: "ncBandHeight", ncBandSpread: "ncBandSpread", ncOctaveDecay: "ncOctaveDecay", ncLayerOffset: "ncLayerOffset", ncColorSpeed: "ncColorSpeed", ncMouseInfluence: "ncMouseInfluence", ncEnableMouseInteraction: "ncEnableMouseInteraction" }, host: { listeners: { "mousemove": "onMouseMove($event)", "mouseleave": "onMouseLeave()" } }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div #container class=\"nc-soft-aurora-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-soft-aurora-canvas-container{position:absolute;inset:0;z-index:0;width:100%;height:100%;background-color:#000}.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: SoftAuroraBackgroundComponent, decorators: [{
type: Component,
args: [{
selector: 'nc-soft-aurora-background',
templateUrl: './soft-aurora-background.component.html',
styleUrls: ['./soft-aurora-background.component.less']
}]
}], ctorParameters: function () { return [{ type: i0.NgZone }]; }, propDecorators: { containerRef: [{
type: ViewChild,
args: ['container', { static: true }]
}], ncSpeed: [{
type: Input
}], ncScale: [{
type: Input
}], ncBrightness: [{
type: Input
}], ncColor1: [{
type: Input
}], ncColor2: [{
type: Input
}], ncNoiseFrequency: [{
type: Input
}], ncNoiseAmplitude: [{
type: Input
}], ncBandHeight: [{
type: Input
}], ncBandSpread: [{
type: Input
}], ncOctaveDecay: [{
type: Input
}], ncLayerOffset: [{
type: Input
}], ncColorSpeed: [{
type: Input
}], ncMouseInfluence: [{
type: Input
}], ncEnableMouseInteraction: [{
type: Input
}], onMouseMove: [{
type: HostListener,
args: ['mousemove', ['$event']]
}], onMouseLeave: [{
type: HostListener,
args: ['mouseleave']
}] } });
class NcSoftAuroraBackgroundModule {
}
NcSoftAuroraBackgroundModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcSoftAuroraBackgroundModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
NcSoftAuroraBackgroundModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcSoftAuroraBackgroundModule, declarations: [SoftAuroraBackgroundComponent], imports: [CommonModule], exports: [SoftAuroraBackgroundComponent] });
NcSoftAuroraBackgroundModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcSoftAuroraBackgroundModule, imports: [[
CommonModule
]] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcSoftAuroraBackgroundModule, decorators: [{
type: NgModule,
args: [{
declarations: [
SoftAuroraBackgroundComponent
],
imports: [
CommonModule
],
exports: [
SoftAuroraBackgroundComponent
]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { NcSoftAuroraBackgroundModule, SoftAuroraBackgroundComponent };
//# sourceMappingURL=ng-cw-v12-soft-aurora-background.js.map