HTML CSS线性渐变无法正常工作

时间:2019-08-28 09:07:09

标签: html css html5-canvas linear-gradients

我只是在CSS中使用线性渐变,顺便说一句,生成的渐变效果与设计不同。我从未在任何Android,iOS,React Native或HTML5画布中遇到过此问题,但仅在CSS上。

.gradient {
  background-image: linear-gradient(to right top, red, blue);
}

我为弄清楚css的linear-gradient和canvas的create createLinearGradient之间的区别做了一个小提琴。 请检查此fiddle link

example

上面是css渐变,下面是画布1。 如您所见,画布的createLinearGradient如预期般运作良好,但在CSS上,same-color-line(上图中的黄线)并非垂直于渐变方向,而是看起来像另一个{{1 }}的元素。 有什么理由为什么要在CSS中使用它?

2 个答案:

答案 0 :(得分:2)

这是设计使然。您可以在此处了解更多信息: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) < / p>

在您的情况下,它将为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/>

答案 1 :(得分:0)

只需将to right top替换为to right。如果将其设置为to right top,则会对linear-gradient()应用一定的程度,因为它以左下角为起点,并一直延伸到矩形的右上角。

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(to right, 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>