**

如何实现一个简单的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动态水球图】相关推荐

  1. linux平台 一个简单的helloworld动态库的制作与使用

    编写一个简单的动态库并调用. 动态库代码: HelloWorld.c /*** 简单动态库文件使用*/ #include "HelloWorld.h"void hello(void ...

  2. 数字信号 fft c源码_如何制作一个简单的人体动态识别微信小程序(附源码)

    知乎小白第一次写专栏,还请多指教. 先放成果. GitHub源码: lrioxh/HAR-applet-of-Wechat​github.com b站演示视频: 居然不需要服务器?!如何制作一个简单的 ...

  3. 基于JavaScript+css写一个简单的h5动态下雨效果

    基于JavaScript+css写一个简单的h5动态下雨效果 文章目录 什么是前端 展示效果 JavaScript是什么? 步骤 1.html 2.css 3.js 什么是前端 前端它是一个工作,它的 ...

  4. 制作一个简单的canvas动画

    制作一个简单的canvas动画 作者:旺仔 一上来先话不多说上代码,代码能看的懂得,ok,就当我下面所有的内容为废话,代码看的不太懂的,没关系我会一点一点让你懂,不过前提是你有一定的html+css+ ...

  5. python画动图-Python绘制动态水球图过程详解

    先来看看绘制的动态水球图: 没有安装PyEcharts的,先安装PyEcharts: # 安装pyecharts模块,直接安装就是最新的版本pip install pyecharts 安装好PyEch ...

  6. 可视化 | Python精美动态水球图

    文章目录 1. 准备工作 1.1 pyechars安装 1.2 导入模块 2. 绘制水球图 2.1 基本水球图 2.2 增加边框,改变形状 2.3 多波浪 2.4 增加标注,改变字体大小,改变填充颜色 ...

  7. Android投票列表设计,AndroidCustomView一个简单的投票排名对比图

    简介(投票 ,排名对比图) 一个简单的自定义 View 可高度定制 支持设置替换 支持 ,和反对的图标 支持自定义线宽和支持反对线的字体颜色 设置比分值 效果图 字段 属性 OppositeBitma ...

  8. echarts社区水球图、echart水球图 动态水球图

    目录 普通水球图 3/4环形图 4层波浪水球图 普通水球图 var value = 0.45; var value1 = 0.76; var data = [value, value1]; var o ...

  9. 快速实现一个简单的canvas迷宫游戏

    前言 (最近设计模式看的有点头大,一直面对纯js实在是有些枯燥-_-.所以写一点有趣的东西调剂一下) 现在canvas已经不算新鲜了,不过由于日常业务中并不常用,所以实践并不多,今天分享一下,如何实现 ...

最新文章

  1. LSA 安装及管理应用程序
  2. JZOJ 5710. 【北大夏令营2018模拟5.13】Mex
  3. LeetCode 1033. 移动石子直到连续
  4. Excellent Service
  5. sql语句为什么大写居多_懂EXCEL就会SQL,从此查数不求人
  6. 华为腾讯众安微众360大咖齐聚,2019中国区块链开发者大会首批议程曝光!
  7. Oracle中shrink space命令详解
  8. Spring MVC @ResponseBody返回中文字符串乱码问题
  9. 一些常用的css小技巧
  10. MyCat分片规则之ASCII码取模范围分片
  11. 斐讯路由器k2p a1刷官改只能刷入k2p_57_v*_*固件无法刷入k2p_mtk_v*_*版本--刷入后无法进入主页面/刷入后无法启动
  12. 高通900e驱动变9008_技术驱动的治理变得更加聪明
  13. tp-801bs单板微型计算机,线切割应知应会
  14. 华为OJ——将真分数分解为埃及分数
  15. I aced it!我做得很好
  16. Elasticsearch-head-master配置 (与es连接)
  17. idea生成文档时:编码GDK的不可映射字符
  18. 大数据时代下的计算机和互联网
  19. 与HR斗智斗勇,你必须知道这20条潜规则
  20. 计算机编程语言用英语怎么说,计算机编程语言(国外英文资料).doc

热门文章

  1. 基于物联网的智能浇水系统(STM32+华为云IOT)
  2. 完整java配置以及简单java源代码使用
  3. 网络工程专业毕设题目选题大全
  4. @程序员,你需要点财商
  5. SpringBoot集成JWT(极简版)
  6. php判断闰年函数,PHP判断一个年份是否为闰年
  7. c语言实现4的阶乘,求10000的阶乘(c语言代码实现)
  8. innerText和innerHTML区别 target和this的区别
  9. 2009/8/15应该是一个愉快的夜晚.为林肯公园中国10月演唱会做好准备
  10. robbin谈如何学习设计模式