最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • CSS3实战:实现一个旋转的3D金币

    正文概述 掘金(字节前端)   2021-05-23   609

    如图CSS3实战:实现一个旋转的3D金币 最近亲爱的产品同学,提了一个需求:在页面某个角落增加一个旋转的金币来吸引用户参加活动~越快上越好~

    拿到这个需求,第一反应 gif+a 标签,简单粗暴+便捷。即将实施就碰到一个问题,UI 小姐姐还没有做设计,排期需要在 x 天后~怎么办?没有难做的工作,只有解决困难的打工人!

    链接好说,旋转的金币怎么整?旋转的金币 = 旋转 + 金币。旋转通过 css3 的动画属性 animation+ @keyframes 就可以搞定:

    .coin {
    
      transform-style: preserve-3d;
    
      animation: rotate3d 3s linear infinite;
    
    }
    
    
    
    @keyframes rotate3d {
    
      0% {
    
        transform: perspective(1000px) rotateY(0deg);
    
      }
    
    
    
      100% {
    
        transform: perspective(1000px) rotateY(360deg);
    
      }
    
    }
    

    那么金币怎么办?我们用 div 来 DIY 一下吧~如果把金币的表面图案都擦掉,那金币就是一个特别矮的圆柱体,我们需要一个正面+背面+弯曲的侧面。那么正面+背面很简单

    $coin-thickness: 4px;
    
    $coin-front: "https://tosv.byted.org/obj/maat/img/d2FuZ3NoaXpoZW4uNzUzMA/file_178a58ae02711.png";
    
    $coin-back: "https://tosv.byted.org/obj/maat/img/d2FuZ3NoaXpoZW4uNzUzMA/file_178a58ae0276.png";
    
    
    
    .coin__front {
    
      background-image: url($coin-front);
    
      background-size: cover;
    
      transform: translateZ($coin-thickness / 2);
    
    }
    
    .coin__back {
    
      background-image: url($coin-back);
    
      background-size: cover;
    
      transform: translateZ(-$coin-thickness / 2) rotateY(180deg);
    
    }
    

    CSS3实战:实现一个旋转的3D金币侧面怎么画?翻了不少 css 文档,除了 border-radius 还真没有找到一个弯曲的属性,我徒手 DIY 金币的过程就要这么结束了么?

    当然不会!!!敬我中华民族智慧一杯~早在数千年前,祖冲之就告诉我们~实现不了完美的圆,那就让它近似圆就好了!数年前端从业经验告诉我,只要能骗过用户的视觉,那什么都是真的!!!就是你了——多棱柱。

    方案有了,但麻烦的是,画多少棱面才能骗过用户的视觉?我得手写多少 css+div?不用慌,less 中的 when 来搞定 n 次循环,前端框架中整个 map 来生成 div

    const n = 80
    
    <div className={styles.coin__edge}>
    
      {Array(n).fill(1).map((value, key) => (<div key={key} />))}
    
    </div>
    

    对这些 div 使用 translate + rotate 来确定位置~

    // 多棱柱体大小(直径)
    
    $coin-diameter: 320px;
    
    // 多棱柱体高度
    
    $coin-thickness: 40px;
    
    // 颜色
    
    $coin-color: rgb(255, 223, 95);
    
    // 多棱柱的棱数
    
    $edge-faces: 100;
    
    // 每个棱的高度 π * 直径 / 棱数
    
    $edge-face-length: 3.14 * $coin-diameter / $edge-faces;
    
    
    
    .coin__edge {
    
      > div {
    
        position: absolute;
    
        height: $edge-face-length;
    
        width: $coin-thickness;
    
      }
    
      @for $i from 1 through $edge-faces {
    
        div:nth-child(#{$i}) {
    
          background: $coin-color;
    
          transform:
    
            // 由于默认绘制div的初始位置在左上角,需要把它移到中心
    
            translateY($coin-diameter / 2 - $edge-face-length / 2)
    
            translateX($coin-diameter / 2 - $coin-thickness / 2)
    
            // 横向旋转
    
            rotateY(90deg)
    
            // 调整每片角度
    
            rotateX(360deg / $edge-faces * $i + 90)
    
            // 移动至多棱柱边缘
    
            translateZ($coin-diameter / 2);
    
        }
    
      }
    
    }
    

    默认绘制的位置CSS3实战:实现一个旋转的3D金币移到中心

    div:nth-child(#{$i}) {
    
      transform:
    
            // 由于默认绘制div的初始位置在左上角,需要把它移到中心
    
            translateY($coin-diameter / 2 - $edge-face-length / 2)
    
            translateX($coin-diameter / 2 - $coin-thickness / 2)
    
    }
    

    CSS3实战:实现一个旋转的3D金币横向旋转

    div:nth-child(#{$i}) {
    
      transform:
    
            // 由于默认绘制div的初始位置在左上角,需要把它移到中心
    
            translateY($coin-diameter / 2 - $edge-face-length / 2)
    
            translateX($coin-diameter / 2 - $coin-thickness / 2)
    
            // 横向旋转
    
            rotateY(90deg)
    
    }
    

    CSS3实战:实现一个旋转的3D金币调整每片角度

    div:nth-child(#{$i}) {
    
      transform:
    
            // 由于默认绘制div的初始位置在左上角,需要把它移到中心
    
            translateY($coin-diameter / 2 - $edge-face-length / 2)
    
            translateX($coin-diameter / 2 - $coin-thickness / 2)
    
            // 横向旋转
    
            rotateY(90deg)
    
            // 调整每片角度
    
            rotateX(360deg / $edge-faces * $i + 90)
    
            // 移动至多棱柱边缘
    
            translateZ($coin-diameter / 2);
    
    }
    

    CSS3实战:实现一个旋转的3D金币移动至多棱柱边缘

    div:nth-child(#{$i}) {
    
      transform:
    
            // 由于默认绘制div的初始位置在左上角,需要把它移到中心
    
            translateY($coin-diameter / 2 - $edge-face-length / 2)
    
            translateX($coin-diameter / 2 - $coin-thickness / 2)
    
            // 横向旋转
    
            rotateY(90deg)
    
            // 调整每片角度
    
            rotateX(360deg / $edge-faces * $i + 90)
    
            // 移动至多棱柱边缘
    
            translateZ($coin-diameter / 2);
    
    }
    

    CSS3实战:实现一个旋转的3D金币最终效果图:CSS3实战:实现一个旋转的3D金币 完美解决~

    最后附上完整代码

    骨架:

    const CoinTrans = () => {
    
      return <div class="coin">
    
        <div className="coin__front"></div>
    
        <div className="coin__back"></div>
    
        <div className="coin__edge">
    
          {Array(100).fill(1).map((item,key)=> <div key={key} />)}
    
        </div>
    
        {/* 阴影 */}
    
        <div className="coin__shadow"></div>
    
      </div>
    
    }
    
    $coin-diameter: 320px;
    
    $coin-thickness: 40px;
    
    $coin-color: rgb(255, 223, 95);
    
    $coin-front: "https://tosv.byted.org/obj/maat/img/d2FuZ3NoaXpoZW4uNzUzMA/file_178a58ae02711.png";
    
    $coin-back: "https://tosv.byted.org/obj/maat/img/d2FuZ3NoaXpoZW4uNzUzMA/file_178a58ae0276.png";
    
    $edge-faces: 100;
    
    $edge-face-length: 3.14 * $coin-diameter / $edge-faces;
    
    $turn-time: 8s;
    
    
    
    .coin {
    
      position: relative;
    
      width: $coin-diameter;
    
      height: $coin-diameter;
    
      margin: 0 auto;
    
      transform-style: preserve-3d;
    
      animation: rotate3d $turn-time linear infinite;
    
      transition: all 0.3s;
    
    }
    
    
    
    .coin__front,
    
    .coin__back {
    
      position: absolute;
    
      width: $coin-diameter;
    
      height: $coin-diameter;
    
      border-radius: 50%;
    
      overflow: hidden;
    
      background-color: $coin-color;
    
      color: #000;
    
      font-size: $coin-diameter * 0.6;
    
      // 金币表面的闪动 buling~buling~~
    
      &:after {
    
        content: "";
    
        position: absolute;
    
        left: -$coin-diameter / 2;
    
        bottom: 100%;
    
        display: block;
    
        height: $coin-diameter / 1.5;
    
        width: $coin-diameter * 2;
    
        background: #fff;
    
        opacity: 0.3;
    
        animation: shine linear $turn-time / 2 infinite;
    
      }
    
    }
    
    
    
    .coin__front {
    
      background-image: url($coin-front);
    
      background-size: cover;
    
      transform: translateZ($coin-thickness / 2);
    
    }
    
    .coin__back {
    
      background-image: url($coin-back);
    
      background-size: cover;
    
      transform: translateZ(-$coin-thickness / 2) rotateY(180deg);
    
    }
    
    
    
    .coin__edge {
    
      > div {
    
        position: absolute;
    
        height: $edge-face-length;
    
        width: $coin-thickness;
    
      }
    
      @for $i from 1 through $edge-faces {
    
        div:nth-child(#{$i}) {
    
          background: $coin-color;
    
          // 另一种移动逻辑
    
          // transform: translateY($coin-diameter / 2 - $edge-face-length / 2)
    
          //   translateX($coin-diameter / 2 - $coin-thickness / 2)
    
          //   rotateZ(360deg / $edge-faces * $i + 90)
    
          //   translateX($coin-diameter / 2)
    
          //   rotateY(90deg);
    
          // rotateZ(360deg / $edge-faces * $i + 90)
    
          transform: translateY($coin-diameter / 2 - $edge-face-length / 2)
    
            translateX($coin-diameter / 2 - $coin-thickness / 2)
    
            rotateY(90deg)
    
            rotateX(360deg / $edge-faces * $i + 90)
    
            translateZ($coin-diameter / 2);
    
        }
    
      }
    
    }
    
    
    
    // 阴影 css
    
    .coin__shadow {
    
      position: absolute;
    
      width: $coin-diameter;
    
      height: $coin-thickness;
    
      border-radius: 50%;
    
      background: #000;
    
      box-shadow: 0 0 $coin-thickness * 5 $coin-thickness * 5 #000;
    
      opacity: 0.125;
    
      transform: rotateX(90deg) translateZ(-$coin-diameter * 1.1) scale(0.5);
    
    }
    
    
    
    @keyframes rotate3d {
    
      0% {
    
        transform: perspective(1000px) rotateY(0deg);
    
      }
    
    
    
      100% {
    
        transform: perspective(1000px) rotateY(360deg);
    
      }
    
    }
    
    
    
    @keyframes shine {
    
      0%,
    
      15% {
    
        transform: translateY($coin-diameter * 2) rotate(-40deg);
    
      }
    
      50% {
    
        transform: translateY(-$coin-diameter) rotate(-40deg);
    
      }
    
    }
    

    数据平台前端团队,在公司内负责风神、TEA、Libra、Dorado 等大数据相关产品的研发。我们在前端技术上保持着非常强的热情,除了数据产品相关的研发外,在数据可视化、海量数据处理优化、web excel、WebIDE、私有化部署、工程工具都方面都有很多的探索和积累,有兴趣可以与我们联系。对产品有任何建议和反馈也可以直接找我们进行反馈 ~


    起源地下载网 » CSS3实战:实现一个旋转的3D金币

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元