From a30f0ff848beb8d205c9e4c061973f5955181f79 Mon Sep 17 00:00:00 2001 From: Julian Viereck Date: Tue, 22 Nov 2011 21:00:04 +0100 Subject: [PATCH 1/2] Implement ctx.mozCurrentTransform and ctx.mozCurrentTransformInverse shim --- src/canvas.js | 109 +++++++++++++++++++++++++++++++++++++++++++++++++ src/pattern.js | 2 + 2 files changed, 111 insertions(+) diff --git a/src/canvas.js b/src/canvas.js index 9b3ed0ba9..d9c60f416 100644 --- a/src/canvas.js +++ b/src/canvas.js @@ -59,6 +59,111 @@ function ScratchCanvas(width, height) { return canvas; } +function addCtxCurrentTransform(ctx) { + // If the context doesn't expose a `mozCurrentTransform`, add a JS based on. + if (!ctx.mozCurrentTransform) { + // Store the original context + ctx._originalSave = ctx.save; + ctx._originalRestore = ctx.restore; + ctx._originalRotate = ctx.rotate; + ctx._originalScale = ctx.scale; + ctx._originalTranslate = ctx.translate; + ctx._originalTransform = ctx.transform; + + ctx._transformMatrix = [1, 0, 0, 1, 0, 0]; + ctx._transformStack = []; + + ctx.__defineGetter__('mozCurrentTransform', function getCurrentTransform() { + return this._transformMatrix; + }); + + ctx.__defineGetter__('mozCurrentTransformInverse', + function getCurrentTransformInverse() { + // Calculation done using WolframAlpha: + // http://www.wolframalpha.com/input/? + // i=Inverse+{{a%2C+c%2C+e}%2C+{b%2C+d%2C+f}%2C+{0%2C+0%2C+1}} + + var m = this._transformMatrix; + var a = m[0], b = m[1], c = m[2], d = m[3], e = m[4], f = m[5]; + + return [ + d / (a * d - b * c), + b / (b * c - a * d), + c / (b * c - a * d), + a / (a * d - b * c), + (d * e - c * f) / (b * c - a * d), + (b * e - a * f) / (a * d - b * c) + ]; + } + ); + + ctx.save = function ctxSave() { + var old = this._transformMatrix; + this._transformStack.push(old); + this._transformMatrix = old.slice(0, 6); + + this._originalSave(); + }; + + ctx.restore = function ctxRestore() { + var prev = this._transformStack.pop(); + if (prev) { + this._transformMatrix = prev; + this._originalRestore(); + } + } + + ctx.translate = function ctxTranslate(x, y) { + var m = this._transformMatrix; + m[4] = m[0] * x + m[2] * y + m[4]; + m[5] = m[1] * x + m[3] * y + m[5]; + + this._originalTranslate(x, y); + } + + ctx.scale = function ctxScale(x, y) { + var m = this._transformMatrix; + m[0] = m[0] * x; + m[1] = m[1] * x; + m[2] = m[2] * y; + m[3] = m[3] * y; + + this._originalScale(x, y); + } + + ctx.transform = function ctxTransform(a, b, c, d, e, f) { + var m = this._transformMatrix; + this._transformMatrix = [ + m[0] * a + m[2] * b, + m[1] * a + m[3] * b, + m[0] * c + m[2] * d, + m[1] * c + m[3] * d, + m[0] * e + m[2] * f + m[4], + m[1] * e + m[3] * f + m[5] + ]; + + ctx._originalTransform(a, b, c, d, e, f); + } + + ctx.rotate = function ctxRotate(angle) { + var cosValue = Math.cos(angle); + var sinValue = Math.sin(angle); + + var m = this._transformMatrix; + this._transformMatrix = [ + m[0] * cosValue + m[2] * sinValue, + m[1] * cosValue + m[3] * sinValue, + m[0] * (-sinValue) + m[2] * cosValue, + m[1] * (-sinValue) + m[3] * cosValue, + m[4], + m[5] + ]; + + this._originalRotate(angle); + } + } +} + var CanvasGraphics = (function canvasGraphics() { // Defines the time the executeIRQueue is going to be executing // before it stops and shedules a continue of execution. @@ -77,6 +182,10 @@ var CanvasGraphics = (function canvasGraphics() { this.xobjs = null; this.ScratchCanvas = ScratchCanvas; this.objs = objs; + + if (canvasCtx) { + addCtxCurrentTransform(canvasCtx); + } } var LINE_CAP_STYLES = ['butt', 'round', 'square']; diff --git a/src/pattern.js b/src/pattern.js index 72d13d896..c565e8b7f 100644 --- a/src/pattern.js +++ b/src/pattern.js @@ -217,6 +217,8 @@ var TilingPattern = (function tilingPattern() { // set the new canvas element context as the graphics context var tmpCtx = tmpCanvas.getContext('2d'); + addCtxCurrentTransform(tmpCtx); + var graphics = new CanvasGraphics(tmpCtx, objs); switch (paintType) { From 36e618c373f718320faa0540536263a7c37068f9 Mon Sep 17 00:00:00 2001 From: Julian Viereck Date: Sun, 27 Nov 2011 09:22:08 +0100 Subject: [PATCH 2/2] Address Yury's review comments + remove call to addCtxCurrentTransform in pattern.js as the contet is added during the CanvasGraphics constructor already --- src/canvas.js | 41 +++++++++++++++++++++++------------------ src/pattern.js | 2 -- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/canvas.js b/src/canvas.js index d9c60f416..035651b0f 100644 --- a/src/canvas.js +++ b/src/canvas.js @@ -59,7 +59,7 @@ function ScratchCanvas(width, height) { return canvas; } -function addCtxCurrentTransform(ctx) { +function addContextCurrentTransform(ctx) { // If the context doesn't expose a `mozCurrentTransform`, add a JS based on. if (!ctx.mozCurrentTransform) { // Store the original context @@ -73,12 +73,14 @@ function addCtxCurrentTransform(ctx) { ctx._transformMatrix = [1, 0, 0, 1, 0, 0]; ctx._transformStack = []; - ctx.__defineGetter__('mozCurrentTransform', function getCurrentTransform() { - return this._transformMatrix; + Object.defineProperty(ctx, 'mozCurrentTransform', { + get: function getCurrentTransform() { + return this._transformMatrix; + } }); - ctx.__defineGetter__('mozCurrentTransformInverse', - function getCurrentTransformInverse() { + Object.defineProperty(ctx, 'mozCurrentTransformInverse', { + get: function getCurrentTransformInverse() { // Calculation done using WolframAlpha: // http://www.wolframalpha.com/input/? // i=Inverse+{{a%2C+c%2C+e}%2C+{b%2C+d%2C+f}%2C+{0%2C+0%2C+1}} @@ -86,16 +88,19 @@ function addCtxCurrentTransform(ctx) { var m = this._transformMatrix; var a = m[0], b = m[1], c = m[2], d = m[3], e = m[4], f = m[5]; + var ad_bc = a * d - b * c; + var bc_ad = b * c - a * d; + return [ - d / (a * d - b * c), - b / (b * c - a * d), - c / (b * c - a * d), - a / (a * d - b * c), - (d * e - c * f) / (b * c - a * d), - (b * e - a * f) / (a * d - b * c) + d / ad_bc, + b / bc_ad, + c / bc_ad, + a / ad_bc, + (d * e - c * f) / bc_ad, + (b * e - a * f) / ad_bc ]; } - ); + }); ctx.save = function ctxSave() { var old = this._transformMatrix; @@ -111,7 +116,7 @@ function addCtxCurrentTransform(ctx) { this._transformMatrix = prev; this._originalRestore(); } - } + }; ctx.translate = function ctxTranslate(x, y) { var m = this._transformMatrix; @@ -119,7 +124,7 @@ function addCtxCurrentTransform(ctx) { m[5] = m[1] * x + m[3] * y + m[5]; this._originalTranslate(x, y); - } + }; ctx.scale = function ctxScale(x, y) { var m = this._transformMatrix; @@ -129,7 +134,7 @@ function addCtxCurrentTransform(ctx) { m[3] = m[3] * y; this._originalScale(x, y); - } + }; ctx.transform = function ctxTransform(a, b, c, d, e, f) { var m = this._transformMatrix; @@ -143,7 +148,7 @@ function addCtxCurrentTransform(ctx) { ]; ctx._originalTransform(a, b, c, d, e, f); - } + }; ctx.rotate = function ctxRotate(angle) { var cosValue = Math.cos(angle); @@ -160,7 +165,7 @@ function addCtxCurrentTransform(ctx) { ]; this._originalRotate(angle); - } + }; } } @@ -184,7 +189,7 @@ var CanvasGraphics = (function canvasGraphics() { this.objs = objs; if (canvasCtx) { - addCtxCurrentTransform(canvasCtx); + addContextCurrentTransform(canvasCtx); } } diff --git a/src/pattern.js b/src/pattern.js index c565e8b7f..72d13d896 100644 --- a/src/pattern.js +++ b/src/pattern.js @@ -217,8 +217,6 @@ var TilingPattern = (function tilingPattern() { // set the new canvas element context as the graphics context var tmpCtx = tmpCanvas.getContext('2d'); - addCtxCurrentTransform(tmpCtx); - var graphics = new CanvasGraphics(tmpCtx, objs); switch (paintType) {