原生JS实现炫酷日食音量播放器

原生JS实现炫酷日食音量播放器

首先 看一下展示效果

在这里插入图片描述

第一步 :完成基本结构

以下是所有HTML代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>音量调节器</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <div class="wrapper">
        <audio src="./tq.mp3" preload="auto"></audio>
        <div class="title">拖动调节音量</div>
        <div class="per">Volume</div>
        <div class="circle sun"></div>
        <div class="circle moon"></div>
    </div>
    <script src="./index.js"></script>
</body>
</html>

先不看样式,大致要完成这样一个结构,我们把金黄色的圆称之为sun 淡黄色的圆环为moon
在这里插入图片描述

第二步:增加样式

样式中有两个很关键的点

  • 产生自适应的两个圆
  • 背景颜色的设定

在这里背景颜色采用了 hsl的设定方式,hsl有三个值 ,分别是 色相/色调 、当前的饱和度 、 当前的亮度 这样做的好处在于方便后期js操纵改变颜色

html,body{
    
    
    width: 100%;
    height: 100%;
    /* 色相/色调    当前饱和度   当前色值亮度 */
    background: hsl(194, 66%, 49%);
}

第二个注意点在于生成两个圆,其实生成两个圆的前提是生成两个正方体,这里因为是自适应的
所以要采用百分比的写法,但是这里仅仅设置了 width : 20% ,但是没有设置heght:20%
是因为 一开始width 和 height 就不是等宽的,所以他们的相对值也不可能是正方体,所以这里采用了padding-top:20% 的方式把高度撑开,实现了一个正方体

/* 自适应的正方形   */
.wrapper .circle{
    
    
    position: absolute;
    width: 20%;
     padding-top: 20%;
     /* vw vh */
    border-radius: 50%;
    top: 30%;
    left: 30%;
}

以下是完整的css代码:

*{
    
    
    margin: 0;
    padding: 0;    
}
html,body{
    
    
    width: 100%;
    height: 100%;
    /* 色相/色调    当前饱和度   当前色值亮度 */
    background: hsl(194, 66%, 49%);
}
.wrapper{
    
    
    position: relative;
    width: 70%;
    height: 100%;
    margin: 0 auto;
}
.wrapper .title{
    
    
    position: absolute;
    color: #ffffff;
    top: 100px ;
    font-size: 20px; 
    font-weight: bolder;
}
.wrapper .per{
    
    
    position: absolute;
    color: #ffffff;
    top: 100px ;
    font-size: 20px;
    width: 100%;
    text-align: center;
}
/* 自适应的正方形   */
.wrapper .circle{
    
    
    position: absolute;
    width: 20%;
     padding-top: 20%;
     /* vw vh */
    border-radius: 50%;
    top: 30%;
    left: 30%;
}
.wrapper .circle.sun{
    
    
    background: #ffff77;
    box-shadow:0px 0px 50px #ffff77;
}
.wrapper .circle.moon{
    
      
    left: 55%;
    /* top: calc(30% + 2px);
    width:  calc(20% - 4px);
    padding-top: calc(20% - 4px); */   
    /*
	这里注释掉的部分是想让moon比sun小一圈,这样移动到中间会有一个圆环的效果,不写的话就是两个等大的圆
	
*/
    box-shadow:inset 0 0 50px #ffff77 ;
    cursor: pointer;
}

第三步:原生js增加行为

这里的编程思路是一个类似于面向对象的思路,一共有四个函数
在这里插入图片描述

第一个函数:init
这是一个入口函数,最后通过对象调用的方式执行整个代码

init : function(){
    
    
        this.moon = document.getElementsByClassName('moon')[0] ;
        this.sun = document.getElementsByClassName('sun')[0 ];
        this.bindEvent();
    },

主要功能是获取标签对象,执行bindEvent函数

第二个函数 : bindEvent

 bindEvent : function(){
    
    
        var moon = this.moon;
        var body = document.getElementsByTagName('body')[0];
        var dis;
        var lock =false;
        //这里设置了一个锁,初始状态为false
        var that = this;
        //这里是为了改变this 的指向 这里的this指向obj 所以that也指向obj
        moon.onmousedown = function (e) {
    
    
            lock = true;
            //鼠标按下的时候,锁的状态变为 true  
            dis = e.clientX - moon.offsetLeft;
        };
        body.onmousemove = function (e) {
    
    
            if(!lock){
    
    
                return
            }
            //鼠标移动事件,如果鼠标在将要移动的时候,锁的状态是false,那么就直接返回出去,
            // 不继续往下执行
             moon.style.left = e.clientX -dis +'px';
             that.getPer();
/*
   这里我想要让obj调用getPer函数,如果直接this.getPer()的话,指向的应该是body,所以用that
*/
        };
        body.onmouseup = function () {
    
    
            lock = false
            //鼠标抬起之后,把锁变为false 这是moon就不会再跟着鼠标移动
        };
    },

这个函数的主要功能就是实现拖拽

dis = e.clientX - moon.offsetLeft;
moon.style.left = e.clientX -dis +‘px’;

这一行代码是在获取一个拖拽的值

在这里插入图片描述

第三个函数 :getPer
这个per 就是一个覆盖的百分比,通过水平的距离来计算,

  getPer:function(){
    
    
         var that = this;
         var per;
         var moon = that.moon;
         var sun  = that.sun;
         var d = moon.clientWidth, // 直径
            mL = moon.offsetLeft,
            mR = moon.offsetLeft + d,
            sL = sun.offsetLeft,
            sR = sun.offsetLeft + d; 
        if(sL > mR || mL > sR){
    
    
            per = 0
//两个圆相离的情况          
        }else{
    
    
//两个圆重合的情况          
// 从右到左
            if(sL < mL){
    
    
                per  = (sR - mL)/d;
// 从左到右
            }else if(mR > sL){
    
    
                per = (mR -sL)/d;
            }
        }
        that.change(per);
    },

第四个函数 change

  change : function(per){
    
    
        var audio = document.getElementsByTagName('audio')[0];
        var body = document.getElementsByTagName('body')[0];
        var volume = document.getElementsByClassName('per')[0];
        var title = document.getElementsByClassName('title')[0];
        per > 0 ? audio.play():audio.pause(); 
        //三目运算符
        audio.volume = per;
        var that = this;
        //改变this指向
        var moon = that.moon;
        moon.style.background = `hsl(194, 66%, ${
      
      (1-per)*60}%) `;
        body.style.
        background = `hsl(${
      
      194 + Math.floor(166 * per)}, 66%, ${
      
      ( 1 - per ) * 60 }%) `
		//	通过改变色调和亮度改变色彩颜色
        var num = new Number(per)
        var str = `volume : ${
      
      num.toFixed(2)}`;
        volume.innerText = str;   //将音量写入到标签中

这里主要使用了 css3属性audio 的内置方法 play()和pause( ) 用于 播放和暂停

猜你喜欢

转载自blog.csdn.net/qq_43377853/article/details/108547729