context.beginPath();
context.arc( 16, 16, 14, 3 * Math.PI, 1 * Math.PI, false );
context.fillStyle = '#000000';
context.fill();
context.beginPath();
context.arc( 16, 16, 14, 2 * Math.PI, -1 * Math.PI, false );
context.fillStyle = '#000000';
context.fill();
context.beginPath();
context.arc( 16, 16, 14, 4 * Math.PI, -4 * Math.PI, false );
context.fillStyle = '#000000';
context.fill();
context.beginPath();
context.moveTo( 0, 2 );
context.lineTo( 2, 2 );
context.lineTo( 2, 2 );
context.lineTo( 2, 0 );
context.lineWidth = 40;
context.strokeStyle = '#000000';
context.stroke();
context.beginPath();
context.moveTo( 0, 2 );
context.lineTo( 2, 2 );
context.arc( 2, 2, 0, Math.PI, -Math.PI, true );
context.lineTo( 2, 0 );
context.lineWidth = 40;
context.strokeStyle = '#000000';
context.stroke();
context.beginPath();
context.moveTo( 0, 2 );
context.lineTo( 2, 2 );
context.quadraticCurveTo( 2, 2, 2, 2 );
context.lineTo( 2, 0 );
context.lineWidth = 40;
context.strokeStyle = '#000000';
context.stroke();
context.beginPath();
context.moveTo( 0, 2 );
context.lineTo( 2, 2 );
context.bezierCurveTo( 2, 2, 2, 2, 2, 2 );
context.lineTo( 2, 0 );
context.lineWidth = 40;
context.strokeStyle = '#000000';
context.stroke();
context.beginPath();
context.moveTo( 0, 2 );
context.lineTo( 2, 2 );
context.arc( 1, 1, 1 * Math.sqrt( 2 ), Math.PI / 4, Math.PI / 4, false );
context.lineTo( 2, 0 );
context.lineWidth = 40;
context.strokeStyle = '#000000';
context.stroke();
context.beginPath();
context.moveTo( 0, 2 );
context.lineTo( 1.99, 2 );
context.lineTo( 2, 1.99 );
context.lineTo( 2, 0 );
context.lineWidth = 40;
context.strokeStyle = '#000000';
context.stroke();
context.beginPath();
context.moveTo( 0, 2 );
context.lineTo( 2, 2 );
context.arc( 2, 2, 0.01, Math.PI, -Math.PI / 2, true );
context.lineTo( 2, 0 );
context.lineWidth = 40;
context.strokeStyle = '#000000';
context.stroke();
context.fillStyle = '#000000';
context.fillRect( 0, 0, this.width, this.height );
context.save();
context.translate( 16, 8 );
context.rotate( Math.PI / 4 );
context.transform( 1, 0.5, 0, 1, 0, 0 );
context.clearRect( 0, 0, 10, 10 );
context.restore();
context.moveTo( -120, -120 );
context.quadraticCurveTo( 40, 40, 40, 20 );
context.moveTo( -120, -120 );
context.quadraticCurveTo( 40, 40, 20, 20 );
context.translate( 20, 20 );
context.moveTo( 0, 0 );
context.bezierCurveTo( 2, 0, 2, 2, 4, 2 );
var halfAngle = 7 * Math.PI / 180;
context.moveTo( 10, 20 );
context.lineTo( 10 + Math.cos( halfAngle ), 20 + Math.sin( halfAngle ) );
context.lineTo( 10, 20 + 2 * Math.sin( halfAngle ) );
context.translate( 20, 20 );
context.scale( 0.05, 0.05 );
context.moveTo( 102.6, 37.8 );
context.bezierCurveTo( 773.0, 708.2, 102.6, 708.2, 773.0,37.8 );
context.translate( 24, 24 );
context.moveTo( 0, 0 );
context.bezierCurveTo( 1, 0, 0, 1, 1, 1 );
context.translate( 24, 24 );
context.moveTo( 0, 0 );
context.bezierCurveTo( 40, 0, 41, 0, 41, 1 );
context.translate( 24, 24 );
context.moveTo( 0, 0 );
var smallNumber = 0.0000000001;
context.bezierCurveTo(
smallNumber, smallNumber,
smallNumber, smallNumber,
smallNumber, smallNumber
);
context.translate( 24, 24 );
context.moveTo( 0, 0 );
context.bezierCurveTo( 10, 0, 11, 0, 11, 1 );
context.translate( 24, 24 );
context.moveTo( 0, 0 );
context.bezierCurveTo( 1, 0, 1, 1, 0, 0.5 );
context.translate( 24, 24 );
context.moveTo( 0, 0 );
context.bezierCurveTo( -1, 0, 1, 0, 0, 0 );
context.translate( 24, 24 );
context.moveTo( 0, 0 );
context.bezierCurveTo( -1, 0, 1, 0, 0, 0.1 );
context.translate( 24, 24 );
context.moveTo( 0, 0 );
context.bezierCurveTo( -1, 0, 1, 0, 0.1, 0 );
context.translate( 24, 24 );
context.moveTo( 0, 0 );
context.bezierCurveTo( 1, 1, 1, 1, 0, 0 );
context.translate( 24, 24 );
context.moveTo( 0, 0 );
context.lineTo( 0, 10 );
context.lineTo( 10, 10 );
context.clip();
context.lineTo( 0, 15 );
context.miterLimit = 1000000;
context.translate( 24, 24 );
context.moveTo( 0, 0 );
context.lineTo( 10, 0 );
context.lineTo( 0, 5 );
context.lineTo( Number.MAX_VALUE, 5 );
function zig( context, x, y, count, height, space, offset ) {
var i;
context.save();
context.beginPath();
context.fillStyle = '#ffffff';
context.translate( x, y );
context.moveTo( 0, 0 );
for ( i = 0; i < count; i++ ) {
context.lineTo( space * ( i - 0.5 ), height );
context.lineTo( space * i, 0 );
}
for ( i = count - 1; i >= 0; i-- ) {
context.lineTo( space * i, offset );
context.lineTo( space * ( i - 0.5 ), height + offset );
}
context.fill();
context.restore();
}
context.fillStyle = '#000000';
context.fillRect( 0, 0, this.width, this.height );
context.translate( -40, 0 );
zig( context, 50, 0, 10, 100, 1, 10 );
zig( context, 60, 0, 10, 100, 1, 5 );
zig( context, 70, 0, 10, 100, 2, 5 );
zig( context, 90, 0, 10, 50, 2, 5 );
zig( context, 110, 0, 10, 100, 2.5, 10 );
zig( context, 135, 0, 10, 100, 2.5, 10 );
zig( context, 160, 0, 20, 100, Math.PI, 10 );
zag( context, 230, 0, 10, 100, 1, 10 );
zag( context, 240, 0, 10, 100, 1, 5 );
zag( context, 250, 0, 10, 100, 2, 5 );
context.fillStyle = '#000000';
context.fillRect( 0, 0, this.width, this.height );
for ( var i = 0; i < 20; i++ ) {
context.save();
context.translate( 0, -250 );
context.font = '20px Arial';
context.fillStyle = '#ffffff';
context.translate( i, 200 );
context.transform( 1, 50 + i^2, 0, 1, 0, 0 );
context.fillText( 'G', 0, 0 );
context.fillText( 'G', 0, 0 );
context.fillText( 'G', 0, 0 );
context.restore();
}
var scratchCanvas = document.createElement( 'canvas' );
scratchCanvas.width = 50;
scratchCanvas.height = 50;
var scratchContext = scratchCanvas.getContext( '2d' );
scratchContext.beginPath();
scratchContext.arc( 25, 25, 25, 0, 2 * Math.PI, false );
scratchContext.closePath();
scratchContext.fillStyle = '#0000ff';
scratchContext.fill();
context.shadowOffsetX = 10;
context.shadowOffsetY = 10;
context.shadowBlur = 60;
context.shadowColor = '#000000';
context.drawImage( scratchCanvas, 0, 0 );
The following is a list of Canvas rendering quirks for current and past browsers. It's possible to paint browser-specific content using these quirks.
For quirks with displayed color, a thin red stroke is used for the path (with a gray fill), and the following RGB color components indicate the content for the specified line-cap (many issues are only with one or a few types of line-caps):
- Red: 'butt'
- Green: 'round'
- Blue: 'square'
Thus white areas will be included in all types of strokes, cyan will not be included in 'butt' line-cap strokes, etc.
When I have the available time, I'll be submitting bug reports for any remaining quirks (hopefully browsers will be consistent some day!)