CSS 线性渐变和 Canvas 线性渐变与不透明度设置不同

2024-01-23

我想在画布上实现 CSS 定义的相同线性渐变外观。使用了一种在不使用透明度设置之前效果很好的方法。当使用相同的线性渐变颜色设置定义 rgba 颜色值时,结果看起来不一样,请参阅以下链接:

JSFiddle: Example https://jsfiddle.net/uwag1q9e/2/

var canvas = document.getElementById("myCanvas");
var ctx = document.getElementById("myCanvas").getContext("2d");
var w = canvas.width;
var h = canvas.height;
var cssAng = Math.PI;
var dir = getDir(cssAng, w, h);
var gr = ctx.createLinearGradient(dir.x0,dir.y0,dir.x1,dir.y1);
gr.addColorStop(0, "rgb(255, 255, 255, 0)");
gr.addColorStop(0.87, "rgb(0, 0, 0, 1)");
ctx.fillStyle = gr;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);


function getDir(radian, width, height) {
        radian += Math.PI;
        const HALF_WIDTH = width * 0.5;
    const HALF_HEIGHT = height * 0.5;
    const lineLength = Math.abs(width * Math.sin(radian)) + Math.abs(height * Math.cos(radian));
    const HALF_LINE_LENGTH = lineLength / 2;

    const x0 = HALF_WIDTH + Math.sin(radian) * HALF_LINE_LENGTH;
    const y0 = HALF_HEIGHT - Math.cos(radian) * HALF_LINE_LENGTH;
    const x1 = width - x0;
    const y1 = height - y0;

return {x0, x1, y0, y1};
}
<!DOCTYPE html>
<html>
<body>
<div style='background-color:gray;display:inline-block;max-height:300px'>
  <div id="myDiv" style="display:inline-block;width:300px;height:300px;border:1px solid #d3d3d3;background:linear-gradient(180deg,rgba(255,255,255, 0) 0%, rgba(0,0,0,1) 87%"> </div>
</div>
<canvas id="myCanvas" width="300" height="300" style="background-color: gray;border:1px solid #d3d3d3;"> </canvas>
</body>
</html>

知道为什么会发生这种情况吗?有没有一个包可以解决这个问题?


CSS 的规格实际上存在差异线性渐变 and 画布线性渐变。它们看起来几乎完全相同,除了颜色需要根据 alpha 值计算的方式不同。对于CSS线性渐变,你有这样的:

3.4.2.为渐变线着色 在每个色标位置,渐变线是该色标的颜色。在第一种颜色之前 stop,渐变线是第一个颜色停止点的颜色,并且 在最后一个颜色停止之后,渐变线是最后一个颜色 颜色停止。在两个颜色停止点之间,渐变线的颜色为 在双色点的颜色之间进行插值,其中 插值发生在预乘 RGBA 空间.

See: https://drafts.c​​sswg.org/css-images-3/#coloring-gradient-line https://drafts.csswg.org/css-images-3/#coloring-gradient-line

而画布:

创建渐变后(见下文),沿 它定义颜色如何沿渐变分布。这 每个停止处的渐变颜色是为其指定的颜色 停止。在每个这样的停止点之间,颜色和 alpha 分量必须 线性插值没有预乘的 RGBA 空间 用于查找在该偏移处使用的颜色的 alpha 值。之前 第一站,颜色必须是第一站的颜色。

See: https://html.spec.whatwg.org/multipage/canvas.html#interpolation https://html.spec.whatwg.org/multipage/canvas.html#interpolation

因此 CSS 版本通过预乘 alpha 值来计算色标。我改变了你的例子以使其更加明显。在下面的示例中,CSS 版本来自RGBA(255, 0, 0, 0) or RGBA(0, 0, 0, 0) to RGBA(0, 0, 0, 1)。因此,在 50% 时,使用预乘 alpha 计算的颜色为RGBA(0, 0, 0, 0.5).

在canvas版本中,计算插值时不进行预乘。所以在 50% 的时候你有RGBA(127,5, 0, 0, 0.5)。对于渐变线的每个点都是如此。

请参阅预乘的含义:https://drafts.c​​sswg.org/css-images-3/#premultiplied https://drafts.csswg.org/css-images-3/#premultiplied

以及例子:

