当前位置: 首页 > news >正文

uniapp微信小程序 canvas绘制圆形半透明阴影 createCircularGradient函数不支持透明度部分解决方案

背景

我需要在微信小程序中,用canvas绘制一个圆形钟表,在ui设计图中,有一部分阴影,这里我节选一下:
图1
即深色发黑的部分

canvas通用阴影绘制

由于canvas中并不支持css那样简单的方式为圆形添加阴影或高光,于是我有了如下想法:

在下面绘制另一个带有黑色渐变效果的圆,在上面绘制原来的圆,这样圆看起来就有了影子,也就是单独给他画个影子出来

参见这篇BootWiki内容:微信小程序API gradient(如何绘制渐变效果)

以下是他提供的demo,由于背景色为白色,看不出来问题

在这里插入图片描述

这里借用他的图片,表达一下我们的想法:

在这里插入图片描述
这是不看起来就有影子了!
有了思路,这里我们付诸实践,代码大致如下

//阴影绘制 version1
const grdD = ctx.createCircularGradient(x坐标+5, y坐标+5,半径)  // 与原图形适当错开grdD.addColorStop(0, 'rgba(0,0,0,255)')  // 渐变起始值为纯黑不透明grdD.addColorStop(1, 'rgba(0)') // 渐变终点为纯黑纯透明ctx.setFillStyle(grdD) //固定用法ctx.fillRect(0, 0, canvasLength, canvasLength)//绘制范围,这里取了全图,后面会改

实际使用上效果不佳,根据实际绘制,诸君按需调整参数。温馨提示:addColorStop()函数可以添加多个。
我就因为阴影效果不理想,调整了addColorStop() 函数,如下

//阴影绘制 version2
const grdD = ctx.createCircularGradient(x坐标+5, y坐标+5,半径)  grdD.addColorStop(0, 'rgba(0,0,0,255)')  grdD.addColorStop(0.8, 'rgba(0,0,0,255)') // 在此处添加一个渐变节点grdD.addColorStop(1, 'rgba(0)') ctx.setFillStyle(grdD) ctx.fillRect(0, 0, canvasLength, canvasLength)

调整后的效果图
在这里插入图片描述
可以看到,我们实际上修改了渐变起始的位置,通过这种方式使边缘的色彩更加浓郁。避免直接渐变导致的外圈颜色过于浅淡。

但不能在微信小程序这样画

在使用官方 devtool 开发的时候,电脑端模拟器是完全支持这种形式的,但真机运行没有任何效果。(2024年8月6日)
经过我控制变量的测试,我发现这是因为真机小程序是不支持 rgba()形式定义颜色的。甚至也不支持 #000000FF 这种形式
在这里插入图片描述
而如果你使用 #000000FF 形式定义透明度,devtool 会直接报错,可是 rgba() 形式定义的颜色则是一个能运行,一个没效果。

尝试在微信端巧妙绘制

我们迎难而上,找了半天,没找到方案,于是决定不使用透明度。如果我直接使用当前底色作为渐变的终点色呢?
在这里插入图片描述
如图:白色底色实现参照组
我们不再使用 fillRect() 函数全图绘制,而是指定一个范围,并使用底色作为渐变终点,黑色作为渐变起点绘制阴影。
在这里插入图片描述
实现效果大致如此,此图为夸张表现
可以见得如果绘制的内容足够简单(没有背景色,或者背景色为纯色),那么只要梳理好绘制顺序,看到这里就够了。

但显然这种大开大合,外面套一个大正方形的绘制形式,实际应用场景有限。

最终方案

方案1(简单场景可用,即起始色为黑色画阴影的情况,或其他较深颜色):

这个方案其实可以放在前面说,因为真的简单,只需要将之前代码,渐变终点的颜色设置为 transparent 就可以了

grd.addColorStop(0, 'green')
grd.addColorStop(0.8, 'green')
grd.addColorStop(1, 'transparent') // 透明作为渐变终点

