Canvas antialiasing & retina

by microbians

HTML

<div id="main1" class="main1">
  <div class="title">FAKE-AntiAliasing = normal<br/>RETINA @1</div>
</div>
<div id="main2" class="main2">
  <div class="title">FAKE-AntiAliasing = 1<br/>RETINA @2</div>
</div>

CSS

* {
		margin: 0;
		padding: 0;
		-webkit-touch-callout: none; /* iOS Safari */
		  -webkit-user-select: none; /* Safari */
		   -khtml-user-select: none; /* Konqueror HTML */
		     -moz-user-select: none; /* Firefox */
		      -ms-user-select: none; /* Internet Explorer/Edge */
		          user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */
	}
	body {
		overflow: hidden;
		background-color: white;
	}
	.main1 canvas {
		border: 1px solid red;
	}

	.main2 canvas {
		border: 1px solid blue;
	}

	.main3 canvas {
		border: 1px solid green;
	}


		.main1 {
		position: absolute;
		display: block;
		top: 10px;
		left: 10px;
		width: 250px;
		height: 250px;
		isolation: isolate; /* Important for blend mode works in alpha zones of canvas */
	}
  		.main2 {
		position: absolute;
		display: block;
		top: 10px;
		left: 270px;
		width: 250x;
		height: 250px;
		isolation: isolate; /* Important for blend mode works in alpha zones of canvas */
	}

  		.main3 {
		position: absolute;
		display: block;
		top: 290px;
		left: 10px;
		width: 250x;
		height: 250px;
		isolation: isolate; /* Important for blend mode works in alpha zones of canvas */
	}

JavaScript

/* CANVAS Antialiasing control by microbians.com (also interesting to use for retina @2 propuses)*/

var layerUID = 0;
var canvasWidth=250;
var canvasHeight=250;
  
layer = function(mainElementID, isBuffer, FAKEAA, RETINA) {
		this.main = document.getElementById(mainElementID);
		this.canvas = document.createElement("canvas");
		this.canvas.id = "layer["+layerUID+"]";
		layerUID++;
		this.canvas.style.position="absolute";
		this.canvas.display="block";
		this.canvas.width  = canvasWidth  * RETINA;
		this.canvas.height = canvasHeight * RETINA;
		this.canvas.style.zoom=( 100 / RETINA )+"%";
		//this.canvas.style.filter="url(#turbnoise)"; // SVG Filters -> investigate...
		this.canvas.style.filter="blur("+ FAKEAA +"px)";

		this.canvas.oncontextmenu = function (e) { e.preventDefault(); };
		if (!isBuffer) this.main.appendChild(this.canvas);

		this.ctx = this.canvas.getContext("2d");

		this.ctx.scale(RETINA,RETINA);

		this.ctx._drawImage = this.ctx.drawImage; // Backup function
		this.ctx.drawImage = function(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) {
			this.scale(1/RETINA,1/RETINA);
			sWidth = sWidth || this.canvas.width;
			sHeight = sHeight || this.canvas.height;
			dx = dx || 0;
			dy = dy || 0;
			dWidth = dWidth || this.canvas.width;
			dHeight = dHeight || this.canvas.height;
			this._drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
			this.scale(RETINA,RETINA);
		}

		return this;
}

stage1 = new layer("main1", false, 0, 1);
stage2 = new layer("main2", false, 1, 2);

var context = stage1.ctx;
context.beginPath();
context.arc(125, 125, 100, 0, 2 * Math.PI, false);
context.lineWidth = 1;
context.strokeStyle = '#000';
context.stroke();

var context = stage2.ctx;
context.beginPath();
context.arc(125, 125, 100, 0, 2 * Math.PI, false);
context.lineWidth = 1;
context.strokeStyle = '#000';
context.stroke();