| /*----------------------------------------------------------------------------\ |
| | IE Canvas 1.0 | |
| |-----------------------------------------------------------------------------| |
| | Created by Emil A Eklund | |
| | (http://eae.net/contact/emil) | |
| |-----------------------------------------------------------------------------| |
| | Implementation of the canvas API for Internet Explorer. Uses VML. | |
| |-----------------------------------------------------------------------------| |
| | Copyright (c) 2005 Emil A Eklund | |
| |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -| |
| | This program is free software; you can redistribute it and/or modify it | |
| | under the terms of the MIT License. | |
| |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -| |
| | Permission is hereby granted, free of charge, to any person obtaining a | |
| | copy of this software and associated documentation files (the "Software"), | |
| | to deal in the Software without restriction, including without limitation | |
| | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| | and/or sell copies of the Software, and to permit persons to whom the | |
| | Software is furnished to do so, subject to the following conditions: | |
| | The above copyright notice and this permission notice shall be included in | |
| | all copies or substantial portions of the Software. | |
| |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -| |
| | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| | DEALINGS IN THE SOFTWARE. | |
| |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -| |
| | http://eae.net/license/mit | |
| |-----------------------------------------------------------------------------| |
| | Dependencies: canvas.js - For initialization of canvas elements | |
| |-----------------------------------------------------------------------------| |
| | 2005-12-27 | Work started. | |
| | 2005-12-29 | First version posted. | |
| | 2006-01-03 | Fixed bug in moveTo and lineTo, arguments where not converted | |
| | | to int which could cause IE to enter an endless loop. Disabled | |
| | | antalias for fillRect to better comply with the Mozilla, Opera | |
| | | and possibly Safari implementations where using fillRect is | |
| | | about the only way to raw non antialiased lines. | |
| |-----------------------------------------------------------------------------| |
| | Created 2005-12-27 | All changes are in the log above. | Updated 2006-01-03 | |
| \----------------------------------------------------------------------------*/ |
| |
| <public:component> |
| <public:method name="getContext" /> |
| <public:attach event="oncontentready" onevent="initCanvas()"/> |
| </public:component> |
| |
| <script language="JScript"> |
| |
| function getContext() { |
| return element.context; |
| } |
| |
| function initCanvas() { |
| element.context = new IECanvasContext(); |
| element.style.position = 'relative'; |
| element.style.display = 'block'; |
| element.style.overflow = 'hidden'; |
| } |
| |
| |
| |
| function IECanvasContext() { |
| this.fillStyle = 'black'; |
| this.globalAlpha = 1.0; |
| this.globalCompositeOperation = ''; |
| this.lineCap = ''; |
| this.lineJoin = ''; |
| this.lineWidth = '0'; |
| this.miterLimit = ''; |
| this.shadowBlur = ''; |
| this.shadowColor = ''; |
| this.shadowOffsetX = ''; |
| this.shadowOffsetY = ''; |
| this.strokeStyle = 'black'; |
| this._path = ''; |
| this._stateStack = new Array(); |
| this._offsetX = 0; |
| this._offsetY = 0; |
| this._rotation = 0; |
| }; |
| |
| IECanvasContext.prototype.save = function() { |
| var o; |
| |
| o = new Object(); |
| this._copyState(this, o); |
| this._stateStack.push(o); |
| }; |
| |
| IECanvasContext.prototype.restore = function() { |
| var o, n; |
| |
| n = this._stateStack.length - 1; |
| if (n < 0) { return; } |
| |
| o = this._stateStack[n]; |
| this._copyState(o, this); |
| this._stateStack.splice(n, 1); |
| }; |
| |
| IECanvasContext.prototype._copyState = function(oFrom, oTo) { |
| oTo.fillStyle = oFrom.fillStyle; |
| oTo.lineCap = oFrom.lineCap; |
| oTo.lineJoin = oFrom.lineJoin; |
| oTo.lineWidth = oFrom.lineWidth; |
| oTo.miterLimit = oFrom.miterLimit; |
| oTo.shadowBlur = oFrom.shadowBlur; |
| oTo.shadowColor = oFrom.shadowColor; |
| oTo.shadowOffsetX = oFrom.shadowOffsetX; |
| oTo.shadowOffsetY = oFrom.shadowOffsetY; |
| oTo._offsetX = oFrom._offsetX; |
| oTo._offsetY = oFrom._offsetY; |
| oTo._rotation = oFrom._rotation; |
| }; |
| |
| IECanvasContext.prototype.rotate = function(r) { |
| var MAX = Math.PI * 2; |
| |
| this._rotation += r; |
| while (this._rotation > MAX) { this._rotation = MAX - this._rotation; } |
| }; |
| |
| IECanvasContext.prototype.scale = function() { }; |
| |
| IECanvasContext.prototype.translate = function(x, y) { |
| this._offsetX += x; |
| this._offsetY += y; |
| }; |
| |
| IECanvasContext.prototype.bezierCurveTo = function(cp1x, cp1y, cp2x, cp2y, x, y) { |
| if (this._path) { this._path += ' '; } |
| |
| this._path += 'qb' + cp1x + ',' + cp1y + ',' + cp2x + ',' + cp2y + ',' + x + ',' + y; |
| }; |
| |
| |
| IECanvasContext.prototype.clip = function() { }; |
| |
| IECanvasContext.prototype.beginPath = function() { |
| this._path = ''; |
| }; |
| |
| IECanvasContext.prototype.closePath = function() { |
| if (this._path) { this._path += ' '; } |
| this._path += 'x'; |
| }; |
| |
| IECanvasContext.prototype.lineTo = function(x, y) { |
| if (this._path) { this._path += ' '; } |
| this._path += 'l' + parseInt(x) + ',' + parseInt(y); |
| }; |
| |
| IECanvasContext.prototype.moveTo = function(x, y) { |
| if (this._path) { this._path += ' '; } |
| this._path += 'm' + parseInt(x) + ',' + parseInt(y); |
| }; |
| |
| IECanvasContext.prototype.stroke = function() { |
| var o, s, cosa, sina, cx, cy, x, y; |
| |
| if (!this._path) { return; } |
| |
| this._path += ' e'; |
| |
| o = element.ownerDocument.createElement('v:shape'); |
| o.fillColor = 'none'; |
| o.filled = false; |
| o.strokeColor = this.strokeStyle; |
| o.stroked = true; |
| o.weight = this.lineWidth; |
| o.coordsize = element.offsetWidth + ',' + element.offsetHeight; |
| o.style.position = 'absolute'; |
| o.style.left = this._offsetX; |
| o.style.top = this._offsetY; |
| o.style.width = element.offsetWidth; |
| o.style.height = element.offsetHeight; |
| o.path = this._path; |
| |
| s = element.ownerDocument.createElement('v:stroke'); |
| s.opacity = this.globalAlpha; |
| o.appendChild(s); |
| |
| if (this._rotation) { |
| r = element.ownerDocument.createElement('v:group'); |
| r.style.position = 'absolute'; |
| r.style.left = 0; |
| r.style.top = 0; |
| r.style.width = element.offsetWidth; |
| r.style.height = element.offsetHeight; |
| r.coordsize = o.coordsize; |
| r.style.rotation = Math.round((this._rotation * 180) / Math.PI); |
| r.style.rotationCenter = '0,0'; |
| r.appendChild(o); |
| element.appendChild(r); |
| |
| cosa = Math.cos(this._rotation); |
| sina = Math.sin(this._rotation); |
| cx = element.offsetWidth / 2; |
| cy = element.offsetHeight / 2; |
| |
| x = ( cx*(1-cosa) + cy*sina); |
| y = (-cx*sina + cy*(1-cosa)); |
| |
| r.style.left = x * -1; |
| r.style.top = y * -1; |
| } |
| else { element.appendChild(o); } |
| }; |
| |
| IECanvasContext.prototype.fill = function() { |
| var o, f, r; |
| |
| if (!this._path) { return; } |
| |
| this._path += ' e'; |
| |
| o = element.ownerDocument.createElement('v:shape'); |
| o.fillColor = this.fillStyle; |
| o.strokeColor = this.strokeStyle; |
| o.stroked = false; |
| o.weight = this.lineWidth; |
| o.coordsize = element.offsetWidth + ',' + element.offsetHeight; |
| o.style.position = 'absolute'; |
| o.style.left = this._offsetX; |
| o.style.top = this._offsetY; |
| o.style.width = element.offsetWidth; |
| o.style.height = element.offsetHeight; |
| o.path = this._path; |
| |
| f = element.ownerDocument.createElement('v:fill'); |
| f.opacity = this.globalAlpha; |
| o.appendChild(f); |
| |
| if (this._rotation) { |
| r = element.ownerDocument.createElement('v:group'); |
| r.style.position = 'absolute'; |
| r.style.left = 0; |
| r.style.top = 0; |
| r.style.width = element.offsetWidth; |
| r.style.height = element.offsetHeight; |
| r.coordsize = o.coordsize; |
| r.style.rotation = Math.round((this._rotation * 180) / Math.PI); |
| r.style.rotationCenter = '0,0'; |
| r.appendChild(o); |
| element.appendChild(r); |
| |
| cosa = Math.cos(this._rotation); |
| sina = Math.sin(this._rotation); |
| cx = (element.offsetWidth) / 2; |
| cy = (element.offsetHeight) / 2; |
| x = ( cx*(1-cosa) + cy*sina); |
| y = (-cx*sina + cy*(1-cosa)); |
| |
| r.style.left = x * -1; |
| r.style.top = y * -1; |
| } |
| else { element.appendChild(o); } |
| }; |
| |
| IECanvasContext.prototype.arcTo = function(x1, y1, x2, y2, radius) { |
| // not implemented in gecko, not implemented here |
| }; |
| |
| IECanvasContext.prototype.quadraticCurveTo = function(cpx, cpy, x, y) { |
| if (this._path) { this._path += ' '; } |
| |
| this._path += 'qb' + cpx + ',' + cpy + ',' + x + ',' + y; |
| }; |
| |
| IECanvasContext.prototype.arc = function(x, y, radius, startAngle, endAngle, clockwise) { |
| var xi, yi, x1, y1, x2, y2, x3, y3, x4, y4; |
| |
| if (this._path) { this._path += ' '; } |
| |
| xi = parseFloat(x); |
| yi = parseFloat(y); |
| |
| x1 = xi - radius; |
| y1 = yi - radius; |
| |
| x2 = xi + radius; |
| y2 = yi + radius; |
| |
| if (clockwise) { |
| x3 = xi + (Math.cos(startAngle) * radius); |
| y3 = yi + (Math.sin(startAngle) * radius); |
| |
| x4 = xi + (Math.cos(endAngle) * radius); |
| y4 = yi + (Math.sin(endAngle) * radius); |
| } |
| else { |
| x3 = xi + (Math.cos(endAngle) * radius); |
| y3 = yi + (Math.sin(endAngle) * radius); |
| |
| x4 = xi + (Math.cos(startAngle) * radius); |
| y4 = yi + (Math.sin(startAngle) * radius); |
| } |
| |
| x3 = Math.round(x3); |
| y3 = Math.round(y3); |
| x4 = Math.round(x4); |
| y4 = Math.round(y4); |
| |
| this._path += 'ar' + x1 + ',' + y1 + ',' + x2 + ',' + y2 + ',' + x3 + ',' + y3 + ',' + x4 + ',' + y4; |
| }; |
| |
| |
| IECanvasContext.prototype.rect = function(x, y, w, h) { |
| var x1, y1, x2, y2; |
| |
| x2 = x + w; |
| y2 = y + h; |
| |
| x1 = Math.round(x); |
| y1 = Math.round(y); |
| x2 = Math.round(x2); |
| y2 = Math.round(y2); |
| |
| this._path += 'm' + x1 + ',' + y1; |
| this._path += ' l' + x2 + ',' + y1; |
| this._path += ' l' + x2 + ',' + y2; |
| this._path += ' l' + x1 + ',' + y2; |
| this._path += ' x' |
| }; |
| |
| IECanvasContext.prototype.strokeRect = function(x, y, w, h) { |
| var o, s; |
| |
| o = element.ownerDocument.createElement('v:rect'); |
| o.fillColor = 'none'; |
| o.filled = false; |
| o.strokeColor = this.strokeStyle; |
| o.stroked = true; |
| o.weight = this.lineWidth; |
| o.style.position = 'absolute'; |
| o.style.left = this._offsetX + x; |
| o.style.top = this._offsetY + y; |
| o.style.width = w; |
| o.style.height = h; |
| |
| s = element.ownerDocument.createElement('v:fill'); |
| s.opacity = this.globalAlpha; |
| o.appendChild(s); |
| |
| element.appendChild(o); |
| }; |
| |
| IECanvasContext.prototype.clearRect = function(x, y, w, h) { }; |
| |
| |
| IECanvasContext.prototype.fillRect = function(x, y, w, h) { |
| var o, f; |
| |
| if ((x == 0) && (y == 0) && (w == element.offsetWidth) && (h == element.offsetHeight) && (this._offsetX == 0) && (this._offsetY == 0) && (this.globalAlpha == 1)) { |
| while (element.firstChild) { element.removeChild(element.lastChild); } |
| } |
| |
| o = element.ownerDocument.createElement('v:rect'); |
| o.fillColor = this.fillStyle; |
| o.filled = true; |
| o.stroked = false; |
| o.weight = 0; |
| o.style.position = 'absolute'; |
| o.style.left = this._offsetX + x; |
| o.style.top = this._offsetY + y; |
| o.style.width = w; |
| o.style.height = h; |
| o.style.antialias = 'false'; |
| |
| f = element.ownerDocument.createElement('v:fill'); |
| f.opacity = this.globalAlpha; |
| o.appendChild(f); |
| |
| element.appendChild(o); |
| }; |
| |
| IECanvasContext.prototype.addColorStop = function() { }; |
| IECanvasContext.prototype.createLinearGradient = function() { }; |
| IECanvasContext.prototype.createPattern = function() { }; |
| IECanvasContext.prototype.createRadialGradient = function() { }; |
| |
| IECanvasContext.prototype.drawImage = function() { }; |
| IECanvasContext.prototype.drawImageFromRect = function() { }; |
| |
| </script> |