「青训营 X 码上掘金」制作一个多面翻转名片

26 阅读3分钟

当青训营遇上码上掘金

名片是向人介绍自我的重要工具,作为一名程序员用代码做自我介绍是一件非常酷炫的事情。用代码制作一张名片最直观地介绍给别人的方式就是通过使用 HTML 绘制一个网页来显示了,下面我们就来制作一个翻转动效的个人名片。

实现

首先就是给body设置一个巨大的高度,然后把展示图片用的ul给固定到视口中间而不是body中间,设置好相关的css,在js中获取对应的元素和视口高度以及滚动高度,然后对应的着更改元素的rotateY属性,当然,这个属性值用变量代替。然后更改对应方式即可实现本文的效果。

HTML

使用用ul嵌套li来实现显示于旋转

<ul>
    <li>
        <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/42d1adf7141d4807a8b5fcfb625abe58~tplv-k3u1fbpfcp-watermark.image" alt="">
        <div class="name">辜负寒彻骨</div>
        <div class="gender"></div>
        <div class="age">20岁</div>
        <div class="address">山西</div>
        
    </li>
    <li>
        <a href="#" ><svg t="1676000673599" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2691" width="52" height="52"><path d="M511.6 76.3C264.3 76.2 64 276.4 64 523.5 64 718.9 189.3 885 363.8 946c23.5 5.9 19.9-10.8 19.9-22.2v-77.5c-135.7 15.9-141.2-73.9-150.3-88.9C215 726 171.5 718 184.5 703c30.9-15.9 62.4 4 98.9 57.9 26.4 39.1 77.9 32.5 104 26 5.7-23.5 17.9-44.5 34.7-60.8-140.6-25.2-199.2-111-199.2-213 0-49.5 16.3-95 48.3-131.7-20.4-60.5 1.9-112.3 4.9-120 58.1-5.2 118.5 41.6 123.2 45.3 33-8.9 70.7-13.6 112.9-13.6 42.4 0 80.2 4.9 113.5 13.9 11.3-8.6 67.3-48.8 121.3-43.9 2.9 7.7 24.7 58.3 5.5 118 32.4 36.8 48.9 82.7 48.9 132.3 0 102.2-59 188.1-200 212.9 23.5 23.2 38.1 55.4 38.1 91v112.5c0.8 9 0 17.9 15 17.9 177.1-59.7 304.6-227 304.6-424.1 0-247.2-200.4-447.3-447.5-447.3z" fill="#333333" p-id="2692"></path></svg></a>
        <a href="#"><svg t="1676000711407" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3622" width="52" height="52"><path d="M824.8 613.2c-16-51.4-34.4-94.6-62.7-165.3C766.5 262.2 689.3 112 511.5 112 331.7 112 256.2 265.2 261 447.9c-28.4 70.8-46.7 113.7-62.7 165.3-34 109.5-23 154.8-14.6 155.8 18 2.2 70.1-82.4 70.1-82.4 0 49 25.2 112.9 79.8 159-26.4 8.1-85.7 29.9-71.6 53.8 11.4 19.3 196.2 12.3 249.5 6.3 53.3 6 238.1 13 249.5-6.3 14.1-23.8-45.3-45.7-71.6-53.8 54.6-46.2 79.8-110.1 79.8-159 0 0 52.1 84.6 70.1 82.4 8.5-1.1 19.5-46.4-14.5-155.8z" fill="#333333" p-id="3623"></path></svg></a>
        <a href="#"><svg t="1676000726242" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4608" width="52" height="52"><path d="M664.250054 368.541681c10.015098 0 19.892049 0.732687 29.67281 1.795902-26.647917-122.810047-159.358451-214.077703-310.826188-214.077703-169.353083 0-308.085774 114.232694-308.085774 259.274068 0 83.708494 46.165436 152.460344 123.281791 205.78483l-30.80868 91.730191 107.688651-53.455469c38.558178 7.53665 69.459978 15.308661 107.924012 15.308661 9.66308 0 19.230993-0.470721 28.752858-1.225921-6.025227-20.36584-9.521864-41.723264-9.521864-63.862493C402.328693 476.632491 517.908058 368.541681 664.250054 368.541681zM498.62897 285.87389c23.200398 0 38.557154 15.120372 38.557154 38.061874 0 22.846334-15.356756 38.156018-38.557154 38.156018-23.107277 0-46.260603-15.309684-46.260603-38.156018C452.368366 300.994262 475.522716 285.87389 498.62897 285.87389zM283.016307 362.090758c-23.107277 0-46.402843-15.309684-46.402843-38.156018 0-22.941502 23.295566-38.061874 46.402843-38.061874 23.081695 0 38.46301 15.120372 38.46301 38.061874C321.479317 346.782098 306.098002 362.090758 283.016307 362.090758zM945.448458 606.151333c0-121.888048-123.258255-221.236753-261.683954-221.236753-146.57838 0-262.015505 99.348706-262.015505 221.236753 0 122.06508 115.437126 221.200938 262.015505 221.200938 30.66644 0 61.617359-7.609305 92.423993-15.262612l84.513836 45.786813-23.178909-76.17082C899.379213 735.776599 945.448458 674.90216 945.448458 606.151333zM598.803483 567.994292c-15.332197 0-30.807656-15.096836-30.807656-30.501688 0-15.190981 15.47546-30.477129 30.807656-30.477129 23.295566 0 38.558178 15.286148 38.558178 30.477129C637.361661 552.897456 622.099049 567.994292 598.803483 567.994292zM768.25071 567.994292c-15.213493 0-30.594809-15.096836-30.594809-30.501688 0-15.190981 15.381315-30.477129 30.594809-30.477129 23.107277 0 38.558178 15.286148 38.558178 30.477129C806.808888 552.897456 791.357987 567.994292 768.25071 567.994292z" fill="#333333" p-id="4609"></path></svg></a>
    </li>
    <li>
        <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/42d1adf7141d4807a8b5fcfb625abe58~tplv-k3u1fbpfcp-watermark.image" alt="">
        <div class="sentence">莫听穿林打叶声 <br>何妨吟啸且徐行</div>
   
    </li>
     <li>
        <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/42d1adf7141d4807a8b5fcfb625abe58~tplv-k3u1fbpfcp-watermark.image" alt="">
        <div class="name">辜负寒彻骨</div>
        <div class="gender"></div>
        <div class="age">20岁</div>
        <div class="address">山西</div>
      
    </li>
  </ul>

