“常温”前端网站框架(四)-- 音乐播放器【附源码】

news2024/11/15 13:54:54

开篇(请大家看完):此网站写给挚爱,后续页面还会慢慢更新,大家敬请期待~ ~ ~

此前端框架,主要侧重于前端页面的视觉效果和交互体验。通过运用各种前端技术和创意,精心打造了一系列引人入胜的页面特效,会为大家带来全新的浏览体验。

同时,我非常支持和鼓励大家对这个框架进行二次创作或修改。您可以根据自己的需求和喜好,对框架进行个性化的定制和扩展,以打造出更符合自己品味的页面效果。

但请注意,如果您打算将这个框架转发给其他人或用于其他场合,请务必注明原创来源。让我们一起维护一个良好的创作环境。

最后,轻舟会继续更新和完善这个前端页面特效框架,为大家带来更多有趣、实用的功能和效果。感谢您的支持和关注!

页面效果:整体色调背景采用柔和渐变的方式呈现,与主页面的“毒药水式”色彩搭配形成了强烈的对比;周边花瓣缓缓飘落到水面之上形成涟漪。整体给人一种温馨、浪漫的感觉,还可以通过中间的3个按钮来播放不同的音乐
在这里插入图片描述
在这里插入图片描述

一:音乐播放.html

<!DOCTYPE HTML>
<html>
<head>
<title>音乐播放</title>
<meta name="Generator" content="EditPlus">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8">
<link rel="stylesheet" href="CSS/音乐播放.css">

<script type="text/javascript" src="JS/jquery-3.7.1.min.js"></script>
</head>

