【如何实现一个简单的canvas动态水球图】
**
如何实现一个简单的canvas动态水球图。
**
由于在项目中遇到有个制作一个水球图需求,在网上查找相关资料比较少,样式又不符合预期,在这样的情况下封装了一个自己可更改、定制化的水球图动效组件。
效果图:
代码如下:
1.封装组件:
<template><div class="sun-waterpolo_conrainer" :style="'box-shadow: 0 0 20px '+lineColor+';width: '+width+'px; height: '+width+'px;'"><span v-show="text">{{text}}</span><span v-show="!text">{{num|rounding}}<span class="unit"> {{unit}}</span></span><div class="sun-canvas_conrainer" :style="'box-shadow: 0 0 5px '+lineColor+' inset;width: '+width+'px; height: '+width+'px;'"><canvas :id="canvasId"></canvas></div></div>
</template><script>
export default {data () {return {oCanvas: null,oContext: null,options: null}},filters: {rounding (value) {if (value === 0) {return '0.00'}if (!value || isNaN(value)) {return '--'}value = Number(value)if (typeof obj === 'number' && value % 1 === 0) {value = value + '.00'} else {value = value.toFixed(2)}return value}},props: {text: {type: [String, Number],default: ''},num: {type: [String, Number],default: '40'},unit: {type: String,default: '%'},canvasId: {type: String,default: 'canvasId_1'},color: {type: String,default: '#01c6df'},lineColor: {type: String,default: '#01c6df'},width: {type: Number,default: 100}},mounted () {this.init()},methods: {init () {this.oCanvas = document.getElementById(this.canvasId)this.context = this.oCanvas.getContext('2d')this.oCanvas.width = this.widththis.oCanvas.height = this.widththis.options = {value: 40,a: this.width / 8, // 振幅pos: [1, this.width * 0.5], // 水球图位置r: this.width / 2 - 1, // 水球图半径color: [this.color, this.color, this.color, this.color]// color: ['#2E5199', '#1567c8', '#1593E7', '#42B8F9']}this.start(this.options)},/*** 绘制图表*/start (options) {this.context.translate(options.pos[0], options.pos[1])this.context.font = 'normal 16px Arial'this.context.textAlign = 'center'this.context.textBaseLine = 'baseline'this.createParams(options)requestAnimationFrame(this.startAnim) // 循环动画},// 生成水波动画参数createParams (options) {options.w = [] // 存储水波的角速度options.theta = [] // 存储每条水波的位移for (let i = 0; i < 4; i++) {options.w.push(Math.PI / (100 + 20 * Math.random()))options.theta.push(20 * Math.random())}},// 绘制水波线drawWaterLines (options) {let offsetlet A = options.a // 正弦曲线振幅let y, x, w, thetalet r = options.r// 遍历每一条水纹理for (let line = 0; line < 4; line++) {this.context.save()// 每次绘制时水波的偏移距离theta = Math.random()offset =r +A / 2 -((r * 19) / 8 + A) * (options.value / 100) +(line * r) / 12// 获取正弦曲线计算参数w = options.w[line]theta = options.theta[line]this.context.fillStyle = options.color[line]this.context.moveTo(0, 0)this.context.beginPath()for (x = 0; x <= 2 * r; x += 0.1) {y = A * Math.sin(w * x + theta) + offset// 绘制点this.context.lineTo(x, y)}// 绘制为封闭图形this.context.lineTo(x, r)this.context.lineTo(x - 2 * r, r)this.context.lineTo(0, A * Math.sin(theta) - options.width)this.context.closePath()// 填充封闭图形this.context.fill()// 截取水波范围,绘制文字this.context.clip()// this.context.fillStyle = '#071C5C'// this.context.fillText(parseInt(options.value, 10) + '%', 1, 1)this.context.restore()}},// 绘制最底层的深色文字drawText1 (options) {this.context.fillStyle = options.color[0]this.context.fillText(parseInt(options.value, 10) + '%', 1, 1)},// 帧动画循环startAnim () {this.options.theta = this.options.theta.map(item => item - 0.03)this.options.value += this.options.value > 100 ? 0 : 0.1this.options.value = this.options.value > 40 ? 40 : this.options.valuethis.context.save()this.resetClip(this.options) // 剪切绘图区// this.drawText1(this.options)// 绘制蓝色文字this.drawWaterLines(this.options) // 绘制水波线this.context.restore()requestAnimationFrame(this.startAnim)},// 重新剪裁绘图区域resetClip (options) {let r = options.rthis.context.strokeStyle = this.lineColorthis.context.fillStyle = '#071C5C'this.context.lineWidth = 1this.context.beginPath()this.context.arc(r, 0, r, 0, 2 * Math.PI, false)this.context.closePath()this.context.fill()this.context.shadowColor = this.lineColorthis.context.shadowBlur = 1this.context.shadowOffsetX = 0this.context.shadowOffsetY = 0this.context.stroke()this.context.beginPath()this.context.arc(r, 0, r + 1, 0, 2 * Math.PI, true)this.context.clip()}}
}
</script>
<style scoped>
.sun-waterpolo_conrainer{border-radius: 50%;position: relative;
}
.sun-canvas_conrainer{display: inline-block;overflow: hidden;border-radius: 50%;position: relative;
}
.sun-waterpolo_conrainer>span{position: absolute;top: 50%;margin-top: -9px;display: inline-block;width: 200%;left: 50%;margin-left: -100%;font-size: 18px;color: #ffffff;text-shadow: 0 3px 3px rgba(0,0,0,1);text-align: center;z-index: 9;
}
.sun-waterpolo_conrainer>span .unit{font-size: 12px;
}
</style>
2.如何引用:
<template><WaterPolo :width="90" :height="90" lineColor="#01c6df" text="40%" canvasId="liquidFill_1" color="rgba(13,245,249,.5)"></WaterPolo><WaterPolo :width="90" :height="90" lineColor="#c2b128" text="40%" canvasId="liquidFill_2" color="rgba(243,214,22,.5)"></WaterPolo>
</template>
<script>import WaterPolo from '@/components/waterpolo/waterpolo'export default {components: {WaterPolo}}
</script>
这样我们就能实现自己喜欢的水球图动画了,冲冲冲!!!。
【如何实现一个简单的canvas动态水球图】相关推荐
- linux平台 一个简单的helloworld动态库的制作与使用
编写一个简单的动态库并调用. 动态库代码: HelloWorld.c /*** 简单动态库文件使用*/ #include "HelloWorld.h"void hello(void ...
- 数字信号 fft c源码_如何制作一个简单的人体动态识别微信小程序(附源码)
知乎小白第一次写专栏,还请多指教. 先放成果. GitHub源码: lrioxh/HAR-applet-of-Wechatgithub.com b站演示视频: 居然不需要服务器?!如何制作一个简单的 ...
- 基于JavaScript+css写一个简单的h5动态下雨效果
基于JavaScript+css写一个简单的h5动态下雨效果 文章目录 什么是前端 展示效果 JavaScript是什么? 步骤 1.html 2.css 3.js 什么是前端 前端它是一个工作,它的 ...
- 制作一个简单的canvas动画
制作一个简单的canvas动画 作者:旺仔 一上来先话不多说上代码,代码能看的懂得,ok,就当我下面所有的内容为废话,代码看的不太懂的,没关系我会一点一点让你懂,不过前提是你有一定的html+css+ ...
- python画动图-Python绘制动态水球图过程详解
先来看看绘制的动态水球图: 没有安装PyEcharts的,先安装PyEcharts: # 安装pyecharts模块,直接安装就是最新的版本pip install pyecharts 安装好PyEch ...
- 可视化 | Python精美动态水球图
文章目录 1. 准备工作 1.1 pyechars安装 1.2 导入模块 2. 绘制水球图 2.1 基本水球图 2.2 增加边框,改变形状 2.3 多波浪 2.4 增加标注,改变字体大小,改变填充颜色 ...
- Android投票列表设计,AndroidCustomView一个简单的投票排名对比图
简介(投票 ,排名对比图) 一个简单的自定义 View 可高度定制 支持设置替换 支持 ,和反对的图标 支持自定义线宽和支持反对线的字体颜色 设置比分值 效果图 字段 属性 OppositeBitma ...
- echarts社区水球图、echart水球图 动态水球图
目录 普通水球图 3/4环形图 4层波浪水球图 普通水球图 var value = 0.45; var value1 = 0.76; var data = [value, value1]; var o ...
- 快速实现一个简单的canvas迷宫游戏
前言 (最近设计模式看的有点头大,一直面对纯js实在是有些枯燥-_-.所以写一点有趣的东西调剂一下) 现在canvas已经不算新鲜了,不过由于日常业务中并不常用,所以实践并不多,今天分享一下,如何实现 ...
最新文章
- LSA 安装及管理应用程序
- JZOJ 5710. 【北大夏令营2018模拟5.13】Mex
- LeetCode 1033. 移动石子直到连续
- Excellent Service
- sql语句为什么大写居多_懂EXCEL就会SQL,从此查数不求人
- 华为腾讯众安微众360大咖齐聚,2019中国区块链开发者大会首批议程曝光!
- Oracle中shrink space命令详解
- Spring MVC @ResponseBody返回中文字符串乱码问题
- 一些常用的css小技巧
- MyCat分片规则之ASCII码取模范围分片
- 斐讯路由器k2p a1刷官改只能刷入k2p_57_v*_*固件无法刷入k2p_mtk_v*_*版本--刷入后无法进入主页面/刷入后无法启动
- 高通900e驱动变9008_技术驱动的治理变得更加聪明
- tp-801bs单板微型计算机,线切割应知应会
- 华为OJ——将真分数分解为埃及分数
- I aced it!我做得很好
- Elasticsearch-head-master配置 (与es连接)
- idea生成文档时:编码GDK的不可映射字符
- 大数据时代下的计算机和互联网
- 与HR斗智斗勇,你必须知道这20条潜规则
- 计算机编程语言用英语怎么说,计算机编程语言(国外英文资料).doc