最近需要用到一个水波球效果的进度展示组件,查阅了一些资料后借鉴了他人的代码,最终完成了需求
主要是通过canvas实现,可以动态设置以下内容:
props
含义
类型
取值范围
default
rate
数值比例
Number
0 ~ 1
0.6
bSize
球的宽高
Number
1 ~ 12
100(单位:px)
waveColor
波浪颜色
String
只能16进制
'#1c86d1'
fontColor
字体颜色
String
16进制 或 RGB
'#8B008B'
fontSize
字体大小
Number
--
26(单位:px)
speed
波浪的速度
Number
1 ~ 12
3
flat
波浪平滑度
Number
200 ~ 600
400
distance
波浪偏移量
Number
0 ~ 200
150
wave
波浪起伏度
Number
5 ~ 60
10
opacity
波浪起伏透明度
Number
200 ~ 600
0.5
代码如下:
<template>
<div
class="content"
:style="{
width: bSize + 'px',
height: bSize + 'px',
borderColor: waveColor,
}"
>
<canvas id="canvas"></canvas>
<p class="value" :style="{ color: fontColor, fontSize:fontSize = 'px' }">{{ rate * 100 }}%</p>
</div>
</template>
<script>
export default {
data() {
return {}
},
props: {
rate: {
type: Number, // 进度 比例 min=0 max=1
default: 0.6,
},
bSize: {
type: Number, // 球的宽高
default: 100,
},
waveColor: {
type: String, // 波浪颜色 只能是16进制
default: '#D8BFD8',
},
fontColor: {
type: String, // 字体颜色
default: '#8B008B',
},
speed: {
type: Number, // 波浪速度 min=1 max=12
default: 3,
},
flat: {
type: Number, // 波浪平滑度 min=200 max=600
default: 400,
},
distance: {
type: Number, // 波浪偏移量 min=0 max=200
default: 150,
},
wave: {
type: Number, // 波浪起伏度 min=5 max=60
default: 10,
},
opacity: {
type: Number, // 波浪起伏透明度 min=5 max=60
default: 0.5,
},
fontSize: {
type:Number, // 字体大小
default:26,
}
},
methods: {
// 曲线函数
drawSin(ctx, mW, color1, color2, wav, dY) {
ctx.save()
ctx.beginPath()
ctx.moveTo(0, mW)
ctx.lineTo(0, dY)
ctx.quadraticCurveTo(mW / 4, dY - wav, mW / 2, dY)
ctx.lineTo(mW / 2, dY)
ctx.quadraticCurveTo((mW * 3) / 4, dY + wav, mW, dY)
ctx.lineTo(mW, mW)
ctx.lineTo(0, mW)
ctx.fillStyle = color1
ctx.fill()
ctx.restore()
},
init() {
var canvas1 = document.getElementById('canvas')
var mW = canvas1.clientWidth
// 设置Canvas元素的高
canvas1.style.height = mW
// 设置Canvas画布的宽高
canvas1.width = canvas1.height = mW
var canvas2 = document.createElement('canvas'),
ctx2 = canvas2.getContext('2d')
canvas2.width = mW
canvas2.height = mW
var canvas3 = document.createElement('canvas'),
ctx3 = canvas3.getContext('2d')
canvas3.width = mW
canvas3.height = mW
var { flat, speed, rate, distance, wave, waveColor, opacity } = this
var x = 0
var ctx1 = canvas1.getContext('2d')
this.drawSin(ctx2, mW, waveColor, waveColor, wave, mW - mW * rate)
this.drawSin(ctx3, mW, `${this.sixteenToRgba(waveColor, opacity)}`, null, wave, mW - mW * rate)
var rate1 = rate,
wave1 = wave
function animation() {
if (rate !== rate1 || wave1 !== wave) {
ctx2.clearRect(0, 0, mW, mW)
ctx3.clearRect(0, 0, mW, mW)
rate1 = rate
wave1 = wave
this.drawSin(ctx2, mW, waveColor, waveColor, wave, mW - mW * rate)
this.drawSin(ctx3, mW, `${this.sixteenToRgba(waveColor, opacity)}`, null, wave, mW - mW * rate)
}
ctx1.clearRect(0, 0, mW, mW)
ctx1.drawImage(canvas2, x, 0, mW + flat, mW)
ctx1.drawImage(canvas2, x - mW - flat, 0, mW + flat, mW)
ctx1.drawImage(canvas3, x + distance, 0, mW + flat, mW)
ctx1.drawImage(canvas3, x - mW + distance - flat, 0, mW + flat, mW)
x >= mW - speed + flat ? (x = 0) : (x += speed)
requestAnimationFrame(animation)
}
animation()
},
// 十六进制颜色转成 rgba 透明度
sixteenToRgba(sixteen, opacity) {
var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
var sColor = sixteen
if (sColor && reg.test(sColor)) {
if (sColor.length === 4) {
var sColorNew = '#'
for (var i = 1; i < 4; i += 1) {
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
}
sColor = sColorNew
}
//处理六位的颜色值
var sColorChange = []
for (var i = 1; i < 7; i += 2) {
sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2)))
}
return 'rgba(' + sColorChange.join(',') + `,${opacity})`
} else {
return sColor
}
},
},
mounted() {
this.init()
},
}
</script>
<style lang='less' scoped>
.content {
position: relative;
border-radius: 50%;
border: 1px solid #1c86d1;
overflow: hidden;
padding: 8px;
box-sizing: border-box;
.value {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
font-size: 24px;
// font-weight: bold;
}
canvas {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
</style>
复制代码
<wave-ball
class="ball"
:rate="0.36"
:bSize="120"
:waveColor="'Thistle'"
:fontColor="'#8B008B'"
:fontSize="28"
></wave-ball>
复制代码
虽然还是很简陋,但希望能帮助到需要的人,也欢迎大佬指点改进~
参考:https://segmentfault.com/a/1190000021043704
原网址: 访问
创建于: 2023-07-28 17:30:01
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论