var canvas = document.getElementById("myCanvas");
var ctx = document.getElementById("myCanvas").getContext("2d");
var w = canvas.width;
var h = canvas.height;
var cssAng = Math.PI;
var dir = getDir(cssAng, w, h);
var gr = ctx.createLinearGradient(dir.x0,dir.y0,dir.x1,dir.y1);
gr.addColorStop(0, "rgb(255, 0, 0, 0)");
gr.addColorStop(1, "rgb(0, 0, 0, 1)");
ctx.fillStyle = gr;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);


function getDir(radian, width, height) {
        radian += Math.PI;
        const HALF_WIDTH = width * 0.5;
    const HALF_HEIGHT = height * 0.5;
    const lineLength = Math.abs(width * Math.sin(radian)) + Math.abs(height * Math.cos(radian));
    const HALF_LINE_LENGTH = lineLength / 2;

    const x0 = HALF_WIDTH + Math.sin(radian) * HALF_LINE_LENGTH;
    const y0 = HALF_HEIGHT - Math.cos(radian) * HALF_LINE_LENGTH;
    const x1 = width - x0;
    const y1 = height - y0;

return {x0, x1, y0, y1};
}
<!DOCTYPE html>
<html>
<body>
<div style='display:inline-block;max-height:300px'>
  <div id="myDiv" style="display:inline-block;width:200px;height:300px;border:1px ;background:linear-gradient(180deg,rgba(255,0,0, 0) 0%, rgba(0,0,0,1) 100%"> </div>
   
</div>
<canvas id="myCanvas" width="200" height="300" > </canvas>
<div style="position: absolute;width:8px;height:8px;background:rgba(0,0,0,0.5); top: 144px; left: 0px; ">

</div>
<div style="position: absolute;width:10px;height:10px;background:rgba(127.5,0,0,0.5); top: 144px; left: 412px; ">

</div>
</body>
</html>

