【别贪心】keep-web

首先放下作者大大的github地址:https://github.com/SJanJan/keep-web
接着我们看下项目
【别贪心】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="width:28px;"
               alt="menu">
        </a>
        <a href="#"
           class="logo"> <img style="width:68px;"
               src="@/assets/phonelogo.png"
               alt="logo">
        </a>
      </div>
    </nav>

    <nav class="nav-wrapper-pc">
      <a href="#"
         class="logo"> <img style="width: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;
  width: 100%;
}
.nav-wrapper-phone {
  display: none;
  position: absolute;
  width: 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-width: 767.98px) {
  .nav-wrapper-phone {
    display: block;
  }
}

@media (min-width: 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-width: 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-width: 1440px;
  margin: 0 auto;
}

.training-item {
  display: block;
  margin: 0;
  width: 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;
    width: 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);
  width: 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-width: 750px) {
  .training-item {
    &:last-child {
      display: inline-block;
    }
  }
}

@media (max-width: 1023px) and (min-width: 768px) {
  .training-wrap {
    height: 1050px;
    position: relative;
  }
  .training-block {
    position: relative;
    width: 740px;
    left: 50%;
    margin-left: -370px;
    top: -45px;
  }
  .training-item {
    display: inline-block;
    width: 356px;
    margin-bottom: 10px;
    margin-right: 10px;
  }

  .training-text {
    position: absolute;
    right: 23px;
    bottom: 0;
    width: 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-width: 1024px) {
  .training-wrap {
    position: relative;
    height: 636px;
    .training-wrap-inner {
      height: 636px;
    }
  }
  .training-block {
    width: 356px;
    position: relative;
    left: 30px;
    top: -15px;
    .training-item + .training-item {
      margin: 10px 0 0;
    }
    .training-item {
      display: block;
      width: 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;
    width: 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-width: 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-width: 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-width: 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 {
  width: 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-width: 1440px;
  margin: 0 auto;
}
.run-config-wrap {
  width: 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 {
      width: 54.6%;
    }
    .speed-bar2 {
      width: 42%;
    }
    .speed-bar3 {
      width: 45.4%;
    }
    .speed-bar4 {
      width: 100%;
    }
    .speed-bar5 {
      width: 48.9%;
    }
    .speed-bar6 {
      width: 45.4%;
    }
    .speed-bar7 {
      width: 50.6%;
    }
  }

  .run-config-frequency {
    position: relative;
    width: 100%;
    height: 319.19px;
    margin-top: 10px;
    .config-title {
      width: 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 {
        width: 100%;
        height: 100%;
      }
    }
  }
}

.run-text-wrap {
  width: 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;
    width: 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-width: 768px) {
  .run-wrap {
    height: 636px;
  }

  .run-text-wrap {
    width: 268px;
    top: 45px;
    right: 27px;
    bottom: initial;
    text-align: right;

    .run-text-cont {
      margin: 20px 0;
    }
  }

  .run-config-wrap {
    width: 700px;
    top: initial;
    bottom: -80px;
    right: 50%;
    margin-right: -350px;

    .run-config-pace,
    .run-config-frequency {
      float: left;
      width: 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 {
      width: 60px;
      height: 60px;
      position: absolute;
      bottom: -8px;
      right: -12px;
      border-radius: 50%;
      background: #fff;
      animation: scale 2s ease infinite normal;
    }
  }
}
@media (min-width: 1024px) {
  .run-config-wrap {
    top: -26px;
    right: 28px;
    bottom: initial;
    width: 384px;
    height: 694px;
    margin-right: initial;

    .run-config-pace,
    .run-config-frequency {
      float: none;
      width: 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-width: 768px) {
  .paragraph {
    padding: 180px 0 100px;

    .para-title {
      font-size: 24px;
    }
    .para-text {
      font-size: 16px;
      margin: 30px 0 0;
    }
  }
}

@media (min-width: 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;
  width: 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;
    width: 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-width: 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-width: 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;
  width: 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;
    width: 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-width: 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;
    width: 698px;
    height: 180px;
    background-image: url(../assets/images/store-goods768.png);
  }

  .store-keleton {
    position: absolute;
    right: initial;
    left: -2%;
    bottom: 180px;
    width: 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-width: 1024px) {
  .store-goods {
    left: 28px;
    top: 42px;
    margin: initial;
    width: 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;
    width: 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-width: 1440px) {
  .store-wrap-inner {
    width: 1200px;
  }
}
</style>

接下来这个就很有意思了,用来处理了自动向上滚动和消失的
【别贪心】keep-web

//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;
  width: 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;
  width: 100%;
  height: 380px;
  overflow: hidden;
  top: 300px;

  .users-list {
    position: relative;
    margin: 0 auto;
    width: 240px;

    li + li {
      margin-top: 28px;
    }
    img {
      display: block;
      float: left;
      width: 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-width: 768px) {
  .users-wrap {
    height: 560px;
  }
  .users-text {
    width: 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;
    width: 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;
  width: 100%;
  height: 100%;
  max-width: 1440px;
  margin: 0 auto;
}
.download-app-wrap {
  position: absolute;
  top: 60px;
  width: 100%;
  p {
    text-align: center;
    line-height: 2;
    font-size: 16px;
    color: #fff;
    margin: 12px 0 27.6px;
  }

  .link-btn-wrap {
    width: 192px;
    margin-top: 24px;
    text-align: center;
    margin: 24px auto 0;
    a {
      display: block;
      width: 100%;
      height: 58px;
      img {
        width: 100%;
        height: 100%;
      }
    }

    .link-text {
      margin-top: 7.2px;
      font-size: 12px;
    }
  }
}
.apppages,
.qrcode {
  display: none;
}
@media (min-width: 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-width: 1024px) {
  .apppages {
    display: block;
    position: absolute;
    left: 72px;
    top: -49px;
  }

  .download-app-wrap {
    position: absolute;
    top: 65px;
    right: 72px;
    width: 354px;
    text-align: right;

    p {
      text-align: right;
      margin-bottom: 60px;
    }

    .link-btn-wrap {
      width: 156px;
      a {
        height: 47px;
      }
    }
  }
}

@media (min-width: 1300px) {
  .qrcode {
    display: block;
    position: absolute;
    width: 140px;
    height: 140px;
    right: 606px;
    top: 170px;
  }
}
</style>

接下来就是重头戏,视频播放那里了
这个地方的处理也是很有技巧的
【别贪心】keep-web
这个方法还直接获取了更深一级的属性
这个可以理解为视频外面的海报

//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 {
  width: 100%;
}

.phone-download {
  text-align: center;
  padding: 35% 0 18%;

  .phone-link {
    display: block;
    width: 170px;
    margin: 26px auto 0;

    img {
      display: block;
      width: 100%;
      height: 100%;
    }
  }
}
.phone-download-warp {
  display: none;
  width: 100%;
  height: 100%;
  background-image: url("../assets/images/head-1.jpg");
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
}

@media (max-width: 767.98px) {
  .phone-download-warp {
    display: block;
  }

  .video-wrap {
    display: none;
  }
}
@media (min-width: 768px) {
  .keep-header {
    position: fixed;
    width: 100%;
    height: calc(49.6vw);
    left: 0;
    top: 0;
  }
  .video-wrap {
    display: block;
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;

    .video-control {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(34, 34, 34, 0.8);

      #video-play {
        display: none;
      }
    }

    .video-bottom {
      width: 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 {
          width: 160px;
        }

        a.qrcode {
          display: none;
        }
      }
    }
  }

  #video-bg {
    width: 100%;
    margin-top: -42px;
    object-fit: contain;
  }

  .filling {
    height: calc(49.6vw);
  }
}

@media (min-width: 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;
      width: 62px;
      height: 50px;
      position: relative;
      border: 1px solid #fff;
      background: transparent;
      border-radius: 5px 5px;

      span {
        display: inline-block;
        width: 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="width: 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;
  width: 100%;
  height: 100%;
  background: #fff;
}
.close-icon {
  position: absolute;
  z-index: 200;
  top: 30px;
  right: 30px;
  cursor: pointer;
}
</style>

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

【别贪心】keep-web

上一篇:Android抓包方法(一)之Fiddler代理


下一篇:获取当前网页的cookies和url