😲什么!!一个开关要这么花里胡哨??

3,950 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情

前言

前几天我的朋友突然找上我,说他公司产品要他做个很花哨的开关特效,我一想一个开关而已,还能花哨到哪去,无非就是加点动画特效吗,随后我承认我低估了这个产品的脑洞,需求是要一个粉粉嫩嫩的爱心开关,关的时候背景色是白的,打开后要粉色,而且爱心开关按钮是从左心房滚动到右心房(这是我朋友对产品心里话:************ 😄)随后我也是去翻了一下收藏集,找了一个效果给了他,让他自己再根据公司需求进行改动

结构

这里我们利用label标签对开关按钮及爱心的点击触发效果,内部使用一个复选框跟一个svg图标来进行布局

<label class="box">
        <!-- 复选框,有选中状态 -->
        <input type="checkbox">

        <!-- 心形图标 -->
        <svg viewBox="0 0 33 23" fill="pink">
            <path
                d="M23.5,0.5 C28.4705627,0.5 32.5,4.52943725 32.5,9.5 C32.5,16.9484448 21.46672,22.5 16.5,22.5 C11.53328,22.5 0.5,16.9484448 0.5,9.5 C0.5,4.52952206 4.52943725,0.5 9.5,0.5 C12.3277083,0.5 14.8508336,1.80407476 16.5007741,3.84362242 C18.1491664,1.80407476 20.6722917,0.5 23.5,0.5 Z">
            </path>
        </svg>
</label>

svg图标大家可以复制这个或者自己去网上找一个图标也可以,不过如果是网上找的则需要自己去重新计算开关打开和关闭的动画位置

样式

结构有了开始写样式,让开关好看点

  • 初始化
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            /* 解决手机浏览器点击有选框的问题 */
            -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
        }
  • 大盒子居中,盒子样式及移入鼠标样式,svg样式调整
        body {
            /* 常规居中显示,简单背景色 */
            display: flex;
            justify-content: center;
            align-items: center;
            overflow: hidden;
            min-height: 100vh;
            background-color: #f6f6ff;
        }

        .box {
            /* 整个父盒子区域都可以点,是个小手 */
            cursor: pointer;
            /* 过渡动画时间,主要是按下缩小一圈 */
            transition: transform 0.2s;
            position: relative;
        }
        .box input {
            /* 去除默认复选框样式 */
            appearance: none;
            /* 中间滑动圆圈的宽高,简单白色背景 */
            width: 20vmin;
            height: 20vmin;
            border-radius: 50%;
            background-color: #ffffff;
            /* 灰色阴影 */
            box-shadow: 0 0.5vmin 2vmin rgba(0, 0, 0, 0.2);
            /* 鼠标小手 */
            cursor: pointer;
        }
        
        .box svg {
            /* 中间心形图标的宽高,撑开整个开关区域 */
            width: 40vmin;
            height: 30vmin;
            /* background-color: skyblue; */

            /* 中间填充颜色 */
            fill: #ffffff;
            /* 描边颜色,描边头是圆润的 */
            stroke: #d6d6ee;
            stroke-linejoin: round;

        }

  • 开关动画
 @keyframes animate-on {

            /* 动画就是简单的位置变换,要根据情况调整 */
            0% {
                top: 2.5vmin;
                left: 1.5vmin;
            }

            25% {
                top: 5.5vmin;
                left: 5vmin;
            }

            50% {
                top: 7vmin;
                left: 10vmin;
                /* 到正中间时圆大一小圈 */
                transform: scale(1.05);
            }

            75% {
                top: 5.5vmin;
                left: 15vmin;
            }

            100% {
                top: 2.5vmin;
                left: 18.5vmin;
            }
        }

        @keyframes animate-off {

            /* 关闭的动画就是反着来 */
            0% {
                top: 2.5vmin;
                left: 18.5vmin;
            }

            25% {
                top: 5.5vmin;
                left: 15vmin;
            }

            50% {
                top: 7vmin;
                left: 10vmin;
                transform: scale(1.05);
            }

            75% {
                top: 5.5vmin;
                left: 5vmin;
            }

            100% {
                top: 2.5vmin;
                left: 1.5vmin;
            }
        }

细节:开关按钮的小球到中间时要变大一点点,因为爱心之间位置比较大一点,这样滑动起来才好看

完整代码

code.juejin.cn/pen/7173909…

结尾

朋友收到代码后连连道谢,还非要请我周末去吃个烤🐏腰子补补,哎!!盛情难却,勉为其难的去吃吧,声明:我可不是为了那🐏腰子去的啊!主要是人家盛情邀请,咱们没办法拒绝😁。如果代码中有任何错误欢迎大家指正,相互学习相互进步