如何删除渐变中的间隙
How to remove gaps in gradient
梯度6、7、8和10在其初始颜色之后具有可见间隙。有办法填补这一空白吗?
我假设,一旦对范围进行了分区,如果整数分区不能被画布的宽度整除,那么它们的总和就会小于原始分区。
信息
-
render1()
-通过生成两种颜色之间的颜色范围来插值。 -
render2()
-JavaScript的createLinearGradient()
,具有n个偶数停止。
$(document).ready(function () {
function addCanvas(ol) {
var canvas = $('<canvas>', {
"width": 240,
"height": 10
}).addClass('grd')
.appendTo($('<li>').appendTo(ol));
return canvas[0];
}
var ol = $('<ol>').appendTo($('body'));
var c1 = '#FF0000';
var c2 = '#00FF00';
var canvas;
for (var i = 1; i <= 30; i+=3) {
canvas = addCanvas(ol);
var colors = generateColors(c1, c2, i);
render(canvas, colors);
}
canvas = addCanvas(ol);
render2(canvas, [c1, c2]);
});
function toHex(c) {
return (function (hex) {
return hex.length == 1 ? "0" + hex : hex;
})(c.toString(16));
}
function hexToRgb(hex) {
var result = /^#?([a-f'd]{2})([a-f'd]{2})([a-f'd]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
function rgbToHex(rgb) {
var r = 0,
g = 0,
b = 0;
if (arguments.length === 1) {
r = rgb.r || 0;
g = rgb.g || 0;
b = rgb.b || 0;
} else if (arguments.length === 3) {
r = arguments[0];
g = arguments[1];
b = arguments[2];
}
return "#" + toHex(r) + toHex(g) + toHex(b);
}
function render(canvas, colors) {
var ctx = canvas.getContext("2d");
var n = colors.length;
var x = 0;
var subWidth = canvas.width / n;
for (var i = 0; i < n; i++) {
var start = i * subWidth;
var end = start + subWidth;
ctx.fillStyle = colors[i];
ctx.fillRect(x + start, 0, x + end, canvas.height);
}
}
function render2(canvas, colors) {
var ctx = canvas.getContext("2d");
var x = canvas.x;
var y = canvas.y;
var width = canvas.width;
var height = canvas.height;
ctx.fillStyle = createGradient(ctx, colors, x, y, width, height)
ctx.fillRect(0, 0, width, height);
}
function generateColors(color1, color2, n) {
function partition(a, b, n) {
function magnitude(a, b) {
if (a === b) return 0;
else if (a > b) return -1 * (a - b);
else return b - a;
}
return magnitude(a, b) / n;
}
var c1 = hexToRgb(color1);
var c2 = hexToRgb(color2);
var rd = partition(c1.r, c2.r, n);
var gd = partition(c1.g, c2.g, n);
var bd = partition(c1.b, c2.b, n);
var colors = [];
var i, r, g, b, h = n/2;
for (i = 0; i < h; i++) {
r = Math.floor(c1.r + rd * i);
g = Math.floor(c1.g + gd * i);
b = Math.floor(c1.b + bd * i);
colors.push(rgbToHex(r, g, b));
}
for (var j = 0; i < n; j++, i++) {
var k = h-j-1;
r = Math.floor(c2.r - rd * k);
g = Math.floor(c2.g - gd * k);
b = Math.floor(c2.b - bd * k);
colors.push(rgbToHex(r, g, b));
}
return colors;
}
function createGradient(ctx, colors, x, y, width, height) {
var h = height / 2;
var grd = ctx.createLinearGradient(0, h, width, h);
var n = Math.max(colors.length - 1, 1);
for (var i = 0; i < colors.length; i++) {
grd.addColorStop(i / n, colors[i]);
}
return grd;
}
canvas.grd {
display: inline-block;
margin: 1px 0;
}
ol {
padding-left: 32px;
list-style-type:decimal;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
更新的答案:新版本的渲染函数,可以分割多余的像素,并在每侧放置大约一半:
function render(canvas, colors) {
var ctx = canvas.getContext("2d");
var n = colors.length;
var r = canvas.width % n;
var a = Math.floor(r/2), b = n - r + a;
var subWidth = Math.floor(canvas.width / n) + 1;
var start = 0;
for (var i = 0; i < n; i++) {
if (i == a) {
subWidth -= 1;
}
if(i == b) {
subWidth += 1;
}
ctx.fillStyle = colors[i];
ctx.fillRect(start, 0, subWidth, canvas.height);
start += subWidth;
}
}
原始答案
几件事:
我认为造成微弱间隙的原因是,一些矩形被绘制成包括分数像素的宽度。你可以做的是把矩形画成精确的像素宽度,有些比另一些宽一个像素。这是对渲染函数的重写(我想。现在已经很晚了:-)
function render(canvas, colors) {
var ctx = canvas.getContext("2d");
var n = colors.length;
var r = canvas.width % n;
var subWidth = Math.floor(canvas.width / n) + 1;
var start = 0;
for (var i = 0; i < n; i++) {
if (i == r) {
subWidth -= 1;
}
ctx.fillStyle = colors[i];
ctx.fillRect(start, 0, subWidth, canvas.height);
start += subWidth;
}
}
这将计算将适合画布宽度colors.length
次的最大整体宽度。然后它计算出还有多少额外的像素(r),然后循环给前r个矩形1个额外的像素宽度。
(此外,请记住fillRect
函数的第三个参数是宽度,而不是结束。您的调用正在工作,因为矩形是在彼此的顶部绘制的,并且每个矩形的起始位置是正确的。)
我相信有一个更优雅的解决方案,但这个似乎有效!
此外,当我玩这个的时候,我注意到在javascript中,canvas.width是300,而不是240。这让我四处搜索,我发现了一个很好的解释,说明了它是如何在HTML5中的SO:Canvas宽度和高度上工作的。我认为代码正在渲染到一个300 x 150的画布中,然后缩小到240 x 10。但最终,这并没有造成问题。
希望这能有所帮助!
相关文章:
- 使用电话间隙在Android应用程序中显示SQL Lite的数据
- Highcharts colorsByPoint与系列中的线性渐变一起使用时不起作用
- 在SVG地图上添加水的渐变,就像在谷歌地图(PHP/JS)中一样
- 画布使用带有角度的线性渐变背景集
- 在文本区域的焦点上分割渐变
- Chart.js-添加渐变而不是纯色-实现解决方案
- 简单的jQuery段落渐变器
- 猫头鹰旋转木马2罐头't使渐变动画工作
- 颜色滑块渐变
- iScroll不断向上滚动(电话间隙)
- jQuery鼠标悬停渐变效果
- jQuery渐变光晕特殊文本效果
- 全宽滑块-交叉渐变过渡问题
- Cufon..简单渐变文本..是't工作
- 如何在three.js中实现不同相机/场景之间的交叉渐变
- 如何在android中使用HTML/CSS赋予文本渐变颜色
- 电话间隙等待数据库事务完成
- JavaScript应用CSS3渐变
- 我怎么能有一个自动渐变背景使用JavaScript,它适用于最新版本的Internet Explorer
- 如何删除渐变中的间隙