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

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

参考

相关推荐
前端 贾公子2 小时前
pnpm 的 resolution-mode 配置 ( pnpm 的版本解析)
前端
伍哥的传说2 小时前
React 自定义Hook——页面或元素滚动到底部监听 Hook
前端·react.js·前端框架
麦兜*4 小时前
Spring Boot 集成Reactive Web 性能优化全栈技术方案,包含底层原理、压测方法论、参数调优
java·前端·spring boot·spring·spring cloud·性能优化·maven
知了一笑4 小时前
独立开发第二周:构建、执行、规划
java·前端·后端
UI前端开发工作室5 小时前
数字孪生技术为UI前端提供新视角:产品性能的实时模拟与预测
大数据·前端
Sapphire~5 小时前
重学前端004 --- html 表单
前端·html
遇到困难睡大觉哈哈6 小时前
CSS中的Element语法
前端·css
Real_man6 小时前
新物种与新法则:AI重塑开发与产品未来
前端·后端·面试
小彭努力中6 小时前
147.在 Vue3 中使用 OpenLayers 地图上 ECharts 模拟飞机循环飞行
前端·javascript·vue.js·ecmascript·echarts
老马聊技术6 小时前
日历插件-FullCalendar的详细使用
前端·javascript