uniapp微信小程序 canvas绘制圆形半透明阴影 createCircularGradient函数不支持透明度部分解决方案
背景
我需要在微信小程序中,用canvas绘制一个圆形钟表,在ui设计图中,有一部分阴影,这里我节选一下:
即深色发黑的部分
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//别忘了改回去
你也可以叠加多个半透明圆,但我还是建议你切图。
相关文章:

uniapp微信小程序 canvas绘制圆形半透明阴影 createCircularGradient函数不支持透明度部分解决方案
背景 我需要在微信小程序中,用canvas绘制一个圆形钟表,在ui设计图中,有一部分阴影,这里我节选一下: 即深色发黑的部分 canvas通用阴影绘制 由于canvas中并不支持css那样简单的方式为圆形添加阴影或高光,…...

W34KN3SS靶机
信息收集: 靶机地址:https://www.vulnhub.com/entry/w34kn3ss-1,270/# (1)ip扫描 nmap 192.168.254.0/24 -sn | grep -B 2 00:0C:29:E8:66:AB (2)端口扫描 nmap -p- -A 192.168.254.145 (3&…...
8.9套题
A. 猴猴吃苹果 题意:给定根节点k,求访问点的顺序,使得每次从上一个点到当前点的权值最大。访问过的点权值为0。权值一样时,输出最小编号 思路:由于是双向边,先求根节点到每一个节点的距离值。在第一轮中&…...

Python 爬取网页水务数据并实现智慧水务前端可视化
提示:本文爬取深圳市环境水务集团有限公司的公开数据作为数据样例进行数据分析与可视化。 文章目录 一、爬虫二、对爬取的数据进行数据库、excel的存储与数据处理1.代码实现 三、应用Flask框架将后端获取数据后渲染到前端四、前端Echarts的使用1.下载echarts.min.js…...

百度智能云发布3款轻量级+2款场景大模型
文心大模型ERNIE 3.5是目前百度智能云千帆大模型平台上最受欢迎的基础大模型之一。针对用户的常见通用的对话场景,ERNIE 3.5 在指令遵循、上下文学习和逻辑推理能力三方面分别进行了能力增强。 ERNIE Speed作为三款轻量级大模型中的“大个子”,推理场景…...

