在uni-App(Vue)中使用 SVG + JS 自定义动画:模拟关键帧
问题
为什么要使用SVG来制作动画?
SVG是矢量图形,放大不会失真,而且动画看起来很丝滑,能够实现很多平面动画效果,这点是CSS动画比不上的
在Vue中使用SVG有哪些难点?
- 注意载入顺序,应该在mounted() 过程中载入动画,并且记得 在destroyed() 过程之后销毁。
- 注意SVG内的锚点定位问题,将你所需的图形放在合适的位置上,并保证屏幕尺寸改变时不会影响到内部的位置。
示例
在此案例中,我需要制作一个Loading 图标,并在不同的页面中显示,当网络发起请求后,loading 变量会控制此图标的显示与隐藏,为此,我制作了一个可复用的组件来实现此目的:
上传的gif因压缩原因看起来比较卡顿,实际上是非常丝滑的
代码中有我自创的实现关键帧的方式,每隔10ms 计算一次svg内图形的各项属性,并赋值,10ms一帧已经超过动画视觉标准了,如果想减轻设备负载,可以适当调高一点,如果想榨干设备性能,就调快一点。
<template><view><svg height="100%" width="100%" viewBox="-20.654044750430295 -21.996557659208264 1241.3080895008607 1243.9931153184166" x="0" y="0" id="document" class="disable-on-play" fill="transparent"><g id="elements" style="isolation: isolate;"><defs id="dynamic-definitions"><linearGradient id="ellipse-q79an5euegn--stroke" x1="0" y1="0.5" x2="1" y2="0.5" spreadMethod="pad" gradientUnits="objectBoundingBox"><stop id="ellipse-q79an5euegn--stroke-stop-0" offset="0" stop-color="rgb(0,163,255)"></stop><stop id="ellipse-q79an5euegn--stroke-stop-1" offset="1" stop-color="rgb(0,52,232)"></stop></linearGradient><linearGradient id="ellipse-51gfnuexh6c--fill" x1="0" y1="0.5" x2="1" y2="0.5" spreadMethod="pad" gradientUnits="objectBoundingBox"><stop id="ellipse-51gfnuexh6c--fill-stop-0" offset="0" stop-color="rgb(0,163,255)"></stop><stop id="ellipse-51gfnuexh6c--fill-stop-1" offset="1" stop-color="rgb(0,52,232)"></stop></linearGradient><linearGradient id="ellipse-th8rfzjaes--fill" x1="0" y1="0.5" x2="1" y2="0.5" spreadMethod="pad" gradientUnits="objectBoundingBox"><stop id="ellipse-th8rfzjaes--fill-stop-0" offset="0" stop-color="rgb(0,163,255)"></stop><stop id="ellipse-th8rfzjaes--fill-stop-1" offset="1" stop-color="rgb(0,52,232)"></stop></linearGradient></defs><defs id="definitions"></defs><g id="elements-wrapper" width="1200" height="1200"><ellipse ref="outter" id="ellipse-q79an5euegn" rx="500" ry="500" transform="matrix(0 -1 1 0 600 600)" fill="none" stroke="url(#ellipse-q79an5euegn--stroke)" stroke-width="100" stroke-linecap="round" :stroke-dasharray="d1 + ' ' + d2" style="mix-blend-mode: normal; paint-order: fill;" :stroke-dashoffset="strokeDashoffset"></ellipse><ellipse ref="inner" id="ellipse-51gfnuexh6c" rx="928.571429" ry="928.571429" :transform="'matrix(' + sH + ' 0 0 ' + sW + ' 600 600)'" fill="url(#ellipse-51gfnuexh6c--fill)" stroke="none" stroke-width="15" style="mix-blend-mode: normal; paint-order: fill;"></ellipse></g></g><path d="M-20.654044750430295 -21.996557659208264 h1241.3080895008607 v1243.9931153184166 h-1241.3080895008607 z M0 0 h1200 v1200 h-1200 z" fill-rule="evenodd" id="overlay"></path> <!----> <!----><g id="tool-selection"><g></g><g> <!----> <!----></g> <!----></g></svg></view>
</template><script>export default {name:"ts-loading",data() {return {d1:0,d2:3600,strokeDashoffset:0,sH:0,sW:0,timer:null,};},computed:{},mounted() {this.addInterval()},onShow() {},destroyed() {clearInterval(this.timer)this.timer = null},methods:{addInterval(){const that = thisvar t = 0; // 时间var et = 2000; //持续时间var keyframes = [0,1000,2000]var scaleFrames = [0,0.35,0]var stockeOffestFrames = [0,0,-3600]var stockDashes1Frames = [0,3600,3600]var stockDashes2Frames = [3600,3600,3600]var targetScale = 0;var targetstockeOffest = 0;var targetstockDashes1 = 0;var targetstockDashes2 = 3600;this.timer = setInterval(() =>{for (var i = 0; i < keyframes.length; i++) {if(t === keyframes[i]){targetScale = scaleFrames[i + 1]targetstockeOffest = stockeOffestFrames[i + 1]targetstockDashes1 = stockDashes1Frames[i + 1]targetstockDashes2 = stockDashes2Frames[i + 1]break}}that.d1 = that.d1 + (targetstockDashes1 - that.d1 ) / 10that.d2 = that.d2 + (targetstockDashes2 - that.d2) / 10that.strokeDashoffset = that.strokeDashoffset + (targetstockeOffest - that.strokeDashoffset) / 10that.sH = that.sH + (targetScale - that.sH) / 10that.sW = that.sW + (targetScale - that.sW) / 10t += 10if(t >= et){t = 0;that.d1 = 0that.d2 = 3600that.strokeDashoffset = 0that.sH = 0that.sW = 0}},10)}}}
</script><style>.outter{stroke-width: 15;transform-origin: center;transform: rotateZ(-90deg);stroke: linear-gradient(to right,#00a3ff,#0034e8) 1 10;}.inner{transform-origin: center;background-color: linear-gradient(to right,#00a3ff,#0034e8) 1 10;}
</style>
调用方式:
<view style="text-align: center;width: 100%" v-show="loading"><ts-loading style="margin: auto;" class="main-loading" ></ts-loading>
</view>
在uni-App(Vue)中使用 SVG + JS 自定义动画:模拟关键帧相关推荐
- vue中config/index.js:配置的详细理解
当我们需要和后台分离部署的时候,必须配置config/index.js: 用vue-cli 自动构建的目录里面 (环境变量及其基本变量的配置) 1 2 3 4 5 6 7 8 9 10 11 12 ...
- vue中使用 svg图片
vue中使用 svg图片 1.assets 中新建 icons 文件夹:icons文件夹下 svg 是svg图片,index.js,svgo.yml 文件如下: a. index.js import ...
- 在 vue 中使用 SVG 建立图标系统并且使用
首先我们先来学一下 svg 标签的基础知识,参考了阮一峰大神的网络日志,链接:http://www.ruanyifeng.com/blog/2018/08/svg.html SVG 全称是可缩放矢量图 ...
- 在Vue中使用svg格式字体图标
在Vue中使用svg格式字体图标 1.新建一条分支,在新分支上修改,测试无误后合并到开发分支(建议) 2.先安装svg-sprite-loader ( 在打包时 处理svg格式并展示到项目中的过滤器 ...
- 如何在 Vue 中使用 Chart.js - 手把手教你搭可视化数据图表
本文首发:<如何在 Vue 中使用 Chart.js - 手把手教你搭可视化数据图表> 使用 Chart.js 在 Vue 搭建的后台管理工具里添加炫酷的图表,是所有数据展示类后台必备的功 ...
- vue中写svg组件svg图片加载不出来
vue中写svg组件svg图片加载不出来 结构 首先要安装3个插件:svg-sprite-loader,svgo,svgo-loader npm install svg-sprite-loader - ...
- vue中使用raphael.js实现地图绘制
一.效果图 二.在vue中引入raphael.js npm i raphael -S 三.封装一个名为StreetMap的组件,代码如下 1 <template> 2 <div> ...
- Vue 中引用第三方js总结
vue中引用第三方js总结 By:授客 QQ:1033553122 实践环境 win10 Vue 2.9.6 本文以引用jsmind为例,讲解怎么在vue中引用第三方js类库 基础示例 1.把下载好的 ...
- Vue中使用SVG图标的步骤【钢镚核恒】
Vue中使用SVG图标的步骤 简介 svg 可缩放矢量图形(Scalable Vector Graphics) svg 优势:任意缩放,超强显示效果,较小文件,可压缩 svgo 用来压缩svg中无用信 ...
最新文章
- 港媒:AI技术有望助力中国核潜艇升级
- mysql 自动生成mapper_自动生成实体类、Mapper、Mapper.xml文件
- 06 - Object-C ARC机制
- linux运维初级课前实战随机考试题含答案(笔试+上机)
- 21-python-time,random模块的应用
- 基于SPSS的交叉表分析
- Flink Window TOPN: The window can only be ordered in ASCENDING mode.
- macbook pro(m1) 安装JD-GUI
- 博图advanced关于vb自动弹出画面
- 2022年中国国债收益率走势(附一年期、二年期、三年期、七年期、十年期、二十年期、三十年期)[图
- 2021.9.15 每日总结
- 什么是HTML语义化标签?为什么要用H5语义化标签?HTML5语义化标签有哪些
- 微信公众号之测试号管理
- autoHotkey — 连击/双击/重复 按键触发
- 解读游戏“仙股”飞鱼科技年内涨幅超400%的逻辑
- 丢弃 HttpClient 了,这款轻量级框架更强!
- 程序猿必备技能之MySQL高级篇
- 独立个人博客有什么用?建独立博客有何意义?
- Vibosoft PDF Locker(PDF加密工具)v2.2.7官方版
- python推荐书-每一页都是干货,这10本Python新书,我必须推荐给你