html,css,js实战;带你手搓一个网易云动画页面

297 阅读9分钟

前言

在这个数字化音乐盛行的时代,网易云音乐凭借其独特的音乐推荐算法、丰富的音乐资源以及活跃的社区氛围,成为了众多音乐爱好者的首选平台。本次设计旨在通过HTMLCSS技术,复刻网易云音乐的经典页面布局与风格,向广大前端开发者及音乐爱好者展示其界面设计的魅力。

基础的画面效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box{
            width: 100px;
            height: 100px;
            background-color: aquamarine;
            /*过度,width属性两秒逐渐变化*/
            /*all就是所有属性变化*/
            transition: all 2s linear;
        }
        /*鼠标移上去变化*/
        .box:hover{
            width:  300px;
            height: 200px;
        }



        .box2{
            width: 100px;
            height: 100px;
           background-color: blue;
            /*上下左右都隔一个一百*/
            margin: 200px;
            /*两秒  匀速   无限循环*/
            animation: span 2s linear infinite;
        }
         /**/
         @keyframes span{
             /*百分之零 转0度  公转零度 变为本身大小*/
            0%{
                transform: rotate(0deg) translateX(0px)     scale(1);
            }
            50%{
                transform: rotate(180deg) translateX(200px) scale(2);
            }
            100%{
                transform: rotate(360deg) translateX(0px)   scale(1);
            }
         }
    </style>
</head>
<body>
    <div class="box"></div>

    <div class="box2"></div>
</body>
</html>

过度动画

我们先设计了一个box容器,然后我们想要实现把鼠标放上去就改变它的大小,我们可以直接 .box:hover,表示鼠标移到这个容器上的时候,会有一个我们所写的效果出来,比如上面我们所写的width变为300px,height变为200px

但是它没有过渡,会很突兀,我们让它看上去有过程的变化,这个也叫过度动画。

我们提前在box容器上放一个transition。意思是过渡,transition: all 2s linear;表示这个变化耗时两秒

转动效果

我们先创建一个box2容器,animation: span 2s linear infinite;,使用animation,使span我们将会设置的动画效果2s匀速执行完,并且无限循环,然后我们创建一个span容器,并在里面写一个动画的旋转效果,在谷歌平台上有个animation css库,里面有许多可以借鉴的动画效果

网易云动画效果页面制作

页面展示

屏幕录制 2024-12-07 160902.gif

制作流程

我们先创建一个html文件,然后在它的同目录下放一个我们需要用的的图标文件,由于样式比较多,我们可以再创建一个css。然后用<link rel="stylesheet" href="style.css">将css引入html当中,我们要在这个页面放入默认背景音乐,使用audio标签放入。然后我们要将文件里的音乐图标固定放在屏幕的左上角,由于它是始终固定的,所以我们采用固定定位。由于我们要可以让用户关掉默认音乐,我们要在这个html中的music-btn容器里面再加一个属性,off表示是这个按键点击是关闭默认音乐的。

这个开启和关闭按键是不能同时产生的,所以我要使用到js代码,我们给这个容器设置一个监听事件,每次点击都会使图标变化,变化的同时也要使音乐是否播放发生变化,在js中我们再将j-bgm这个背景音乐导入,然后使它在music-btn上的图标变化的同时也变化

const musicBtn = document.querySelector('.music-btn')
        const bgMusic = document.getElementById('j-bgm')
        let isPlay = false
        musicBtn.addEventListener('click',function(){
            /*toggle方法有就添加,无就添加*/
            musicBtn.classList.toggle('off')
            isPlay= !isPlay
            if(isPlay){
                bgMusic.play()
            }else{
                bgMusic.pause()
            }
        })

isPlay是我们为了判断容器是否发生变化所创建的变量

因为是写页面,所以后端用到的很少,接下来我们就是写样式,插图片,制作画面效果了

可以看到中间有一圈白的,然后还有一个秋千并且上面有一个人,还有文字,我们创建一个动画容器,然后在这个目录下放上秋千,文字,太阳三个容器,

动画

.view{
    width: 100%;
    height: 100%;
    overflow: hidden;
    position: relative;
    background:linear-gradient(60deg,#f8ddd1,#faece5 73%,#fad2c0) ;
}

我们设置它的宽高和电子产品一样大,然后设置一个超出部分则隐藏,并给它一个相对定位,使这个容器里面的子容器能够相对它来定位,背景色是渐变的,至于怎么渐变,渐变的角度不在我们的业务范围,我们可以使用别人测好的,然后我们进行设定就可以了。

太阳

.sun{
    width: 283px;
    height: 283px;
    background-image: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/sun.a3f575ae2fef2cfdae15011e6081a094.png);
    background-size: cover;
    position: absolute;
    left: 50%;
    top: 45%;
    transform: translate(-50%, -50%);
  }

