前言
有需求,就要動手豐衣足食...公司考慮相容IE9,那麼css3 animation
寫的loading就無緣了
因為keyframes
IE10+ , 那麼要實現會動且可控的(顏色,大小),好像就剩下svg
大佬了;
依舊不廢話,看效果圖
- 2017-07-26: 調整了樣式,加入了可控的提示文字
效果圖
先說說實現的思路
- 一個遮罩層,一個顯示loading...通用法則
- svg動效的loading直接git上找,一搜一大堆;(會寫動效svg的小夥伴贊一個,我沒時間研究這個)
- 遮罩層有兩種情況下,一個是全域性
fixed
,一個是相對relative
的absolute
,所以這塊抽離 - svg要可控顏色大小,那麼必須是
svg程式碼
渲染,圖片引入是沒法更改的
你能學到什麼?
props
的欄位限制,預設值computed
的運用- 部分webpack配置的改動
svg
一丟丟知識
大體就這樣了,再來說說爬的坑
svg
可以繼承顏色和大小(css),前提哈,svg
內建程式碼沒有fill(填充的顏色)
,width
,height
,所以要刪除掉那三個屬性, 上碼
// 記得刪除,一般用軟體生成的svg匯出都有帶這些屬性,刪除後預設為黑色
<svg class="icon-loading" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32" fill="red">
<path transform="translate(-8 0)" d="M4 12 A4 4 0 0 0 4 20 A4 4 0 0 0 4 12">
<animateTransform attributeName="transform" type="translate" values="-8 0; 2 0; 2 0;" dur="0.8s" repeatCount="indefinite" begin="0" keytimes="0;.25;1" keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8" calcMode="spline" />
</path>
<path transform="translate(2 0)" d="M4 12 A4 4 0 0 0 4 20 A4 4 0 0 0 4 12">
<animateTransform attributeName="transform" type="translate" values="2 0; 12 0; 12 0;" dur="0.8s" repeatCount="indefinite" begin="0" keytimes="0;.35;1" keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8" calcMode="spline" />
</path>
<path transform="translate(12 0)" d="M4 12 A4 4 0 0 0 4 20 A4 4 0 0 0 4 12">
<animateTransform attributeName="transform" type="translate" values="12 0; 22 0; 22 0;" dur="0.8s" repeatCount="indefinite" begin="0" keytimes="0;.45;1" keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8" calcMode="spline" />
</path>
<path transform="translate(24 0)" d="M4 12 A4 4 0 0 0 4 20 A4 4 0 0 0 4 12">
<animateTransform attributeName="transform" type="translate" values="22 0; 32 0; 32 0;" dur="0.8s" repeatCount="indefinite" begin="0" keytimes="0;.55;1" keySplines="0.2 0.2 0.4 0.8;0.2 0.6 0.4 0.8" calcMode="spline" />
</path>
</svg>複製程式碼
- webpack你若是配置url-loader , 比如
vue-cli
預設的配置寫了會把svg
轉為base64
, 解決方案是拆開,引入一個raw-loader
,可以保證svg
程式碼不會轉化為url或者base64,上碼
{
test: /\.(png|jpe?g|gif)(\?.*)?$/,
loader: "url-loader",
options: {
limit: 10000,
name: utils.assetsPath("img/[name].[hash:7].[ext]")
}
},
{
test: /\.(svg)(\?.*)?$/,
loader: "raw-loader",
}複製程式碼
有什麼特性!
svg
大小,顏色,型別可控- 遮罩層的樣式可控
程式碼
- index.js -- 先把svg預設全部匯出
// 引入所有svg loading
export { default as balls } from "./loading-balls.svg";
export { default as bars } from "./loading-bars.svg";
export { default as bubbles } from "./loading-bubbles.svg";
export { default as cubes } from "./loading-cubes.svg";
export { default as cylong } from "./loading-cylon.svg";
export { default as cylongred } from "./loading-cylon-red.svg";
export { default as spin } from "./loading-spin.svg";
export { default as spinning } from "./loading-spinning-bubbles.svg";
export { default as spokes } from "./loading-spokes.svg";複製程式碼
- loading.vue
<template>
<div class="loading-layout" :style="layoutLoadingStyle">
<div class="loading">
<p v-html="svgShow" :style="svgStyle"></p>
<p class="loadingText" :style="{color:svgColor}" v-if="showText">{{loadingText}}</p>
</div>
</div>
</template>
<script>
// 引入所有svg loading
import * as allsvg from './svg';
export default {
name: 'loading',
data: function () {
return {}
},
props: {
svgType: {
type: String, // 字串型別
default: 'bars' // 預設的loading圖形
},
svgColor: {
type: String,
default: '#20a0ff'
},
svgSize: {
type: Object, // 物件型別
default: function () {
return {
width: '50px',
height: '50px'
}
}
},
showText:{ // 是否顯示loading文字
type: Boolean,
default:false,
},
loadingText: {
type: String,
default: '拼命載入中....'
},
lbgColor: { // loading包裹層的樣式
type: Object,
default: function () {
return {
color: 'rgba(255,255,255,.5)'
}
}
},
lsize: {
type: Object, // 物件型別
default: function () {
return {
width: '100%',
height: '100%'
}
}
},
lpos: {
type: Object,
default: function () {
return { // 遮罩層初始化位置
position: 'absolute',
top: '0',
left: '0'
}
}
}
},
computed: {
svgShow () {
return allsvg[this.svgType];
},
svgStyle () {
return { fill: this.svgColor, width: this.svgSize.width, height: this.svgSize.height }
},
layoutLoadingStyle () {
return {
position: this.lpos.position,
top: this.lpos.top,
left: this.lpos.left,
width: this.lsize.width,
height: this.lsize.height,
'background-color': this.lbgColor.color
}
}
}
}
</script>
<style scoped lang="scss">
.loading-layout {
position: relative;
height: 100%;
width: 100%;
z-index: 2001;
.loading {
position: absolute;
top: 50%;
left: 45%;
transform: translate(-50%, -50%);
text-align: center;
p {
margin: 0 auto;
}
svg {
fill: inherit;
height: inherit;
width: inherit;
}
}
.loadingText {
white-space: nowrap;
}
}
</style>複製程式碼
總結
自此,一個不大靠譜的loading元件就實現了..有更好的方案和實現思路可以往下面留言...
浪裡個浪~~~