其他分享
首页 > 其他分享> > b站三连特效

b站三连特效

作者:互联网

index.html

<!DOCTYPE html>
<html lang="zh-Hans">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>分享课</title>
    <link rel="stylesheet" href="iconfont.css">
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <div class="channel">
         分享课
    </div>
    <div class="container">
        <div class="icon">
            <i class="iconfont icon-dianzan"></i>
            <div class="shine">
                <!-- 这里是放射用的线段 -->
                <span style="--i:1"></span>
                <span style="--i:2"></span>
                <span style="--i:3"></span>
                <span style="--i:4"></span>
                <span style="--i:5"></span>
                <span style="--i:6"></span>
                <span style="--i:7"></span>
                <span style="--i:8"></span>
                <span style="--i:9"></span>
                <span style="--i:10"></span>
                <span style="--i:11"></span>
                <span style="--i:12"></span>
                <span style="--i:13"></span>
                <span style="--i:14"></span>
                <span style="--i:15"></span>
                <span style="--i:16"></span>
            </div>
        </div>
        <div class="icon">
            <i class="iconfont icon-toubi"></i>
            <div class="shine">
                <span style="--i:1"></span>
                <span style="--i:2"></span>
                <span style="--i:3"></span>
                <span style="--i:4"></span>
                <span style="--i:5"></span>
                <span style="--i:6"></span>
                <span style="--i:7"></span>
                <span style="--i:8"></span>
                <span style="--i:9"></span>
                <span style="--i:10"></span>
                <span style="--i:11"></span>
                <span style="--i:12"></span>
                <span style="--i:13"></span>
                <span style="--i:14"></span>
                <span style="--i:15"></span>
                <span style="--i:16"></span>
            </div>
        </div>
        <div class="icon">
            <i class="iconfont icon-shoucang"></i>
            <div class="shine">
                <span style="--i:1"></span>
                <span style="--i:2"></span>
                <span style="--i:3"></span>
                <span style="--i:4"></span>
                <span style="--i:5"></span>
                <span style="--i:6"></span>
                <span style="--i:7"></span>
                <span style="--i:8"></span>
                <span style="--i:9"></span>
                <span style="--i:10"></span>
                <span style="--i:11"></span>
                <span style="--i:12"></span>
                <span style="--i:13"></span>
                <span style="--i:14"></span>
                <span style="--i:15"></span>
                <span style="--i:16"></span>
            </div>
        </div>
    </div>

    <script>
        // 开始写js脚本代码

        // 定义两个计时器,分别控制按住过程中,另一个控制按住超过3秒钟
        let timer_start = null;
        let timer_end = null;

        // 是否长按
        let is_long = true;
        // 鼠标按下的时间,统计计算鼠标弹起时的时间差来判断时长安还是点击
        let mouse_down_start_time = 0;
        // 鼠标弹起时的时间
        let mouse_up_end_time = 0;

        // 找到所有的icon
        let icons = document.querySelectorAll('.icon');

        // 增加绑定事件
        icons.forEach((icon, index) => {
            // 增加点击事件
            icon.addEventListener('click', () => {
                // 点击时增加样式点亮
                // 这里我们切换样式
                if (index == 0) {
                    // 第一个图标时不是长按时才会点亮
                    // 快速点击有效,长按失效
                    if (!is_long) {
                        icon.classList.toggle('light');
                    }
                } else {
                    icon.classList.toggle('light');
                }
            });
        })

        // 第一个图标增加按下事件
        icons[0].addEventListener('mousedown', () => {
            // 在这里我们需要控制一下放置于鼠标点击事件冲突
            mouse_down_start_time = new Date().getTime();

            // 鼠标按下 触发第一个计时器.5s后执行
            timer_start = setTimeout(() => {
                // 增加样式
                icons.forEach((icon, index) => {
                    // 第一个不同
                    // 第一个增加抖动样式
                    // 其他增加加载样式
                    if (index == 0) {
                        icon.classList.add('shake');
                    } else {
                        icon.classList.add('loading');
                    }
                });

            }, 500);

            // 移除加载样式增加爆炸和点亮样式
            // 这里延迟3.5s等待加载动画完成
            timer_end = setTimeout(() => {
                icons.forEach((icon, index) => {
                    // 样式移除
                    icon.classList.remove('shake');
                    icon.classList.remove('loading');
                    // 增加爆炸效果和完成之后的点亮
                    icon.classList.add('bang');
                    icon.classList.add("light");
                });

                // 在增加一个计时器,让bang动画执行完成时清理掉样式
                setTimeout(() => {
                    icons.forEach((icon, index) => {
                        icon.classList.remove('bang');
                    });
                }, 1000);


            }, 3500);


        });
        // 第一个图标增加弹起事件
        icons[0].addEventListener('mouseup', () => {
            // 在这里我们需要控制一下放置于鼠标点击事件冲突
            mouse_up_end_time = new Date().getTime();
            // 时间差超过300毫秒则为长按
            if (mouse_up_end_time - mouse_down_start_time > 300) {
                is_long = true;
            } else {
                is_long = false;
            }

            //基本样式有了,我们需要通过判断时长,让没有完成3s以上的加载不触发完成和放射效果
            if (timer_start) {
                clearTimeout(timer_start);
            }
            // 先把样式移除,然后把计时器取消
            // 300-3500毫秒之间时需要结束加载动画,然后取消掉完成样式计时器的
            if (mouse_up_end_time - mouse_down_start_time < 3500) {
                icons.forEach((icon, index) => {
                    icon.classList.remove('shake');
                    icon.classList.remove('loading');
                });

                if (timer_end) {
                    clearTimeout(timer_end);
                    timer_end = null;
                }
            }
        });


    </script>
