首页
留言
友链
壁纸
更多
直播
追番
统计
关于
Search
1
欢迎使用 Typecho
191 阅读
2
为Joe主题增加表情包
165 阅读
3
『转载』Linux文件自动备份百度网盘
142 阅读
4
Java的一些基础知识总结
141 阅读
5
Js 音频律动
126 阅读
默认分类
Java
Java基础知识
Java面向对象
JavaWeb服务
前端三剑客
HTML
JS
Typecho
前端小结
Vue
登录
/
注册
Search
标签搜索
Java
Servlet
HTML
面向对象
Vue
Web
JS
Typecho
Typora
Markdown
乐抖系统
Typecho主题
技术教程
类与对象
基础知识
Tomcat
Maven
Linux
MySQL
Mybatis
白衣少年
累计撰写
49
篇文章
累计收到
42
条评论
首页
栏目
默认分类
Java
Java基础知识
Java面向对象
JavaWeb服务
前端三剑客
HTML
JS
Typecho
前端小结
Vue
页面
留言
友链
壁纸
直播
追番
统计
关于
用户登录
登录
注册
搜索到
3
篇
标签为
JS
的文章
2023-08-23
HTML - 鱼群跳跃
在访问网站的时候经常会看到网站底部有个蓝色的鱼群跳跃动画,可根据鼠标的移动来跳动,很有互动和娱乐性,今天就分享一下鱼群跳跃如何来实现
2023年08月23日
77 阅读
0 评论
1 点赞
2023-07-05
HTML - 圆环时钟
一款好看的时间时钟html代码,加在网站侧边栏也是非常好看,强力推荐!!<html> <head> <style> * { border: 0; box-sizing: border-box; margin: 0; padding: 0; } :root { --hue: 223; --bg: hsl(var(--hue), 10%, 90%); --fg: hsl(var(--hue), 10%, 10%); font-size: calc(16px + (24 - 16) * (100vw - 320px) / (1280 - 320)); } body, button { color: #fff; font: 1em/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; } body { background-color: #1F1F1F; height: 100vh; display: grid; place-items: center; } .progress-clock { display: grid; justify-content: center; align-content: center; position: relative; text-align: center; width: 16em; height: 16em; } .progress-clock__time-date, .progress-clock__time-digit, .progress-clock__time-colon, .progress-clock__time-ampm { transition: color 0.2s linear; -webkit-user-select: none; -moz-user-select: none; user-select: none; } .progress-clock__time-date, .progress-clock__time-digit { background: transparent; } .progress-clock__time-date, .progress-clock__time-ampm { grid-column: 1 / 6; } .progress-clock__time-date { font-size: 0.75em; line-height: 1.33; } .progress-clock__time-digit, .progress-clock__time-colon { font-size: 2em; font-weight: 400; grid-row: 2; } .progress-clock__time-colon { line-height: 1.275; } .progress-clock__time-ampm { cursor: default; grid-row: 3; } .progress-clock__rings { display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; } .progress-clock__ring { opacity: 0.1; } .progress-clock__ring-fill { transition: opacity 0s 0.3s linear, stroke-dashoffset 0.3s ease-in-out; } .progress-clock__ring-fill--360 { opacity: 0; stroke-dashoffset: 0; transition-duration: 0.3s; } [data-group]:focus { outline: transparent; } [data-units] { transition: opacity 0.2s linear; } [data-group="d"]:focus, [data-group="d"]:hover { color: hsl(333, 90%, 55%); } [data-group="h"]:focus, [data-group="h"]:hover { color: hsl(33, 90%, 55%); } [data-group="m"]:focus, [data-group="m"]:hover { color: hsl(213, 90%, 55%); } [data-group="s"]:focus, [data-group="s"]:hover { color: hsl(273, 90%, 55%); } [data-group]:focus~.progress-clock__rings [data-units], [data-group]:hover~.progress-clock__rings [data-units] { opacity: 0.2; } [data-group="d"]:focus~.progress-clock__rings [data-units="d"], [data-group="d"]:hover~.progress-clock__rings [data-units="d"], [data-group="h"]:focus~.progress-clock__rings [data-units="h"], [data-group="h"]:hover~.progress-clock__rings [data-units="h"], [data-group="m"]:focus~.progress-clock__rings [data-units="m"], [data-group="m"]:hover~.progress-clock__rings [data-units="m"], [data-group="s"]:focus~.progress-clock__rings [data-units="s"], [data-group="s"]:hover~.progress-clock__rings [data-units="s"] { opacity: 1; } /* Dark theme */ @media (prefers-color-scheme: dark) { :root { --bg: hsl(var(--hue), 10%, 10%); --fg: hsl(var(--hue), 10%, 90%); } .progress-clock__ring { opacity: 0.2; } } </style> </head> <body> <div id="clock" class="progress-clock"> <button class="progress-clock__time-date" data-group="d" type="button"> <small data-unit="w">Sunday</small><br> <span data-unit="mo">January</span> <span data-unit="d">1</span> </button> <button class="progress-clock__time-digit" data-unit="h" data-group="h" type="button">12</button><span class="progress-clock__time-colon">:</span><button class="progress-clock__time-digit" data-unit="m" data-group="m" type="button">00</button><span class="progress-clock__time-colon">:</span><button class="progress-clock__time-digit" data-unit="s" data-group="s" type="button">00</button> <span class="progress-clock__time-ampm" data-unit="ap">AM</span> <svg class="progress-clock__rings" width="256" height="256" viewBox="0 0 256 256"> <defs> <linearGradient id="pc-red" x1="1" y1="0.5" x2="0" y2="0.5"> <stop offset="0%" stop-color="hsl(343,90%,55%)" /> <stop offset="100%" stop-color="hsl(323,90%,55%)" /> </linearGradient> <linearGradient id="pc-yellow" x1="1" y1="0.5" x2="0" y2="0.5"> <stop offset="0%" stop-color="hsl(43,90%,55%)" /> <stop offset="100%" stop-color="hsl(23,90%,55%)" /> </linearGradient> <linearGradient id="pc-blue" x1="1" y1="0.5" x2="0" y2="0.5"> <stop offset="0%" stop-color="hsl(223,90%,55%)" /> <stop offset="100%" stop-color="hsl(203,90%,55%)" /> </linearGradient> <linearGradient id="pc-purple" x1="1" y1="0.5" x2="0" y2="0.5"> <stop offset="0%" stop-color="hsl(283,90%,55%)" /> <stop offset="100%" stop-color="hsl(263,90%,55%)" /> </linearGradient> </defs> <!-- Days of Month --> <g data-units="d"> <circle class="progress-clock__ring" cx="128" cy="128" r="74" fill="none" opacity="0.1" stroke="url(#pc-red)" stroke-width="12" /> <circle class="progress-clock__ring-fill" data-ring="mo" cx="128" cy="128" r="74" fill="none" stroke="url(#pc-red)" stroke-width="12" stroke-dasharray="465 465" stroke-dashoffset="465" stroke-linecap="round" transform="rotate(-90,128,128)" /> </g> <!-- Hours of Day --> <g data-units="h"> <circle class="progress-clock__ring" cx="128" cy="128" r="90" fill="none" opacity="0.1" stroke="url(#pc-yellow)" stroke-width="12" /> <circle class="progress-clock__ring-fill" data-ring="d" cx="128" cy="128" r="90" fill="none" stroke="url(#pc-yellow)" stroke-width="12" stroke-dasharray="565.5 565.5" stroke-dashoffset="565.5" stroke-linecap="round" transform="rotate(-90,128,128)" /> </g> <!-- Minutes of Hour --> <g data-units="m"> <circle class="progress-clock__ring" cx="128" cy="128" r="106" fill="none" opacity="0.1" stroke="url(#pc-blue)" stroke-width="12" /> <circle class="progress-clock__ring-fill" data-ring="h" cx="128" cy="128" r="106" fill="none" stroke="url(#pc-blue)" stroke-width="12" stroke-dasharray="666 666" stroke-dashoffset="666" stroke-linecap="round" transform="rotate(-90,128,128)" /> </g> <!-- Seconds of Minute --> <g data-units="s"> <circle class="progress-clock__ring" cx="128" cy="128" r="122" fill="none" opacity="0.1" stroke="url(#pc-purple)" stroke-width="12" /> <circle class="progress-clock__ring-fill" data-ring="m" cx="128" cy="128" r="122" fill="none" stroke="url(#pc-purple)" stroke-width="12" stroke-dasharray="766.5 766.5" stroke-dashoffset="766.5" stroke-linecap="round" transform="rotate(-90,128,128)" /> </g> </svg> </div> </body> <script> window.addEventListener("DOMContentLoaded", () => { const clock = new ProgressClock("#clock"); }); class ProgressClock { constructor(qs) { this.el = document.querySelector(qs); this.time = 0; this.updateTimeout = null; this.ringTimeouts = []; this.update(); } getDayOfWeek(day) { switch (day) { case 1: return "Monday"; case 2: return "Tuesday"; case 3: return "Wednesday"; case 4: return "Thursday"; case 5: return "Friday"; case 6: return "Saturday"; default: return "Sunday"; } } getMonthInfo(mo, yr) { switch (mo) { case 1: return { name: "February", days: yr % 4 === 0 ? 29 : 28 }; case 2: return { name: "March", days: 31 }; case 3: return { name: "April", days: 30 }; case 4: return { name: "May", days: 31 }; case 5: return { name: "June", days: 30 }; case 6: return { name: "July", days: 31 }; case 7: return { name: "August", days: 31 }; case 8: return { name: "September", days: 30 }; case 9: return { name: "October", days: 31 }; case 10: return { name: "November", days: 30 }; case 11: return { name: "December", days: 31 }; default: return { name: "January", days: 31 }; } } update() { this.time = new Date(); if (this.el) { // date and time const dayOfWeek = this.time.getDay(); const year = this.time.getFullYear(); const month = this.time.getMonth(); const day = this.time.getDate(); const hr = this.time.getHours(); const min = this.time.getMinutes(); const sec = this.time.getSeconds(); const dayOfWeekName = this.getDayOfWeek(dayOfWeek); const monthInfo = this.getMonthInfo(month, year); const m_progress = sec / 60; const h_progress = (min + m_progress) / 60; const d_progress = (hr + h_progress) / 24; const mo_progress = ((day - 1) + d_progress) / monthInfo.days; const units = [{ label: "w", value: dayOfWeekName }, { label: "mo", value: monthInfo.name, progress: mo_progress }, { label: "d", value: day, progress: d_progress }, { label: "h", value: hr > 12 ? hr - 12 : hr, progress: h_progress }, { label: "m", value: min < 10 ? "0" + min : min, progress: m_progress }, { label: "s", value: sec < 10 ? "0" + sec : sec }, { label: "ap", value: hr > 12 ? "PM" : "AM" } ]; // flush out the timeouts this.ringTimeouts.forEach(t => { clearTimeout(t); }); this.ringTimeouts = []; // update the display units.forEach(u => { // rings const ring = this.el.querySelector(`[data-ring="${u.label}"]`); if (ring) { const strokeDashArray = ring.getAttribute("stroke-dasharray"); const fill360 = "progress-clock__ring-fill--360"; if (strokeDashArray) { // calculate the stroke const circumference = +strokeDashArray.split(" ")[0]; const strokeDashOffsetPct = 1 - u.progress; ring.setAttribute( "stroke-dashoffset", strokeDashOffsetPct * circumference ); // add the fade-out transition, then remove it if (strokeDashOffsetPct === 1) { ring.classList.add(fill360); this.ringTimeouts.push( setTimeout(() => { ring.classList.remove(fill360); }, 600) ); } } } // digits const unit = this.el.querySelector(`[data-unit="${u.label}"]`); if (unit) unit.innerText = u.value; }); } clearTimeout(this.updateTimeout); this.updateTimeout = setTimeout(this.update.bind(this), 1e3); } } </script> </html>
2023年07月05日
98 阅读
0 评论
1 点赞
2023-06-13
Js 音频律动
这段时间在独立写音乐项目,在学习过程中接触到了JS的音频律动,于是找到了以下项目以上是效果图下面分享代码:HTML结构<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="index.css"> </head> <body style="background-color: #000;"> <div class="music-box"> <canvas class="my-canvas"></canvas> <button class="my-music-btn rotate"></button> </div> <script src="index.js"></script> </body> </html>CSS样式* { margin: 0; padding: 0; } body { height: 100vh; display: flex; justify-content: center; align-items: center; overflow: hidden; background: url(./test.jpg) center; background-size: cover; backdrop-filter: blur(50px) grayscale(50%); } .music-box { position: relative; width: 400px; height: 400px; display: flex; justify-content: center; align-items: center; } .my-canvas { position: absolute; top: 0; } .my-music-btn { position: relative; width: 250px; height: 250px; background: url(./test.jpg); background-size: cover; border-radius: 50%; border: none; outline: none; animation: music-btn-anim 20s infinite linear; } .my-music-btn.rotate { animation-play-state: paused; } @keyframes music-btn-anim { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }JS{tabs}{tabs-pane label="代码部分"}// 音乐播放器 class MusicPlayer { constructor(data = { musicSrc: "./test.mp3", // musicImgSrc: "./music.jpg", effectColor: "#FFFFFF" }) { this._requestID = null; // 特效单体 this._effectEntity = new Entity(); this._effectEntity.addComp(new MusicBtnSingleComp({ callback: () => { this._effectEntity.getComp("MusicBtnSingleComp").isRotate = !this._effectEntity.getComp("MusicBtnSingleComp").isRotate; !this._effectEntity.getComp("MusicSingleComp").isReady &&(this._effectEntity.getComp("MusicSingleComp").isReady = true); this._effectEntity.getComp("MusicSingleComp").isPlay = !this._effectEntity.getComp("MusicSingleComp").isPlay; if(!this._effectEntity.getComp("MusicSingleComp").isPlay) { cancelAnimationFrame(this._requestID); } else { this._requestID = requestAnimationFrame(this._renderFrame.bind(this)); } } })); this._effectEntity.addComp(new MusicSingleComp({ musicSrc: data.musicSrc })); this._effectEntity.addComp(new MusicEffectSingleComp({ effectColor: data.effectColor })) } _renderFrame() { this._requestID = requestAnimationFrame(this._renderFrame.bind(this)); this._effectEntity.getComp("MusicEffectSingleComp").byteFrequencyDate = this._effectEntity.getComp("MusicSingleComp").byteFrequencyDate; } } // 单体 class Entity { constructor() { this._compMap = new Map(); } addComp(comp) { this._compMap.set(comp.name, comp); } getComp(compName) { return this._compMap.get(compName); } } // 音乐按钮 class MusicBtnSingleComp { constructor(data) { this.name = "MusicBtnSingleComp"; this._isRotate = false; this._musicBtnDom = document.querySelector(".my-music-btn"); this._musicBtnDom.addEventListener("click", data.callback); } set isRotate(value) { if (value) { this._musicBtnDom.classList.remove("rotate"); } else { this._musicBtnDom.classList.add("rotate"); } this._isRotate = value; } get isRotate() { return this._isRotate; } } // 音乐 class MusicSingleComp { constructor(data) { this.name = "MusicSingleComp"; this._fftSize = 512; this._myAudioDom = document.createElement("audio"); this._myAudioDom.src = data.musicSrc; this._myAudioDom.loop = true; this._isReady = false; this._isPlay = false; this._analyser = null; this._dataArray = []; } set isReady(value) { if (value) { const ctx = new window.AudioContext(); this._analyser = ctx.createAnalyser(); this._analyser.fftSize = this._fftSize; const source = ctx.createMediaElementSource(this._myAudioDom); source.connect(this._analyser); this._analyser.connect(ctx.destination); const bufferLength = this._analyser.frequencyBinCount; this._dataArray = new Uint8Array(bufferLength); } this._isReady = value; } get isReady() { return this._isReady; } set isPlay(value) { if (value) { this._myAudioDom.play(); } else { this._myAudioDom.pause(); } this._isPlay = value; } get isPlay() { return this._isPlay; } get byteFrequencyDate() { this._analyser.getByteFrequencyData(this._dataArray); return this._dataArray.slice(0, 120); } } // 音乐特效 class MusicEffectSingleComp { constructor(data) { this.name = "MusicEffectSingleComp"; this._effectColor = data.effectColor; this._canvasDom = document.querySelector(".my-canvas"); this._canvasDom.width = 400; this._canvasDom.height = 400; this._ctx = this._canvasDom.getContext("2d"); this._byteFrequencyData; this._randomData = Uint8Array.from(new Uint8Array(120), (v,k) => k); this._randomData.sort(() => Math.random() - 0.5); this.byteFrequencyDate = new Uint8Array(120).fill(0); } set byteFrequencyDate(value) { this._byteFrequencyData = value; const bData = []; this._randomData.forEach(value => { bData.push(this._byteFrequencyData[value]); }) const angle = Math.PI * 2 / bData.length; this._ctx.clearRect(0, 0, this._canvasDom.width, this._canvasDom.height); this._ctx.fillStyle = this._effectColor; this._ctx.save(); this._ctx.translate(this._canvasDom.width / 2, this._canvasDom.height / 2); bData.forEach((value, index) => { this._ctx.save(); this._ctx.rotate(angle * index); this._ctx.beginPath(); const h = value / 256 * 60; this._ctx.roundRect(-4, 140, 4, (h < 4) ? 4 : h, 4); // 若上行的 roundRect 存在兼容性问题可以更换为下面注释的代码 // this._ctx.fillRect(-4, 140, 4, (h < 4) ? 4 : h); this._ctx.fill(); this._ctx.restore(); }); this._ctx.restore(); } } new MusicPlayer();{/tabs-pane}{tabs-pane label="代码解释"} 这是一个使用 JavaScript 原生 API 实现的音乐播放器,包含音乐按钮、音乐、音乐特效三个部分。其中:MusicPlayer:音乐播放器类,通过构造函数创建音乐播放器实例,同时包含特效单体(EffectEntity)。Entity:单体类,通过 addComp 和 getComp 方法向特效单体中添加和获取组件。MusicBtnSingleComp:音乐按钮组件,包含事件监听、旋转特效等。MusicSingleComp:音乐组件,负责音乐的加载、配置播放参数和获取音频频谱数据。MusicEffectSingleComp:音乐特效组件,通过获取音频频谱数据,实现了可视化的音乐特效。其中 MusicEffectSingleComp 中的 _ctx.roundRect 方法,可能是用户自定义的实现;如果有兼容性问题,可以更换到代码注释处的相应代码。{/tabs-pane}{/tabs}使用时仅需将图片和音频放于项目根目录并重命名为test.jpg 和 test.mp3即可
2023年06月13日
126 阅读
0 评论
3 点赞