echarts 实现环形渐变

前言

最近产品在ecahrts官网上找到一个 饼图 想要实现这种从头到尾的渐变交互效果,一开始以为非常简单,echarts应该是提供了类似的配置项,知道做起来才发现,这其中没那么简单。

官网案例分析

官网例子中的渐变并不是echarts提供的配置项实现的,而是通过一张 图片 作为背景实现的渐变,所以一开始想着是先来实现一个渐变的饼图,然后通过多个饼图进行拼接来实现类似指针一样的效果,这样就能够实现自定义这个渐变的颜色,并且也很快就写出来一个demo

认识 Echarts 渐变色

在 echarts 的渐变色中,提供了三种类型,包括线性渐变(linear gradient)、径向渐变(radial gradient)和纹理填充(pattern)。

主要了解了一下 线性渐变 以及 径向渐变 的实现效果,在这之后,也意识到了一个严重的问题:通过echarts提供的颜色填充,貌似没办法实现案例里面这种从头到尾的渐变效果,通过线性渐变能够实现下面这种效果

这种固定方向的渐变,但是并不符合我们的要求,

并且我也上网找了一些饼图渐变的案例,发现都是通过这种线性渐变来实现的,只不过会去计算这个渐变的角度,来实现类似从头到尾的渐变,但是一旦进度的幅度较大,就马上露馅了。

  • 例子

可以看到一旦我调大某一个区域的比例,就会发现最后的实现原理还是线性渐变,只不过动态的计算了角度,这种适合多个比例差不多的饼图,但是一旦有某个块比例过大,就还是会出现样式不够美观

奇思妙想

突然意识到,我们最终的目的是自定义这个圆环的起点和终点的颜色,这并不是非得用echarts提供的渐变功能,图片本身并没有问题,图片最大的限制就在于颜色是定好的,但是我们是不是可以让图片的颜色变成动态生成的?

当然可以!

与似乎,就有了下面的方案,通过 canvas 动态生成渐变背景,在讲这张背景图作为圆环的背景图,这样我们就能够实现自定义圆环的起点颜色和终点颜色了

canvas 生成渐变背景

canvas生成背景这个并不是什么难事,百度一下就能够找到类似的案例,然后丢给ai进行美化一下,修改参数变成自己想要的一个函数,我定义的是能够通过传入起点角度,起点颜色,终点颜色 图片大小 四个参数生成一张 base64 的图片

ts 复制代码
/**
 * 创建圆形渐变图片
 * @param startAngle 起始角度
 * @param startColor 起始颜色
 * @param endColor 结束颜色
 * @param size 大小
 * @returns
 */
export function createCircularGradientImage(startAngle = 0, startColor = '#fff', endColor = 'blue', size = 200) {
  // 创建一个canvas元素
  const canvas = document.createElement('canvas')
  // 设置canvas的宽度
  canvas.width = size
  // 设置canvas的高度
  canvas.height = size
  // 获取2D绘图上下文
  const ctx = canvas.getContext('2d')
  // 检查是否成功获取上下文
  if (!ctx) {
    throw new Error('ctx is null')
  }
  // 创建圆锥渐变
  // 参数:起始角度,圆心x坐标,圆心y坐标
  const gradient = ctx.createConicGradient(startAngle, size / 2, size / 2)
  // 添加渐变的起始颜色
  gradient.addColorStop(0, startColor)
  // 添加渐变的结束颜色
  gradient.addColorStop(1, endColor)
  // 设置填充样式并绘制矩形
  ctx.fillStyle = gradient
  ctx.fillRect(0, 0, size, size)
  // 将canvas转换为base64格式的图片数据
  const res = canvas.toDataURL('image/png')
  // 从DOM中移除canvas元素
  canvas.remove()
  // 返回生成的图片数据
  return res
}

最终我们能够得到一张类似这样的图片

结果

接下来的步骤就简单了,参考官网的案例,我们只不过是替换了图片的来源,这样就能够通过传参获得一个自定义颜色的结果。

js 复制代码
const _panelImageURL = createCircularGradientImage(0, '#E5E5FF', 'red')

最后的效果:

至于文字颜色和阴影颜色,这些都有着很明显的配置项,这里就不做过多的赘述了,本文主要是分享一下通过canvas构造图片来实现渐变的这种思路

如果有大佬有更好的实现渐变的思路欢迎评论区留言!

相关推荐
前端啵啵猪3 分钟前
useCallback 和 useMemo,什么时候用才是有效的?
前端·react.js
星哥说事14 分钟前
跨平台开源笔记神器,用DeepSeek写笔记 , 效率翻倍
前端
喜欢你,还有大家42 分钟前
FTP文件传输服务
linux·运维·服务器·前端
该用户已不存在1 小时前
你没有听说过的7个Windows开发必备工具
前端·windows·后端
Bi1 小时前
Dokploy安装和部署项目流程
运维·前端
普通网友1 小时前
前端安全攻防:XSS, CSRF 等防范与检测
前端·安全·xss
携欢1 小时前
PortSwigger靶场之Reflected XSS into attribute with angle brackets HTML-encoded通关秘籍
前端·xss
小爱同学_1 小时前
React知识:useState和useRef的使用
前端·react.js
再学一点就睡1 小时前
双 Token 认证机制:从原理到实践的完整实现
前端·javascript·后端
wallflower20201 小时前
滑动窗口算法在前端开发中的探索与应用
前端·算法