</body>

</html>

  style.css

:root {
    --background-color: #f5f5f5;
    --border-color    : #7591AD;
    --text-color      : #34495e;
    --color1          : #EC3E27;
    --color2          : #fd79a8;
    --color3          : #0984e3;
    --color4          : #00b894;
    --color5          : #fdcb6e;
    --color6          : #e056fd;
    --color7          : #F97F51;
    --color8          : #BDC581;
}

* {
    margin : 0;
    padding: 0;
}

html {
    font-size: 14px;
}

body {
    width           : 100vw;
    height          : 100vh;
    background-color: var(--background-color);
    display         : flex;
    justify-content : center;
    align-items     : center;
    font-family     : 'Montserrat', sans-serif, Arial, 'Microsoft Yahei';
}

.channel {
    position   : absolute;
    width      : 80%;
    text-align : center;
    top        : 50%;
    left       : 50%;
    transform  : translate(-50%, -200px);
    font-size  : 30px;
    font-weight: bold;
    color      : #fff;
}

/* 样式部分开始 */
.container {
    width              : 400px;
    height             : 200px;
    /* background-color: rosybrown; */

    /* 布局 */
    display        : flex;
    justify-content: space-around;
    align-items    : center;
}

.icon {
    position           : relative;
    width              : 70px;
    height             : 70px;
    color              : var(--border-color);
    /* background-color: #0984e3; */
    /* 居中 */
    display            : flex;
    justify-content    : center;
    align-items        : center;

    /* 鼠标 */
    cursor: pointer;

}

.icon i {
    font-size: 50px;
}

/* 鼠标移入的效果 */
.icon:hover {
    color: var(--color4);
}

/* 
点亮之后的样式 
稍后使用js控制
*/
.icon.light {
    color: var(--color3);
}

/* 按住点赞按钮抖动的效果 */
.icon.shake {

    animation: shake 0.3s linear infinite;

}

@keyframes shake {
    0% {
        transform: translate(-5%, -5%)
    }

    25% {
        transform: translate(5%, 5%)
    }

    50% {
        transform: translate(-5%, 5%)
    }

    75% {
        transform: translate(5%, -5%)
    }

    100% {
        transform: translate(0%, 0%)
    }
}

/* 按住后 投币和收藏的圆形加载进度 */
/* 我们之前做过了,这里我们再写一遍 */
/* 后期我们用js控制icon增加loading样式 */
.icon.loading::after {
    position           : absolute;
    content            : '';
    box-sizing         : border-box;
    left               : 0;
    top                : 0;
    width              : 70px;
    height             : 70px;
    /* background-color: #0984e311; */
    /* 增加圆角 */
    border-radius      : 50%;
    border             : 2px solid #EC3E27;
    transform          : rotate(45deg);
    /* 这里我们实用贝塞尔曲线函数让动画加载更流畅 */
    /* 只需要执行1次为了让最后现实的跳转更清晰,时间用2.9s */
    animation          : loading 2.9s cubic-bezier(.25, .45, .75, .55) 1;
}

/* 加载动画 还是实用clip-path实现 */

@keyframes loading {

    0% {
        clip-path: polygon(0% 0%,
                0% 0%,
                0% 0%,
                0% 0%,
                0% 0%,
                50% 50%);
    }

    25% {
        clip-path: polygon(0% 0%,
                100% 0%,
                100% 0%,
                100% 0%,
                100% 0%,
                50% 50%);
    }

    50% {
        clip-path: polygon(0% 0%,
                100% 0%,
                100% 100%,
                100% 100%,
                100% 100%,
                50% 50%);
    }

    75% {
        clip-path: polygon(0% 0%,
                100% 0%,
                100% 100%,
                0% 100%,
                0% 100%,
                50% 50%);
    }

    90% {
        /* 从90%开始逐渐隐藏 */
        opacity: 1;
    }

    100% {
        clip-path: polygon(0% 0%,
                100% 0%,
                100% 100%,
                0% 100%,
                0% 0%,
                50% 50%);
        opacity: 0;
    }

}


/* 爆炸放射线效果 */
/* 之前也做过了 */
.icon.bang {
    /* 这样就好了,我们再试一下 */
    animation:  grow 0.3s linear 1;
}

/* 这里我们忘记写了一个动画 */
/* 点击结束的时候会有一个放大缩小的动画效果 */

@keyframes grow{
    0%{
        transform: scale(0.8);
    }
    100%{
        transform: scale(1.2);
    }
}


.icon.bang .shine {
    position: absolute;
    top     : 0;
    top     : 0;
    width   : 70px;
    height  : 70px;
    z-index : 20;

    /* 居中 */
    display        : flex;
    justify-content: center;
    align-items    : center;
}

/* 我们把圆环应用到.shine::after上 */
.icon.bang .shine::after {
    position              : absolute;
    content               : '';
    box-sizing            : border-box;
    /* 用这种方式居中,方便放大 */
    left                  : 50%;
    top                   : 50%;
    transform             : translate(-50%, -50%);
    /* width              : 30px;
    height                : 30px; */
    border-radius         : 50%;
    /* background-color   : #00b894; */

    animation: ray_border 0.4s linear 1 both;
}

/* 在放射的同时还有一个圆环放大效果 */
/* 变化时间与上面的放射同步 */
@keyframes ray_border {
    0% {
        width  : 20px;
        height : 20px;
        border : 2px solid var(--color3);
        opacity: .1;
    }

    60% {
        width  : 100px;
        height : 100px;
        border : 20px solid var(--color3);
        opacity: .1;
    }

    100% {
        width  : 120px;
        height : 120px;
        border : 2px solid var(--color3);
        opacity: 0;
    }
}

/* 这是射线 */
.icon.bang .shine span {

    position           : absolute;
    display            : block;
    width              : 5px;
    /* 高度在动画中定义 */
    /* height          : 100px; */
    /* 增加个圆角 */
    border-radius      : 50%;
    background-color   : var(--color3);
    transform          : rotate(calc(var(--i) * 22.5deg)) translateY(0px);
}

/* 射线奇数偶数的长度和变化不一样,我们分开定义 */
.icon.bang .shine span:nth-child(even) {
    height   : 15px;
    animation: ray_even 0.6s ease 1 both;

}

.icon.bang .shine span:nth-child(odd) {
    height   : 8px;
    animation: ray_odd 0.6s ease 1 both;
}

/* 奇偶动画定义 */

/* 从中心放射向外并边长,直行到60%,开始变短,并清晰度变为0 */

@keyframes ray_even {
    0% {
        transform: rotate(calc(var(--i) * 22.5deg)) translateY(0px);
    }

    60% {
        opacity: 0.8;
        height : 15px;
    }

    100% {
        transform: rotate(calc(var(--i) * 22.5deg)) translateY(60px);
        height   : 5px;
        opacity  : 0;
    }
}

