CSS 实现卡牌翻转

在一些运营活动中,为了增加用户参与的趣味性,会在随机的事件中使用卡牌翻转的效果,如下👇

初始 翻转中 完成

👌,下面,我们就来实现这个效果。

实现

我们有下面的 HTML 骨架:

html 复制代码
<div class="flip">
  <div class="flip-inner">
    <div class="flip-inner-front">
      <div class="flip-inner-front-text">Front Side</div>
    </div>
    <div class="flip-inner-back">
      <div  class="flip-inner-back-text">Back Side</div>
    </div>
  </div>
</div>

我们设定了前面和后面元素,并用下面的 scss 样式进行润色:

scss 复制代码
.flip {
  width: 300px;
  height: 200px;
  margin: 0 auto;
  &-inner {
    position: relative;
    width: 100%;
    height: 100%;
    &-front, &-back {
      width: 100%;
      height: 100%;
      position: absolute;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    &-front {
      background-color: #BBBBBB;
      z-index: 2;
    }
    &-back {
      background: #444444;
      transform: rotateY(180deg);
      z-index: 1;
    }
  }
}

在上面,我们设定了正面和背面两个 DIV,并用绝对定位来重叠这两个 DIV,并使用 zIndex 来做层级的区分。并对背面的 DIVY 轴的 180 度的旋转。

因为,我们是模拟空间 3d 效果,还需要更改下👇

scss 复制代码
.flip {
  perspective: 1000px;
  transform: rotateY(45deg);
  &-inner {
    transform-style: perserve-3d;
    transform: rotateY(45deg);
  }
}

这里我们设定了旋转 45 度。并且通过 perspective 指定了观察者与 Z=0 平面的距离,使其具有三维位置变换的元素产生透视效果。然后,我们通过 transform-styleperserve-3d 设置元素的子元素位于 3D 空间中。

这里的效果如下所示👇

嗯~

接下来,我们就可以实现下动画效果了。

我们通过点击事件,添加翻转的类 flipped:

html 复制代码
<div class="flip" onclick="this.classList.toggle('flipped')">
  <!--其他的内容-->
</div>

然后,我们在 scss 文件中添加下面的内容:

scss 复制代码
.flip {
  &-inner {
    transition: transform 1.5s;
    &-front, &-back {
      backface-visibility: hidden; // backface-visibility 指定当前元素背面朝向观察者时是否可见
    }
  }
  &.flipped &-inner {
    transform: rotateY(540deg);
  }
}

注意:这里的 &.flipped &-inner 别写成 &.flipped, &-inner。它们是两种不同的意思。

上面,我们通过 transition 来定义 transform 的动画。这里是在 1.5s 内将旋转到 450deg

当我们点击 flip 这个类元素的时候,就会切换到 .flip.flipped 类上,就会触发翻转到背面的动效。

嗯~这就是我们想要的效果。

那么,我们是否对翻牌增加前置的操作呢?比如 - 随机选牌子👇

这里我们假设了 6 张牌:

react 复制代码
render (
  <div className="container">
    {
      [1,2,3,4,5,6].map((item: number, index: number) => {
        return <div key={index} className="container-item">other content</div>
      })
    }
  </div>
)

然后,我们让选中效果从 0 ~ 5 循环进行展示:

typescript 复制代码
const [activeIndex, setActiveIndex] = useState<number>(0);

useEffect(() => {
  const timer = setInterval(() => {
    setActiveIndex((activeIndex) => (activeIndex + 1) % 6); // 0-5循环【当然,我们也可以随机获取 Math.floor(Math.random()*6)】
  }, 200);
  
  return () => {
    timer && clearInterval(timer);
  }
},[])

当随机翻牌的动效播放结束之后,然后触发翻牌的旋转动画出牌结果。

ps: 使用关键帧 @keyframe 也不错

当然,读者可以发动下自己的小脑袋,想想还有什么趣味的操作,增加用户在页面上的停留时间🤔

参考

相关推荐
HaanLen2 小时前
React19源码系列之 Hooks (useState、useReducer、useOptimistic)
服务器·前端
yuanyxh4 小时前
《精通正则表达式》精华摘要
前端·javascript·正则表达式
小飞大王6665 小时前
简单实现HTML在线编辑器
前端·编辑器·html
百万蹄蹄向前冲5 小时前
大学期末考,AI定制个性化考试体验
前端·人工智能·面试
向明天乄6 小时前
在 Vue 3 项目中集成高德地图(附 Key 与安全密钥申请全流程)
前端·vue.js·安全
sunshine_程序媛6 小时前
vue3中的watch和watchEffect区别以及demo示例
前端·javascript·vue.js·vue3
电商数据girl6 小时前
【经验分享】浅谈京东商品SKU接口的技术实现原理
java·开发语言·前端·数据库·经验分享·eclipse·json
Senar7 小时前
听《富婆KTV》让我学到个新的API
前端·javascript·浏览器
烛阴7 小时前
提升Web爬虫效率的秘密武器:Puppeteer选择器全攻略
前端·javascript·爬虫