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

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

参考

相关推荐
snow@li31 分钟前
Java:Java 服务器(Web 容器 / Servlet 容器)完整工作清单
java·服务器·前端
洋子1 小时前
Yank Note 系列 14 - 我和 AI 怎么一起写文章
前端·markdown
江华森2 小时前
前端构建工具 Webpack 速览
前端·webpack·node.js
谙忆10242 小时前
HTTP 图片缓存实战:Cache-Control、ETag、内容哈希文件名与 CDN 回源到底怎么配
前端
小妖6662 小时前
React input 输入卡顿问题
前端·javascript·react.js
এ慕ོ冬℘゜2 小时前
JavaScript 数据类型检测与转换、运算符超全实战详解
前端·html
kyriewen3 小时前
我用 AI 写代码快了 3 倍——然后同事的 Code Review 全变成了我的
前端·程序员·ai编程
李明卫杭州4 小时前
Vue2 portal-target 组件与 Vue3 的针对性优化
前端·javascript·vue.js
Tyler_15 小时前
iOS PlayWright mcp server
前端·ios·ai编程
嘟嘟07175 小时前
从零理解 MCP:手写一个本地 MCP Server 并接入 LangChain Agent
前端·后端