当前位置: 首页 > news >正文

【样式效果】Vue3实现仿制iOS按钮动态效果

iOS开关效果

PixPin_2025-07-18_14-27-00

定义变量:

<style scoped lang="scss">.layout {// 按钮宽度$button-width: 500px;//  按钮高度$button-height: 250px;//  按钮里面圆形直径$circle-diameter: 200px;//  按钮背景与里面圆形间距$button-circle-offset:calc(($button-height - $circle-diameter) / 2);//  里面圆形阴影大小$circle-shadow-size: 10px;//  里面圆形在长按情况下的宽度$circle-wider-size: 350px;//  浅灰色$light-gray: #e0e0e0;//  深灰色$dark-gray: #616161;//  绿色$green: #4caf50;}
</style>

绘制按钮图形:

<template><div class="layout"><div class="button"></div></div>
</template><style scoped lang="scss">
.layout {// 上面👆定义的变量display: flex;justify-content: center;align-items: center;min-height: 100vh;.button{width: $button-width;height: $button-height;background: $light-gray;border-radius:calc($button-width / 2);}
}
</style>

里面的圆形使用伪类选择器

&:after{content: '';display: block;width: $circle-diameter;height: $circle-diameter;border-radius: $circle-diameter;background-color: #fff;
}

给元素添加上定位让圆形固定到指定位置:

  .button{// ...其他效果;position: relative;&:after{// ...其他效果;position: absolute;top:$button-circle-offset;transform: translateX($button-circle-offset); // 为了后面方便做动画,所以使用translateX
box-shadow:$button-circle-offset 0 calc($circle-shadow-size * 4) $dark-gray ;}}

处理点击效果:

<template>
<div class="layout"><div class="button" @click="clickBtn" :class="{ 'btnClick': isActive }" ></div></div>
</template><script setup lang="ts">import {ref} from "vue";const isActive = ref(false)const clickBtn = () => {isActive.value = !isActive.value}
</script><style scoped lang="scss">.btnClick {background: $green;&:after{transform: translateX( calc( $button-width - $circle-diameter - $button-circle-offset ) );box-shadow: calc( $button-circle-offset * -1 ) 0 calc($circle-shadow-size * 4) $dark-gray ;}}
</style>

加入transition动画:

.button{transition:.3s all ease-in-out;&:after{transition:.3s all ease-in-out;}
}

接下来处理长按效果:

.button{&:active:after{width: $circle-wider-size;}
}
.btnClick {&:active:after{transform: translateX( calc( $button-width - $circle-wider-size - $button-circle-offset ) );}
}

这样按钮效果就实现啦🎉

完整代码:

<template><div class="layout"><div class="button" @click="clickBtn" :class="{ 'btnClick': isActive }" ></div></div>
</template><script setup lang="ts">
import {ref} from "vue";
const isActive = ref(false)const clickBtn = () => {isActive.value = !isActive.value
}
</script><style scoped lang="scss">
.layout {// 按钮宽度$button-width: 500px;//  按钮高度$button-height: 250px;//  按钮里面圆形直径$circle-diameter: 200px;//  按钮背景与里面圆形间距$button-circle-offset:calc(($button-height - $circle-diameter) / 2);//  里面圆形阴影大小$circle-shadow-size: 10px;//  里面圆形在长按情况下的宽度$circle-wider-size: 350px;//  浅灰色$light-gray: #e0e0e0;//  深灰色$dark-gray: rgba(97, 97, 97, 0.34);//  绿色$green: #71d575;display: flex;justify-content: center;align-items: center;min-height: 100vh;.button{width: $button-width;height: $button-height;background: $light-gray;border-radius:calc($button-width / 2);position: relative;transition:.3s all ease-in-out;&:after{content: '';display: block;width: $circle-diameter;height: $circle-diameter;border-radius: $circle-diameter;background-color: #fff;position: absolute;top:$button-circle-offset;transform: translateX($button-circle-offset); // 为了后面方便做动画,所以使用translateXbox-shadow:$button-circle-offset 0 calc($circle-shadow-size * 4) $dark-gray ;transition:.3s all ease-in-out;}&:active:after{width: $circle-wider-size;}}.btnClick {background: $green;&:after{transform: translateX( calc( $button-width - $circle-diameter - $button-circle-offset ) );box-shadow: calc( $button-circle-offset * -1 ) 0 calc($circle-shadow-size * 4) $dark-gray ;}&:active:after{transform: translateX( calc( $button-width - $circle-wider-size - $button-circle-offset ) );}}
}
</style>
http://www.dtcms.com/a/285431.html

相关文章:

  • 基于K8s ingress灰度发布配置
  • 飞书,正在成为中国AI制造故事的新阵地
  • 微信小程序161~170
  • 30、鸿蒙Harmony Next开发:应用文件上传下载,压缩与解压
  • VUE项目学习笔记 v-for绑定数据,该数据异步获取,同时需要对v-for的DOM节点进行js操作
  • 苍穹外卖项目日记(day12)
  • Linux驱动学习day24(UART子系统)
  • AI产品经理面试宝典第36天:AI+旅游以及行业痛点相关面试题的指导
  • Python爬虫实战:研究opengraph库相关技术
  • linux 的list_for_each_entry
  • 【c++】STL-容器 list 的实现
  • 20250718-2-Kubernetes 应用程序生命周期管理-Pod对象:基本概念(豌豆荚)_笔记
  • [AI8051U入门第五步]modbus_RTU主机
  • 怎么把图片做成实拍的感觉?给图片加上拍摄时间,相机信息等就可以了
  • PostgreSQL 16 Administration Cookbook 读书笔记:第7章 Database Administration
  • 如何下载并安装AIGCPanel
  • 设计模式五:桥模式(Bridge Pattern)
  • charles雷电模拟器抓包教程
  • 大数据时代下的时序数据库选型指南:基于工业场景的IoTDB技术优势与适用性研究
  • CCF编程能力等级认证GESP—C++2级—20250628
  • 张力场中的领航者:驾驭二元对立的“情境智慧”模型
  • UVC for USBCamera in Android - 篇二
  • HAL库的串口
  • Vite/Vue 项目 | 开发环境指定Host(允许其它电脑访问)
  • uniapp+vue2——自定义底部导航tabbar
  • STC89C52系列单片机内部结构详解
  • 我用EV-21569-SOM评估来开发ADSP-21569(八)-UART串口例程
  • 基于单片机的点阵式汉字电子显示屏的设计
  • Vue3 业务落地全景:脚手架、权限、国际化、微前端、跨端与低代码 50 条实战心法
  • 基于单片机的便携太阳能光伏系统研究