<body>
    <div id="jsi-cherry-container" class="container"></div>
    <script>
        var RENDERER = {
            INIT_CHERRY_BLOSSOM_COUNT: 30,
            MAX_ADDING_INTERVAL: 10,

            init: function () {
                this.setParameters();
                this.reconstructMethods();
                this.createCherries();
                this.render();
            },
            setParameters: function () {
                this.$container = $('#jsi-cherry-container');
                this.width = this.$container.width();
                this.height = this.$container.height();
                this.context = $('<canvas />').attr({ width: this.width, height: this.height }).appendTo(this.$container).get(0).getContext('2d');
                this.cherries = [];
                this.maxAddingInterval = Math.round(this.MAX_ADDING_INTERVAL * 1000 / this.width);
                this.addingInterval = this.maxAddingInterval;
            },
            reconstructMethods: function () {
                this.render = this.render.bind(this);
            },
            createCherries: function () {
                for (var i = 0, length = Math.round(this.INIT_CHERRY_BLOSSOM_COUNT * this.width / 1000); i < length; i++) {
                    this.cherries.push(new CHERRY_BLOSSOM(this, true));
                }
            },
            render: function () {
                requestAnimationFrame(this.render);
                this.context.clearRect(0, 0, this.width, this.height);

                this.cherries.sort(function (cherry1, cherry2) {
                    return cherry1.z - cherry2.z;
                });
                for (var i = this.cherries.length - 1; i >= 0; i--) {
                    if (!this.cherries[i].render(this.context)) {
                        this.cherries.splice(i, 1);
                    }
                }
                if (--this.addingInterval == 0) {
                    this.addingInterval = this.maxAddingInterval;
                    this.cherries.push(new CHERRY_BLOSSOM(this, false));
                }
            }
        };
        var CHERRY_BLOSSOM = function (renderer, isRandom) {
            this.renderer = renderer;
            this.init(isRandom);
        };
        CHERRY_BLOSSOM.prototype = {
            FOCUS_POSITION: 300,
            FAR_LIMIT: 600,
            MAX_RIPPLE_COUNT: 100,
            RIPPLE_RADIUS: 100,
            SURFACE_RATE: 0.5,
            SINK_OFFSET: 20,

            init: function (isRandom) {
                this.x = this.getRandomValue(-this.renderer.width, this.renderer.width);
                this.y = isRandom ? this.getRandomValue(0, this.renderer.height) : this.renderer.height * 1.5;
                this.z = this.getRandomValue(0, this.FAR_LIMIT);
                this.vx = this.getRandomValue(-2, 2);
                this.vy = -2;
                this.theta = this.getRandomValue(0, Math.PI * 2);
                this.phi = this.getRandomValue(0, Math.PI * 2);
                this.psi = 0;
                this.dpsi = this.getRandomValue(Math.PI / 600, Math.PI / 300);
                this.opacity = 0;
                this.endTheta = false;
                this.endPhi = false;
                this.rippleCount = 0;

                var axis = this.getAxis(),
                    theta = this.theta + Math.ceil(-(this.y + this.renderer.height * this.SURFACE_RATE) / this.vy) * Math.PI / 500;
                theta %= Math.PI * 2;

                this.offsetY = 40 * ((theta <= Math.PI / 2 || theta >= Math.PI * 3 / 2) ? -1 : 1);
                this.thresholdY = this.renderer.height / 2 + this.renderer.height * this.SURFACE_RATE * axis.rate;
                this.entityColor = this.renderer.context.createRadialGradient(0, 40, 0, 0, 40, 80);
                this.entityColor.addColorStop(0, 'hsl(330, 70%, ' + 50 * (0.3 + axis.rate) + '%)');
                this.entityColor.addColorStop(0.05, 'hsl(330, 40%,' + 55 * (0.3 + axis.rate) + '%)');
                this.entityColor.addColorStop(1, 'hsl(330, 20%, ' + 70 * (0.3 + axis.rate) + '%)');
                this.shadowColor = this.renderer.context.createRadialGradient(0, 40, 0, 0, 40, 80);
                this.shadowColor.addColorStop(0, 'hsl(330, 40%, ' + 30 * (0.3 + axis.rate) + '%)');
                this.shadowColor.addColorStop(0.05, 'hsl(330, 40%,' + 30 * (0.3 + axis.rate) + '%)');
                this.shadowColor.addColorStop(1, 'hsl(330, 20%, ' + 40 * (0.3 + axis.rate) + '%)');
            },
            getRandomValue: function (min, max) {
                return min + (max - min) * Math.random();
            },
            getAxis: function () {
                var rate = this.FOCUS_POSITION / (this.z + this.FOCUS_POSITION),
                    x = this.renderer.width / 2 + this.x * rate,
                    y = this.renderer.height / 2 - this.y * rate;
                return { rate: rate, x: x, y: y };
            },
            renderCherry: function (context, axis) {
                context.beginPath();
                context.moveTo(0, 40);
                context.bezierCurveTo(-60, 20, -10, -60, 0, -20);
                context.bezierCurveTo(10, -60, 60, 20, 0, 40);
                context.fill();

                for (var i = -4; i < 4; i++) {
                    context.beginPath();
                    context.moveTo(0, 40);
                    context.quadraticCurveTo(i * 12, 10, i * 4, -24 + Math.abs(i) * 2);
                    context.stroke();
                }
            },
            render: function (context) {
                var axis = this.getAxis();

                if (axis.y == this.thresholdY && this.rippleCount < this.MAX_RIPPLE_COUNT) {
                    context.save();
                    context.lineWidth = 2;
                    context.strokeStyle = 'hsla(0, 0%, 100%, ' + (this.MAX_RIPPLE_COUNT - this.rippleCount) / this.MAX_RIPPLE_COUNT + ')';
                    context.translate(axis.x + this.offsetY * axis.rate * (this.theta <= Math.PI ? -1 : 1), axis.y);
                    context.scale(1, 0.3);
                    context.beginPath();
                    context.arc(0, 0, this.rippleCount / this.MAX_RIPPLE_COUNT * this.RIPPLE_RADIUS * axis.rate, 0, Math.PI * 2, false);
                    context.stroke();
                    context.restore();
                    this.rippleCount++;
                }
                if (axis.y < this.thresholdY || (!this.endTheta || !this.endPhi)) {
                    if (this.y <= 0) {
                        this.opacity = Math.min(this.opacity + 0.01, 1);
                    }
                    context.save();
                    context.globalAlpha = this.opacity;
                    context.fillStyle = this.shadowColor;
                    context.strokeStyle = 'hsl(330, 30%,' + 40 * (0.3 + axis.rate) + '%)';
                    context.translate(axis.x, Math.max(axis.y, this.thresholdY + this.thresholdY - axis.y));
                    context.rotate(Math.PI - this.theta);
                    context.scale(axis.rate * -Math.sin(this.phi), axis.rate);
                    context.translate(0, this.offsetY);
                    this.renderCherry(context, axis);
                    context.restore();
                }
                context.save();
                context.fillStyle = this.entityColor;
                context.strokeStyle = 'hsl(330, 40%,' + 70 * (0.3 + axis.rate) + '%)';
                context.translate(axis.x, axis.y + Math.abs(this.SINK_OFFSET * Math.sin(this.psi) * axis.rate));
                context.rotate(this.theta);
                context.scale(axis.rate * Math.sin(this.phi), axis.rate);
                context.translate(0, this.offsetY);
                this.renderCherry(context, axis);
                context.restore();

                if (this.y <= -this.renderer.height / 4) {
                    if (!this.endTheta) {
                        for (var theta = Math.PI / 2, end = Math.PI * 3 / 2; theta <= end; theta += Math.PI) {
                            if (this.theta < theta && this.theta + Math.PI / 200 > theta) {
                                this.theta = theta;
                                this.endTheta = true;
                                break;
                            }
                        }
                    }
                    if (!this.endPhi) {
                        for (var phi = Math.PI / 8, end = Math.PI * 7 / 8; phi <= end; phi += Math.PI * 3 / 4) {
                            if (this.phi < phi && this.phi + Math.PI / 200 > phi) {
                                this.phi = Math.PI / 8;
                                this.endPhi = true;
                                break;
                            }
                        }
                    }
                }
                if (!this.endTheta) {
                    if (axis.y == this.thresholdY) {
                        this.theta += Math.PI / 200 * ((this.theta < Math.PI / 2 || (this.theta >= Math.PI && this.theta < Math.PI * 3 / 2)) ? 1 : -1);
                    } else {
                        this.theta += Math.PI / 500;
                    }
                    this.theta %= Math.PI * 2;
                }
                if (this.endPhi) {
                    if (this.rippleCount == this.MAX_RIPPLE_COUNT) {
                        this.psi += this.dpsi;
                        this.psi %= Math.PI * 2;
                    }
                } else {
                    this.phi += Math.PI / ((axis.y == this.thresholdY) ? 200 : 500);
                    this.phi %= Math.PI;
                }
                if (this.y <= -this.renderer.height * this.SURFACE_RATE) {
                    this.x += 2;
                    this.y = -this.renderer.height * this.SURFACE_RATE;
                } else {
                    this.x += this.vx;
                    this.y += this.vy;
                }
                return this.z > -this.FOCUS_POSITION && this.z < this.FAR_LIMIT && this.x < this.renderer.width * 1.5;
            }
        };
        $(function () {
            RENDERER.init();
        });
    </script>