我们先设置这个容器的宽高,然后导入这张原型图片,然后我们用 background-size: cover;使我们导入的图片在完整的情况下,最大限度的放入这个容器中,然后我们给这个容器设置一个定位,由于我们在动画中设置了相对定位,所以设置定位后我们使用动画这个容器作为参考标准,然后我们先设定离父容器的左边为50%,上面为45%,这样是相对父容器,我们想的是sun这个容器的中点为标准,所以我们相对容器本身设定调回x和y轴都移回50%,然后这个圆就设定好了

荡秋千

  .art{
    position: absolute;
    width: 750px;
    height: 1334px;
    transform: scale(0.5);
    right: 0;
    top: -140px;
    transform-origin: top right;
  }
  .swing{
    position: absolute;
    left: 226px;
    top: -180px;
    width: 478px;
    height: 1038px;
    background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/swing.88545d6c8e1ac798465e367f8e5357ab.png);
    transform-origin: -16% -30%;
    animation: ani_qiuqian 6s cubic-bezier(0.45, 0.03, 0.515, 0.955) infinite;
  }
  @keyframes ani_qiuqian{
    0%{
      transform: rotate(0deg);
    }
    50%{
      transform: rotate(32deg);
    }
    100%{
      transform: rotate(0deg);
    }
  }
  .leg1{
    position: absolute;
    width: 63px;
    height: 130px;
    left: 290.375px;
    top: 955.25px;
    background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/leg1.b1df6a7d1a794d36fbd0e1277733e1cf.png);
    transform-origin: 17.857% 13.365%;
    animation: ani_leg1 8s ease infinite;
  }
  @keyframes ani_leg1{
    0%{
      transform: rotate(0deg);
    }
    25%{
      transform: rotate(109deg);
    }
    50%{
      transform: rotate(0deg);
    }
    75%{
      transform: rotate(109deg);
    }
    100%{
      transform: rotate(0deg);
    }
  }
  
  .leg1 .jiojio{
    width: 39px;
    height: 62px;
    background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/leg1-part.f2f17703a6af8fd2af5e0f5a9f320623.png);
    position: absolute;
    left: 26.25px;
    top: 102.5px;
  }
  
  .leg2{
    position: absolute;
    left: 185.375px;
    top: 958px;
    width: 130px;
    height: 32px;
    background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/leg2.d7bc44a91b6974450f2ccc430846c63d.png);
    transform-origin: 91.15% 33.59%;
    animation: ani_leg2 8s ease infinite;
  }
  @keyframes ani_leg2{
    0%{
      transform: rotate(0deg);
    }
    25%{
      transform: rotate(-87deg);
    }
    50%{
      transform: rotate(0deg);
    }
    75%{
      transform: rotate(-87deg);
    }
    100%{
      transform: rotate(0deg);
    }
  }
  
  .leg2 .jiojio{
    width: 57px;
    height: 44px;
    background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/leg2-part.8f70bb7fc789a70bc78c48aa7718a765.png);
    left: -27.75px;
    top: -10.5px;
    position: absolute;
  }
  .swing .neck {
    position: absolute;
    left: 451.125px;
    top: 855.5px;
    width: 51px;
    height: 42px;
    background: url(//s5.music.126.net/static_public/5c21db8d4684556c72180904/neck.07a0013beff9796ed79c2cea542e5af2.png) no-repeat;
  }
  /* 头 */
  .swing .neck, .swing .head {
    display: block;
    position: absolute;
    left: 451.125px;
    top: 855.5px;
    width: 51px;
    height: 42px;
  }
  /* 脖子 */
  .swing .neck {
    background: url(//s5.music.126.net/static_public/5c21db8d4684556c72180904/neck.07a0013beff9796ed79c2cea542e5af2.png) no-repeat;
  }
  /* 头 */
  .swing .head {
    background: url(//s5.music.126.net/static_public/5c21db8d4684556c72180904/head.90bf892023d7df0522a4b53fc07e38df.png) no-repeat;
    animation: ani2_head 8s ease infinite;
  }
  /* 头发 */
  .swing .head .part {
    background: url(//s5.music.126.net/static_public/5c21db8d4684556c72180904/head-part.22d4381c4bd6cb1c3afd2b1bfcfe22f1.png) no-repeat;
    left: 20px;
    top: 2px;
    width: 40px;
    height: 47px;
    position: absolute;
  }
  @keyframes ani2_head {
    0% {
      transform: rotate(0deg);
  }
  25% {
      transform: rotate(-55deg);
  }
  62.5% {
      transform: rotate(-55deg);
  }
  87.92% {
      transform: rotate(0deg);
  }
  100% {
      transform: rotate(0deg);
  }
  }

我们给荡秋千这个整体创建一个容器,然后我们设定这个容器为绝对定位,然后相对父容器,且要有资格做这个容器的标准,就是view,设置这个容器的宽高,因为这个秋千要超出屏幕,所以我们TOP的定位要超出屏幕,因为这个秋千要旋转,所以我们要transform-origin: top right;,定一个右上角的旋转基点。

然后我们设置秋千容器部分的位置和宽高,在把秋千图片放上去,这些在具体开发中都会有数据给我们的,然后我们秋千是超出父容器的,所以我们也要设置一个旋转基点,然后我们就要让它转起来了,我们来设置一个动画效果,使最低点旋转最快

接下来就是这个人了,写它身体各个部分的样式,脚,腿,身子,头,头发,由于腿和脚不是和父容器一起旋转,而是相对父容器旋转,所以我们也要给它们设置一个旋转基点,给它们加一个旋转动画效果,并将它们的容器放入秋千容器里面,头和身子,头发可以放入整个荡秋千的容器,并给它们设定好位置和宽高,这样一个人坐在秋千上的动画效果就做好了

文字

我们在html上面写好了文字,创建好了容器,然后在css里面设置好它的位置和大小,还有它的字体颜色就好了

html

<div class="paras">
        <p class="para f-animLineUp" style="transition-delay: 0.2s;">
          <em class="s-fcRed">11月1日</em>
        </p>
        <p class="para f-animLineUp" style="transition-delay: 0.3s;">
          大概是很特别的一天
        </p>
        <p class="para f-animLineUp" style="transition-delay: 0.4s;">
          这一天里
        </p>
        <p class="para f-animLineUp" style="transition-delay: 0.5s;">
          TA把Richard Clayderma...的
          <em class="s-fcRed">《梦中的婚礼》</em>
        </p>
        <p class="para f-animLineUp" style="transition-delay: 0.6s;">
          反复听了
          <em class="s-fcRed">10次</em>
        </p>
      </div>

css

  .paras {
    bottom: 110px;
    left: 10.67%;
    position: absolute;
    line-height: 1.6667;
    letter-spacing: 1px;
    color: #333;
  }

这样一段简短的优美的文字就添加到图片上去了

最后我们来看看完整的html代码和css代码

html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <audio id="j-bgm" src="./assets/bgm.mp3"></audio>
  <div class="music-btn off"></div>

  <!-- 动画 -->
  <div class="view">
    <!-- 太阳 -->
    <div class="sun"></div>

    <!-- 秋千 -->
    <div class="art">
      <div class="swing">

        <div class="leg1">
          <div class="jiojio"></div>
        </div>

        <div class="leg2">
          <div class="jiojio"></div>
        </div>

        <!-- 脖子 -->
        <div class="neck"></div>
        <!-- 头 -->
        <div class="head">
          <div class="part"></div>
        </div>

      </div>
    </div>

    <!-- 文字 -->
    <div class="paras">
        <p class="para f-animLineUp" style="transition-delay: 0.2s;">
          <em class="s-fcRed">11月1日</em>
        </p>
        <p class="para f-animLineUp" style="transition-delay: 0.3s;">
          大概是很特别的一天
        </p>
        <p class="para f-animLineUp" style="transition-delay: 0.4s;">
          这一天里
        </p>
        <p class="para f-animLineUp" style="transition-delay: 0.5s;">
          TA把Richard Clayderma...的
          <em class="s-fcRed">《梦中的婚礼》</em>
        </p>
        <p class="para f-animLineUp" style="transition-delay: 0.6s;">
          反复听了
          <em class="s-fcRed">10次</em>
        </p>
      </div>
  </div>



  
  <script>
    const musicBtn = document.querySelector('.music-btn')
    const bgMusic = document.getElementById('j-bgm')
    let isPlay = false

    musicBtn.addEventListener('click', function() {
      musicBtn.classList.toggle('off')
      isPlay = !isPlay
      if (isPlay) {
        bgMusic.play()
      } else {
        bgMusic.pause()
      }
    })
  </script>
</body>
</html>

css

*{
    margin: 0;
    padding: 0;
  }
  html, body{
    width: 100%;
    height: 100%;
  }
  .music-btn{
    width: 40px;
    height: 40px;
    position: fixed;
    top: 25px;
    left: 25px;
    background: url('./assets/close.png');
    background-size: cover;
    z-index: 3;
  }
  .music-btn.off{
    background-image: url('./assets/music.png');
  }
  
  .view{
    width: 100%;
    height: 100%;
    overflow: hidden;
    position: relative;
    background-image: linear-gradient(60deg, #f8ddd1, #faece5 73%, #fad2c0);
  }
  .sun{
    width: 283px;
    height: 283px;
    background-image: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/sun.a3f575ae2fef2cfdae15011e6081a094.png);
    background-size: cover;
    position: absolute;
    left: 50%;
    top: 45%;
    transform: translate(-50%, -50%);
  }
  .art{
    position: absolute;
    width: 750px;
    height: 1334px;
    transform: scale(0.5);
    right: 0;
    top: -140px;
    transform-origin: top right;
  }
  .swing{
    position: absolute;
    left: 226px;
    top: -180px;
    width: 478px;
    height: 1038px;
    background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/swing.88545d6c8e1ac798465e367f8e5357ab.png);
    transform-origin: -16% -30%;
    animation: ani_qiuqian 6s cubic-bezier(0.45, 0.03, 0.515, 0.955) infinite;
  }
  @keyframes ani_qiuqian{
    0%{
      transform: rotate(0deg);
    }
    50%{
      transform: rotate(32deg);
    }
    100%{
      transform: rotate(0deg);
    }
  }
  .leg1{
    position: absolute;
    width: 63px;
    height: 130px;
    left: 290.375px;
    top: 955.25px;
    background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/leg1.b1df6a7d1a794d36fbd0e1277733e1cf.png);
    transform-origin: 17.857% 13.365%;
    animation: ani_leg1 8s ease infinite;
  }
  @keyframes ani_leg1{
    0%{
      transform: rotate(0deg);
    }
    25%{
      transform: rotate(109deg);
    }
    50%{
      transform: rotate(0deg);
    }
    75%{
      transform: rotate(109deg);
    }
    100%{
      transform: rotate(0deg);
    }
  }
  
  .leg1 .jiojio{
    width: 39px;
    height: 62px;
    background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/leg1-part.f2f17703a6af8fd2af5e0f5a9f320623.png);
    position: absolute;
    left: 26.25px;
    top: 102.5px;
  }
  
  .leg2{
    position: absolute;
    left: 185.375px;
    top: 958px;
    width: 130px;
    height: 32px;
    background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/leg2.d7bc44a91b6974450f2ccc430846c63d.png);
    transform-origin: 91.15% 33.59%;
    animation: ani_leg2 8s ease infinite;
  }
  @keyframes ani_leg2{
    0%{
      transform: rotate(0deg);
    }
    25%{
      transform: rotate(-87deg);
    }
    50%{
      transform: rotate(0deg);
    }
    75%{
      transform: rotate(-87deg);
    }
    100%{
      transform: rotate(0deg);
    }
  }
  
  .leg2 .jiojio{
    width: 57px;
    height: 44px;
    background: url(https://s5.music.126.net/static_public/5c21db8d4684556c72180904/leg2-part.8f70bb7fc789a70bc78c48aa7718a765.png);
    left: -27.75px;
    top: -10.5px;
    position: absolute;
  }
  .swing .neck {
    position: absolute;
    left: 451.125px;
    top: 855.5px;
    width: 51px;
    height: 42px;
    background: url(//s5.music.126.net/static_public/5c21db8d4684556c72180904/neck.07a0013beff9796ed79c2cea542e5af2.png) no-repeat;
  }
  /* 头 */
  .swing .neck, .swing .head {
    display: block;
    position: absolute;
    left: 451.125px;
    top: 855.5px;
    width: 51px;
    height: 42px;
  }
  /* 脖子 */
  .swing .neck {
    background: url(//s5.music.126.net/static_public/5c21db8d4684556c72180904/neck.07a0013beff9796ed79c2cea542e5af2.png) no-repeat;
  }
  /* 头 */
  .swing .head {
    background: url(//s5.music.126.net/static_public/5c21db8d4684556c72180904/head.90bf892023d7df0522a4b53fc07e38df.png) no-repeat;
    animation: ani2_head 8s ease infinite;
  }
  /* 头发 */
  .swing .head .part {
    background: url(//s5.music.126.net/static_public/5c21db8d4684556c72180904/head-part.22d4381c4bd6cb1c3afd2b1bfcfe22f1.png) no-repeat;
    left: 20px;
    top: 2px;
    width: 40px;
    height: 47px;
    position: absolute;
  }
  @keyframes ani2_head {
    0% {
      transform: rotate(0deg);
  }
  25% {
      transform: rotate(-55deg);
  }
  62.5% {
      transform: rotate(-55deg);
  }
  87.92% {
      transform: rotate(0deg);
  }
  100% {
      transform: rotate(0deg);
  }
  }
  .paras {
    bottom: 110px;
    left: 10.67%;
    position: absolute;
      line-height: 1.6667;
      letter-spacing: 1px;
      color: #333;
  }

看完希望对你设计页面有所帮助