javascript - How to remove gaps in gradient -
gradients 6, 7, 8 , 10 have visible gaps after initial color. there way fill gap in?
i assume 1 time range partitioned, sum of integer partitions less original if not divisible width of canvas.
inforender1()
- interpolates values generating range of colors between 2 colors.
render2()
- javascript's createlineargradient()
n-number of stops.
class="snippet-code-js lang-js prettyprint-override">$(document).ready(function () { function addcanvas(ol) { var canvas = $('<canvas>', { "width": 240, "height": 10 }).addclass('grd') .appendto($('<li>').appendto(ol)); homecoming canvas[0]; } var ol = $('<ol>').appendto($('body')); var c1 = '#ff0000'; var c2 = '#00ff00'; var canvas; (var = 1; <= 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) { homecoming (function (hex) { homecoming 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); homecoming 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]; } homecoming "#" + 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; (var = 0; < n; i++) { var start = * 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) homecoming 0; else if (a > b) homecoming -1 * (a - b); else homecoming b - a; } homecoming 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; (i = 0; < 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)); } (var j = 0; < 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)); } homecoming 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); (var = 0; < colors.length; i++) { grd.addcolorstop(i / n, colors[i]); } homecoming grd; }
class="snippet-code-css lang-css prettyprint-override">canvas.grd { display: inline-block; margin: 1px 0; } ol { padding-left: 32px; list-style-type:decimal; }
class="snippet-code-html lang-html prettyprint-override"><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
updated answer: new version of render function splits pixels , puts around half on each side:
function render(canvas, colors) { var ctx = canvas.getcontext("2d"); var n = colors.length; var r = canvas.width % n; var = math.floor(r/2), b = n - r + a; var subwidth = math.floor(canvas.width / n) + 1; var start = 0; (var = 0; < 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; } }
original answer
a few things:
i think causing faint gaps of rectangles beingness drawn widths include fractional pixels. can draw rectangles exact pixel widths, beingness 1 pixel wider others. here's rewrite of render function (i think. it's pretty late here :-))
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; (var = 0; < n; i++) { if (i == r) { subwidth -= 1; } ctx.fillstyle = colors[i]; ctx.fillrect(start, 0, subwidth, canvas.height); start += subwidth; } }
this calculates largest whole width fit width of canvas colors.length
times. figures out how many pixels there left (r) , loops through giving first r rectangles 1 pixel width.
(also, remember fillrect
function's 3rd parameter width, not end. phone call working because rectangles beingness drawn on top of each other , start position of each rectangle correct.)
i'm sure there's more elegant solution this, 1 seems work!
also, while playing around noticed in javascript, canvas.width 300, not 240. led me search around , found nice explanation of how works on so: canvas width , height in html5. think code rendering 300 x 150 canvas , beingness scaled downwards 240 x 10. though, wasn't causing problem.
hope helps!
javascript algorithm interpolation linear-gradients
No comments:
Post a Comment