Make rectangle overlay image with canvas
canvas, css, html, javascript, jquery
Solution
You have the image being drawn in the asynchronous callback onload. The result will change depending on if the image loads first, or the canvas draw is called first.
Try moving your draw code into the same callback.
For more efficient clipping you can use the non-zero winding order rule: http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/
TLDR: Consecutive canvas draw calls will add or subtract from the previous calls depending on whether the order of points is clockwise or anti-clockwise.
See: http://jsfiddle.net/jJjt7/2/
context.fillStyle = sectorColor;
context.rect(0, 0, canvasWidth, canvasHeight);
context.arc(canvasWidth/2, canvasHeight/2, radius, 0, Math.PI*2, true);
context.fill();
The above example draws a rectangle with a clockwise point order, then subtracts the arc (circle) by using an anti-clockwise point order. The last argument of the arc method defines 'anti-clockwise'. In this case true.
Edit: This negates the need to draw twice. Efficiency, FTW.
Problem
I'd like to reach the following with HTML5 canvas: My code: jsfiddle ``` // Options var maxImageWidth = 250, maxImageHeight = 196, radius = 50; var canvas = $('#ddayCanvas'), canvasWidth = canvas.width(), canvasHeight = canvas.height(), sectorColor = $('.product-box').css('background-color'), context = canvas[0].getContext('2d'), imageSrc = canvas.data('image'); function drawDday (option) { var imageObj = new Image(); imageObj.onload = function() { if (option == 'clip'){ context.save(); context.clip(); } var imageWidth = imageObj.width, imageHeight = imageObj.height; if (imageWidth > maxImageWidth){ imageHeight = imageHeight - (imageWidth - maxImageWidth); imageWidth = maxImageWidth; } if (imageHeight > maxImageHeight) { imageWidth = imageWidth - (imageHeight - maxImageHeight); imageHeight = maxImageHeight; } context.drawImage(imageObj, Math.ceil((canvasWidth - imageWidth) / 2), Math.ceil((canvasHeight - imageHeight) / 2), imageWidth, imageHeight); }; imageObj.src = imageSrc; } drawDday(); // Why does this rectangle not overlay the previous image? context.fillStyle = sectorColor; context.fillRect(0, 0, canvasWidth, canvasHeight); drawDday('clip'); context.restore(); context.moveTo(0, 0); context.beginPath(); context.fillStyle = '#fff'; context.arc(canvasWidth / 2, canvasHeight/2, radius, 0, 2*Math.PI); context.fill(); ``` Why does the rectangular I'm drawing not overlay the previous image? It's also weird that the canvas is drawn differently sometimes when reloading the site..