UE基础 —— 编辑器界面
菜单栏 UE中每个编辑器都有一个菜单栏,部分菜单会出现在所有编辑器窗口中,如File、Window、Help,其他则是其编辑器特有的; 主工具栏 UE中部分最常用的工具和命令的快捷方式; 1,保存按钮(ctrls&a…...

2024年Vue组件库大比拼:谁将成为下一个Element?
2024 年,Vue生态蓬勃发展,越来越多的开发者开始探索更适合自己项目的组件库。 今天我们来看一下2024年最受欢迎的几款Vue开源组件库,除了Element,开发者们还有哪些选择呢? 1.Vuetify Vuetify是由社区支持的Vue组件库&…...

SS9283403 sqlite3交叉编译并部署到SS928(六)
1.Sqlite3下载 连接:SQLite Download Page 2.解压 tar zxvf sqlite-autoconf-3460000.tar.gz 3.配置并编译 进入解压目录,打开命令行,输入如下命令 ./configure CCaarch64-mix210-linux-gcc --hostarm-linux --prefix/home/mc/work/sqlite…...

java3d-1_4_0_01-windows-i586.exe
下载 Java 3D API 安装 C:\Program Files\Java\Java3D\1.4.0_01\bin C:\Java\jre6 C:\Java\jdk1.6.0_45 C:\Windows 记录下这 4 个目录,去检查下 4 哥目录下文件多了什么 检查目录① C:\Program Files\Java\Java3D\1.4.0_01\bin 检查目录② C:\Java\jre6 C:…...

Vue3中的history模式路由:打造无缝导航体验!
Hey小伙伴们,今天给大家带来Vue3中使用history模式路由的实战案例!🌟 🔍 项目背景 Vue3的路由功能非常强大,可以帮助我们轻松实现单页面应用中的页面切换。但是你知道吗?默认情况下Vue Router使用的是has…...

python(6)
一、datetime函数 方法一: 前一个datetime是模块。后一个datetime是类型 方法二: 方法三: 二、逆序字符串 三 、旋转字符串...

以Zed项目为例学习大型Rust项目的组织与管理
说明 Zed项目代码:https://github.com/zed-industries/zed.git本文项目代码:https://github.com/VinciYan/zed_workspace.git Zed是一款由Atom创始人开发的高性能、协作友好的现代开源代码编辑器,使用Rust编写,集成AI辅助功能&a…...

正点原子imx6ull-mini-Linux驱动之Linux RS232/485/GPS 驱动实验(23)
错误1:我一直找不到为什么我的minicom用不了,编译啥的都通过了,原来是我的密码文件命名错了,我就习以为常的命名为password,谁知道应该是passwd,所以以后该复制的还是复制,不然就容易找不到源头…...

用户上下文打通+本地缓存Guava
文章目录 🌞 Sun Frame:SpringBoot 的轻量级开发框架(个人开源项目推荐)🌟 亮点功能📦 spring cloud模块概览常用工具 🔗 更多信息1.设计1.链路流程2.详细设计 2.网关过滤器获取唯一标识放到Hea…...

Windows图形界面(GUI)-MFC-C/C++ - 树形视图(Tree Control) - CTreeCtrl
公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 树形视图(Tree Control) - CTreeCtrl 创建和初始化 添加和删除项 获取和设置项属性 操作项 项选择变化 项双击 项展开 示例代码 树形视图(Tree Control) - CTreeCtrl 创建和初始…...

C语言 --- 枚举、位运算
(一)枚举 1.概念:枚举是指将变量的值一一列举出来,变量的值只限于列举出来的值的范围 2.作用:a.提高代码可读性;b.提高代码的安全性 3.枚举类型: enum 枚举名 { 列举各种值 //枚举元素或枚…...

12322222222
当您和老王不在同一个网段时,您们之间的通信需要通过路由器来实现。这是因为不同的网段被视为不同的网络,而路由器的作用之一就是连接不同的网络并负责数据包的转发。下面是详细的通信流程: 本地网络通信尝试:您的设备࿰…...

知识改变命运:Java 语言 【可变参数】
可变参数 概念:Java允许一个类中多个同名同功能但是参数不同的方法,封装为一个方法。 基本语法: 访问修饰符 返回值 方法名 (数据类型...参数名) { ...... }案例:写一个类名DyMethod 方法名sum 计算两个整数和,三个整…...

Spring及相关框架的重要的问题
Java框架 问题一:Spring框架中的单例bean是线程安全的吗? 看下图,不能被修改的成员变量就是无状态的类,无状态的类没有线程安全问题,所以在开发中尽量避免可修改的成员变量。 回答:不是线程安全的…...

Linux Vim教程
Linux Vim 教程 Vim(Vi IMproved)是一个强大的文本编辑器,广泛用于编程和系统管理。本文将带你全面了解 Vim 的基础使用、常用命令、高级功能等。 1. 安装 Vim 在大多数 Linux 发行版中,Vim 已经预装。如果没有,可以…...

【学习笔记】多进程信号量控制
目录 1、CreateSemaphore 2、ReleaseSemaphore 3、CreateEvent 4、SetEvent 5、WaitForSingleObject 程序案例1: 程序案例2: 1、CreateSemaphore 创建一个计数信号量对象,成功时返回信号量对象的句柄;失败时返回NULL&…...

Redis与Memorycache的区别
Redis与Memorycache主要是持久线程和持久化的区别 1、从性能方面来说: Redis是单线程的,优点是CPU开销小,省去多线程线程之间切换的开销,但是相对于Memorycache来说海量数据的相对较低 Memorycache使用了多线程技术,数…...

docker和Helm Chart的基本命令和操作
一、docker基本命令和操作 1. docker login【登录】 登录 docker client,登录成功之后会显示 Login Succeeded。 docker login登陆到指定的镜像仓库,docker pull 和 docker push 操作都需要预先执行 docker login 操作; 指令:&a…...

Node中的CSRF攻击和防御
Node中的CSRF攻击和防御 假设有一个网上银行系统,用户可以通过该系统进行转账操作。转账功能的URL可能是这样的: https://www.bank.com/transfer?toAccount123456&amount1000当用户登录到银行系统,并在浏览器中访问这个URL时ÿ…...

CSS 多按钮根据半圆弧度排列
需求 多个按钮根据弧度,延边均匀排列。 实现 HTML 分两级;第一级,外层定义按钮的 compose-container 宽度;第二级,按钮集合,使用方法 styleBtn(index),根据索引计算; <div c…...

【Linux】网络编程套接字Scoket:UDP网络编程
目录 一、了解UDP协议 二、了解端口和IP地址 三、套接字概述与Socket的概念 四、Socket的类型 五、 Socket的信息数据结构 六、网络字节序与主机字节序的互相转换 七、地址转换函数 八、UDP网络编程流程及相关函数 socket函数 bind函数 recvfrom函数 sendto函数 …...

基于模糊PID控制器的puma560机器人控制系统的simulink建模与仿真
目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 PUMA 560机器人的数学模型 4.2 PID控制原理 4.3 模糊PID控制器的设计 5.完整工程文件 1.课题概述 基于模糊PID控制器的puma560机器人控制系统的simulink建模与仿真,对比传统的PID控制器…...

C语言文件操作超详解
文章目录 1. 为什么使用文件2. 什么是文件2. 1 程序文件2. 2 数据文件2. 3 文件名3. 二进制文件和文本文件? 4. 文件的打开和关闭4. 1 流和标准流4. 1. 1 流4. 1. 2 标准流 4. 2 文件指针4. 3 文件的打开和关闭 5. 文件的顺序读写5. 1 顺序读写函数介绍5. 2 对比一组函数: 6. …...

表字段显示tip
需求背景: 生成的报表,前端只展示字段名称,计算逻辑没有解释,使用方频繁“骚扰”,实在受不了,增加一个字段tip,实现效果(下图): 代码 结合使用el-table-colu…...

十二、享元模式
文章目录 1 基本介绍2 案例2.1 Digit 接口2.2 Color 枚举2.3 BigDigit 类2.4 DigitFactory 类2.5 Client 类2.6 Client 类的测试结果2.7 总结 3 各角色之间的关系3.1 角色3.1.1 Flyweight ( 抽象享元 )3.1.2 ConcreteFlyweight ( 具体享元 )3.1.3 UnsharedFlyweight ( 非享元 )…...