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 也不错

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

参考

相关推荐
乘风gg1 小时前
还在养虾吗?虾王已诞生:微信龙虾 ClawBot
前端·ai编程·claude
小小小小宇2 小时前
LLM 长期记忆构建
前端
lichenyang4532 小时前
从 Express 老项目到 NestJS + Docker:一次车辆管理系统的渐进式重构
前端
Momo__3 小时前
VueUse createReusableTemplate —— 单文件组件内的模板复用神器
前端·vue.js
程序员小富3 小时前
我开源了一个开发者专属的智能 JSON 工具,得到了媳妇高度认可
前端·vue.js·后端
小小小小宇3 小时前
程序员如何给 LLM 装工具以及看懂推理过程
前端
写代码的皮筏艇3 小时前
React中的forwardRef
前端·react.js·面试
槑有老呆3 小时前
花三个月工资请了个 AI 程序员,结果它连青岛啤酒股价都查不了
前端
风骏时光牛马3 小时前
Verilog开发常见问题汇总解析
前端
子兮曰3 小时前
AI Coding Method Map:一张图看懂 AI 编程的完整链路
前端·人工智能·后端