系列文章
序号 | 目录 |
1 | HTML满屏跳动的爱心(可写字) |
2 | HTML五彩缤纷的爱心 |
3 | HTML满屏漂浮爱心 |
4 | HTML情人节快乐 |
5 | HTML蓝色爱心射线 |
6 | HTML跳动的爱心(简易版) |
7 | HTML粒子爱心 |
8 | HTML蓝色动态爱心 |
9 | HTML跳动的爱心(双心版) |
10 | HTML橙色动态粒子爱心 |
11 | HTML旋转爱心 |
12 | HTML爱情树 |
13 | HTML3D相册 |
14 | HTML旋转相册 |
15 | HTML基础烟花秀 |
16 | HTML炫酷烟花秀 |
17 | HTML粉色烟花秀 |
18 | HTML新春烟花 |
19 | HTML龙年大吉 |
20 | HTML音乐圣诞树 |
21 | HTML大雪纷飞 |
22 | HTML想见你 |
23 | HTML元素周期表 |
24 | HTML飞舞的花瓣 |
25 | HTML星空特效 |
26 | HTML黑客帝国字母雨 |
27 | HTML哆啦A梦 |
28 | HTML流星雨 |
29 | HTML沙漏爱心 |
30 | HTML爱心字母雨 |
31 | HTML爱心流星雨 |
32 | HTML生日蛋糕 |
33 | HTML3D旋转相册 |
34 | HTML流光爱心 |
35 | HTML满屏飘字 |
36 | HTML飞舞爱心 |
37 | HTML雪花圣诞树 |
写在前面
HTML语言实现礼物圣诞树的完整代码。
HTML语言
HTML语言(Hypertext Markup Language)是一种用于创建网页的标记语言。它使用标记来描述网页的结构和内容,并定义了网页中的各种元素和布局。
HTML语言由一系列标签组成,每个标签都用尖括号包围,例如:`<tag>content</tag>`。标签用于定义网页中的各种元素,如标题、段落、列表、链接等。
HTML语言的标签主要分为两类:块级元素和内联元素。块级元素占据一整行,例如段落标签`<p>`、标题标签`<h1>`等,它们可以包含其他块级元素或内联元素。内联元素只占据一定的空间,例如加粗标签`<b>`、链接标签`<a>`等,它们不能包含块级元素。
除了标签,HTML语言还有属性。属性用于为标签提供附加信息,如链接的目标网址、图片的地址、元素的样式等。属性通常在标签的开始标签中进行定义,例如:`<tag attribute="value">content</tag>`。
HTML语言的结构主要由`<!DOCTYPE>`声明、`<html>`元素、`<head>`元素和`<body>`元素组成。`<!DOCTYPE>`声明用于指定HTML版本,`<html>`元素是HTML文档的根元素,`<head>`元素用于定义文档的元信息,如标题、样式和脚本等,`<body>`元素包含网页的实际内容。
在HTML语言中,可以通过嵌套标签、引用外部样式表和脚本、使用CSS语言定义样式、使用JavaScript语言添加交互功能等来实现丰富的网页效果和功能。
HTML语言是一种简单易学的标记语言,几乎所有的网页都是使用HTML语言来创建的。它被广泛应用于互联网和Web开发领域,是构建网页和浏览器显示内容的基础。随着技术的进步,HTML语言不断更新和发展,目前最新的版本是HTML5,它提供了更多的新特性和改进,如多媒体支持、本地存储、Canvas绘图等。
总的来说,HTML语言是一种用于创建网页的标记语言,通过标签和属性来描述网页的结构和内容。它是构建网页和Web应用的基础,广泛应用于互联网和Web开发领域,是学习Web开发的重要基础知识。
完整代码
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>圣诞快乐</title><style><script>THREE.EffectComposer = function ( renderer, renderTarget ) {this.renderer = renderer;if ( renderTarget === undefined ) {var parameters = {minFilter: THREE.LinearFilter,magFilter: THREE.LinearFilter,format: THREE.RGBAFormat,stencilBuffer: false};var size = renderer.getSize( new THREE.Vector2() );this._pixelRatio = renderer.getPixelRatio();this._width = size.width;this._height = size.height;renderTarget = new THREE.WebGLRenderTarget( this._width * this._pixelRatio, this._height * this._pixelRatio, parameters );renderTarget.texture.name = 'EffectComposer.rt1';} else {this._pixelRatio = 1;this._width = renderTarget.width;this._height = renderTarget.height;}this.renderTarget1 = renderTarget;this.renderTarget2 = renderTarget.clone();this.renderTarget2.texture.name = 'EffectComposer.rt2';this.writeBuffer = this.renderTarget1;this.readBuffer = this.renderTarget2;this.renderToScreen = true;this.passes = [];// dependenciesif ( THREE.CopyShader === undefined ) {console.error( 'THREE.EffectComposer relies on THREE.CopyShader' );}if ( THREE.ShaderPass === undefined ) {console.error( 'THREE.EffectComposer relies on THREE.ShaderPass' );}this.copyPass = new THREE.ShaderPass( THREE.CopyShader );this.clock = new THREE.Clock();};Object.assign( THREE.EffectComposer.prototype, {swapBuffers: function () {var tmp = this.readBuffer;this.readBuffer = this.writeBuffer;this.writeBuffer = tmp;},addPass: function ( pass ) {this.passes.push( pass );pass.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );},insertPass: function ( pass, index ) {this.passes.splice( index, 0, pass );},isLastEnabledPass: function ( passIndex ) {for ( var i = passIndex + 1; i < this.passes.length; i ++ ) {if ( this.passes[ i ].enabled ) {return false;}}return true;},render: function ( deltaTime ) {// deltaTime value is in secondsif ( deltaTime === undefined ) {deltaTime = this.clock.getDelta();}var currentRenderTarget = this.renderer.getRenderTarget();var maskActive = false;var pass, i, il = this.passes.length;for ( i = 0; i < il; i ++ ) {pass = this.passes[ i ];if ( pass.enabled === false ) continue;pass.renderToScreen = ( this.renderToScreen && this.isLastEnabledPass( i ) );pass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime, maskActive );if ( pass.needsSwap ) {if ( maskActive ) {var context = this.renderer.getContext();var stencil = this.renderer.state.buffers.stencil;//context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );stencil.setFunc( context.NOTEQUAL, 1, 0xffffffff );this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime );//context.stencilFunc( context.EQUAL, 1, 0xffffffff );stencil.setFunc( context.EQUAL, 1, 0xffffffff );}this.swapBuffers();}if ( THREE.MaskPass !== undefined ) {if ( pass instanceof THREE.MaskPass ) {maskActive = true;} else if ( pass instanceof THREE.ClearMaskPass ) {maskActive = false;}}}this.renderer.setRenderTarget( currentRenderTarget );},reset: function ( renderTarget ) {if ( renderTarget === undefined ) {var size = this.renderer.getSize( new THREE.Vector2() );this._pixelRatio = this.renderer.getPixelRatio();this._width = size.width;this._height = size.height;renderTarget = this.renderTarget1.clone();renderTarget.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );}this.renderTarget1.dispose();this.renderTarget2.dispose();this.renderTarget1 = renderTarget;this.renderTarget2 = renderTarget.clone();this.writeBuffer = this.renderTarget1;this.readBuffer = this.renderTarget2;},setSize: function ( width, height ) {this._width = width;this._height = height;var effectiveWidth = this._width * this._pixelRatio;var effectiveHeight = this._height * this._pixelRatio;this.renderTarget1.setSize( effectiveWidth, effectiveHeight );this.renderTarget2.setSize( effectiveWidth, effectiveHeight );for ( var i = 0; i < this.passes.length; i ++ ) {this.passes[ i ].setSize( effectiveWidth, effectiveHeight );}},setPixelRatio: function ( pixelRatio ) {this._pixelRatio = pixelRatio;this.setSize( this._width, this._height );}} );THREE.Pass = function () {// if set to true, the pass is processed by the composerthis.enabled = true;// if set to true, the pass indicates to swap read and write buffer after renderingthis.needsSwap = true;// if set to true, the pass clears its buffer before renderingthis.clear = false;// if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.this.renderToScreen = false;};Object.assign( THREE.Pass.prototype, {setSize: function ( /* width, height */ ) {},render: function ( /* renderer, writeBuffer, readBuffer, deltaTime, maskActive */ ) {console.error( 'THREE.Pass: .render() must be implemented in derived pass.' );}} );// Helper for passes that need to fill the viewport with a single quad.THREE.Pass.FullScreenQuad = ( function () {var camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );var geometry = new THREE.PlaneBufferGeometry( 2, 2 );var FullScreenQuad = function ( material ) {this._mesh = new THREE.Mesh( geometry, material );};Object.defineProperty( FullScreenQuad.prototype, 'material', {get: function () {return this._mesh.material;},set: function ( value ) {this._mesh.material = value;}} );Object.assign( FullScreenQuad.prototype, {dispose: function () {this._mesh.geometry.dispose();},render: function ( renderer ) {renderer.render( this._mesh, camera );}} );return FullScreenQuad;} )();</script><script>THREE.RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) {THREE.Pass.call( this );this.scene = scene;this.camera = camera;this.overrideMaterial = overrideMaterial;this.clearColor = clearColor;this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 0;this.clear = true;this.clearDepth = false;this.needsSwap = false;};THREE.RenderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), {constructor: THREE.RenderPass,render: function ( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {var oldAutoClear = renderer.autoClear;renderer.autoClear = false;var oldClearColor, oldClearAlpha, oldOverrideMaterial;if ( this.overrideMaterial !== undefined ) {oldOverrideMaterial = this.scene.overrideMaterial;this.scene.overrideMaterial = this.overrideMaterial;}if ( this.clearColor ) {oldClearColor = renderer.getClearColor().getHex();oldClearAlpha = renderer.getClearAlpha();renderer.setClearColor( this.clearColor, this.clearAlpha );}if ( this.clearDepth ) {renderer.clearDepth();}renderer.setRenderTarget( this.renderToScreen ? null : readBuffer );// TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );renderer.render( this.scene, this.camera );if ( this.clearColor ) {renderer.setClearColor( oldClearColor, oldClearAlpha );}if ( this.overrideMaterial !== undefined ) {this.scene.overrideMaterial = oldOverrideMaterial;}renderer.autoClear = oldAutoClear;}} );</script><script>/*** @author alteredq / http://alteredqualia.com/*/THREE.ShaderPass = function ( shader, textureID ) {THREE.Pass.call( this );this.textureID = ( textureID !== undefined ) ? textureID : "tDiffuse";if ( shader instanceof THREE.ShaderMaterial ) {this.uniforms = shader.uniforms;this.material = shader;} else if ( shader ) {this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );this.material = new THREE.ShaderMaterial( {defines: Object.assign( {}, shader.defines ),uniforms: this.uniforms,vertexShader: shader.vertexShader,fragmentShader: shader.fragmentShader} );}this.fsQuad = new THREE.Pass.FullScreenQuad( this.material );};THREE.ShaderPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), {constructor: THREE.ShaderPass,render: function ( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {if ( this.uniforms[ this.textureID ] ) {this.uniforms[ this.textureID ].value = readBuffer.texture;}this.fsQuad.material = this.material;if ( this.renderToScreen ) {renderer.setRenderTarget( null );this.fsQuad.render( renderer );} else {renderer.setRenderTarget( writeBuffer );// TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );this.fsQuad.render( renderer );}}} );</script><script>/*** @author alteredq / http://alteredqualia.com/** Full-screen textured quad shader*/THREE.CopyShader = {uniforms: {"tDiffuse": { value: null },"opacity": { value: 1.0 }},vertexShader: ["varying vec2 vUv;","void main() {"," vUv = uv;"," gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join( "\n" ),fragmentShader: ["uniform float opacity;","uniform sampler2D tDiffuse;","varying vec2 vUv;","void main() {"," vec4 texel = texture2D( tDiffuse, vUv );"," gl_FragColor = opacity * texel;","}"].join( "\n" )};</script><script>THREE.LuminosityHighPassShader = {shaderID: "luminosityHighPass",uniforms: {"tDiffuse": { value: null },"luminosityThreshold": { value: 1.0 },"smoothWidth": { value: 1.0 },"defaultColor": { value: new THREE.Color( 0x000000 ) },"defaultOpacity": { value: 0.0 }},vertexShader: ["varying vec2 vUv;","void main() {"," vUv = uv;"," gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join( "\n" ),fragmentShader: ["uniform sampler2D tDiffuse;","uniform vec3 defaultColor;","uniform float defaultOpacity;","uniform float luminosityThreshold;","uniform float smoothWidth;","varying vec2 vUv;","void main() {"," vec4 texel = texture2D( tDiffuse, vUv );"," vec3 luma = vec3( 0.299, 0.587, 0.114 );"," float v = dot( texel.xyz, luma );"," vec4 outputColor = vec4( defaultColor.rgb, defaultOpacity );"," float alpha = smoothstep( luminosityThreshold, luminosityThreshold + smoothWidth, v );"," gl_FragColor = mix( outputColor, texel, alpha );","}"].join( "\n" )};</script><script>/*** UnrealBloomPass is inspired by the bloom pass of Unreal Engine. It creates a* mip map chain of bloom textures and blurs them with different radii. Because* of the weighted combination of mips, and because larger blurs are done on* higher mips, this effect provides good quality and performance.** Reference:* - https://docs.unrealengine.com/latest/INT/Engine/Rendering/PostProcessEffects/Bloom/*/THREE.UnrealBloomPass = function ( resolution, strength, radius, threshold ) {THREE.Pass.call( this );this.strength = ( strength !== undefined ) ? strength : 1;this.radius = radius;this.threshold = threshold;this.resolution = ( resolution !== undefined ) ? new THREE.Vector2( resolution.x, resolution.y ) : new THREE.Vector2( 256, 256 );// create color only once here, reuse it later inside the render functionthis.clearColor = new THREE.Color( 0, 0, 0 );// render targetsvar pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };this.renderTargetsHorizontal = [];this.renderTargetsVertical = [];this.nMips = 5;var resx = Math.round( this.resolution.x / 2 );var resy = Math.round( this.resolution.y / 2 );this.renderTargetBright = new THREE.WebGLRenderTarget( resx, resy, pars );this.renderTargetBright.texture.name = "UnrealBloomPass.bright";this.renderTargetBright.texture.generateMipmaps = false;for ( var i = 0; i < this.nMips; i ++ ) {var renderTargetHorizonal = new THREE.WebGLRenderTarget( resx, resy, pars );renderTargetHorizonal.texture.name = "UnrealBloomPass.h" + i;renderTargetHorizonal.texture.generateMipmaps = false;this.renderTargetsHorizontal.push( renderTargetHorizonal );var renderTargetVertical = new THREE.WebGLRenderTarget( resx, resy, pars );renderTargetVertical.texture.name = "UnrealBloomPass.v" + i;renderTargetVertical.texture.generateMipmaps = false;this.renderTargetsVertical.push( renderTargetVertical );resx = Math.round( resx / 2 );resy = Math.round( resy / 2 );}// luminosity high pass materialif ( THREE.LuminosityHighPassShader === undefined )console.error( "THREE.UnrealBloomPass relies on THREE.LuminosityHighPassShader" );var highPassShader = THREE.LuminosityHighPassShader;this.highPassUniforms = THREE.UniformsUtils.clone( highPassShader.uniforms );this.highPassUniforms[ "luminosityThreshold" ].value = threshold;this.highPassUniforms[ "smoothWidth" ].value = 0.01;this.materialHighPassFilter = new THREE.ShaderMaterial( {uniforms: this.highPassUniforms,vertexShader: highPassShader.vertexShader,fragmentShader: highPassShader.fragmentShader,defines: {}} );// Gaussian Blur Materialsthis.separableBlurMaterials = [];var kernelSizeArray = [ 3, 5, 7, 9, 11 ];var resx = Math.round( this.resolution.x / 2 );var resy = Math.round( this.resolution.y / 2 );for ( var i = 0; i < this.nMips; i ++ ) {this.separableBlurMaterials.push( this.getSeperableBlurMaterial( kernelSizeArray[ i ] ) );this.separableBlurMaterials[ i ].uniforms[ "texSize" ].value = new THREE.Vector2( resx, resy );resx = Math.round( resx / 2 );resy = Math.round( resy / 2 );}// Composite materialthis.compositeMaterial = this.getCompositeMaterial( this.nMips );this.compositeMaterial.uniforms[ "blurTexture1" ].value = this.renderTargetsVertical[ 0 ].texture;this.compositeMaterial.uniforms[ "blurTexture2" ].value = this.renderTargetsVertical[ 1 ].texture;this.compositeMaterial.uniforms[ "blurTexture3" ].value = this.renderTargetsVertical[ 2 ].texture;this.compositeMaterial.uniforms[ "blurTexture4" ].value = this.renderTargetsVertical[ 3 ].texture;this.compositeMaterial.uniforms[ "blurTexture5" ].value = this.renderTargetsVertical[ 4 ].texture;this.compositeMaterial.uniforms[ "bloomStrength" ].value = strength;this.compositeMaterial.uniforms[ "bloomRadius" ].value = 0.1;this.compositeMaterial.needsUpdate = true;var bloomFactors = [ 1.0, 0.8, 0.6, 0.4, 0.2 ];this.compositeMaterial.uniforms[ "bloomFactors" ].value = bloomFactors;this.bloomTintColors = [ new THREE.Vector3( 1, 1, 1 ), new THREE.Vector3( 1, 1, 1 ), new THREE.Vector3( 1, 1, 1 ),new THREE.Vector3( 1, 1, 1 ), new THREE.Vector3( 1, 1, 1 ) ];this.compositeMaterial.uniforms[ "bloomTintColors" ].value = this.bloomTintColors;// copy materialif ( THREE.CopyShader === undefined ) {console.error( "THREE.UnrealBloomPass relies on THREE.CopyShader" );}var copyShader = THREE.CopyShader;this.copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms );this.copyUniforms[ "opacity" ].value = 1.0;this.materialCopy = new THREE.ShaderMaterial( {uniforms: this.copyUniforms,vertexShader: copyShader.vertexShader,fragmentShader: copyShader.fragmentShader,blending: THREE.AdditiveBlending,depthTest: false,depthWrite: false,transparent: true} );this.enabled = true;this.needsSwap = false;this.oldClearColor = new THREE.Color();this.oldClearAlpha = 1;this.basic = new THREE.MeshBasicMaterial();this.fsQuad = new THREE.Pass.FullScreenQuad( null );};THREE.UnrealBloomPass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), {constructor: THREE.UnrealBloomPass,dispose: function () {for ( var i = 0; i < this.renderTargetsHorizontal.length; i ++ ) {this.renderTargetsHorizontal[ i ].dispose();}for ( var i = 0; i < this.renderTargetsVertical.length; i ++ ) {this.renderTargetsVertical[ i ].dispose();}this.renderTargetBright.dispose();},setSize: function ( width, height ) {var resx = Math.round( width / 2 );var resy = Math.round( height / 2 );this.renderTargetBright.setSize( resx, resy );for ( var i = 0; i < this.nMips; i ++ ) {this.renderTargetsHorizontal[ i ].setSize( resx, resy );this.renderTargetsVertical[ i ].setSize( resx, resy );this.separableBlurMaterials[ i ].uniforms[ "texSize" ].value = new THREE.Vector2( resx, resy );resx = Math.round( resx / 2 );resy = Math.round( resy / 2 );}},render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {this.oldClearColor.copy( renderer.getClearColor() );this.oldClearAlpha = renderer.getClearAlpha();var oldAutoClear = renderer.autoClear;renderer.autoClear = false;renderer.setClearColor( this.clearColor, 0 );if ( maskActive ) renderer.state.buffers.stencil.setTest( false );// Render input to screenif ( this.renderToScreen ) {this.fsQuad.material = this.basic;this.basic.map = readBuffer.texture;renderer.setRenderTarget( null );renderer.clear();this.fsQuad.render( renderer );}// 1. Extract Bright Areasthis.highPassUniforms[ "tDiffuse" ].value = readBuffer.texture;this.highPassUniforms[ "luminosityThreshold" ].value = this.threshold;this.fsQuad.material = this.materialHighPassFilter;renderer.setRenderTarget( this.renderTargetBright );renderer.clear();this.fsQuad.render( renderer );// 2. Blur All the mips progressivelyvar inputRenderTarget = this.renderTargetBright;for ( var i = 0; i < this.nMips; i ++ ) {this.fsQuad.material = this.separableBlurMaterials[ i ];this.separableBlurMaterials[ i ].uniforms[ "colorTexture" ].value = inputRenderTarget.texture;this.separableBlurMaterials[ i ].uniforms[ "direction" ].value = THREE.UnrealBloomPass.BlurDirectionX;renderer.setRenderTarget( this.renderTargetsHorizontal[ i ] );renderer.clear();this.fsQuad.render( renderer );this.separableBlurMaterials[ i ].uniforms[ "colorTexture" ].value = this.renderTargetsHorizontal[ i ].texture;this.separableBlurMaterials[ i ].uniforms[ "direction" ].value = THREE.UnrealBloomPass.BlurDirectionY;renderer.setRenderTarget( this.renderTargetsVertical[ i ] );renderer.clear();this.fsQuad.render( renderer );inputRenderTarget = this.renderTargetsVertical[ i ];}// Composite All the mipsthis.fsQuad.material = this.compositeMaterial;this.compositeMaterial.uniforms[ "bloomStrength" ].value = this.strength;this.compositeMaterial.uniforms[ "bloomRadius" ].value = this.radius;this.compositeMaterial.uniforms[ "bloomTintColors" ].value = this.bloomTintColors;renderer.setRenderTarget( this.renderTargetsHorizontal[ 0 ] );renderer.clear();this.fsQuad.render( renderer );// Blend it additively over the input texturethis.fsQuad.material = this.materialCopy;this.copyUniforms[ "tDiffuse" ].value = this.renderTargetsHorizontal[ 0 ].texture;if ( maskActive ) renderer.state.buffers.stencil.setTest( true );if ( this.renderToScreen ) {renderer.setRenderTarget( null );this.fsQuad.render( renderer );} else {renderer.setRenderTarget( readBuffer );this.fsQuad.render( renderer );}// Restore renderer settingsrenderer.setClearColor( this.oldClearColor, this.oldClearAlpha );renderer.autoClear = oldAutoClear;},getSeperableBlurMaterial: function ( kernelRadius ) {return new THREE.ShaderMaterial( {defines: {"KERNEL_RADIUS": kernelRadius,"SIGMA": kernelRadius},uniforms: {"colorTexture": { value: null },"texSize": { value: new THREE.Vector2( 0.5, 0.5 ) },"direction": { value: new THREE.Vector2( 0.5, 0.5 ) }},vertexShader:"varying vec2 vUv;\n\void main() {\n\vUv = uv;\n\gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\}",fragmentShader:"#include <common>\varying vec2 vUv;\n\uniform sampler2D colorTexture;\n\uniform vec2 texSize;\uniform vec2 direction;\\float gaussianPdf(in float x, in float sigma) {\return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;\}\void main() {\n\vec2 invSize = 1.0 / texSize;\float fSigma = float(SIGMA);\float weightSum = gaussianPdf(0.0, fSigma);\vec3 diffuseSum = texture2D( colorTexture, vUv).rgb * weightSum;\for( int i = 1; i < KERNEL_RADIUS; i ++ ) {\float x = float(i);\float w = gaussianPdf(x, fSigma);\vec2 uvOffset = direction * invSize * x;\vec3 sample1 = texture2D( colorTexture, vUv + uvOffset).rgb;\vec3 sample2 = texture2D( colorTexture, vUv - uvOffset).rgb;\diffuseSum += (sample1 + sample2) * w;\weightSum += 2.0 * w;\}\gl_FragColor = vec4(diffuseSum/weightSum, 1.0);\n\}"} );},getCompositeMaterial: function ( nMips ) {return new THREE.ShaderMaterial( {defines: {"NUM_MIPS": nMips},uniforms: {"blurTexture1": { value: null },"blurTexture2": { value: null },"blurTexture3": { value: null },"blurTexture4": { value: null },"blurTexture5": { value: null },"dirtTexture": { value: null },"bloomStrength": { value: 1.0 },"bloomFactors": { value: null },"bloomTintColors": { value: null },"bloomRadius": { value: 0.0 }},vertexShader:"varying vec2 vUv;\n\void main() {\n\vUv = uv;\n\gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\}",fragmentShader:"varying vec2 vUv;\uniform sampler2D blurTexture1;\uniform sampler2D blurTexture2;\uniform sampler2D blurTexture3;\uniform sampler2D blurTexture4;\uniform sampler2D blurTexture5;\uniform sampler2D dirtTexture;\uniform float bloomStrength;\uniform float bloomRadius;\uniform float bloomFactors[NUM_MIPS];\uniform vec3 bloomTintColors[NUM_MIPS];\\float lerpBloomFactor(const in float factor) { \float mirrorFactor = 1.2 - factor;\return mix(factor, mirrorFactor, bloomRadius);\}\\void main() {\gl_FragColor = bloomStrength * ( lerpBloomFactor(bloomFactors[0]) * vec4(bloomTintColors[0], 1.0) * texture2D(blurTexture1, vUv) + \lerpBloomFactor(bloomFactors[1]) * vec4(bloomTintColors[1], 1.0) * texture2D(blurTexture2, vUv) + \lerpBloomFactor(bloomFactors[2]) * vec4(bloomTintColors[2], 1.0) * texture2D(blurTexture3, vUv) + \lerpBloomFactor(bloomFactors[3]) * vec4(bloomTintColors[3], 1.0) * texture2D(blurTexture4, vUv) + \lerpBloomFactor(bloomFactors[4]) * vec4(bloomTintColors[4], 1.0) * texture2D(blurTexture5, vUv) );\}"} );}} );THREE.UnrealBloomPass.BlurDirectionX = new THREE.Vector2( 1.0, 0.0 );THREE.UnrealBloomPass.BlurDirectionY = new THREE.Vector2( 0.0, 1.0 );</script><div id="overlay"><ul><li class="title">To 萌萌:</li><li><button class="btn" id="btnA" type="button"><!-- Merry Christmas -->🎁</button></li><!-- <li class="separator">或者</li><li><input type="file" id="upload" hidden /><label for="upload">Upload File</label></li> --></ul></div><div id="labels"></div><script id="rendered-js">const my_labels = ["圣诞快乐!","Merry Christmas!",];const { PI, sin, cos } = Math;const TAU = 2 * PI;const map = (value, sMin, sMax, dMin, dMax) => {return dMin + ((value - sMin) / (sMax - sMin)) * (dMax - dMin);};const range = (n, m = 0) =>Array(n).fill(m).map((i, j) => i + j);const rand = (max, min = 0) => min + Math.random() * (max - min);const randInt = (max, min = 0) =>Math.floor(min + Math.random() * (max - min));const randChoise = (arr) => arr[randInt(arr.length)];const polar = (ang, r = 1) => [r * cos(ang), r * sin(ang)];let scene, camera, renderer, analyser;let step = 0;const uniforms = {time: { type: "f", value: 0.0 },step: { type: "f", value: 0.0 },};const params = {exposure: 1,bloomStrength: 0.9,bloomThreshold: 0,bloomRadius: 0.5,};let composer;const fftSize = 2048;const totalPoints = 4000;const listener = new THREE.AudioListener();const audio = new THREE.Audio(listener);// document// .querySelector("input")// .addEventListener("change", uploadAudio, false);const buttons = document.querySelectorAll(".btn");buttons.forEach((button, index) =>button.addEventListener("click", () => loadAudio(index)));// loadAudio(0);function init() {const overlay = document.getElementById("overlay");overlay.remove();const labels = document.getElementById("labels");for (let i = 0; i < my_labels.length; i++) {setTimeout(() => {labels.className = "hide";labels.innerHTML = my_labels[i];labels.className = "show";}, 2000 * i);}scene = new THREE.Scene();renderer = new THREE.WebGLRenderer({ antialias: true });renderer.setPixelRatio(window.devicePixelRatio);renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);camera = new THREE.PerspectiveCamera(60,window.innerWidth / window.innerHeight,1,1000);camera.position.set(-0.09397456774197047,-2.5597086635726947,24.420789670889008);camera.rotation.set(0.10443543723052419,-0.003827152981119352,0.0004011488708739715);const format = renderer.capabilities.isWebGL2? THREE.RedFormat: THREE.LuminanceFormat;uniforms.tAudioData = {value: new THREE.DataTexture(analyser.data, fftSize / 2, 1, format),};addPlane(scene, uniforms, 3000);addSnow(scene, uniforms);range(10).map((i) => {addTree(scene, uniforms, totalPoints, [20, 0, -20 * i]);addTree(scene, uniforms, totalPoints, [-20, 0, -20 * i]);});const renderScene = new THREE.RenderPass(scene, camera);const bloomPass = new THREE.UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight),1.5,0.4,0.85);bloomPass.threshold = params.bloomThreshold;bloomPass.strength = params.bloomStrength;bloomPass.radius = params.bloomRadius;composer = new THREE.EffectComposer(renderer);composer.addPass(renderScene);composer.addPass(bloomPass);addListners(camera, renderer, composer);animate();}function animate(time) {analyser.getFrequencyData();uniforms.tAudioData.value.needsUpdate = true;step = (step + 1) % 1000;uniforms.time.value = time;uniforms.step.value = step;composer.render();requestAnimationFrame(animate);}function loadAudio(i) {document.getElementById("overlay").innerHTML ='<div class="text-loading">Merry Christmas ...</div>';const files = [//"http://music.163.com/song/media/outer/url?id=448704788.mp3", // ! 音乐资源获取// 修改下面这个链接//"http://m10.music.126.net/20231210135814/b2ca7948cdbf1e3be2513d0a82c4bb92/ymusic/3bc8/7ba8/8643/56e188fb5a29b25ce695510164a28331.mp3",//"https://music.163.com/outchain/player?type=2&id=1824020871",//"这里填你自己的音乐链接",// 海外用户使用下面这个音乐平台"https://files.freemusicarchive.org/storage-freemusicarchive-org/music/no_curator/Simon_Panrucker/Happy_Christmas_You_Guys/Simon_Panrucker_-_01_-_Snowflakes_Falling_Down.mp3",];const file = files[i];const loader = new THREE.AudioLoader();loader.load(file, function (buffer) {console.log(buffer)audio.setBuffer(buffer);audio.play();analyser = new THREE.AudioAnalyser(audio, fftSize);init();});function getJSON(url) {return new Promise(function(resolve, reject) {var xhr = new XMLHttpRequest();xhr.open('get', url, true);// xhr.responseType = 'json';console.log(xhr)xhr.onloadstart = function() {console.log(xhr);}xhr.onload = function() {console.log(xhr);var status = xhr.status;if (status == 200) {resolve(xhr.responseURL);} else {reject(status);}};xhr.send();});}function requestListData(url) {getJSON(url).then(function(data) {const loader = new THREE.AudioLoader();loader.load(data, function (buffer) {console.log(buffer)audio.setBuffer(buffer);audio.play();analyser = new THREE.AudioAnalyser(audio, fftSize);init();});}, function(status) { //error detection....alert('Something went wrong.');});
}}function uploadAudio(event) {document.getElementById("overlay").innerHTML ='<div class="text-loading">请稍等...</div>';const files = event.target.files;const reader = new FileReader();reader.onload = function (file) {var arrayBuffer = file.target.result;listener.context.decodeAudioData(arrayBuffer, function (audioBuffer) {audio.setBuffer(audioBuffer);audio.play();analyser = new THREE.AudioAnalyser(audio, fftSize);init();});};reader.readAsArrayBuffer(files[0]);}function addTree(scene, uniforms, totalPoints, treePosition) {const vertexShader = `attribute float mIndex;varying vec3 vColor;varying float opacity;uniform sampler2D tAudioData;float norm(float value, float min, float max ){return (value - min) / (max - min);}float lerp(float norm, float min, float max){return (max - min) * norm + min;}float map(float value, float sourceMin, float sourceMax, float destMin, float destMax){return lerp(norm(value, sourceMin, sourceMax), destMin, destMax);}void main() {vColor = color;vec3 p = position;vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 );float amplitude = texture2D( tAudioData, vec2( mIndex, 0.1 ) ).r;float amplitudeClamped = clamp(amplitude-0.4,0.0, 0.6 );float sizeMapped = map(amplitudeClamped, 0.0, 0.6, 1.0, 20.0);opacity = map(mvPosition.z , -200.0, 15.0, 0.0, 1.0);gl_PointSize = sizeMapped * ( 100.0 / -mvPosition.z );gl_Position = projectionMatrix * mvPosition;}`;const fragmentShader = `varying vec3 vColor;varying float opacity;uniform sampler2D pointTexture;void main() {gl_FragColor = vec4( vColor, opacity );gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord ); }`;const shaderMaterial = new THREE.ShaderMaterial({uniforms: {...uniforms,pointTexture: {value: new THREE.TextureLoader().load(`https://assets.codepen.io/3685267/spark1.png`),},},vertexShader,fragmentShader,blending: THREE.AdditiveBlending,depthTest: false,transparent: true,vertexColors: true,});const geometry = new THREE.BufferGeometry();const positions = [];const colors = [];const sizes = [];const phases = [];const mIndexs = [];const color = new THREE.Color();for (let i = 0; i < totalPoints; i++) {const t = Math.random();const y = map(t, 0, 1, -8, 10);const ang = map(t, 0, 1, 0, 6 * TAU) + (TAU / 2) * (i % 2);const [z, x] = polar(ang, map(t, 0, 1, 5, 0));const modifier = map(t, 0, 1, 1, 0);positions.push(x + rand(-0.3 * modifier, 0.3 * modifier));positions.push(y + rand(-0.3 * modifier, 0.3 * modifier));positions.push(z + rand(-0.3 * modifier, 0.3 * modifier));color.setHSL(map(i, 0, totalPoints, 1.0, 0.0), 1.0, 0.5);colors.push(color.r, color.g, color.b);phases.push(rand(1000));sizes.push(1);const mIndex = map(i, 0, totalPoints, 1.0, 0.0);mIndexs.push(mIndex);}geometry.setAttribute("position",new THREE.Float32BufferAttribute(positions, 3).setUsage(THREE.DynamicDrawUsage));geometry.setAttribute("color",new THREE.Float32BufferAttribute(colors, 3));geometry.setAttribute("size",new THREE.Float32BufferAttribute(sizes, 1));geometry.setAttribute("phase",new THREE.Float32BufferAttribute(phases, 1));geometry.setAttribute("mIndex",new THREE.Float32BufferAttribute(mIndexs, 1));const tree = new THREE.Points(geometry, shaderMaterial);const [px, py, pz] = treePosition;tree.position.x = px;tree.position.y = py;tree.position.z = pz;scene.add(tree);}function addSnow(scene, uniforms) {const vertexShader = `attribute float size;attribute float phase;attribute float phaseSecondary;varying vec3 vColor;varying float opacity;uniform float time;uniform float step;float norm(float value, float min, float max ){return (value - min) / (max - min);}float lerp(float norm, float min, float max){return (max - min) * norm + min;}float map(float value, float sourceMin, float sourceMax, float destMin, float destMax){return lerp(norm(value, sourceMin, sourceMax), destMin, destMax);}void main() {float t = time* 0.0006;vColor = color;vec3 p = position;p.y = map(mod(phase+step, 1000.0), 0.0, 1000.0, 25.0, -8.0);p.x += sin(t+phase);p.z += sin(t+phaseSecondary);opacity = map(p.z, -150.0, 15.0, 0.0, 1.0);vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 );gl_PointSize = size * ( 100.0 / -mvPosition.z );gl_Position = projectionMatrix * mvPosition;}`;const fragmentShader = `uniform sampler2D pointTexture;varying vec3 vColor;varying float opacity;void main() {gl_FragColor = vec4( vColor, opacity );gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord ); }`;function createSnowSet(sprite) {const totalPoints = 300;const shaderMaterial = new THREE.ShaderMaterial({uniforms: {...uniforms,pointTexture: {value: new THREE.TextureLoader().load(sprite),},},vertexShader,fragmentShader,blending: THREE.AdditiveBlending,depthTest: false,transparent: true,vertexColors: true,});const geometry = new THREE.BufferGeometry();const positions = [];const colors = [];const sizes = [];const phases = [];const phaseSecondaries = [];const color = new THREE.Color();for (let i = 0; i < totalPoints; i++) {const [x, y, z] = [rand(25, -25), 0, rand(15, -150)];positions.push(x);positions.push(y);positions.push(z);color.set(randChoise(["#f1d4d4", "#f1f6f9", "#eeeeee", "#f1f1e8"]));colors.push(color.r, color.g, color.b);phases.push(rand(1000));phaseSecondaries.push(rand(1000));sizes.push(rand(4, 2));}geometry.setAttribute("position",new THREE.Float32BufferAttribute(positions, 3));geometry.setAttribute("color",new THREE.Float32BufferAttribute(colors, 3));geometry.setAttribute("size",new THREE.Float32BufferAttribute(sizes, 1));geometry.setAttribute("phase",new THREE.Float32BufferAttribute(phases, 1));geometry.setAttribute("phaseSecondary",new THREE.Float32BufferAttribute(phaseSecondaries, 1));const mesh = new THREE.Points(geometry, shaderMaterial);scene.add(mesh);}const sprites = ["https://assets.codepen.io/3685267/snowflake1.png","https://assets.codepen.io/3685267/snowflake2.png","https://assets.codepen.io/3685267/snowflake3.png","https://assets.codepen.io/3685267/snowflake4.png","https://assets.codepen.io/3685267/snowflake5.png",];sprites.forEach((sprite) => {createSnowSet(sprite);});}function addPlane(scene, uniforms, totalPoints) {const vertexShader = `attribute float size;attribute vec3 customColor;varying vec3 vColor;void main() {vColor = customColor;vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );gl_PointSize = size * ( 300.0 / -mvPosition.z );gl_Position = projectionMatrix * mvPosition;}`;const fragmentShader = `uniform vec3 color;uniform sampler2D pointTexture;varying vec3 vColor;void main() {gl_FragColor = vec4( vColor, 1.0 );gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );}`;const shaderMaterial = new THREE.ShaderMaterial({uniforms: {...uniforms,pointTexture: {value: new THREE.TextureLoader().load(`https://assets.codepen.io/3685267/spark1.png`),},},vertexShader,fragmentShader,blending: THREE.AdditiveBlending,depthTest: false,transparent: true,vertexColors: true,});const geometry = new THREE.BufferGeometry();const positions = [];const colors = [];const sizes = [];const color = new THREE.Color();for (let i = 0; i < totalPoints; i++) {const [x, y, z] = [rand(-25, 25), 0, rand(-150, 15)];positions.push(x);positions.push(y);positions.push(z);color.set(randChoise(["#93abd3", "#f2f4c0", "#9ddfd3"]));colors.push(color.r, color.g, color.b);sizes.push(1);}geometry.setAttribute("position",new THREE.Float32BufferAttribute(positions, 3).setUsage(THREE.DynamicDrawUsage));geometry.setAttribute("customColor",new THREE.Float32BufferAttribute(colors, 3));geometry.setAttribute("size",new THREE.Float32BufferAttribute(sizes, 1));const plane = new THREE.Points(geometry, shaderMaterial);plane.position.y = -8;scene.add(plane);}function addListners(camera, renderer, composer) {document.addEventListener("keydown", (e) => {const { x, y, z } = camera.position;console.log(`camera.position.set(${x},${y},${z})`);const { x: a, y: b, z: c } = camera.rotation;console.log(`camera.rotation.set(${a},${b},${c})`);});window.addEventListener("resize",() => {const width = window.innerWidth;const height = window.innerHeight;camera.aspect = width / height;camera.updateProjectionMatrix();renderer.setSize(width, height);composer.setSize(width, height);},false);}</script></body>
</html>
写在后面
我是一只有趣的兔子,感谢你的喜欢!