js实现可拖拽快进快退老式碟片音乐播放器效果代码
代码语言:html
所属分类:多媒体
代码描述:js实现可拖拽快进快退老式碟片音乐播放器效果代码
代码标签: js 拖拽 快进 快退 老式 碟片 音乐 播放器
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> :root { --color-theme:rgb(2,176,236); --color-record-center:#fff; --color-record-inner:#131313; --color-record-groove:#000; --color-record-outer:#000; --spacing-groove:10%; --font-family:"Poppins",cursive; --turntable-height:clamp(300px,90vmin,500px); --disc-dimension:calc(var(--turntable-height) * .9) } html { box-sizing:border-box } *,*:before,*:after { box-sizing:inherit } html,body { margin:0; padding:0 } body { width:100%; height:100vh; overflow:hidden; overscroll-behavior:contain } .layout { width:100vw; height:100vh; display:flex; justify-content:center; align-items:center } .turntable { height:var(--turntable-height); display:inline-flex; gap:1rem; padding:calc(var(--turntable-height) * .05); background:rgb(233,233,233); border-radius:3px; box-shadow:12px 14px 18px 2px #a6a1a17f } .disc-container { aspect-ratio:1; height:100%; display:flex; justify-content:center; align-items:center; border-radius:50%; border:2px solid #000; background:linear-gradient(45deg,rgb(255,255,255),rgb(66,66,66)) } .disc { position:relative; aspect-ratio:1; width:91%; overflow:hidden; border-radius:50%; background:repeating-radial-gradient(var(--color-record-inner),var(--color-record-groove) 2px,var(--color-record-groove) 2px,var(--color-record-inner) 4px); cursor:grab } .disc.is-scratching { cursor:grabbing } .disc__que { --dim:10px; position:absolute; top:50%; right:30px; width:var(--dim); height:var(--dim); background:var(--color-theme); border-radius:50% } .disc__label { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); display:flex; justify-content:center; align-items:center; text-align:center; width:calc(var(--disc-dimension) * .4); height:calc(var(--disc-dimension) * .4); background:no-repeat url(//repo.bfw.wiki/bfwrepo/icon/617245a85118d.png) center center; background-size:cover; border-radius:50%; pointer-events:none } .disc__middle { --dim:10px; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:var(--dim); height:var(--dim); background:rgb(26,26,26); border-radius:50% } .disc__glare { width:var(--disc-dimension); height:15%; position:absolute; top:50%; transform:translateY(-50%) rotate(-30deg); background:rgba(255,255,255,.15); filter:blur(10px); pointer-events:none } .sidebar { display:flex; height:100% } .controls { height:100%; display:flex; align-items:flex-end } .controls__row { justify-content:center; gap:10px } .control { font-family:var(--font-family); text-transform:uppercase } .rewind { display:none } .button { border-radius:0; border:none; background:rgb(69,69,69); font-size:10px; padding:.4rem; color:#fff; line-height:1.3; cursor:pointer; box-shadow:1px 1px 0 1px #000,0 0 0 0 var(--color-theme); will-change:box-shadow; transition:box-shadow .2s ease-out,transform .05s ease-in } .button.is-active { transform:translate(1px,2px); box-shadow:0 0 5px 1px var(--color-theme) } </style> </head> <body > <div class="layout"> <div class="turntable"> <div class="disc-container"> <div class="disc" id="disc"> <div class="disc__que"></div> <div class="disc__label"></div> <div class="disc__middle"></div> </div> <div class="disc__glare"></div> </div> <div class="sidebar"> <div class="controls"> <div class="controls__row"> <button class="control button" id="playToggle">Power</button> <button class="control button rewind" id="rewind"> << </button> </div> </div> </div> </div> </div> <script > (function() { const e = document.createElement("link").relList; if (e && e.supports && e.supports("modulepreload")) return; for (const n of document.querySelectorAll('link[rel="modulepreload"]')) s(n); new MutationObserver(n => { for (const o of n) if (o.type === "childList") for (const a of o.addedNodes) a.tagName === "LINK" && a.rel === "modulepreload" && s(a); }).observe(document, { childList: !0, subtree: !0 }); function t(n) { const o = {}; return n.integrity && (o.integrity = n.integrity), n.referrerpolicy && (o.referrerPolicy = n.referrerpolicy), n.crossorigin === "use-credentials" ? o.credentials = "include" : n.crossorigin === "anonymous" ? o.credentials = "omit" : o.credentials = "same-origin", o; } function s(n) { if (n.ep) return; n.ep = !0; const o = t(n); fetch(n.href, o); } })(); const y = (i, e, t) => Math.max(e, Math.min(i, t)), P = i => { const { left: e, top: t, width: s, height: n } = i.getBoundingClientRect(), o = e + s / 2, a = t + n / 2; return { x: o, y: a }; }, w = (i, e) => Math.atan2(e.y - i.y, e.x - i.x), R = (i, e) => Math.atan2(Math.sin(i - e), Math.cos(i - e)), A = (i, e, t = n => n, s) => { const n = t, o = []; for (let a = 0; a < i.length; a += 1) { const l = a - e, g = l >= 0 ? l : 0, p = a + e + 1; let f = 0, m = 0; for (let h = g; h < p && h < i.length; h += 1) m += n(i[h]), f += 1; o[a] = s ? s(i[a], m / f) : m / f; } return o; }, B = i => i.reduce((e, t) => e + t, 0) / i.length, E = (i, e = 10) => { const t = Math.max(0, i.length - e); return i.slice(t); }, _ = Math.PI * 2, v = .75, C = v * 60, L = C * _, M = L / 60, b = M * .001, S = Math.PI * 2, u = () => {}; class x { constructor(e) { this.el = e, this._isPoweredOn = !1, this._playbackSpeed = 1, this._duration = 0, this._isDragging = !1, this.center = P(this.el), this.angle = 0, this.anglePrevious = 0, this.maxAngle = S, this.rafId = null, this.timestampPrevious = performance.now(), this.draggingSpeeds = [], this.draggingFrom = {}, this.isReversed = !1, this.onDragStart = this.onDragStart.bind(this), this.onDragProgress = this.onDragProgress.bind(this), this.onDragEnd = this.onDragEnd.bind(this), this.loop = this.loop.bind(this), this.callbacks = { onDragEnded: u, onAutoRotate: u, onStop: u, onLoop: u }, this.init(); } init() { this.el.addEventListener("pointerdown", this.onDragStart); } get playbackSpeed() { return this._playbackSpeed; } set pl.........完整代码请登录后点击上方下载按钮下载查看
网友评论0