我认为除了计算渐变线的每个点之外,没有办法使 2 相等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CSS 线性渐变和 Canvas 线性渐变与不透明度设置不同 的相关文章

  • 如何为 TBODY 应用垂直滚动条

    我的表中有 4 列和 5 行数据 我必须为 TBODY 应用垂直滚动条 TH 标题内容不应滚动 我对场景进行了编码 并且在我将滚动类应用于 TBODY 之前它工作正常 一旦我将滚动样式类应用于 TBODY 它就会破坏之前的对齐方式 任何人都
  • 应用旋转时,HTML5 canvas Clip() 在 Chrome 中不起作用

    我试图在画布上使用剪辑区域 一旦坐标系旋转任何非零值 它就会停止工作 window onload function var canvas document getElementById mainCanvas var ctx canvas g
  • CSS:水平滚动时背景不存在

    好的 我的背景设置如下 HTML div div CONTENT HERE div div CSS container background url image gif content width 800px margin auto 因此
  • 使用deployJava.runApplet来定位特定元素

    经过多年成功维护一个使用旧有的小程序 嵌入Java小程序的方法 我们无法捂住耳朵唱 啦啦啦 不再了 是时候使用 deployJava runApplet 当我使用点击处理程序触发此方法时 此处通过 jQuery 在按钮上使用事件侦听器 但这
  • div 边框上的内边距

    我想在 css 边框上添加填充 将其拉入 div 内 远离边缘 使用 css 可以吗 css3 很好 webkit 这是设计 我通过将一个 div 放在一个 div 中 然后给内部 div 一个边框来做到这一点 我想让标记尽可能精简 所以如
  • Textmate“注释”命令对于 css 代码无法正常工作

    当我在 TextMate 中切换 CSS 源代码的注释时遇到一些问题 Using the shortcut CMD I activate the Comment Line Selection command from the source
  • 防止浮动换行,直到元素达到最小宽度

    我有可变宽度的 HTML 布局 内容左侧有一个固定宽度的菜单 div 可变宽度 由 css max width 和 min width 设置 对于非常窄的浏览器窗口 我希望内容包裹在菜单下方 我目前通过设置来实现这一点float left在
  • 覆盖并重置 CSS 样式:auto 或 none 不起作用

    我想覆盖为所有表定义的以下 CSS 样式 table font size 12px width 100 min width 400px display inline table 我有一个特定的表 其类名为 other 最后的餐桌装饰应该是这
  • 我可以停止 :hover 应用于元素吗?

    假设我有一些 CSS button hover font weight bold 我怎样才能防止 hover随意应用样式 我的目标用例是当元素被禁用时 例如 使用这个 HTML
  • 为范围旋钮 ionic-range 添加边框颜色

    我正在使用离子范围添加范围滑块 并想向范围旋钮添加边框 由于它的 ionic4 和范围旋钮是 Shadow dom 的一部分 我无法使用范围旋钮的 border 属性直接更改边框 我已附上我想要实现的图像 范围旋钮周围有白色边框 现有属性只
  • 显示覆盖以覆盖整个页面

    我有一个正在加载的网络应用程序iframe 我需要显示一个覆盖 div 来覆盖整个页面 问题是叠加层当前仅显示在iframe区域而不覆盖整个页面 我们的应用程序 子应用程序 是加载的一组应用程序的一部分iframe 你可以做这样的事情 di
  • 如何在悬停标签时显示块div

    如何在悬停标签时打开 div 标签 服务是标签的id services是div标签的id 我的 HTML 代码是 ul li a href Services a li ul div h1 Hello h1 div 我的CSS代码是这样的 S
  • 是否可以通过 CSS 3 使用文本内容设置元素中文本的颜色?

    好吧 这更像是一个有很多非 CSS 解决方案的问题 但我希望更多地从理论角度来做这件事 我有一个它的应用程序 但不值得以任何其他方式对其进行编码 有趣的 问题 如何使用元素的文本为元素的文本着色 我有一个元素 全部都是它自己的 它将包含颜色
  • 菜单作为水平无序列表或表格?

    我有一个无序列表 水平显示为页面的顶部菜单栏 我已经让它显示得相对较好 尽管我一直在调整 IE6 和 IE7 的间距 因为它无法正常显示 令人震惊 无论哪种情况 使用表格来显示菜单还是使用一些CSS hack 我找不到解决方法 会更好吗 显
  • 如何更改chart.js中的标签颜色?

    我有一个像这样定义的饼图 var myChart new Chart ctx type doughnut data labels data labels datasets data data values backgroundColor r
  • 排除单个浏览器使用 CSS 类

    我想排除 Internet Explorer 使用特定的 CSS 类 这可能吗 Details 我有一个 css 类 看起来像 input type radio checked input type radio hover box shad
  • 如何淡化循环背景图像?

    这里的菜鸟 我试图让我的静态背景变成一个轮播 我当前的html看起来像这样 div class pageContent div 和我的CSS body background url http placehold it 1600x1200 n
  • iOS 11 浏览器图像错误

    在 iOS 11 中滚动页面时出现以下错误 在 Firefox Safari 和 Chrome 中 在 Android 设备中 不会发生该错误 这些是背景图像 我不知道这是否是导致错误的原因 图 2 显示了图像在 Android 中的用途和
  • HTML colorpicker 发生变化时如何获取新值?

    我正在开发一个需要更改 HTML 颜色的网络应用程序canvas基于的价值观colorpicker 我有一个colorpicker在我需要获取的 HTML 中value从每次更新开始
  • 如何使 jQuery 向上动画

    我有一些 jquery 运行得相当好 但是当我将鼠标悬停在有问题的元素上时 底部向下扩展 这并不意外 但不是所需的效果 我希望元素的底部保持静止 而元素的顶部向上扩展 如果您想查看我目前拥有的内容 您可以导航至http demo ivann

