0


芜湖,这是一棵会唱歌的圣诞树

🐏小羊简介:


💖博客主页:小羊不会飞

🚀年龄:20 大二在读

💪爱好:干饭,运动,码代码,看书,旅游

📃即将更新:

🎯1、手把手带你搭建个人博客网站

🎯2、后台管理系统模块更新

🚍:感兴趣的朋友,赶紧上车吧!!

🎉欢迎关注🔍点赞👍收藏🎇留言📙

🎄有任何疑问,欢迎留言讨论!!!

小羊最近发现了一个比较好玩的圣诞树的demo,demo在Hbuilder上成功运行后,就会展现出下面的样子,代码我放在下面了哈,好玩的东西当然要一起分享呀!🛒

小羊把代码已经打包好上传到服务器了,大家也可以直接访问网站:Christmas_小🐏

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

本文转载自: https://blog.csdn.net/m0_55858611/article/details/122180407
版权归原作者 小羊不会飞 所有, 如有侵权,请联系我们删除。

“芜湖,这是一棵会唱歌的圣诞树”的评论:

还没有评论