程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

HTML圣诞树代码(动态音效)(我非原创作者,原作者是复旦大学的学长,如有侵权请联系)

发布于2022-03-18 23:51     阅读(1227)     评论(0)     点赞(23)     收藏(2)


  1. <!DOCTYPE html>
  2. <html lang="en" >
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>来自复旦大学学长的圣诞树</title>
  6. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
  7. <style>
  8. *
  9. {
  10. box-sizing: border-box;
  11. }
  12. body
  13. {
  14. margin: 0;
  15. height: 100vh;
  16. overflow: hidden;
  17. display: flex;
  18. align-items: center;
  19. justify-content: center;
  20. background: #161616;
  21. color: #c5a880;
  22. font-family: sans-serif;
  23. }
  24. label
  25. {
  26. display: inline-block;
  27. background-color: #161616;
  28. padding: 16px;
  29. border-radius: 0.3rem;
  30. cursor: pointer;
  31. margin-top: 1rem;
  32. width: 300px;
  33. border-radius: 10px;
  34. border: 1px solid #c5a880;
  35. text-align: center;
  36. }
  37. ul
  38. {
  39. list-style-type: none;
  40. padding: 0;
  41. margin: 0;
  42. }
  43. .btn
  44. {
  45. background-color: #161616;
  46. border-radius: 10px;
  47. color: #c5a880;
  48. border: 1px solid #c5a880;
  49. padding: 16px;
  50. width: 300px;
  51. margin-bottom: 16px;
  52. line-height: 1.5;
  53. cursor: pointer;
  54. }
  55. .separator
  56. {
  57. font-weight: bold;
  58. text-align: center;
  59. width: 300px;
  60. margin: 16px 0px;
  61. color: #a07676;
  62. }
  63. .title
  64. {
  65. color: #a07676;
  66. font-weight: bold;
  67. font-size: 1.25rem;
  68. margin-bottom: 16px;
  69. }
  70. .text-loading
  71. {
  72. font-size: 2rem;
  73. }
  74. </style>
  75. <script>
  76. window.console = window.console || function(t) {};
  77. </script>
  78. <script>
  79. if (document.location.search.match(/type=embed/gi)) {
  80. window.parent.postMessage("resize", "*");
  81. }
  82. </script>
  83. </head>
  84. <body translate="no" >
  85. <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/build/three.min.js"></script>
  86. <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/EffectComposer.js"></script>
  87. <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/RenderPass.js"></script>
  88. <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/ShaderPass.js"></script>
  89. <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/shaders/CopyShader.js"></script>
  90. <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/shaders/LuminosityHighPassShader.js"></script>
  91. <script src="https://cdn.jsdelivr.net/npm/three@0.115.0/examples/js/postprocessing/UnrealBloomPass.js"></script>
  92. <div id="overlay">
  93. <ul>
  94. <li class="title">请选择音乐</li>
  95. <li>
  96. <button class="btn" id="btnA" type="button">
  97. Snowflakes Falling Down by Simon Panrucker
  98. </button>
  99. </li>
  100. <li><button class="btn" id="btnB" type="button">This Christmas by Dott</button></li>
  101. <li><button class="btn" id="btnC" type="button">No room at the inn by TRG Banks</button></li>
  102. <li><button class="btn" id="btnD" type="button">Jingle Bell Swing by Mark Smeby</button></li>
  103. <li class="separator">或者</li>
  104. <li>
  105. <input type="file" id="upload" hidden />
  106. <label for="upload">Upload File</label>
  107. </li>
  108. </ul>
  109. </div>
  110. <script id="rendered-js" >
  111. const { PI, sin, cos } = Math;
  112. const TAU = 2 * PI;
  113. const map = (value, sMin, sMax, dMin, dMax) => {
  114. return dMin + (value - sMin) / (sMax - sMin) * (dMax - dMin);
  115. };
  116. const range = (n, m = 0) =>
  117. Array(n).
  118. fill(m).
  119. map((i, j) => i + j);
  120. const rand = (max, min = 0) => min + Math.random() * (max - min);
  121. const randInt = (max, min = 0) => Math.floor(min + Math.random() * (max - min));
  122. const randChoise = arr => arr[randInt(arr.length)];
  123. const polar = (ang, r = 1) => [r * cos(ang), r * sin(ang)];
  124. let scene, camera, renderer, analyser;
  125. let step = 0;
  126. const uniforms = {
  127. time: { type: "f", value: 0.0 },
  128. step: { type: "f", value: 0.0 } };
  129. const params = {
  130. exposure: 1,
  131. bloomStrength: 0.9,
  132. bloomThreshold: 0,
  133. bloomRadius: 0.5 };
  134. let composer;
  135. const fftSize = 2048;
  136. const totalPoints = 4000;
  137. const listener = new THREE.AudioListener();
  138. const audio = new THREE.Audio(listener);
  139. document.querySelector("input").addEventListener("change", uploadAudio, false);
  140. const buttons = document.querySelectorAll(".btn");
  141. buttons.forEach((button, index) =>
  142. button.addEventListener("click", () => loadAudio(index)));
  143. function init() {
  144. const overlay = document.getElementById("overlay");
  145. overlay.remove();
  146. scene = new THREE.Scene();
  147. renderer = new THREE.WebGLRenderer({ antialias: true });
  148. renderer.setPixelRatio(window.devicePixelRatio);
  149. renderer.setSize(window.innerWidth, window.innerHeight);
  150. document.body.appendChild(renderer.domElement);
  151. camera = new THREE.PerspectiveCamera(
  152. 60,
  153. window.innerWidth / window.innerHeight,
  154. 1,
  155. 1000);
  156. camera.position.set(-0.09397456774197047, -2.5597086635726947, 24.420789670889008);
  157. camera.rotation.set(0.10443543723052419, -0.003827152981119352, 0.0004011488708739715);
  158. const format = renderer.capabilities.isWebGL2 ?
  159. THREE.RedFormat :
  160. THREE.LuminanceFormat;
  161. uniforms.tAudioData = {
  162. value: new THREE.DataTexture(analyser.data, fftSize / 2, 1, format) };
  163. addPlane(scene, uniforms, 3000);
  164. addSnow(scene, uniforms);
  165. range(10).map(i => {
  166. addTree(scene, uniforms, totalPoints, [20, 0, -20 * i]);
  167. addTree(scene, uniforms, totalPoints, [-20, 0, -20 * i]);
  168. });
  169. const renderScene = new THREE.RenderPass(scene, camera);
  170. const bloomPass = new THREE.UnrealBloomPass(
  171. new THREE.Vector2(window.innerWidth, window.innerHeight),
  172. 1.5,
  173. 0.4,
  174. 0.85);
  175. bloomPass.threshold = params.bloomThreshold;
  176. bloomPass.strength = params.bloomStrength;
  177. bloomPass.radius = params.bloomRadius;
  178. composer = new THREE.EffectComposer(renderer);
  179. composer.addPass(renderScene);
  180. composer.addPass(bloomPass);
  181. addListners(camera, renderer, composer);
  182. animate();
  183. }
  184. function animate(time) {
  185. analyser.getFrequencyData();
  186. uniforms.tAudioData.value.needsUpdate = true;
  187. step = (step + 1) % 1000;
  188. uniforms.time.value = time;
  189. uniforms.step.value = step;
  190. composer.render();
  191. requestAnimationFrame(animate);
  192. }
  193. function loadAudio(i) {
  194. document.getElementById("overlay").innerHTML =
  195. '<div class="text-loading">正在下载音乐,请稍等...</div>';
  196. const files = [
  197. "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/no_curator/Simon_Panrucker/Happy_Christmas_You_Guys/Simon_Panrucker_-_01_-_Snowflakes_Falling_Down.mp3",
  198. "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/no_curator/Dott/This_Christmas/Dott_-_01_-_This_Christmas.mp3",
  199. "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/ccCommunity/TRG_Banks/TRG_Banks_Christmas_Album/TRG_Banks_-_12_-_No_room_at_the_inn.mp3",
  200. "https://files.freemusicarchive.org/storage-freemusicarchive-org/music/ccCommunity/Mark_Smeby/En_attendant_Nol/Mark_Smeby_-_07_-_Jingle_Bell_Swing.mp3"];
  201. const file = files[i];
  202. const loader = new THREE.AudioLoader();
  203. loader.load(file, function (buffer) {
  204. audio.setBuffer(buffer);
  205. audio.play();
  206. analyser = new THREE.AudioAnalyser(audio, fftSize);
  207. init();
  208. });
  209. }
  210. function uploadAudio(event) {
  211. document.getElementById("overlay").innerHTML =
  212. '<div class="text-loading">请稍等...</div>';
  213. const files = event.target.files;
  214. const reader = new FileReader();
  215. reader.onload = function (file) {
  216. var arrayBuffer = file.target.result;
  217. listener.context.decodeAudioData(arrayBuffer, function (audioBuffer) {
  218. audio.setBuffer(audioBuffer);
  219. audio.play();
  220. analyser = new THREE.AudioAnalyser(audio, fftSize);
  221. init();
  222. });
  223. };
  224. reader.readAsArrayBuffer(files[0]);
  225. }
  226. function addTree(scene, uniforms, totalPoints, treePosition) {
  227. const vertexShader = `
  228. attribute float mIndex;
  229. varying vec3 vColor;
  230. varying float opacity;
  231. uniform sampler2D tAudioData;
  232. float norm(float value, float min, float max ){
  233. return (value - min) / (max - min);
  234. }
  235. float lerp(float norm, float min, float max){
  236. return (max - min) * norm + min;
  237. }
  238. float map(float value, float sourceMin, float sourceMax, float destMin, float destMax){
  239. return lerp(norm(value, sourceMin, sourceMax), destMin, destMax);
  240. }
  241. void main() {
  242. vColor = color;
  243. vec3 p = position;
  244. vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 );
  245. float amplitude = texture2D( tAudioData, vec2( mIndex, 0.1 ) ).r;
  246. float amplitudeClamped = clamp(amplitude-0.4,0.0, 0.6 );
  247. float sizeMapped = map(amplitudeClamped, 0.0, 0.6, 1.0, 20.0);
  248. opacity = map(mvPosition.z , -200.0, 15.0, 0.0, 1.0);
  249. gl_PointSize = sizeMapped * ( 100.0 / -mvPosition.z );
  250. gl_Position = projectionMatrix * mvPosition;
  251. }
  252. `;
  253. const fragmentShader = `
  254. varying vec3 vColor;
  255. varying float opacity;
  256. uniform sampler2D pointTexture;
  257. void main() {
  258. gl_FragColor = vec4( vColor, opacity );
  259. gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );
  260. }
  261. `;
  262. const shaderMaterial = new THREE.ShaderMaterial({
  263. uniforms: {
  264. ...uniforms,
  265. pointTexture: {
  266. value: new THREE.TextureLoader().load(`https://assets.codepen.io/3685267/spark1.png`) } },
  267. vertexShader,
  268. fragmentShader,
  269. blending: THREE.AdditiveBlending,
  270. depthTest: false,
  271. transparent: true,
  272. vertexColors: true });
  273. const geometry = new THREE.BufferGeometry();
  274. const positions = [];
  275. const colors = [];
  276. const sizes = [];
  277. const phases = [];
  278. const mIndexs = [];
  279. const color = new THREE.Color();
  280. for (let i = 0; i < totalPoints; i++) {
  281. const t = Math.random();
  282. const y = map(t, 0, 1, -8, 10);
  283. const ang = map(t, 0, 1, 0, 6 * TAU) + TAU / 2 * (i % 2);
  284. const [z, x] = polar(ang, map(t, 0, 1, 5, 0));
  285. const modifier = map(t, 0, 1, 1, 0);
  286. positions.push(x + rand(-0.3 * modifier, 0.3 * modifier));
  287. positions.push(y + rand(-0.3 * modifier, 0.3 * modifier));
  288. positions.push(z + rand(-0.3 * modifier, 0.3 * modifier));
  289. color.setHSL(map(i, 0, totalPoints, 1.0, 0.0), 1.0, 0.5);
  290. colors.push(color.r, color.g, color.b);
  291. phases.push(rand(1000));
  292. sizes.push(1);
  293. const mIndex = map(i, 0, totalPoints, 1.0, 0.0);
  294. mIndexs.push(mIndex);
  295. }
  296. geometry.setAttribute(
  297. "position",
  298. new THREE.Float32BufferAttribute(positions, 3).setUsage(
  299. THREE.DynamicDrawUsage));
  300. geometry.setAttribute("color", new THREE.Float32BufferAttribute(colors, 3));
  301. geometry.setAttribute("size", new THREE.Float32BufferAttribute(sizes, 1));
  302. geometry.setAttribute("phase", new THREE.Float32BufferAttribute(phases, 1));
  303. geometry.setAttribute("mIndex", new THREE.Float32BufferAttribute(mIndexs, 1));
  304. const tree = new THREE.Points(geometry, shaderMaterial);
  305. const [px, py, pz] = treePosition;
  306. tree.position.x = px;
  307. tree.position.y = py;
  308. tree.position.z = pz;
  309. scene.add(tree);
  310. }
  311. function addSnow(scene, uniforms) {
  312. const vertexShader = `
  313. attribute float size;
  314. attribute float phase;
  315. attribute float phaseSecondary;
  316. varying vec3 vColor;
  317. varying float opacity;
  318. uniform float time;
  319. uniform float step;
  320. float norm(float value, float min, float max ){
  321. return (value - min) / (max - min);
  322. }
  323. float lerp(float norm, float min, float max){
  324. return (max - min) * norm + min;
  325. }
  326. float map(float value, float sourceMin, float sourceMax, float destMin, float destMax){
  327. return lerp(norm(value, sourceMin, sourceMax), destMin, destMax);
  328. }
  329. void main() {
  330. float t = time* 0.0006;
  331. vColor = color;
  332. vec3 p = position;
  333. p.y = map(mod(phase+step, 1000.0), 0.0, 1000.0, 25.0, -8.0);
  334. p.x += sin(t+phase);
  335. p.z += sin(t+phaseSecondary);
  336. opacity = map(p.z, -150.0, 15.0, 0.0, 1.0);
  337. vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 );
  338. gl_PointSize = size * ( 100.0 / -mvPosition.z );
  339. gl_Position = projectionMatrix * mvPosition;
  340. }
  341. `;
  342. const fragmentShader = `
  343. uniform sampler2D pointTexture;
  344. varying vec3 vColor;
  345. varying float opacity;
  346. void main() {
  347. gl_FragColor = vec4( vColor, opacity );
  348. gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );
  349. }
  350. `;
  351. function createSnowSet(sprite) {
  352. const totalPoints = 300;
  353. const shaderMaterial = new THREE.ShaderMaterial({
  354. uniforms: {
  355. ...uniforms,
  356. pointTexture: {
  357. value: new THREE.TextureLoader().load(sprite) } },
  358. vertexShader,
  359. fragmentShader,
  360. blending: THREE.AdditiveBlending,
  361. depthTest: false,
  362. transparent: true,
  363. vertexColors: true });
  364. const geometry = new THREE.BufferGeometry();
  365. const positions = [];
  366. const colors = [];
  367. const sizes = [];
  368. const phases = [];
  369. const phaseSecondaries = [];
  370. const color = new THREE.Color();
  371. for (let i = 0; i < totalPoints; i++) {
  372. const [x, y, z] = [rand(25, -25), 0, rand(15, -150)];
  373. positions.push(x);
  374. positions.push(y);
  375. positions.push(z);
  376. color.set(randChoise(["#f1d4d4", "#f1f6f9", "#eeeeee", "#f1f1e8"]));
  377. colors.push(color.r, color.g, color.b);
  378. phases.push(rand(1000));
  379. phaseSecondaries.push(rand(1000));
  380. sizes.push(rand(4, 2));
  381. }
  382. geometry.setAttribute(
  383. "position",
  384. new THREE.Float32BufferAttribute(positions, 3));
  385. geometry.setAttribute("color", new THREE.Float32BufferAttribute(colors, 3));
  386. geometry.setAttribute("size", new THREE.Float32BufferAttribute(sizes, 1));
  387. geometry.setAttribute("phase", new THREE.Float32BufferAttribute(phases, 1));
  388. geometry.setAttribute(
  389. "phaseSecondary",
  390. new THREE.Float32BufferAttribute(phaseSecondaries, 1));
  391. const mesh = new THREE.Points(geometry, shaderMaterial);
  392. scene.add(mesh);
  393. }
  394. const sprites = [
  395. "https://assets.codepen.io/3685267/snowflake1.png",
  396. "https://assets.codepen.io/3685267/snowflake2.png",
  397. "https://assets.codepen.io/3685267/snowflake3.png",
  398. "https://assets.codepen.io/3685267/snowflake4.png",
  399. "https://assets.codepen.io/3685267/snowflake5.png"];
  400. sprites.forEach(sprite => {
  401. createSnowSet(sprite);
  402. });
  403. }
  404. function addPlane(scene, uniforms, totalPoints) {
  405. const vertexShader = `
  406. attribute float size;
  407. attribute vec3 customColor;
  408. varying vec3 vColor;
  409. void main() {
  410. vColor = customColor;
  411. vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
  412. gl_PointSize = size * ( 300.0 / -mvPosition.z );
  413. gl_Position = projectionMatrix * mvPosition;
  414. }
  415. `;
  416. const fragmentShader = `
  417. uniform vec3 color;
  418. uniform sampler2D pointTexture;
  419. varying vec3 vColor;
  420. void main() {
  421. gl_FragColor = vec4( vColor, 1.0 );
  422. gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );
  423. }
  424. `;
  425. const shaderMaterial = new THREE.ShaderMaterial({
  426. uniforms: {
  427. ...uniforms,
  428. pointTexture: {
  429. value: new THREE.TextureLoader().load(`https://assets.codepen.io/3685267/spark1.png`) } },
  430. vertexShader,
  431. fragmentShader,
  432. blending: THREE.AdditiveBlending,
  433. depthTest: false,
  434. transparent: true,
  435. vertexColors: true });
  436. const geometry = new THREE.BufferGeometry();
  437. const positions = [];
  438. const colors = [];
  439. const sizes = [];
  440. const color = new THREE.Color();
  441. for (let i = 0; i < totalPoints; i++) {
  442. const [x, y, z] = [rand(-25, 25), 0, rand(-150, 15)];
  443. positions.push(x);
  444. positions.push(y);
  445. positions.push(z);
  446. color.set(randChoise(["#93abd3", "#f2f4c0", "#9ddfd3"]));
  447. colors.push(color.r, color.g, color.b);
  448. sizes.push(1);
  449. }
  450. geometry.setAttribute(
  451. "position",
  452. new THREE.Float32BufferAttribute(positions, 3).setUsage(
  453. THREE.DynamicDrawUsage));
  454. geometry.setAttribute(
  455. "customColor",
  456. new THREE.Float32BufferAttribute(colors, 3));
  457. geometry.setAttribute("size", new THREE.Float32BufferAttribute(sizes, 1));
  458. const plane = new THREE.Points(geometry, shaderMaterial);
  459. plane.position.y = -8;
  460. scene.add(plane);
  461. }
  462. function addListners(camera, renderer, composer) {
  463. document.addEventListener("keydown", e => {
  464. const { x, y, z } = camera.position;
  465. console.log(`camera.position.set(${x},${y},${z})`);
  466. const { x: a, y: b, z: c } = camera.rotation;
  467. console.log(`camera.rotation.set(${a},${b},${c})`);
  468. });
  469. window.addEventListener(
  470. "resize",
  471. () => {
  472. const width = window.innerWidth;
  473. const height = window.innerHeight;
  474. camera.aspect = width / height;
  475. camera.updateProjectionMatrix();
  476. renderer.setSize(width, height);
  477. composer.setSize(width, height);
  478. },
  479. false);
  480. }
  481. </script>
  482. </body>
  483. </html>




所属网站分类: 技术文章 > 博客

作者:Bhbvhbbgg

链接:http://www.qianduanheidong.com/blog/article/318701/a97a521eb3dc215afff3/

来源:前端黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

23 0
收藏该文
已收藏

评论内容:(最多支持255个字符)