zoukankan      html  css  js  c++  java
  • 【别贪心】keep-web

    首先放下作者大大的github地址:https://github.com/SJanJan/keep-web
    接着我们看下项目

    //main.js
    import Vue from 'vue'
    import App from './App.vue'
    import '@/styles/reset.scss'
    Vue.config.productionTip = false
    
    new Vue({
      render: h => h(App)
    }).$mount('#app')
    
    
    //AppNavbar.vue
    
    <template>
      <div class="header">
        <nav class="nav-wrapper-phone">
          <div style="padding: 22px 5.6%;">
            <a href="#"
               class="menu">
              <img src="@/assets/images/menu.png"
                   style="28px;"
                   alt="menu">
            </a>
            <a href="#"
               class="logo"> <img style="68px;"
                   src="@/assets/phonelogo.png"
                   alt="logo">
            </a>
          </div>
        </nav>
    
        <nav class="nav-wrapper-pc">
          <a href="#"
             class="logo"> <img style="112px;"
                 src="@/assets/logo.png"
                 alt="logo">
          </a>
    
          <div class="head-right">
            <a href="#">发现精选</a>
            <a href="#">课程内容</a>
          </div>
        </nav>
      </div>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style lang="scss" scoped>
    .header {
      position: relative;
      z-index: 2;
       100%;
    }
    .nav-wrapper-phone {
      display: none;
      position: absolute;
       100%;
    
      a > img {
        vertical-align: middle;
      }
    
      .logo {
        position: absolute;
        left: 50%;
        margin-left: -30px;
      }
    }
    
    .nav-wrapper-pc {
      display: none;
      padding: 20px 30px 0;
    
      .head-right {
        a {
          text-decoration: none;
          color: #fff;
        }
    
        a + a {
          margin-left: 20px;
        }
      }
    }
    
    @media (max- 767.98px) {
      .nav-wrapper-phone {
        display: block;
      }
    }
    
    @media (min- 768px) {
      .header {
        position: fixed;
      }
    
      .nav-wrapper-pc {
        display: flex;
        justify-content: space-between;
        align-items: center;
      }
    }
    </style>
    
    //AppFooter.vue
    
    <template>
      <footer>
        <div class="footer-wrapper">
          <p style="color:#fff;">哪有什么天生如此,只是我们天天坚持
            自律给我自由</p>
        </div>
      </footer>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style lang="scss" scoped>
    footer {
      position: relative;
      background: #584f60;
    }
    .footer-wrapper {
      color: black;
      text-align: center;
      padding: 100px 0;
    }
    </style>
    
    //AppContent.vue
    
    <template>
      <div class="content-wrap">
        <ParagraphContent />
        <TrainingContent />
        <RunParaContent />
        <RunContent />
        <CommunityParaContent />
        <Community />
        <ParagraphStoreContent />
        <StoreContent />
        <UsersContent />
        <LinkContent />
      </div>
    </template>
    
    <script>
    import ParagraphContent from "@/components/ParagraphContent";
    import TrainingContent from "@/components/TrainingContent";
    import RunParaContent from "@/components/RunParaContent";
    import RunContent from "@/components/RunContent";
    import CommunityParaContent from "@/components/CommunityParaContent";
    import Community from "@/components/Community";
    import ParagraphStoreContent from "@/components/ParagraphStoreContent";
    import StoreContent from "@/components/StoreContent";
    import UsersContent from "@/components/UsersContent";
    import LinkContent from "@/components/LinkContent";
    export default {
      components: {
        ParagraphContent,
        TrainingContent,
        RunParaContent,
        RunContent,
        CommunityParaContent,
        Community,
        ParagraphStoreContent,
        StoreContent,
        UsersContent,
        LinkContent,
      },
    }
    </script>
    
    <style lang="scss" scoped>
    .content-wrap {
      position: relative;
      z-index: 2;
      background-color: #fff;
    }
    </style>
    
    //ParagraphContent.vue
    <template>
      <section>
        <div class="paragraph">
          <div class="para-title">量体裁衣 &amp; 多种健身训练供你选择</div>
          <div class="para-text">训练计划针对不同人群、各种器械和阶段健身目标组合编排,适用最广泛的健身场景。</div>
        </div>
      </section>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style lang="scss" scoped>
    .paragraph {
      padding: 54px 0;
      text-align: center;/*  */
    
      .para-title {
        font-size: 18px;
        color: #584f60;
        font-weight: bold;
      }
    
      .para-text {
        font-size: 14px;
        color: #666;
        margin: 19px 48px 0;
      }
    }
    
    @media (min- 768px) {
      .paragraph {
        padding: 130px 0 140px;
    
        .para-title {
          font-size: 24px;
        }
    
        .para-text {
          margin-top: 32px;
          font-size: 18px;
        }
      }
    }
    </style>
    
    //TrainingContent.vue
    <template>
      <section class="container">
        <div class="training-wrap">
          <div class="training-wrap-inner">
            <div class="training-block">
              <a href="#"
                 class="training-item"
                 :style="{backgroundImage:'url('+bg1+')' }">
                <div class="training-detail">
                  <div class="training-title">瘦腿训练</div>
                  <div>13分钟 49千卡</div>
                  <div class="training-population">48,385,041人训练</div>
                </div>
              </a>
              <a href="#"
                 class="training-item"
                 :style="{backgroundImage:'url('+bg2+')' }">
                <div class="training-detail">
                  <div class="training-title">马甲线养成</div>
                  <div>12分钟 61千卡</div>
                  <div class="training-population">49,252,615人训练</div>
                </div>
              </a>
    
              <a href="#"
                 class="training-item"
                 :style="{backgroundImage:'url('+bg3+')' }">
                <div class="training-detail">
                  <div class="training-title">瑜伽 · 身体韵律</div>
                  <div>32分钟 135千卡</div>
                  <div class="training-population">928,978人训练</div>
                </div>
              </a>
    
              <a href="#"
                 class="training-item"
                 :style="{backgroundImage:'url('+bg4+')' }">
                <div class="training-detail">
                  <div class="training-title">地狱Burpees挑战</div>
                  <div>13分钟 191千卡</div>
                  <div class="training-population">1,247,907人训练</div>
                </div>
              </a>
    
            </div>
    
            <div class="training-text">
              <div class="text-title">真人同步训练记录训练进度</div>
              <div class="text-cont">全程语音督导,自动同步进度,不需要背动作、记组数,跟着 Keep 马上练起来。</div>
              <a href="#"
                 class="training-btn"><span>查看课程</span></a>
            </div>
    
            <div class="training-data">
              <div class="data-text">
                <span class="text-line"></span>
                <span>累积训练:</span>
              </div>
              <div class="data-time">
                <span class="data-min">68.79</span>
                <span class="data-text data-unit">亿分钟</span>
              </div>
              <div class="data-cont">
                <span>
                  <span class="data-num">4.93</span>
                  <span class="data-text data-unit">亿次</span>
                </span>
                <span>
                  <span class="data-num data-cal">388.56</span>
                  <span class="data-text data-unit">亿千卡</span>
                </span>
              </div>
            </div>
    
            <div class="body-pic-wrap">
              <img src="@/assets/images/body.png"
                   class="body-pic">
              <img src="@/assets/images/bodycircle.png"
                   class="circle-pic">
              <img src="@/assets/images/heart.png"
                   class="animate-heart">
            </div>
    
            <img src="@/assets/images/traindata.png"
                 class="data-pic">
            <img src="@/assets/images/trainchart.png"
                 class="chart-pic">
            <img src="@/assets/images/trainpic.png"
                 class="cal-pic">
          </div>
        </div>
      </section>
    </template>
    
    <script>
    import bg1 from "@/assets/images/1478591073270_750x700.jpg";
    import bg2 from "@/assets/images/1478588565783_750x700.jpg";
    import bg3 from "@/assets/images/1488452269169_750x700.jpg";
    import bg4 from "@/assets/images/54cc47743b800000.jpg";
    export default {
      data () {
        return {
          bg1: bg1,
          bg2: bg2,
          bg3: bg3,
          bg4: bg4,
        }
      },
    }
    </script>
    
    <style lang="scss" scoped>
    .container {
      background: #3d3744;
    }
    .training-wrap {
      max- 1440px;
      margin: 0 auto;
    }
    
    .training-item {
      display: block;
      margin: 0;
       100%;
      height: 222px;
      position: relative;
      background-size: cover;
      background-repeat: no-repeat;
      background-position: center center;
    
      transition: all 0.5s;
    
      &:hover {
        transform: scale(1.05, 1.05);
      }
    
      &:last-child {
        display: none;
      }
    }
    .training-detail {
      display: block;
      position: relative;
      height: 100%;
      font-size: 14px;
      padding: 22px;
    }
    .training-title {
      font-size: 18px;
      font-weight: bold;
      margin-bottom: 10px;
    }
    .training-population {
      position: absolute;
      bottom: 22px;
    }
    .training-text {
      margin-top: 120px;
      text-align: center;
    
      .text-title {
        font-size: 18px;
      }
    
      .text-cont {
        font-size: 12px;
        margin: 18px 33px 28px;
        color: #999;
      }
      .training-btn {
        cursor: pointer;
        display: inline-block;
         138px;
        height: 40px;
        line-height: 40px;
        margin-bottom: 60px;
        text-align: center;
        border: 1px solid #8e8893;
        border-radius: 40px;
        font-size: 14px;
      }
    }
    a {
      text-decoration: none;
      color: #fff;
    }
    .training-data,
    .body-pic-wrap,
    .data-pic,
    .chart-pic,
    .cal-pic {
      display: none;
    }
    
    .body-pic-wrap {
      position: absolute;
      left: calc(50% - 170px);
       340px;
      height: 538px;
      .body-pic {
        position: absolute;
        top: 0;
        left: 73px;
      }
    
      .circle-pic {
        position: absolute;
        left: 0;
        bottom: 0;
      }
    
      .animate-heart {
        position: absolute;
        top: 104px;
        left: 188px;
        animation: heartbeat 2s ease infinite normal;
      }
    }
    
    .training-data {
      line-height: 1;
    
      span {
        display: inline-block;
      }
      .data-text {
        font-size: 12px;
        color: #8e8893;
        .text-line {
          height: 10px;
          border: 2px solid #25c085;
          margin-right: 5px;
        }
      }
      .data-time {
        margin: 16px 0 0;
    
        .data-min {
          font-size: 44px;
          font-weight: 700;
        }
        .data-unit {
          margin-left: 8px;
        }
      }
    
      .data-cont {
        margin: 32px 0 0;
        .data-num {
          font-size: 26px;
          font-weight: 600;
        }
        .data-unit {
          margin-left: 8px;
        }
        .data-cal {
          margin-left: 32px;
        }
      }
    }
    
    @media (min- 750px) {
      .training-item {
        &:last-child {
          display: inline-block;
        }
      }
    }
    
    @media (max- 1023px) and (min- 768px) {
      .training-wrap {
        height: 1050px;
        position: relative;
      }
      .training-block {
        position: relative;
         740px;
        left: 50%;
        margin-left: -370px;
        top: -45px;
      }
      .training-item {
        display: inline-block;
         356px;
        margin-bottom: 10px;
        margin-right: 10px;
      }
    
      .training-text {
        position: absolute;
        right: 23px;
        bottom: 0;
         265px;
        margin: 0;
        text-align: right;
        .text-cont {
          font-size: 14px;
          margin: 14px 0 22px;
        }
      }
      .training-data {
        display: block;
        position: absolute;
        left: 23px;
        bottom: 60px;
      }
    
      .body-pic-wrap {
        display: block;
      }
    
      .data-pic {
        display: block;
        position: absolute;
        top: 498px;
        right: 96px;
      }
    
      .chart-pic {
        display: block;
        position: absolute;
        top: 498px;
        left: 25px;
      }
    }
    
    @media (min- 1024px) {
      .training-wrap {
        position: relative;
        height: 636px;
        .training-wrap-inner {
          height: 636px;
        }
      }
      .training-block {
         356px;
        position: relative;
        left: 30px;
        top: -15px;
        .training-item + .training-item {
          margin: 10px 0 0;
        }
        .training-item {
          display: block;
           356px;
          height: 207px;
    
          &:last-child {
            display: none;
          }
        }
      }
    
      .body-pic-wrap {
        display: block;
        position: absolute;
        top: 70px;
        left: calc(50% - 120px);
      }
    
      .training-text {
        position: absolute;
        right: 23px;
        bottom: 40px;
         265px;
        margin: 0;
        text-align: right;
        .text-cont {
          font-size: 14px;
          margin: 14px 0 22px;
        }
        .training-btn {
          margin: 0;
        }
      }
    
      .training-data {
        display: block;
        position: absolute;
        right: 25px;
        top: 260px;
        text-align: right;
        .data-cont {
          margin-top: 22px;
        }
        .data-unit {
          display: block;
          margin-top: 12px;
        }
      }
    
      .data-pic {
        display: block;
        position: absolute;
        top: 40px;
        right: 160px;
      }
    
      .cal-pic {
        display: block;
        position: absolute;
        right: 27px;
        top: 140px;
      }
    }
    
    @media (min- 1440px) {
      .body-pic-wrap {
        left: calc(50% - 30px);
      }
      .chart-pic {
        display: block;
        position: absolute;
        top: 35px;
        left: 430px;
      }
      .cal-pic {
        display: block;
        position: absolute;
        top: 305px;
        left: 446px;
      }
      .training-data {
        display: block;
        position: absolute;
        top: initial;
        left: 445px;
        bottom: 53px;
        right: initial;
        text-align: left;
    
        .data-unit {
          display: inline-block;
        }
      }
    }
    
    @keyframes heartbeat {
      from {
        transform: scale(1);
        opacity: 1;
      }
      to {
        transform: scale(3);
        opacity: 0;
      }
    }
    </style>
    
    //RunParaContent.vue
    <template>
      <section>
        <div class="paragraph run-para">
          <div class="para-title">户外跑步 &amp; 精准跑步记录,让你的跑步更加系统</div>
          <div class="para-text">精准跑步路线记录,跑前热身与跑后拉伸,Keep 提供更加完善和专业的跑步指导。</div>
        </div>
      </section>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style lang="scss" scoped>
    .paragraph {
      text-align: center;
    }
    .para-title {
      color: #584f60;
      font-weight: bold;
    }
    .para-text {
      color: #666;
    }
    @media (max- 767px) {
      .paragraph.run-para {
        padding: 72px 0 250px;
      }
      .para-title {
        font-size: 21px;
        padding: 0 27.6px;
      }
      .para-text {
        font-size: 14px;
        margin: 19.2px 48px 0;
      }
    }
    @media (min- 768px) {
      .paragraph {
        padding: 130px 0 140px;
      }
      .para-title {
        font-size: 24px;
      }
      .para-text {
        font-size: 16px;
        margin-top: 32px;
      }
    }
    </style>
    
    //RunContent.vue
    
    
    <template>
      <section>
        <div class="run-wrap">
          <div class="run-wrap-inner">
            <div class="run-track-wrap">
              <img src="@/assets/images/runtrack.png">
              <div class="animate-circle"></div>
            </div>
            <div class="run-config-wrap">
              <div class="run-config-pace">
                <div class="config-title"><i class="keep-icon-speed"></i><span>配速</span></div>
                <div class="config-cont"><span>公里</span><span>配速</span><span class="right">用时</span></div>
                <div class="speed-bar speed-bar1">
                  <div class="speed-bar-fill"></div>
                </div>
                <div class="speed-bar speed-bar2">
                  <div class="speed-bar-fill"></div>
                </div>
                <div class="speed-bar speed-bar3">
                  <div class="speed-bar-fill"></div>
                </div>
                <div class="speed-bar speed-bar4">
                  <div class="speed-bar-fill"></div>
                </div>
                <div class="speed-bar speed-bar5">
                  <div class="speed-bar-fill"></div>
                </div>
                <div class="speed-bar speed-bar6">
                  <div class="speed-bar-fill"></div>
                </div>
                <div class="speed-bar speed-bar7">
                  <div class="speed-bar-fill"></div>
                </div>
              </div>
              <div class="run-config-frequency">
                <div class="config-title">
                  <div>
                    <i class="keep-icon-frequency"></i>
                    <span>步频</span>
                    <span class="right">(步/分钟)</span>
                  </div>
                  <div class="chart-title">平均步频<span>146</span></div>
                </div>
                <!-- <img src="https://staticweb.keepcdn.com/staticShow/images/homepage/runchart-ae8422d700.png"
                     class="config-bg"> -->
                <div id="freq-img"><img src="@/assets/images/runcover.png"></div>
              </div>
            </div>
    
            <div class="run-text-wrap">
              <div class="run-text-title">用步伐丈量世界</div>
              <div class="run-text-cont">在 Keep 记录你的跑步轨迹,制定有氧课程表,助你更快达成你的跑步目标</div>
              <a href="#"
                 class="run-btn"><span>跑步轨迹</span><i></i></a>
            </div>
    
            <div class="run-data">
              <div class="data-block">
                <div class="data-title"><span class="text-line"></span><span>累计跑步</span></div>
                <div class="data-val">8415.57</div>
                <div class="data-unit">万公里</div>
              </div>
              <div class="data-block-right">
                <div class="data-block2">
                  <div class="data-title"><i class="icon-speed"></i></div>
                  <div class="data-val">9.27</div>
                  <div class="data-unit">分/公里</div>
                </div>
                <div class="data-block2">
                  <div class="data-title"><i class="icon-duration"></i></div>
                  <div class="data-val">7.80</div>
                  <div class="data-unit">亿分钟</div>
                </div>
                <div class="data-block2">
                  <div class="data-title"><i class="icon-cal"></i></div>
                  <div class="data-val">62.05</div>
                  <div class="data-unit">亿千卡</div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </section>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style lang="scss" scoped>
    .run-wrap {
       100%;
      height: 763.19px;
      position: relative;
      background-color: #3d3744;
      background-image: url(../assets/images/runbg.jpg);
      background-size: cover;
      background-repeat: no-repeat;
      background-position: center center;
    }
    .run-wrap-inner {
      position: relative;
      height: 100%;
      max- 1440px;
      margin: 0 auto;
    }
    .run-config-wrap {
       360px;
      position: absolute;
      top: -182.4px;
      right: 50%;
      margin-right: -180px;
    
      .run-config-pace {
        height: 319.2px;
        padding: 22px 18px 20px;
        background-color: #5e5566;
        border-radius: 5px;
        font-size: 12px;
        .config-title {
          color: #dddddd;
        }
        .config-cont {
          color: #827a89;
          margin: 24px 0 12px;
    
          span:first-child {
            margin-right: 20px;
          }
    
          .right {
            float: right;
          }
        }
    
        .speed-bar {
          height: 21.6px;
          border-radius: 21.6px;
          margin-top: 9.6px;
          background-color: rgba(36, 199, 137, 0.3);
        }
        .speed-bar1 {
           54.6%;
        }
        .speed-bar2 {
           42%;
        }
        .speed-bar3 {
           45.4%;
        }
        .speed-bar4 {
           100%;
        }
        .speed-bar5 {
           48.9%;
        }
        .speed-bar6 {
           45.4%;
        }
        .speed-bar7 {
           50.6%;
        }
      }
    
      .run-config-frequency {
        position: relative;
         100%;
        height: 319.19px;
        margin-top: 10px;
        .config-title {
           100%;
          padding: 0 18px;
          position: absolute;
          top: 22px;
          left: 0;
    
          div {
            font-size: 12px;
            color: #ddd;
            .right {
              float: right;
              color: #827a89;
            }
          }
    
          .chart-title {
            text-align: center;
            margin-top: 20px;
    
            span {
              margin-left: 5px;
              color: #24c789;
            }
          }
        }
    
        #freq-img {
          img {
             100%;
            height: 100%;
          }
        }
      }
    }
    
    .run-text-wrap {
       100%;
      position: absolute;
      bottom: 60px;
      text-align: center;
    
      .run-text-title {
        color: #fff;
        font-size: 18px;
      }
      .run-text-cont {
        font-size: 12px;
        color: #999999;
        margin: 21.6px 39.6px 33.6px;
      }
      .run-btn {
        display: inline-block;
        color: #fefefe;
        background-color: #24c789;
         138px;
        height: 42px;
        line-height: 42px;
        text-align: center;
        border-radius: 42px;
        font-size: 14px;
        box-shadow: 0 4px 16px 0 rgba(32, 178, 122, 0.27);
        text-decoration: none;
      }
    }
    
    .run-data,
    .run-track-wrap,
    .data-block-right {
      display: none;
    }
    @media (min- 768px) {
      .run-wrap {
        height: 636px;
      }
    
      .run-text-wrap {
         268px;
        top: 45px;
        right: 27px;
        bottom: initial;
        text-align: right;
    
        .run-text-cont {
          margin: 20px 0;
        }
      }
    
      .run-config-wrap {
         700px;
        top: initial;
        bottom: -80px;
        right: 50%;
        margin-right: -350px;
    
        .run-config-pace,
        .run-config-frequency {
          float: left;
           340px;
          height: 302px;
        }
        .run-config-frequency {
          margin-top: initial;
          margin-left: 10px;
    
          #freq-img {
            margin-bottom: 0;
            img {
              height: 100%;
            }
          }
        }
      }
    
      .run-data {
        display: block;
        position: absolute;
        left: 40px;
        bottom: 255px;
        .data-block {
          .data-title {
            font-size: 12px;
            color: #8e8893;
            .text-line {
              display: inline-block;
              height: 10px;
              border: 2px solid #25c085;
              margin-right: 7px;
            }
          }
    
          .data-val {
            display: inline-block;
            font-size: 44px;
            color: #ddd;
            line-height: 1;
            margin: 16px 0;
            font-weight: bold;
          }
    
          .data-unit {
            display: inline-block;
            margin-left: 12px;
            font-size: 12px;
            color: #8e8893;
          }
        }
      }
    
      .run-track-wrap {
        display: block;
        position: absolute;
        left: 20%;
        top: 115px;
    
        .animate-circle {
           60px;
          height: 60px;
          position: absolute;
          bottom: -8px;
          right: -12px;
          border-radius: 50%;
          background: #fff;
          animation: scale 2s ease infinite normal;
        }
      }
    }
    @media (min- 1024px) {
      .run-config-wrap {
        top: -26px;
        right: 28px;
        bottom: initial;
         384px;
        height: 694px;
        margin-right: initial;
    
        .run-config-pace,
        .run-config-frequency {
          float: none;
           384px;
          height: 342px;
        }
    
        .run-config-frequency {
          margin-top: 10px;
          margin-left: initial;
        }
      }
    
      .run-text-wrap {
        top: 46px;
        left: 298px;
        right: initial;
      }
    
      .run-track-wrap {
        left: 45px;
      }
    
      .run-data {
        right: initial;
        left: 44px;
        bottom: 44px;
        .data-block {
          display: inline-block;
        }
        .data-block-right {
          display: inline-block;
          margin-left: 120px;
    
          .data-block2 {
            display: inline-block;
            margin: 0 30px;
            text-align: center;
    
            .data-val {
              color: #fff;
              font-size: 27px;
              line-height: 1;
              margin: 16px 0;
              font-weight: bold;
            }
            .data-unit {
              font-size: 12px;
              color: #8e8893;
            }
          }
        }
      }
    }
    @keyframes scale {
      0% {
        transform: scale(1);
        opacity: 0.3;
      }
      100% {
        transform: scale(2);
        opacity: 0;
      }
    }
    </style>
    
    //CommunityParaContent.vue
    <template>
      <section>
        <div class="paragraph community-para">
          <div class="para-title">运动社区 &amp; 分享健身成果,一起进步</div>
          <div class="para-text">拍照记录每一天的变化,分享好友相互勉励,在 Keep 健身不再是孤独的坚持。</div>
        </div>
      </section>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style lang="scss" scoped>
    .paragraph {
      text-align: center;
      padding: 54px 0;
    
      .para-title {
        font-size: 18px;
        color: #584f60;
        font-weight: bold;
      }
      .para-text {
        font-size: 13.6px;
        color: #666;
        margin: 19.2px 48px 0;
      }
    }
    
    @media (min- 768px) {
      .paragraph {
        padding: 180px 0 100px;
    
        .para-title {
          font-size: 24px;
        }
        .para-text {
          font-size: 16px;
          margin: 30px 0 0;
        }
      }
    }
    
    @media (min- 1024px) {
      .paragraph {
        padding: 130px 0 140px;
      }
    }
    </style>
    
    //Community.vue
    
    <template>
      <section>
        <div class="community-wrap">
          <img src="@/assets/images/camera.png"
               class="camera-pic">
          <div class="community-text">
            <div class="text-title">千万用户伴你训练</div>
            <div class="text-cont">Keep 希望创造一个专业、有趣的健身社区,在这里你会找到渴望共同进步的小伙伴。</div>
            <a href="#"
               class="text-btn">
              <span>社区精选</span><i></i>
            </a>
          </div>
        </div>
      </section>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style lang="scss" scoped>
    .community-wrap {
      position: relative;
      height: 763.19px;
      padding: 0;
      background-color: #3d3744;
      background-image: url(../assets/images/communitybg-sm.jpg);
      background-size: cover;
      background-repeat: no-repeat;
      background-position: center center;
    }
    .camera-pic {
      position: absolute;
      left: 50%;
      bottom: 0;
      margin-left: -154px;
    }
    
    .community-text {
      position: absolute;
      top: 197px;
      left: 50%;
      margin-left: -135px;
       284px;
      text-align: center;
    
      .text-title {
        font-size: 16px;
        color: #ffffff;
      }
    
      .text-cont {
        color: #8e8893;
        font-size: 14px;
        margin: 14px 0 22px;
      }
    
      .text-btn {
        display: inline-block;
         138px;
        height: 42px;
        line-height: 42px;
        text-align: center;
        background: #584f60;
        border-radius: 42px 42px;
        font-size: 14px;
        color: #ddd;
        text-decoration: none;
      }
    }
    
    @media (min- 768px) {
      .community-wrap {
        height: 636px;
        background: #3d3744;
      }
    }
    </style>
    
    //ParagraphStoreContent.vue
    <template>
      <section>
        <div class="paragraph">
          <div class="para-title">品牌装备 &amp; 商城,伴你尽兴挥汗</div>
          <div class="para-text">Keep 品牌服饰、器械及智能装备,打破 App 边界成为你触手可及的运动伙伴。</div>
        </div>
      </section>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style lang="scss" scoped>
    .paragraph {
      padding: 54px 0;
      text-align: center;
    
      .para-title {
        font-size: 18px;
        font-weight: bold;
        color: #584f60;
        margin: 0 27.6px;
      }
    
      .para-text {
        font-size: 13.6px;
        color: #666666;
        margin: 19.2px 48px 0;
      }
    }
    @media (min- 768px) {
      .paragraph {
        padding: 130px 0 140px;
        .para-title {
          font-size: 24px;
        }
        .para-text {
          font-size: 16px;
          margin: 32px 0 0;
        }
      }
    }
    </style>
    
    //StoreContent.vue
    <template>
      <section>
        <div class="store-wrap">
          <div class="store-wrap-inner">
            <img src="@/assets/images/store-bg320.jpg"
                 class="store-bg-pic">
            <div class="store-goods"></div>
            <div class="store-goods-text">更多智能运动产品 持续推出中</div>
            <div class="store-keleton"></div>
            <div class="store-text">
              <div class="store-title">Keep 跑步机</div>
              <div class="store-subtitle">跟 着 跑 就 对 了</div>
              <div class="store-cont">科技互联的运动新装备<br>专注于家庭与个人的运动新体验<br>带给你有效果的运动方式</div>
              <div class="store-btn-wrap"><a href="https://mo.gotokeep.com/pc/mall"
                   target="_blank"
                   class="store-btn"><span>查看更多</span><i></i></a></div>
            </div>
          </div>
        </div>
      </section>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style lang="scss" scoped>
    .store-wrap-inner {
      position: relative;
      height: 100%;
      margin: 0 auto;
    }
    .store-bg-pic {
      display: block;
       100%;
    }
    
    .store-text {
      position: absolute;
      top: initial;
      right: initial;
      left: 50%;
      transform: translate(-50%, 0);
      bottom: 31.4%;
      text-align: center;
    
      .store-title {
        font-size: 18px;
      }
      .store-subtitle {
        font-size: 12px;
        margin: 12px 0;
      }
      .store-cont {
        font-size: 12px;
        color: #999999;
        margin: 21.6px 0 31.6px;
      }
      .store-btn {
        display: inline-block;
         138px;
        height: 42px;
        line-height: 42px;
        text-align: center;
        background: #584f60;
        border-radius: 42px 42px;
        font-size: 14px;
        color: #ddd;
        text-decoration: none;
      }
    }
    
    .store-goods-text {
      display: none;
    }
    
    @media (min- 768px) {
      .store-wrap {
        position: relative;
        height: 636px;
        background-color: #3d3744;
        background-image: url(../assets/images/storebg.jpg);
        background-size: cover;
        background-repeat: no-repeat;
        background-position: center center;
      }
      .store-bg-pic {
        display: none;
      }
    
      .store-goods {
        position: absolute;
        left: 50%;
        margin-left: -349px;
        top: initial;
        bottom: 38px;
         698px;
        height: 180px;
        background-image: url(../assets/images/store-goods768.png);
      }
    
      .store-keleton {
        position: absolute;
        right: initial;
        left: -2%;
        bottom: 180px;
         583px;
        height: 419px;
        background-image: url(../assets/images/store-keleton768.png);
      }
    
      .store-text {
        top: 90px;
        left: initial;
        bottom: initial;
        right: 26px;
        transform: none;
        text-align: right;
    
        .store-title {
          font-size: 14px;
        }
        .store-subtitle {
          font-size: 18px;
        }
        .store-cont {
          font-size: 14px;
          line-height: 1.6;
          margin: 15px 0 35px;
        }
      }
    }
    @media (min- 1024px) {
      .store-goods {
        left: 28px;
        top: 42px;
        margin: initial;
         355px;
        height: 506px;
        background-image: url(../assets/images/store-goods1024.png);
        background-size: cover;
        background-repeat: no-repeat;
        background-position: center center;
      }
    
      .store-keleton {
        position: absolute;
        right: 0;
        left: initial;
        bottom: -20px;
         700px;
        height: 500px;
        background-image: url(../assets/images/store-keleton1024.png);
        background-size: cover;
        background-repeat: no-repeat;
        background-position: center center;
      }
    
      .store-goods-text {
        display: block;
        position: absolute;
        bottom: 38px;
        left: 28px;
        color: #8e8893;
        font-size: 14px;
      }
    }
    
    @media (min- 1440px) {
      .store-wrap-inner {
         1200px;
      }
    }
    </style>
    

    接下来这个就很有意思了,用来处理了自动向上滚动和消失的

    //UsersContent.vue
    <template>
      <section class="users-wrap">
        <div class="users-wrap-inner">
          <div class="users-text">
            <div class="users-title">
              <div class="icon-qoute"></div>
              <div>此刻在 Keep 运动</div>
            </div>
            <div class="users-cont">每分每秒,都有来自全世界的 Keepers 在这里留下他们的汗水。</div>
          </div>
          <div class="user-list-wrap">
            <ul class="users-list"
                ref="usersList"
                :class="{move:isMove}">
              <li v-for="(item) in list"
                  :key="item.username">
                <a href="#"
                   target="_blank">
                  <img :src="item.img">
                  <div class="user-info">
                    <div class="user-name">{{item.username}}</div>
                    <div class="user-act">{{item.userAct}}</div>
                  </div>
                </a>
              </li>
            </ul>
          </div>
        </div>
      </section>
    </template>
    
    <script>
    
    import userAvatar from "@/assets/images/userAvatar.jpg";
    const USERS = [
      {
        img: userAvatar,
        username: '左小立1',
        userAct: '刚做完了一组 全身拉伸',
      },
      {
        img: userAvatar,
        username: '左小立2',
        userAct: '刚做完了一组 全身拉伸',
      },
      {
        img: userAvatar,
        username: '左小立3',
        userAct: '刚做完了一组 全身拉伸',
      },
      {
        img: userAvatar,
        username: '左小立4',
        userAct: '刚做完了一组 全身拉伸',
      },
      {
        img: userAvatar,
        username: '左小立5',
        userAct: '刚做完了一组 全身拉伸',
      },
      {
        img: userAvatar,
        username: '左小立6',
        userAct: '刚做完了一组 全身拉伸',
      },
      {
        img: userAvatar,
        username: '左小立7',
        userAct: '刚做完了一组 全身拉伸',
      },
      {
        img: userAvatar,
        username: '左小立8',
        userAct: '刚做完了一组 全身拉伸',
      }
    ]
    export default {
      data () {
        return {
          isMove: false,
          list: [...USERS],
          nextNum: 0
        }
      },
      mounted () {
        this.run();
      },
    
      methods: {
        async run () {
          await this.fadeout();
          await this.move()
          await this.pop()
          await this.push();
          this.run();
        },
        fadeout () {
          return new Promise((resolve) => {
            this.$refs['usersList'].firstElementChild.classList.add('fadeout');
    
            setTimeout(() => {
              resolve();
            }, 1000);
          })
        },
        move () {
          return new Promise((resolve) => {
            this.isMove = true;
            setTimeout(() => {
              this.isMove = false;
              resolve();
            }, 1000);
          })
        },
        // 始终往数组末尾添加被删除的首个元素
        push: function () {
          let length = USERS.length;
          let item = USERS[this.nextNum % length];
          this.list.splice(this.list.length, 0, item)
          this.nextNum++
    
          if (this.nextNum > length - 1) this.nextNum = 0;
    
          return this.$nextTick()
        },
        // 移除首个元素
        pop: function () {
          this.list.splice(0, 1)
          return this.$nextTick()
        },
      },
    }
    </script>
    
    <style lang="scss" scoped>
    .users-wrap {
      height: 696px;
    }
    .users-wrap-inner {
      position: relative;
      height: 100%;
    }
    .users-text {
      position: absolute;
       100%;
      top: 80px;
      text-align: center;
      .users-title {
        font-size: 18px;
        color: #584f60;
      }
      .users-cont {
        font-size: 12px;
        color: #999999;
        margin: 24px;
      }
    }
    
    .user-list-wrap {
      position: absolute;
       100%;
      height: 380px;
      overflow: hidden;
      top: 300px;
    
      .users-list {
        position: relative;
        margin: 0 auto;
         240px;
    
        li + li {
          margin-top: 28px;
        }
        img {
          display: block;
          float: left;
           36px;
          height: 36px;
          margin-top: 3px;
          border-radius: 50%;
        }
    
        .user-info {
          margin-left: 56px;
    
          .user-name {
            font-size: 12px;
            color: #999;
          }
          .user-act {
            font-size: 14px;
            color: #584f60;
          }
        }
      }
    }
    
    @media (min- 768px) {
      .users-wrap {
        height: 560px;
      }
      .users-text {
         270px;
        left: 100px;
        top: 104px;
        text-align: left;
        .users-title {
          font-size: 24px;
          font-weight: bold;
          margin-bottom: 22px;
        }
        .users-cont {
          margin: 0;
        }
      }
    
      .user-list-wrap {
        right: 126px;
        top: 104px;
         280px;
      }
    }
    
    .fadeout {
      animation: fadeout 1s ease;
      animation-fill-mode: forwards;
    }
    
    .move {
      animation: move 1s ease;
    }
    
    @keyframes move {
      from {
        transform: translateY(0);
      }
      to {
        transform: translateY(-64px);
      }
    }
    
    @keyframes fadeout {
      from {
        opacity: 1;
      }
      to {
        opacity: 0;
      }
    }
    ul,
    li {
      margin: 0;
      padding: 0;
      list-style: none;
    }
    a {
      text-decoration: none;
    }
    </style>
    
    //LinkContent.vue
    <template>
      <section class="link-wrap">
        <div class="link-wrap-inner">
          <img src="@/assets/images/apppages.png"
               class="apppages">
          <img src="@/assets/images/qrcode.png"
               class="qrcode">
          <div class="download-app-wrap">
            <p>荣获 App Store 2015 年度精选<br>App Store 官方推荐的移动健身工具</p>
            <div class="link-btn-wrap">
              <a href="#">
                <img src="@/assets/images/appledownload.png">
              </a>
              <div class="link-text">&nbsp;&nbsp;适用于 Apple Watch</div>
            </div>
            <div class="link-btn-wrap">
              <a href="#">
                <img src="@/assets/images/androiddownload.png">
              </a>
              <div class="link-text">&nbsp;TV 版可在电视应用市场下载</div>
            </div>
          </div>
        </div>
      </section>
    </template>
    
    <script>
    export default {
    
    }
    </script>
    
    <style lang="scss" scoped>
    .link-wrap {
      position: relative;
      height: 441.59px;
      background-image: url(../assets/images/linkbg.jpg);
      background-size: cover;
      background-repeat: no-repeat;
      background-position: center center;
    }
    .link-wrap-inner {
      position: relative;
       100%;
      height: 100%;
      max- 1440px;
      margin: 0 auto;
    }
    .download-app-wrap {
      position: absolute;
      top: 60px;
       100%;
      p {
        text-align: center;
        line-height: 2;
        font-size: 16px;
        color: #fff;
        margin: 12px 0 27.6px;
      }
    
      .link-btn-wrap {
         192px;
        margin-top: 24px;
        text-align: center;
        margin: 24px auto 0;
        a {
          display: block;
           100%;
          height: 58px;
          img {
             100%;
            height: 100%;
          }
        }
    
        .link-text {
          margin-top: 7.2px;
          font-size: 12px;
        }
      }
    }
    .apppages,
    .qrcode {
      display: none;
    }
    @media (min- 768px) {
      .link-wrap {
        height: 368px;
      }
    
      .download-app-wrap {
        text-align: center;
    
        p {
          margin-bottom: 36px;
        }
        .link-btn-wrap {
          display: inline-block;
          margin-top: initial;
        }
        .link-btn-wrap + .link-btn-wrap {
          margin-left: 20px;
        }
      }
    }
    
    @media (min- 1024px) {
      .apppages {
        display: block;
        position: absolute;
        left: 72px;
        top: -49px;
      }
    
      .download-app-wrap {
        position: absolute;
        top: 65px;
        right: 72px;
         354px;
        text-align: right;
    
        p {
          text-align: right;
          margin-bottom: 60px;
        }
    
        .link-btn-wrap {
           156px;
          a {
            height: 47px;
          }
        }
      }
    }
    
    @media (min- 1300px) {
      .qrcode {
        display: block;
        position: absolute;
         140px;
        height: 140px;
        right: 606px;
        top: 170px;
      }
    }
    </style>
    

    接下来就是重头戏,视频播放那里了
    这个地方的处理也是很有技巧的

    这个方法还直接获取了更深一级的属性
    这个可以理解为视频外面的海报

    //AppHeader.vue
    <template>
      <div>
        <header class="keep-header">
          <div class="phone-download-warp">
            <div class="phone-download">
              <p class="phone-title"
                 style="font-size:24px;font-weight:bold">Keep • 自律给我自由</p>
              <p class="phone-cont"
                 style="font-size:14px;margin-bottom:40px;">一站式解决你所有的运动需求</p>
              <a class="phone-link"
                 href="#"><img src="@/assets/images/appledownload.png"
                     alt=""></a>
              <a class="phone-link"
                 href="#"><img src="@/assets/images/androiddownload.png"
                     alt=""></a>
            </div>
          </div>
    
          <div class="video-wrap">
            <video id="video-bg"
                   src="@/assets/mp4/5s.mp4"
                   muted
                   autoplay
                   loop></video>
            <div class="video-control">
              <img src="@/assets/images/slogan.png">
              <img @click="$emit('playVideo')"
                   id="video-play"
                   src="@/assets/images/play.png">
            </div>
            <div class="video-bottom">
              <div class="bottom-left">
                Keep • 自律给我自由
                <br>
                <br>
                一站式解决你所有的运动需求
              </div>
              <div class="bottom-right">
                <a href="#"><img src="@/assets/images/appledownload.png"
                       alt=""></a>
                <a href="#"><img src="@/assets/images/androiddownload.png"
                       alt=""></a>
                <a href="javascript:;"
                   class="qrcode"><span></span><img src="@/assets/images/qrcode.png"
                       class="qrcode"></a>
              </div>
            </div>
          </div>
        </header>
        <div class="filling"></div>
      </div>
    </template>
    
    <script>
    
    export default {}
    </script>
    
    <style lang="scss" scoped>
    .keep-header {
       100%;
    }
    
    .phone-download {
      text-align: center;
      padding: 35% 0 18%;
    
      .phone-link {
        display: block;
         170px;
        margin: 26px auto 0;
    
        img {
          display: block;
           100%;
          height: 100%;
        }
      }
    }
    .phone-download-warp {
      display: none;
       100%;
      height: 100%;
      background-image: url("../assets/images/head-1.jpg");
      background-size: cover;
      background-repeat: no-repeat;
      background-position: center center;
    }
    
    @media (max- 767.98px) {
      .phone-download-warp {
        display: block;
      }
    
      .video-wrap {
        display: none;
      }
    }
    @media (min- 768px) {
      .keep-header {
        position: fixed;
         100%;
        height: calc(49.6vw);
        left: 0;
        top: 0;
      }
      .video-wrap {
        display: block;
        position: relative;
         100%;
        height: 100%;
        overflow: hidden;
    
        .video-control {
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          position: absolute;
          top: 0;
          left: 0;
           100%;
          height: 100%;
          background: rgba(34, 34, 34, 0.8);
    
          #video-play {
            display: none;
          }
        }
    
        .video-bottom {
           100%;
          display: flex;
          justify-content: space-between;
          align-items: center;
          position: absolute;
          bottom: 30px;
          line-height: 1;
    
          .bottom-left {
            margin-left: 35px;
          }
    
          .bottom-right {
            margin-right: 35px;
    
            a + a {
              margin-left: 15px;
            }
    
            a > img {
               160px;
            }
    
            a.qrcode {
              display: none;
            }
          }
        }
      }
    
      #video-bg {
         100%;
        margin-top: -42px;
        object-fit: contain;
      }
    
      .filling {
        height: calc(49.6vw);
      }
    }
    
    @media (min- 1024px) {
      .video-wrap .video-control #video-play {
        display: block;
        cursor: pointer;
      }
    
      .bottom-right {
        display: flex;
        align-items: center;
        a.qrcode {
          display: inline-flex !important;
          justify-content: center;
          align-items: center;
          text-align: center;
           62px;
          height: 50px;
          position: relative;
          border: 1px solid #fff;
          background: transparent;
          border-radius: 5px 5px;
    
          span {
            display: inline-block;
             26px;
            height: 26px;
            background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAAM1BMVEUAAAD///////////////////////////////////////////////////////////////+3leKCAAAAEHRSTlMA3cO7mfDSeKeP9+/QydtIakY+VAAAAIZJREFUKM+VkksOgCAMRKtFqX/uf1qRWmscI/EtWPBIMxlK3ChCRNLcmKlPSptVm250WU3MPL0qvSxnDMbyVE6sqjHHGYsSy2YKEnanCqwMqC48YX61HecHPhDwGD869IGonKJW6xCVWFE4UCgyByhKlaTUQ72g7FNgIKoCKg9fXRsF1ceK7rjBEHokzscQAAAAAElFTkSuQmCC")
              no-repeat center center;
            background-size: 26px 26px;
            color: #fff;
          }
    
          &:hover {
            img.qrcode {
              display: block;
            }
          }
        }
        img.qrcode {
          display: none;
          position: absolute;
          right: 0;
          bottom: 60px;
        }
      }
    }
    </style>
    

    子组件给父组件传递了事件,然后又通过事件去根据值处理播放,项目最核心的地方就是这里了

    //VideoPlay.vue
    
    <template>
      <div class="video-container"
           v-if="visible">
        <svg t="1571816192757"
             @click="close"
             class="close-icon"
             viewBox="0 0 1024 1024"
             version="1.1"
             xmlns="http://www.w3.org/2000/svg"
             p-id="2452"
             width="24"
             height="24">
          <path d="M559.5392 512l250.1888-250.1888a32.6912 32.6912 0 0 0 0-46.0544l-1.3824-1.3568a32.6912 32.6912 0 0 0-46.0544 0l-250.1632 250.4704-250.1888-250.5984a32.6912 32.6912 0 0 0-46.0544 0l-1.3568 1.3824a32.128 32.128 0 0 0 0 46.0544l250.1632 250.2656-250.1632 250.1888a32.6912 32.6912 0 0 0 0 46.0544l1.3568 1.3568a32.6912 32.6912 0 0 0 46.08 0l250.1632-250.1632 250.1632 250.1632a32.6912 32.6912 0 0 0 46.0544 0l1.3824-1.3568a32.6912 32.6912 0 0 0 0-46.0544l-250.1888-250.1888z"
                fill="#999999"
                p-id="2453"></path>
        </svg>
        <video id="video-large"
               style=" 100%;height: 100%;object-fit: contain;"
               autoplay
               src="@/assets/mp4/full.mp4"
               controls></video>
      </div>
    </template>
    
    <script>
    export default {
      data () {
        return {
          visible: false
        }
      },
      methods: {
        show () {
          this.visible = true;
        },
        close () {
          this.visible = false;
        }
      },
    }
    </script>
    
    <style lang="scss" scoped>
    .video-container {
      position: absolute;
      z-index: 200;
      top: 0;
      left: 0;
       100%;
      height: 100%;
      background: #fff;
    }
    .close-icon {
      position: absolute;
      z-index: 200;
      top: 30px;
      right: 30px;
      cursor: pointer;
    }
    </style>
    

    感谢作者大大给我们开源项目,感恩,感谢

  • 相关阅读:
    002-html表格
    001-html常见的标记
    获取本地内外网ip地址
    Windows10设置默认简体美式键盘输入法
    C# 历史版本特性变更
    SQL Server Report Builder RDLC按记录数分页
    自动补全(备份)
    t:datagrid 行编辑 类型备份
    自动生成编号
    文本框上绑校验
  • 原文地址:https://www.cnblogs.com/smart-girl/p/13401478.html
Copyright © 2011-2022 走看看