canvas multiply、screen

这篇博客介绍了canvas中两种颜色混合模式——multiply和screen的计算过程,以及如何结合透明度进行颜色转换。multiply模式下,RGB通道值相乘并除以255得到混合色;screen模式中,颜色取反相乘后再取反。同时,文章阐述了透明度计算方法,即原图RGB乘以透明度加上底图RGB乘以(1-透明度)。这些概念在前端开发中的canvas应用中至关重要。

一。canvas multiply、screen计算过程

multiply 计算:r/g/b/a 分别相乘除以255及是混合后的值。

 function aM(left, right) {
          let newArr = []
          for(let i = 0; i < left.length; i++) {
            newArr.push(left[i] * right[i] / 255)
          }
          console.log(left, right, newArr)
          return newArr
        }

screen 计算:rgba取反相乘,之后再取反。

function aS(left, right) {
          let newArr = []
          let result = []
          for(let i = 0; i < left.length; i++) {
            const newLeft = 255 - left[i]
            const newRight = 255 - right[i]
            newArr.push(newLeft * newRight / 255)
          }
          for (let i = 0; i < newArr.length; i++) {
            result.push(255 - newArr[i])
          }
          console.log(newArr)
          return result
        }

透明度计算:原图的rgb乘以透明度加上底图的rgb乘以(1-透明度)。left 代表底图,right代表原图。

function alphaA(left, right, alpha) {
          const newArr = []
          for(let i = 0; i < left.length; i++) {
            const val = right[i] * alpha + (1 - alpha) * left[i]
            newArr.push(val)
          }
          return newArr
        }

计算操作:先计算混合然后再将透明度与混合后的值进行转换得出新的颜色。透明度的底图就是混合的底图。