<div class="music-player">
    <div class="music-info">
        <img src="images/空白logo.jpg" alt="Cover" id="cover">
        <h2 id="title">歌曲标题</h2>
    </div>
    <div class="controls">
        <button id="prev">上一首</button>
        <button id="play">播放</button>
        <button id="next">下一首</button>
    </div>
    <audio id="audioPlayer" src="images/二.mp3"></audio>
</div>
<script src="JS/音乐播放.js"></script>
</body>

</html>

二:音乐播放.css

body {
  display: flex;
  grid: 2rem auto/repeat(2, 50%);
  grid-column-gap: 2rem;
  justify-content: center;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

.music-player {
    text-align: center;
    padding: 30px;
    border-radius: 10px;
}

.music-info img {
    width: 240px;
    height: 200px;
    border-radius: 50%;
    margin-bottom: 10px;
    position: relative;
}

.controls button {
    padding: 10px 20px;
    margin: 5px;
    cursor: pointer;
    font-size: 16px;
    position: relative;
     background-image: linear-gradient(to right, rgba(154, 89, 168, 0.67), rgba(30, 145, 199, 0.67), rgba(0, 255, 153, 0.67));
}

    html,
    body {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
    }

    .container {
    width: 100%;
    height: 100%;
    margin: 0;
    position: absolute;
    padding: 0;
     background-image: linear-gradient(to right, rgba(154, 89, 168, 0.67), rgba(30, 145, 199, 0.67), rgba(0, 255, 153, 0.67));
}

三:音乐播放.js

const player = document.getElementById('audioPlayer');
const playButton = document.getElementById('play');
const prevButton = document.getElementById('prev');
const nextButton = document.getElementById('next');
const title = document.getElementById('title');
const cover = document.getElementById('cover');

const songs = [
    { title: '24/7, 365', src: 'images/二.mp3', cover: 'images/24.jpg' },
    { title: '因为喜欢你', src: 'images/因为喜欢你.mp3', cover: 'images/因为喜欢你.jpg' },
    { title: 'Love Story', src: 'images/Love Story.mp3', cover: 'images/Lover Story.jpg' },
    { title: 'Lover', src: 'images/Lover.mp3', cover: 'images/Lover.jpg' }
];

let currentIndex = 0;

function loadSong(song) {
    title.textContent = song.title;
    cover.src = song.cover;
    player.src = song.src;
}

function playSong() {
    player.play();
    playButton.textContent = '暂停';
}

function pauseSong() {
    player.pause();
    playButton.textContent = '播放';
}

playButton.addEventListener('click', () => {
    const isPlaying = player.paused;
    if (isPlaying) {
        playSong();
    } else {
        pauseSong();
    }
});

prevButton.addEventListener('click', () => {
    currentIndex = (currentIndex - 1 + songs.length) % songs.length;
    loadSong(songs[currentIndex]);
    playSong();
});

nextButton.addEventListener('click', () => {
    currentIndex = (currentIndex + 1) % songs.length;
    loadSong(songs[currentIndex]);
    playSong();
});

loadSong(songs[currentIndex]);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1970830.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高龙海洋增收不增利:毛利率有所下滑,产能利用率下降仍扩产?

《港湾商业观察》廖紫雯 日前&#xff0c;高龙海洋集团有限公司&#xff08;以下简称&#xff1a;高龙海洋&#xff09;递表港交所&#xff0c;保荐机构为越秀融资。高龙海洋国内运营主体为福建高龙海洋生物工程有限公司。 自2008年公司成立以来&#xff0c;高龙海洋一直从事…

vue3中 provide/inject用法详解

依赖注入&#xff1a;provide 和 inject 什么情况下推荐provide/inject使用&#xff1a;Prop 多层级数据透传 通常情况下&#xff0c;当我们需要从父组件向子组件传递数据时&#xff0c;会使用 props。想象一下这样的结构&#xff1a;有一些多层级嵌套的组件&#xff0c;形成了…

云HIS综合管理系统源码,云端SaaS服务,与监管系统有序对接,扩展性强

云HIS系统&#xff1a; 本套云HIS系统是一款适用于二级及以下医院、专科医院和社区卫生机构的综合性医院信息系统&#xff0c;它包含门诊预约挂号、收费结算、排班、医护协同、药房、药库、电子病历等10大功能模块&#xff0c;支持门诊、住院、医技、后勤各项核心业务。 采用…

每天五分钟玩转深度学习框架PyTorch:选择函数where和gather

本文重点 如图表所示,这几个方法可以理解为索引函数,有些函数在切片和索引一章进行了简单的介绍,本文将再次进行介绍,温故知新。 index_select 通过特殊的索引来获取数据index_select,这个这样来理解,第一个参数表示a的第几维度,第二个参数表示获取该维度的哪部分。 我…

strimzi operator 部署kafka集群

Strimzi介绍 官方文档:https://strimzi.io/docs/operators/0.42.0/overview#kafka-components_str Strimzi介绍 Strimzi 是一个用于 Apache Kafka 在 Kubernetes 上部署和管理的开源项目。它提供了一组 Kubernetes 自定义资源定义(Custom Resource Definitions,CRDs)、控制…

Oracle11.2.0 安装手册V1.0.doc

文档说明 编写目的 本手册是给系统技术人员人员提供Red Hat Enterprise Linux 5.4环境下得Oracle 11g的安装和配置指导&#xff0c;帮助实施人员或用户能够快速安装配置Oracle 11g。 准备介质 适用于Linux x86-64的Oracle Database 11g第2版 linux.x64_11gR2_database_1of2.…

校园课程助手【4】-使用Elasticsearch实现课程检索

本节将介绍本项目的查询模块&#xff0c;使用Elasticsearch又不是查询接口&#xff0c;具体流程如图所示&#xff08;如果不了解Elasticsearch可以使用sql语句进行查询&#xff09;&#xff1a; 这里是两种方法的异同点&#xff1a; Mysql&#xff1a;擅长事务类型操作&#…

​EtherCAT、CANopen、RS485在电机控制中的对比

​EtherCAT、CANopen、RS485在电机控制中的对比 EtherCAT 特点&#xff1a; 高速通信&#xff1a;EtherCAT是一种实时以太网技术&#xff0c;数据传输速度快&#xff0c;具有极低的通信延迟和抖动。 高同步性&#xff1a;可精确同步多台设备&#xff0c;适用于高要求的控制任…

Python爬虫技术 第23节 数据清洗和预处理

在使用Python进行网络爬虫项目时&#xff0c;数据清洗和预处理是非常重要的步骤。这些步骤有助于确保从网页上抓取的数据准确、一致&#xff0c;并且适合后续的分析或机器学习任务。下面我将详细介绍如何使用Python来进行数据清洗和预处理。 1. 数据获取 首先&#xff0c;你需…

Java 实现 AVL树

在二叉平衡树中&#xff0c;我们进行插入和删除操作时都需要遍历树&#xff0c;可见树的结构是很影响操作效率的。在最坏的情况下&#xff0c;树成了一个单支树&#xff0c;查找的时间复杂度成了O(N)&#xff0c;建树跟没建树一样。那么是不是有什么办法可以建一个树避免这种情…

基于 KubeSphere 的 Kubernetes 生产环境部署架构设计及成本分析

转载&#xff1a;基于 KubeSphere 的 Kubernetes 生产环境部署架构设计及成本分析 前言 导图 1. 简介 1.1 架构概要说明 今天分享一个实际小规模生产环境部署架构设计的案例&#xff0c;该架构设计概要说明如下&#xff1a; 本架构设计适用于中小规模(<50)的 Kubernetes …

本地生活服务商公司有哪些?一文教你搭建本地生活系统!

当前&#xff0c;本地生活领域群雄环伺&#xff0c;日益激烈的竞争推动各家互联网大厂调整布局模式的同时&#xff0c;也让本地生活市场持续迸发新的活力。在此背景下&#xff0c;想要通过本地生活服务商身份入局的创业者数量不断增多&#xff0c;以本地生活服务商公司有哪些等…

前端面试题整理-CSS

两栏布局 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>两栏布局</title><style>…

java计算机毕设课设—基于网络爬虫技术的网络新闻分析系统(附源码、文章、相关截图、部署视频)

这是什么系统&#xff1f; java计算机毕设课设—基于网络爬虫技术的网络新闻分析系统 基于网络爬虫技术的新闻分析系统&#xff0c;它能够实时抓取凤凰网、网易、新浪、搜狐等网站的新闻数据&#xff0c;提取正文和点击量&#xff0c;每日定时抓取。系统还能对抓取的新闻进行…

给echarts图表线条、数据点和区域设置颜色

let myChart echarts.init(document.getElementById("chartmainCop"));// 获取当前干部的各项评分const allIndicators Object.keys(this.dialogEacherTable[0]).filter(key > key ! "CadreID" && key ! "xm").map(key > ({name…

window电脑上使用python将pdf转换为word文档

1、电脑上安装Python运行环境 一、python官网下载链接 二、下载到电脑后&#xff0c;直接运行安装 三、安装完成后按&#xff1a;winR键进入window命令控制窗口&#xff0c;输入 python --version2、设置python依赖包国内镜像源 pip config set global.index-url https://mirr…

国家发改委区域司韩振海副司长一行莅临麒麟信安调研

7月31日&#xff0c;国家发改委区域司韩振海副司长一行莅临麒麟信安调研。湖南省发改委区域处处长孙健军&#xff0c;长沙市发改委党组成员、市长株潭一体化发展事务中心主任邹犇淼等相关领导陪同调研。麒麟信安总裁刘文清热情接待。 在麒麟信安展厅&#xff0c;韩振海副司长一…

在MANET中的TCP增强

本文内容节选自一篇系统性文献综述&#xff08;Systematic Literature Review, SLR&#xff09;&#xff0c;标题为“TCP Performance Enhancement in IoT and MANET”&#xff0c;由 Sultana Parween 和 Syed Zeeshan Hussain 撰写&#xff0c;发表在《International Journal …

Windows下Rust OpenCV环境配置

首发于Enaium的个人博客 安装Chocolatey 首先我们需要安装Chocolatey&#xff0c;Chocolatey是一个Windows的包管理器。 我们点击右上角的Install进入到Installing Chocolatey&#xff0c;选择Individual 复制命令 Set-ExecutionPolicy Bypass -Scope Process -Force; [Sys…

springboot餐饮管理系统-计算机毕业设计源码73168

摘要 随着科技的不断进步和互联网时代的深入发展&#xff0c;餐饮行业正面临着一场由传统向智能化、信息化转变的革命。传统的餐饮管理方式&#xff0c;如手工点餐、纸质菜单、人工结算等&#xff0c;已经无法满足现代餐饮企业对于效率、准确性和用户体验的高要求。因此&#x…