随机推荐

  • R group by 和aggregate - 使用 plyr 返回组内的相对排名

    更新 我有一个数据框 测试 如下所示 session id seller feedback score 1 1 282470 2 1 275258 3 1 275258 4 1 275258 5 1 37831 6 1 282470 7 1
  • R 热图,Y 轴上的标签非常接近

    我正在使用 R 绘制 CSV 文件中数据的热图 10 列 条件和 1000 罗瓦 以下是我正在使用的代码 nba lt read csv 1317754115 csv sep nba matrix lt data matrix nba ce
  • 表动态加载SAPUI5/UI5

    我想在 SAPUI5 Table 组件中显示大量数据 我曾经通过动态加载来实现这些数据表 这意味着该表最初加载了约 50 条记录 用户向下滚动足够远后 下一组 50 条记录将加载到表中 这样我就可以显示包含超过 160 000 个条目的表格
  • 如何调试在客户计算机上崩溃的 Windows 应用商店应用程序?

    我收到一位客户的支持电子邮件 说他的应用程序在启动时崩溃 他收到的只是一条类似以下的消息 应用程序名称 遇到问题您可以向 Microsoft 发送有关以下内容的信息 出了什么问题来帮助改进这个应用程序 将发送给 Microsoft 的文件
  • Android Studio 禁用换行

    我在 Android Studio 上有这个奇怪的换行符 我想禁用它 因为它让我害怕 It s also available under the context menu
  • 放弃对 JRE 1.3 的支持

    我们提供了一个流行的开源 Java FTP 库 称为edtFTPj http www enterprisedt com products edtftpj overview html 我们希望放弃对 JRE 1 3 的支持 这将清理代码库 并
  • 将 Python 字典列表转换为 Postgresql json 数组

    我正在尝试将 jsonb 元素的 Python 2 7 列表插入到具有数据类型列的 Postgresql 9 4 表中 jsonb 这是一些代码 import json anArray name Joe age 51 yob 1964 ge
  • 通过手写汇编调用本机代码

    我正在尝试从托管程序集中调用本机函数 我已经在预编译库上完成了此操作 一切都很顺利 目前我正在建立自己的图书馆 但我无法完成这项工作 本机 DLL 源代码如下 define DERM SIMD EXPORT declspec dllexpo
  • 春天。 @RequestBody 的映射字段与 @PathVariable

    现在我有这样的代码 RestController public class ChildController RequestMapping value parents parentId addChild method RequestMetho
  • 从选定的数据库中选择选项值

    我有一个小问题 我有一个 edit php 页面 该页面列出了可以编辑的产品信息 我运行一个查询 while rows mysql fetch assoc query echo
  • 如何使用 Cython 将 Python 3 编译为 C

    我正在尝试将 Python 3 脚本转换为 C 然后将该 C 文件编译为可执行文件 我有这个简单的 python 脚本 def greet name print Hello 0 format name if len name gt 0 el
  • 更改命名空间前缀 WCF 信封

    我想知道是否可以更改 WCF SOAP 请求的命名空间前缀 正如您在下面的示例中看到的 The Envelope 的命名空间为 http www w3 org 2005 08 addressing 前缀为 a 我想将其更改为 foo 我怎样
  • 如何将任务的已取消状态传播到继续任务

    我在我的应用程序中使用任务并行库 我有一个任务 我们称之为 DoSomething 可能会被取消 无论任务出现故障 取消还是成功完成 我都会向该任务附加一个延续来执行一些清理工作 在启动此任务的代码中 我想返回一个 Task 对象 其状态
  • SWIG C++ 到 Python:警告(362):运算符=被忽略

    我正在将 C 类导出到 Python 我注意到在编译过程中 SWIG 发出以下警告 Warning 362 operator ignored 我不确定为什么操作符超载 因为它在SWIG 文档 http www swig org Doc1 3
  • camera2 捕获的图片 - 从 YUV_420_888 转换为 NV21

    通过camera2 API 我们接收以下格式的图像对象YUV 420 888 然后我们使用以下函数转换为NV21 private static byte YUV 420 888toNV21 Image image byte nv21 Byt
  • Oracle中INSTR和LIKE有什么区别?

    有人可以告诉我两者之间的区别吗INSTR and LIKE在甲骨文中 Oracle10g中哪一个更快 这取决于数据和模式 如果你使用like a 那么 Oracle 可以使用 BTree 索引来查找匹配项 因为它可以以模式开头搜索 BTre
  • Angular CLI 无法创建新项目

    如何从 angular cli 创建新项目 Angular CLI 有问题 已经关门了 我认为仍然存在问题https github com angular angular cli issues 5543 event 1009616731 h
  • 故事板静态单元:dequeueReusableCellWithIdentifier 返回 nil

    使用故事板 静态单元格cellForRowAtIndexPath 线 UITableViewCell cell tableView dequeueReusableCellWithIdentifier CellIdentifier 总是返回n
  • Capybara webkit 不传递来自 Angular 的参数

    我正在尝试将 selenium 测试套件移植到 capybara webkit Rails 应用程序在 Rails 视图中嵌入了一个角度应用程序 并且其行为不符合预期webkit 像这样的测试 需要 spec helper feature
  • CSS 线性渐变和 Canvas 线性渐变与不透明度设置不同

    我想在画布上实现 CSS 定义的相同线性渐变外观 使用了一种在不使用透明度设置之前效果很好的方法 当使用相同的线性渐变颜色设置定义 rgba 颜色值时 结果看起来不一样 请参阅以下链接 JSFiddle Example https jsfi