📄 excanvas.js
字号:
// Copyright 2006 Google Inc.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// TODO: Patterns// TODO: Radial gradient// TODO: Clipping paths// TODO: Coordsize// TODO: Painting mode// TODO: Optimize// TODO: canvas width/height sets content size in moz, border size in ie// TODO: Painting outside the canvas should not be allowed// only add this code if we do not already have a canvas implementationif (!window.CanvasRenderingContext2D) {(function () { var G_vmlCanvasManager_ = { init: function (opt_doc) { var doc = opt_doc || document; if (/MSIE/.test(navigator.userAgent) && !window.opera) { var self = this; doc.attachEvent("onreadystatechange", function () { self.init_(doc); }); } }, init_: function (doc, e) { if (doc.readyState == "complete") { // create xmlns if (!doc.namespaces["g_vml_"]) { doc.namespaces.add("g_vml_", "urn:schemas-microsoft-com:vml"); } // setup default css var ss = doc.createStyleSheet(); ss.cssText = "canvas{display:inline-block;overflow:hidden;" + "text-align:left;}" + "canvas *{behavior:url(#default#VML)}"; // find all canvas elements var els = doc.getElementsByTagName("canvas"); for (var i = 0; i < els.length; i++) { if (!els[i].getContext) { this.initElement(els[i]); } } } }, fixElement_: function (el) { // in IE before version 5.5 we would need to add HTML: to the tag name // but we do not care about IE before version 6 var outerHTML = el.outerHTML; var newEl = document.createElement(outerHTML); // if the tag is still open IE has created the children as siblings and // it has also created a tag with the name "/FOO" if (outerHTML.slice(-2) != "/>") { var tagName = "/" + el.tagName; var ns; // remove content while ((ns = el.nextSibling) && ns.tagName != tagName) { ns.removeNode(); } // remove the incorrect closing tag if (ns) { ns.removeNode(); } } el.parentNode.replaceChild(newEl, el); return newEl; }, /** * Public initializes a canvas element so that it can be used as canvas * element from now on. This is called automatically before the page is * loaded but if you are creating elements using createElement yuo need to * make sure this is called on the element. * @param el {HTMLElement} The canvas element to initialize. */ initElement: function (el) { el = this.fixElement_(el); el.getContext = function () { if (this.context_) { return this.context_; } return this.context_ = new CanvasRenderingContext2D_(this); }; var self = this; //bind el.attachEvent("onpropertychange", function (e) { // we need to watch changes to width and height switch (e.propertyName) { case "width": case "height": // coord size changed? break; } }); // if style.height is set var attrs = el.attributes; if (attrs.width && attrs.width.specified) { // TODO: use runtimeStyle and coordsize // el.getContext().setWidth_(attrs.width.nodeValue); el.style.width = attrs.width.nodeValue + "px"; } if (attrs.height && attrs.height.specified) { // TODO: use runtimeStyle and coordsize // el.getContext().setHeight_(attrs.height.nodeValue); el.style.height = attrs.height.nodeValue + "px"; } //el.getContext().setCoordsize_() } }; G_vmlCanvasManager_.init(); // precompute "00" to "FF" var dec2hex = []; for (var i = 0; i < 16; i++) { for (var j = 0; j < 16; j++) { dec2hex[i * 16 + j] = i.toString(16) + j.toString(16); } } function createMatrixIdentity() { return [ [1, 0, 0], [0, 1, 0], [0, 0, 1] ]; } function matrixMultiply(m1, m2) { var result = createMatrixIdentity(); for (var x = 0; x < 3; x++) { for (var y = 0; y < 3; y++) { var sum = 0; for (var z = 0; z < 3; z++) { sum += m1[x][z] * m2[z][y]; } result[x][y] = sum; } } return result; } function copyState(o1, o2) { o2.fillStyle = o1.fillStyle; o2.lineCap = o1.lineCap; o2.lineJoin = o1.lineJoin; o2.lineWidth = o1.lineWidth; o2.miterLimit = o1.miterLimit; o2.shadowBlur = o1.shadowBlur; o2.shadowColor = o1.shadowColor; o2.shadowOffsetX = o1.shadowOffsetX; o2.shadowOffsetY = o1.shadowOffsetY; o2.strokeStyle = o1.strokeStyle; } function processStyle(styleString) { var str, alpha = 1; styleString = String(styleString); if (styleString.substring(0, 3) == "rgb") { var start = styleString.indexOf("(", 3); var end = styleString.indexOf(")", start + 1); var guts = styleString.substring(start + 1, end).split(","); str = "#"; for (var i = 0; i < 3; i++) { str += dec2hex[parseInt(guts[i])]; } if ((guts.length == 4) && (styleString.substr(3, 1) == "a")) { alpha = guts[3]; } } else { str = styleString; } return [str, alpha]; } function processLineCap(lineCap) { switch (lineCap) { case "butt": return "flat"; case "round": return "round"; case "square": default: return "square"; } } /** * This class implements CanvasRenderingContext2D interface as described by * the WHATWG. * @param surfaceElement {HTMLElement} The element that the 2D context should * be associated with */ function CanvasRenderingContext2D_(surfaceElement) { this.m_ = createMatrixIdentity(); this.element_ = surfaceElement; this.mStack_ = []; this.aStack_ = []; this.currentPath_ = []; // Canvas context properties this.strokeStyle = "#000"; this.fillStyle = "#ccc"; this.lineWidth = 1; this.lineJoin = "miter"; this.lineCap = "butt"; this.miterLimit = 10; this.globalAlpha = 1; }; var contextPrototype = CanvasRenderingContext2D_.prototype; contextPrototype.clearRect = function() { this.element_.innerHTML = ""; this.currentPath_ = []; }; contextPrototype.beginPath = function() { // TODO: Branch current matrix so that save/restore has no effect // as per safari docs. this.currentPath_ = []; }; contextPrototype.moveTo = function(aX, aY) { this.currentPath_.push({type: "moveTo", x: aX, y: aY}); }; contextPrototype.lineTo = function(aX, aY) { this.currentPath_.push({type: "lineTo", x: aX, y: aY}); }; contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) { this.currentPath_.push({type: "bezierCurveTo", cp1x: aCP1x, cp1y: aCP1y, cp2x: aCP2x, cp2y: aCP2y, x: aX, y: aY}); }; contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) { // VML's qb produces different output to Firefox's // FF's behaviour seems to have changed in 1.5.0.1, check this this.bezierCurveTo(aCPx, aCPy, aCPx, aCPy, aX, aY); }; contextPrototype.arc = function(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) { if (!aClockwise) { var t = aStartAngle; aStartAngle = aEndAngle; aEndAngle = t; } var xStart = aX + (Math.cos(aStartAngle) * aRadius); var yStart = aY + Math.round(Math.sin(aStartAngle) * aRadius); var xEnd = aX + (Math.cos(aEndAngle) * aRadius); var yEnd = aY + Math.round(Math.sin(aEndAngle) * aRadius); this.currentPath_.push({type: "arc", x: aX, y: aY, radius: aRadius, xStart: xStart, yStart: yStart, xEnd: xEnd, yEnd: yEnd}); }; contextPrototype.rect = function(aX, aY, aWidth, aHeight) { this.moveTo(aX, aY); this.lineTo(aX + aWidth, aY); this.lineTo(aX + aWidth, aY + aHeight); this.lineTo(aX, aY + aHeight); this.closePath(); }; contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) { // Will destroy any existing path (same as FF behaviour) this.beginPath(); this.moveTo(aX, aY); this.lineTo(aX + aWidth, aY); this.lineTo(aX + aWidth, aY + aHeight); this.lineTo(aX, aY + aHeight); this.closePath(); this.stroke(); }; contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { // Will destroy any existing path (same as FF behaviour) this.beginPath(); this.moveTo(aX, aY); this.lineTo(aX + aWidth, aY); this.lineTo(aX + aWidth, aY + aHeight); this.lineTo(aX, aY + aHeight); this.closePath(); this.fill(); }; contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { var gradient = new CanvasGradient_("gradient"); return gradient; }; contextPrototype.createRadialGradient = function(aX0, aY0, aR0, aX1, aY1, aR1) { var gradient = new CanvasGradient_("gradientradial"); gradient.radius1_ = aR0; gradient.radius2_ = aR1; gradient.focus_.x = aX0; gradient.focus_.y = aY0; return gradient; }; contextPrototype.drawImage = function (image, var_args) { var dx, dy, dw, dh, sx, sy, sw, sh; var w = image.width; var h = image.height;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -