loading动效实现

在站上闲逛发现一个非常有意思的loading效果,跟着大佬仿写了一下Vue版本的。

https://blog.csdn.net/tianjian4592/article/details/44538605

在这里插入图片描述
直接放源码

<script setup>
import {ref, defineProps, watch} from "vue";

const props = defineProps({
    isShow: {
        type: Boolean,
        default: false
    },
    leafNum: {
        type: Number,
        default: 5
    }  // 叶子数量
})

const isLoading = ref(false);
const progressNum = ref(0);
let progress;
let leafIntervalArr;  // 保存leaf的定时器

watch(() => props.isShow, () => {
    if (!props.isShow) {
        // 触发关闭loading的时候延迟1.4s关闭,确保动画完整
        progressNum.value = 100;
        clearInterval(progress);
        setTimeout(() => {
            isLoading.value = false;
            progressNum.value = 0;
            // 结束动画后清空定时器
            for (let i = 0; i < leafIntervalArr.length; i++) {
                clearInterval(leafIntervalArr[i]);
            }
        }, 1400)
    } else {
        isLoading.value = true;
        setInterval(() => {
            if (progressNum.value <= 90) {
                progressNum.value += 1;
            }
        }, 300);
        setTimeout(() => {
            randomLeaf();
        }, 1000)
    }
})

function randomLeaf() {
    leafIntervalArr = new Array(props.leafNum);
    for (let i = 0; i < props.leafNum; i++) {
        let leaf = document.createElement('img');
        leaf.className = 'leaf';
        leaf.src = '/src/assets/images/loading/leaf.png';
        leaf.alt = '叶子';
        console.log(document.querySelector('.loading-progress'));
        document.querySelector('.loading-progress').appendChild(leaf);
        // 随机时间 1~5s
        setTimeout(() => {
            let activeLeaf = document.querySelectorAll('.leaf')[i];
            let x = 260, y = 0;
            activeLeaf.style.left = x + "px"; //初始坐标x
            activeLeaf.style.top = y + "px"; //初始坐标y

            leafIntervalArr[i] = setInterval(function () {
                x = x - 5; //运动速度
                y = Math.floor(Math.sin(x / 260 * 2 * Math.PI) * Math.floor(Math.random() * 10)) + Math.floor(Math.random() * 10); //运动的高度
                if (x < 0) x = 260;
                activeLeaf.style.left = x + "px";
                activeLeaf.style.top = y + "px";
                activeLeaf.style.transform = "rotate(" + Math.floor(Math.random() * 360) + "deg)";
            }, 100);
        }, Math.floor(Math.random() * 5000) + 1);
    }
}
</script>

<template>
    <transition>
        <div class="loading-container" v-if="isLoading">
            <div class="loading-text">loading...</div>
            <div class="loading-wrapper">
                <div class="loading-progress">
                    <div class="loading-progress-content" :style="{width: progressNum + '%'}"></div>
                    <!-- 叶子区域 -->
                </div>
                <div class="loading-fan fan-container">
                    <img class="fan" :class="{'fan-close':progressNum === 100}"
                         src="../../assets/images/loading/fan.png" alt="风扇">
                    <img class="max" v-if="progressNum === 100" src="../../assets/images/loading/100.png"
                         alt="100%">
                </div>
            </div>
        </div>
    </transition>
</template>

<style scoped>
.loading-container {
    width: 100vw;
    height: 100vh;
    background-color: #E3B12FD0;
    display: flex;
    justify-content: center;
    align-content: center;
    align-items: center;
    flex-wrap: wrap;
    position: fixed;
    top: 0;
    right: 0;
}

.loading-text {
    width: 100%;
    text-align: center;
    font-size: 20px;
    font-weight: bold;
    color: rgb(255, 168, 0);
    margin-bottom: 20px;
}

.loading-wrapper {
    width: 300px;
    height: 48px;
    background-color: #EED385D2;
    border-radius: 24px;
    position: relative;
    z-index: 9;
}

.loading-progress {
    width: 260px;
    height: 36px;
    background-color: #EED385D2;
    border-top-left-radius: 16px;
    border-bottom-left-radius: 16px;
    margin: 6px 0 6px 6px;
    overflow: hidden;
    position: absolute;
    top: 0;
    left: 0;
}

.loading-progress-content {
    width: 0;
    height: 36px;
    background-color: rgb(255, 168, 0);
    transition: all 0.5s;
    position: relative;
    z-index: 9;
}

.loading-fan {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background-color: rgb(251, 205, 81);
    border: 3px solid rgba(255, 255, 255, 0.6);
    box-sizing: border-box;
    position: absolute;
    top: 0;
    right: 0;
    z-index: 9;
}

.fan {
    width: 36px;
    height: 36px;
    position: absolute;
    top: 3px;
    left: 4px;
    animation: spin 2s infinite linear;
}

.fan-close {
    animation: fanClose 1.3s 1 linear;
    animation-fill-mode: forwards;
}

.max {
    width: 36px;
    height: 36px;
    position: absolute;
    top: 3px;
    left: 3px;
    animation: maxFont 1.3s 1 linear;
    animation-fill-mode: forwards;
}

@keyframes spin {
    from {
        transform: rotate(360deg);
    }
    to {
        transform: rotate(0deg);
    }
}

@keyframes fanClose {
    from {
        transform: rotate(360deg) scale(1);
    }
    to {
        transform: rotate(0deg) scale(0);
    }
}

@keyframes maxFont {
    from {
        transform: scale(0);
    }
    to {
        transform: scale(1);
    }
}
</style>
<style>
.leaf {
    width: 15px;
    height: 15px;
    position: absolute;
    top: 0;
    left: 260px;
    z-index: 5;
    transition: all 0.01s;
}
</style>

核心思想:

  1. css动画旋转风扇,根据时间慢慢增加进度条的宽度。
  2. 生成最大数量的叶子,随机事件、随机振幅、随机旋转角度从右向左沿正弦曲线运动

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/141445.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis 连接不上 WRONGPASS invalid username-password pair

1.我的RedisDesktopManager 可以连接 但是 Springboot远程使用Redis就是连不上 2.我的密码是 abc123.. 多了英文的 ..符号 在Springboot过不了&#xff0c;所以Redis密码尽量字母数字&#xff0c;不要其他符号

打开Outlook报错修复

打开Outlook报错修复 故障现象 打开outlook提示&#xff0c;outlook.exe --系统错误 故障截图 故障原因 原因是软连接指向错误重建即可。 解决方案 下载并运行下面批处理解决 del /F /Q "C:\Program Files\Microsoft Office\root\Office16\AppvIsvStream64.dll"…

Vue 的h()

在你的示例中&#xff0c;h(div, { id: foo }, hello) 使用的是 Vue.js 中的虚拟DOM(hyperscript)的写法&#xff0c;这种写法用于创建虚拟节点。让我来详细解释一下&#xff1a; h 是一个用于创建虚拟节点的函数&#xff0c;通常是由 Vue.js 或其他类似的库提供的。这个函数通…

原生JS实现视频截图

视频截图效果预览 利用Canvas进行截图 要用原生js实现视频截图&#xff0c;可以利用canvas的绘图功能 ctx.drawImage&#xff0c;只需要获取到视频标签&#xff0c;就可以通过drawImage把视频当前帧图像绘制在canvas画布上。 const video document.querySelector(video) con…

[Android]新建项目使用AppCompatActivity后运行闪退

报错 日志&#xff1a; Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity. FATAL EXCEPTION: main Process: com.example.gatestdemol, PID: 26071 java.lang.RuntimeException: Unable to start a…

文心一言 VS 讯飞星火 VS chatgpt (134)-- 算法导论11.2 6题

六、用go语言&#xff0c;假设将n 个关键字存储到一个大小为 m 且通过链接法解决冲突的散列表中&#xff0c;同时已知每条链的长度&#xff0c;包括其中最长链的长度 L&#xff0c;请描述从散列表的所有关键字中均匀随机地选择某一元素并在 O(L(11/a))的期望时间内返回该关键字…

邻里注意Transformer(CVPR2023)

Neighborhood Attention Transformer 摘要1、介绍2、相关工作2.1 新的卷积基线 3、方法3.1 邻居注意力3.2 Tiled NA and NATTEN3.3 邻居注意力Transformer 4、结论 代码 摘要 我们提出邻居注意力(NA)&#xff0c;第一个有效和可伸缩的滑动窗口的视觉注意机制。 NA是一种像素级…

链表题(3)

链表题 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 本篇内容继续给大家带来链表的一些练习题 链表分割 知识点&#xff1a; 编程基础 链表…

北京智达鑫业信息咨询有限公司专业的信息技术服务领域资质认证解决方案供应商

北京智达鑫业信息咨询有限公司成立于2014年1月8日&#xff0c;注册资本为500万元人民币.公司主要致力于信息化项目的资质咨询、指导、和培训服务&#xff0c;以及为互联网技术领域服务的企业。主要业务有&#xff1a;&#xff08;CS&#xff09;信息系统建设和服务能力评估、&a…

vue 数字软键盘 插件 封装 可拖动

1、效果图 2、使用方式 <Keyboard v-if"show" close"show false" :inputDom"$refs.input" /> 封装的数字键盘 Keyboard.vue 组件代码 <template><divclass"keyboard"ref"keyboard":style"{ left: …

《QT从基础到进阶·二十四》按钮组QButtonGroup,单选框QRadioButton和多选框QCheckBox

1、按钮组QButtonGroup 如果有多个单选按钮&#xff0c;可以统一放进一个按钮组。 图中有三个单选按钮放进了一个QGroupBox,并且设置了水平布局&#xff0c;现在要将这三个单选按钮放进一个按钮组&#xff0c;之前的想法是先把三个按钮加入按钮组&#xff0c;再把按钮组放进QG…

图的表示与基础--Java

1.图的基础知识 该图片来自于&#xff1a; https://b23.tv/KHCF2m6 2.稀疏图与稠密图 G(V,E)&#xff1a;V顶点个数&#xff0c;E边的个数 稀疏图&#xff1a;E<<V 一般用邻接表表示(数组链表) 稠密图&#xff1a;E接近V 一般用邻接矩阵表示&#xf…

S32K3基础学习 linker链接器脚本ld文件的学习(一)

一、简介 最近学习NXP新推出的S32K3系列芯片&#xff0c;我在学习容易转牛角尖&#xff0c;非得要搞明白这个芯片的启动流程&#xff0c;所以花费了一些时间&#xff0c;进行查阅资料进行学习&#xff0c;这里做下详细的记录&#xff0c;希望有用&#xff0c;如果有错误欢迎指正…

海上船舶交通事故VR模拟体验低成本高效率-深圳华锐视点

在海上运输行业&#xff0c;安全事故的防范和应对能力是企业安全教育的重中之重。针对这一问题&#xff0c;海上运输事故VR模拟逃生演练成为了一种创新且高效的教育手段。通过这种演练&#xff0c;企业能够在提升员工安全意识和技能方面获得多方面的帮助。 在VR船舶搜救演练中&…

第十五章,输入输出流例题

package 例题;import java.io.File;public class 例题1 {public static void main(String[] args) {//创建文件对象File file new File("D:\\Java15-1.docx");//判断&#xff0c;如果该文件存在。exists存在的意思if (file.exists()) {//删除//file.delete();//Syst…

轻量封装WebGPU渲染系统示例<28>- MRT纹理(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/MRT.ts 当前示例运行效果: 此示例基于此渲染系统实现&#xff0c;当前示例TypeScript源码如下: export class MRT {private mRscene new RendererScene();initial…

拼多多商品详情API接口接入流程如下:

拼多多商品详情API接口可以用于获取拼多多商品的具体信息&#xff0c;包括商品ID、商品名称、价格、销量、评价等。以下是使用拼多多商品详情API接口的步骤&#xff1a; 进入拼多多开放平台&#xff0c;注册并登录账号。在开放平台页面中&#xff0c;找到“商品详情”或“商品…

DDD领域驱动设计模式结构图面向接口编程

DDD领域驱动设计模式结构图面向接口编程 9.资源库 在刚接触资源库(Repository)时&#xff0c;第一反应便是这就是个 DAO 层&#xff0c;访问数据库&#xff0c;然后吧啦吧啦&#xff0c;但是&#xff0c;当接触的越久&#xff0c;越发认识到第一反应是错的&#xff0c;资源库更…

No194.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

azkaban的安装

一、下载上传文件 二、创建目录 mkdir /opt/soft/azkaban 三、解压 tar -zxvf /opt/install/azkaban-db-3.84.4.tar.gz -C /opt/soft/azkaban tar -zxvf /opt/install/azkaban-exec-server-3.84.4.tar.gz -C /opt/soft/azkaban tar -zxvf /opt/install/azkaban-web-server-…