在这里插入图片描述

方案2(不完美,聊胜于无):

但说实话彩色的并不常见,常见的还是绘制黑色和白色,作为阴影或者高光使用。
但方案1不支持白色,为什么?请看图👇
在这里插入图片描述

//上图代码如下
grd.addColorStop(0, 'white')
grd.addColorStop(0.5, 'white')
grd.addColorStop(1, 'transparent')

怎么说呢,我就觉得这效果挺抽象的。。。

你说,能不能是这玩意对white的支持有问题,那么我写 #FFFFFF 行不行,或者近似颜色 #FFFFF0 呢?

能想到这一层我只能说真是个小机灵鬼,但没用,我试过了

grd.addColorStop(0, '#fefefe')
grd.addColorStop(0.8, '#dedede')//这两种颜色我分别试过了,这里放在一张图展示
grd.addColorStop(1, 'transparent')

在这里插入图片描述
后经测试,当白色程度超过约 #888888 的情况下,就会出现黑边问题,如图使用 #FFFF88较为明显
在这里插入图片描述
经查询,我发觉问题是: transparent 指代的是 rgba(0,0,0,0) 的值,也就是完全透明的黑色。但我们需要的是完全透明的白色。所以浅色下才会有一个同时向黑色和透明色过度的过程。暂时来看似乎没办法解决。

能切图还是切图!!!不要在这个功能上再浪费时间了!!!
这里给出一个凑合用的替代方案,即绘制半透明白色圆。半透明代码如下:

// 直接画个半透明白色圆替代
ctx.beginPath();
ctx.globalAlpha = 0.5 //调整全局画笔透明度
ctx.setStrokeStyle("white")
ctx.arc(outsideX, outsideY, outsideR, 0 * deg, 360 * deg)
ctx.setFillStyle("white")
ctx.fill()
ctx.stroke()
ctx.globalAlpha = 1//别忘了改回去

你也可以叠加多个半透明圆,但我还是建议你切图。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 100道C/C++面试题
  • mysql8.4.2数据库做主从复制
  • 【Python基础】Python六种标准数据类型中哪些是可变数据,哪些是不可变数据
  • SQL Zoo 9-.Window functions
  • linux证书生成详解
  • 堆的实现(偷懒版)
  • DVWA DOM Based Cross Site Scripting (DOM型 XSS)
  • 第三方jar自带logback导致本地日志文件不生成
  • 前端(HTML + CSS)小兔鲜儿项目(仿)
  • CSS3下拉菜单实现
  • windows 版本Jenkins的Jenkinsfile中共享变量
  • 数据结构--第七天
  • 【AI绘图】基于Midjourney开发的AI绘画平台,对中文很友好!
  • Ubuntu文件操作(压缩与解压缩、用户组管理、权限)
  • 鸿蒙应用服务开发【华为支付服务】客户端
  • 「译」Node.js Streams 基础
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • Android系统模拟器绘制实现概述
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • CSS 三角实现
  • JavaScript 基本功--面试宝典
  • laravel with 查询列表限制条数
  • laravel 用artisan创建自己的模板
  • OSS Web直传 (文件图片)
  • Python 基础起步 (十) 什么叫函数?
  • 阿里云应用高可用服务公测发布
  • 不上全站https的网站你们就等着被恶心死吧
  • 电商搜索引擎的架构设计和性能优化
  • 分享几个不错的工具
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 如何编写一个可升级的智能合约
  • 提醒我喝水chrome插件开发指南
  • 异常机制详解
  • Hibernate主键生成策略及选择
  • 翻译 | The Principles of OOD 面向对象设计原则
  • ​Java基础复习笔记 第16章:网络编程
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #pragma once
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (1)Hilt的基本概念和使用
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (C语言)fread与fwrite详解
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (八)Flask之app.route装饰器函数的参数
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (转载)Linux 多线程条件变量同步
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException