html - HTML css 线性渐变未按预期工作
问题描述
我只是在 css 中使用线性渐变,顺便说一句,生成的渐变效果与设计不同。我从未在任何 Android、iOS、React Native 或 HTML5 画布中遇到过这个问题,但仅限于 css。
.gradient {
background-image: linear-gradient(to right top, red, blue);
}
linear-gradient
我做了一个小提琴来展示 css和 canvas之间的差异create createLinearGradient
。请检查这个小提琴链接。
上面是css渐变,下面是canvas之一。如您所见,画布createLinearGradient
按预期运行良好,但在 css 上same-color-line
(上图中的黄线)不垂直于渐变的方向,而是看起来像另一个diagonal
元素。有什么理由为什么它在css中?
解决方案
这是设计使然。您可以在此处阅读更多信息:https ://drafts.csswg.org/css-images-3/#linear-gradients 。
如果参数改为指定框的角,例如
to top left
,则渐变线必须倾斜,使其指向与指定角相同的象限,并且垂直于与渐变框的两个相邻角相交的线。这会导致 50% 处的色标与两个相邻角相交。
基本上,当使用这样的关键字时,你会得到一种从角落开始的拉伸梯度,并且你会失去对角线的垂直特征。
.child {
position:relative;
width: 100px;
height: 100px;
border: 1px solid red;
background-image: linear-gradient(to top right, red 50%, blue 0);
}
.child.alt {
width:200px;
}
.child:before {
content:"";
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
background:linear-gradient(to top left,transparent calc(50% - 5px),green,transparent calc(50% + 5px) );
}
this one is good because it's a square
<div class="child"></div>
but not this one
<div class="child alt"></div>
如果您想获得第二个输出,您需要使用显式角度并找到使渐变线与对角线相同的角度,为此您需要考虑角度等于arctang(width/height)
在您的情况下,它将是arctang(300/75) = arctang(4) = 75.69deg
. 由于您使用的是 JS,因此您可以轻松地进行此计算。
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var grd = ctx.createLinearGradient(0, 75, 300, 0);
grd.addColorStop(0, "red");
grd.addColorStop(1, "blue");
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 300, 75);
.parent {
width: 300px;
height: 300px;
align-items: center;
justify-content: center;
display: flex;
flex-direction: column;
background-color: #6EE2F5;
}
.child {
width: 300px;
height: 75px;
border: 1px solid red;
background-image: linear-gradient(75.69deg, red, blue);
}
#canvas {
width: 300px;
height: 75px;
border: 1px solid green;
}
<div class="parent">
<div class="child"></div>
<canvas id="canvas" width=300 height=75/>
</div>
这是一个交互式演示
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
function update() {
var H = $('[name=h]').val();
var W = $('[name=w]').val();
$('.child').css('height',H);
$('.child').css('width',W);
$('canvas').attr("width", W);
$('canvas').attr("height", H);
var angle = Math.atan(W/H)
$('.child').css("--a", (angle * 180 / Math.PI)+"deg");
var grd = ctx.createLinearGradient(0, H, W, 0);
grd.addColorStop(0.4, "red");
grd.addColorStop(0.6, "blue");
ctx.fillStyle = grd;
ctx.fillRect(0, 0, W, H);
}
$('input').change(update);
update();
.child {
border: 1px solid;
background-image: linear-gradient(var(--a), red 40%, blue 60%);
}
#canvas {
border: 1px solid green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
W: <input type="number" name="w" step="1" value="300">
H: <input type="number" name="h" step="1" value="75">
<div class="child"></div>
<canvas id="canvas" width=300 height=75/>
推荐阅读
- oauth - OKTA - 无法检索授权码
- ios - 推送视图控制器后 UISearchBar 从 NavigationItem 中消失
- java - 挂钩到集合创建以设置模式 Spring Data Mongo
- php - 逐一检索计数值
- django - 如何在 Ubuntu 中为 Django 项目的 Postgresql 设置 apache 权限?
- apache-nifi - Nifi在HDFS路径上为前一天合并的json文件移动文件
- macos - MacOS 上 SwiftUI 中的按钮问题
- mysql - 为插入后创建 My sql 触发器,使用插入的记录更新另一个表列
- c# - EF Core - 用于处理特定类型的全局设置
- docker - 使用 `-e` 运行时需要为图像提供环境变量