CSS

css需要注意使用fixed,固定到视口中,这样滑动就能一直看到

   *, *::before, *::after {
  padding: 0;
  margin: 0 auto;
  box-sizing: border-box;
}

body {
  background-image: linear-gradient(to right,#00d9ff8c, #006eff8c);
  height: 10000px;
}
div{
  position: fixed;
  top: 12%;
  left: 10%;
  text-align: center;
  width: 520px;
  height: 50px;
  font-size: 22px;
}
ul {
  position: fixed;
  top: calc(50% - 260px);
  left: calc(50% - 260px);
  width: 520px;
  height: 320px;
  perspective: 1000px;
  border-radius: 25px;
}

/* li 部分 */
li {
  /* 提前设置好旋转值 */
  --ang: 180deg;
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 100%;
  background-image: linear-gradient(to right,#00d9ff8c, #2270d6b7);
  perspective: 2000px;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.5) inset;
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
  padding: 48px 32px;
  font-size: 24px;
  border-radius: 25px;
  transform: rotateY(var(--ang));
  transform-style: preserve-3d;
  /* 先隐藏 */
  -webkit-backface-visibility: hidden;
          backface-visibility: hidden;
}

/* li 中 img */
li > img {
  position: absolute;
  top: 70px;
  left: 60px;
  width: 150px;
  height: 150px;
  z-index: -2;
  border: 1px solid #fff;
  border-radius: 50%;
}
li .name{
    margin-left: 40px;
    margin-top: 50px;
    font-size: 40px;
    font-weight: 600;
}
li .age{
    margin-left: -20px;
    margin-top: 130px;
}
li .gender{
    margin-left: 40px;
    margin-top: 130px;
}
li .address{
    margin-left: 100px;
    margin-top: 130px;
}
li a{
    width: 50px;
    background-color: #fff;
    border-radius: 50%;
    position: relative;
    top: 20px;
}
li a:hover{
    top: 5px;
    transition: 1s;
}
li a svg{
    width: 40px;
    margin-left: 5px;
    margin-top: 5px;
}
li .sentence{
    margin-left: 40px;
    margin-top: 50px;
    font-size: 30px;
    line-height: 50px;
    font-family: serif;
    font-weight: 800;
}

backface-visibility:hidden;这个属性代表了当元素背对着用户的时候就会隐藏起来不展示,配合3D实现。

JS

依然是获取元素,并顺便获取视口高度和滚动高度,绑定滚动事件

const body = document.querySelector("body")
const lis = document.querySelectorAll("li")
window.addEventListener("scroll", () => { onscrl() }, false)
onscrl(false)

function onscrl() {
  // this ==> Window
  const s = (body.scrollHeight - window.innerHeight) / 3
  lis.forEach((li, index) => {
    const ang = ((this.scrollY - (s * (index - 1))) * 360 / (s * 2)) - 180
    li.style.setProperty('--ang',
      Math.max(-180, Math.min(180, ang)) + 'deg'
    )
    rollBottom();
  })

}

function rollBottom(){
    var t = body.scrollHeight;
    window.scroll({ top: t, left: 0, behavior: 'smooth' });
  }

rollBottom()控制滚动条自动滚动,达到名片自动滚动的目的。

这里定义s的时候之所以要除以3,是因为一共四张图片,要把每个图片的旋转角度平均分配给滚动高度,除以3可以保证每果冻一个视口高度的时候刚好可以让一张图片旋转180°。

参考(juejin.cn/post/718944…

完整代码