@keyframes ray_odd {
    0% {
        transform: rotate(calc(var(--i) * 22.5deg)) translateY(0px);
    }

    60% {
        opacity: 0.8;
        height : 8px;
    }

    100% {
        transform: rotate(calc(var(--i) * 22.5deg)) translateY(65px);
        height   : 8px;
        opacity  : 0;
    }
}

iconfont.css

@font-face {
  font-family: "iconfont";
  src        : url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAPkAAsAAAAAB9QAAAOYAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDHAqDFIJ8ATYCJAMQCwoABCAFhG0HRBvqBsgekkRJFFSCBAooiYgRgudff+p9kmwr3yHgMSkjTYA89nREgHn9yxTglAI6soDy/zn/5XLlWk/2NHmz907dmsDU4j7PNXUpnt/O5lRJ0VRNjUd7AxxF64C6sdIGvAnjhrErL2I7BHCIJxepUau0FnhiMPoJIAP6sl3AM6XF1MQKFsFdMtUgS3Bh1Vx1Bljs/15eUywWFC6NMbRJL2UvkDzj2Sw95f8UOrgUxOOZATYLNJALGJA+pdZuuISBXDSO0tqVcsBiUTBWXcyzsf//kWQvKmv+5YFC0CBujGhfAEpRUMMzbAIKnsUQEHg2KwoN8EJ6W8ADTASwHzFjTywYVFq0BDv5x1qnwutr94/uXBvTUL+4dt2ujIaGtV3zd0TV1R3sWLM6tLZuxTnr/LBzfy308HbozU2oWnPS67ftuly/Hrr2JFTE39m8PKxpZUuEz7ZV4S4rt2abjr9ypfbq1brr1xumXjNe2dZq6Vor5a2XXmnRwrth6fXW4i1+OCy72rLlb3bA8/Pshd6enOPL2Oz7+yvOzNi4Lfknudf5kMdpnzu9z3uSFHRsf9rZzSuz3uMePP1T1PTxXdFX05izS9PWmbxyy8YbyX/Cey4kl7qLX6J3BfMrimDs4qrLJe45bEXgcAwHPqJ+BQIJn+F+l5cvXbB8HxVAYfzmfS0qFumIxYqqWI92qamdaiJa5a3VKCuykUd1kUf3yOqRgf68UZ6cN8KrGeal9fQwwwGA/+kTOttn04d13dB6rU76g91o8bXedAQI/jy9l5Bze2LLQ2T/z9Be/BvEivh/iVumGVVq6IyRZbZIsxnyE/1QgIMD/KUIBHNvDE1Y62gQLGExFB7ioLGkUg0zFy68lMKNpRIOOdSe7SWEYbggxgfIZiaAEMg+KPw5Dk0gZ6mGeRcuwnkLN4Gi4dBKQpb0ki59Hfkw1EVRL+wehMYebGMsA/UOYqsR67B0kaTUZ9UjYje6YU5+YTasRjZExhhh72NzKWUgQ7AVqsBuyGLBkCPYhHpopoFSjpdV0KvsSpk92Aq8qQ4B0QUF0QukG4NA+tIDxgbjZqd4575fDYLFgYUuSA2pwl8PgmDH2DikiHwKW1DVKlsr0rXsM5w+WHIZAYUB0gsCxgqkFjAjLGYAAxlS3skEogdKJn16+Dh4FKBMvdqqMufXWJ9wCeBgLGlEiRYjLuzwPtjR02VjPXr7uvIhK8WNDnZ0GwEA') format('woff2');
}

/* 
提前准备好的字体图标 
from:http://www.iconfont.cn/
*/

.iconfont {
  font-family            : "iconfont" !important;
  font-size              : 16px;
  font-style             : normal;
  -webkit-font-smoothing : antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* 分别是点赞、投币、收藏 */
.icon-shoucang:before {
  content: "\e61b";
}

.icon-dianzan:before {
  content: "\e600";
}

.icon-toubi:before {
  content: "\e686";
}

 

标签:特效,--,100%,50%,height,0%,icon
来源: https://www.cnblogs.com/blinker/p/16247845.html