<think>我们正在讨论H5 Canvas中透明色的设置方法及相关应用。根据引用[1]中提到的镂空文字效果,以及引用[4]中关于globalCompositeOperation的使用,我们可以知道在Canvas中实现透明效果不仅可以通过设置透明度,还可以利用合成操作来创建复杂的透明效果。 ### 一、设置透明色的基本方法 1. **使用RGBA颜色值** 在Canvas中,可以通过RGBA颜色值设置透明色,其中A代表Alpha通道(透明度),取值范围为0.0(完全透明)到1.0(完全不透明): ```javascript ctx.fillStyle = &#39;rgba(255, 0, 0, 0.5)&#39;; // 半透明红色 ctx.fillRect(10, 10, 100, 100); ``` 2. **设置全局透明度** 使用`globalAlpha`属性设置后续绘制的全局透明度: ```javascript ctx.globalAlpha = 0.5; // 设置全局透明度为50% ctx.fillStyle = &#39;red&#39;; ctx.fillRect(10, 10, 100, 100); ``` ### 二、透明色的高级应用 1. **创建镂空效果(如引用[1])** 利用合成操作`globalCompositeOperation`实现文字镂空: ```javascript // 绘制背景图片 ctx.drawImage(img, 0, 0); // 设置合成模式为&#39;destination-out&#39;(新内容透明时,使原有内容透明) ctx.globalCompositeOperation = &#39;destination-out&#39;; // 绘制文字(文字区域将变为透明) ctx.fillText(&#39;Hello&#39;, 50, 50); ``` 2. **实现颜色混合(如引用[4])** 在唇膏换色示例中,通过合成模式(如&#39;multiply&#39;)与透明度结合实现颜色叠加: ```javascript hiddenCtx.globalCompositeOperation = &#39;multiply&#39;; hiddenCtx.fillStyle = &#39;rgba(255, 0, 0, 0.6)&#39;; // 半透明红色 hiddenCtx.fillRect(0, 0, canvas.width, canvas.height); ``` 3. **渐变透明效果** 使用渐变对象(`createLinearGradient`)添加透明色阶: ```javascript const gradient = ctx.createLinearGradient(0,0,200,0); gradient.addColorStop(0, &#39;rgba(255,0,0,1)&#39;); // 不透明红 gradient.addColorStop(1, &#39;rgba(255,0,0,0)&#39;); // 完全透明 ctx.fillStyle = gradient; ctx.fillRect(10,10,200,100); ``` ### 三、透明色与性能优化 1. **离屏Canvas** 复杂透明效果可通过离屏Canvas预先渲染,避免主Canvas重复计算[^4]: ```javascript const offscreen = document.createElement(&#39;canvas&#39;); const offCtx = offscreen.getContext(&#39;2d&#39;); // 在离屏Canvas上绘制复杂透明效果 // ... // 将离屏内容绘制到主Canvas ctx.drawImage(offscreen, 0, 0); ``` 2. **分层渲染** 将静态背景与动态透明元素分离到不同Canvas层,减少重绘区域。 ### 四、注意事项 1. **合成模式兼容性** 部分`globalCompositeOperation`模式(如&#39;lighter&#39;)在低版本浏览器中支持有限。 2. **透明度叠加计算** 多次叠加透明色可能导致颜色值超出预期,需通过公式预计算: $$ R_{result} = R_{front} \times \alpha_{front} + R_{back} \times (1 - \alpha_{front}) $$ --- ### 相关问题 1. 如何解决Canvas中透明区域点击事件穿透问题? 2. Canvas中如何实现高性能的实时透明度动画? 3. 不同浏览器下Canvas透明度渲染差异如何处理? [^1]: 镂空文字效果实现原理 [^2]: Canvas基础操作指南 [^3]: 渐变与图案样式应用 [^4]: 合成模式与离屏渲染优化</think>在 H5 Canvas 中设置透明色是实现高级视觉效果的关键技术,以下是详细方法和应用场景: ### 一、透明色设置方法 1. **RGBA 颜色格式** 使用 RGBA 颜色值,其中 A 表示透明度(0-1): ```javascript ctx.fillStyle = &#39;rgba(255, 0, 0, 0.5)&#39;; // 半透明红色 ctx.fillRect(10, 10, 100, 100); ``` 2. **全局透明度属性** 设置 `globalAlpha` 影响后续所有绘制: ```javascript ctx.globalAlpha = 0.3; // 30% 透明度 ctx.fillStyle = &#39;blue&#39;; ctx.fillRect(50, 50, 100, 100); ``` 3. **透明渐变** 在渐变中添加透明色阶(如引用[3]): ```javascript const gradient = ctx.createLinearGradient(0,0,200,0); gradient.addColorStop(0, &#39;rgba(0,255,0,1)&#39;); // 不透明绿 gradient.addColorStop(1, &#39;rgba(0,255,0,0)&#39;); // 完全透明 ctx.fillStyle = gradient; ctx.fillRect(0,0,200,100); ``` 4. **合成操作实现镂空**(如引用[1][4]) 使用 `globalCompositeOperation` 创建透明区域: ```javascript // 绘制背景 ctx.drawImage(img, 0, 0); // 设置合成模式为"挖空" ctx.globalCompositeOperation = &#39;destination-out&#39;; // 绘制文字(文字区域变透明) ctx.fillText(&#39;CANVAS&#39;, 100, 100); ``` ### 二、核心应用场景 1. **图片镂空文字**(引用[1]) ```javascript // 1. 绘制图片 ctx.drawImage(image, 0, 0); // 2. 设置合成模式 ctx.globalCompositeOperation = &#39;destination-out&#39;; // 3. 绘制文字(创建透明区域) ctx.font = &#39;bold 60px Arial&#39;; ctx.fillText(&#39;HELLO&#39;, 50, 150); ``` 2. **产品换色效果**(引用[4]) ```javascript // 1. 绘制原始产品图 ctx.drawImage(lipstickImg, 0, 0); // 2. 使用混合模式叠加颜色 ctx.globalCompositeOperation = &#39;multiply&#39;; ctx.fillStyle = &#39;rgba(255, 0, 0, 0.7)&#39;; // 半透明红色 ctx.fillRect(0, 0, canvas.width, canvas.height); ``` 3. **图层叠加效果** ```javascript // 底层:半透明蓝色矩形 ctx.fillStyle = &#39;rgba(0, 0, 255, 0.5)&#39;; ctx.fillRect(20, 20, 200, 150); // 上层:半透明红色圆形 ctx.fillStyle = &#39;rgba(255, 0, 0, 0.5)&#39;; ctx.beginPath(); ctx.arc(150, 100, 70, 0, Math.PI * 2); ctx.fill(); ``` 4. **渐变消失效果** ```javascript const gradient = ctx.createLinearGradient(0,0,0,200); gradient.addColorStop(0, &#39;rgba(0,0,0,1)&#39;); gradient.addColorStop(1, &#39;rgba(0,0,0,0)&#39;); // 渐变为透明 ctx.fillStyle = gradient; ctx.fillRect(0, 0, 300, 200); ``` ### 三、注意事项 1. **性能优化** - 复杂透明效果使用离屏 Canvas 预渲染 - 避免频繁切换 `globalAlpha` 和 `globalCompositeOperation` 2. **混合模式支持** ```javascript // 常用模式: &#39;source-over&#39; // 默认覆盖 &#39;destination-out&#39; // 挖空效果 &#39;multiply&#39; // 正片叠底(引用[4]) &#39;screen&#39; // 滤色 ``` 3. **透明通道保存** 导出 PNG 格式保留透明度: ```javascript const dataURL = canvas.toDataURL(&#39;image/png&#39;); ``` > 透明度处理是 Canvas 高级应用的核心技术,结合混合模式可实现专业级视觉效果[^1][^4]。实际应用中需注意浏览器兼容性,部分混合模式在移动端支持有限。 --- ### 相关问题 1. 如何解决 Canvas 中透明区域点击事件穿透问题? 2. Canvas 中如何实现高性能的实时透明度动画? 3. 不同浏览器下 Canvas 透明度渲染差异如何处理? 4. 如何结合 WebGL 实现更复杂的透明材质效果? [^1]: 镂空文字效果实现原理 [^2]: Canvas 基础操作指南 [^3]: 渐变与图案样式应用 [^4]: 合成模式与换色功能实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值