UNPKG

bodymovin

Version:

After Effects plugin for exporting animations to SVG + JavaScript or canvas + JavaScript

161 lines (146 loc) 5.46 kB
/** * Copyright 2014 Google Inc. All rights reserved. * * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. * * @fileoverview Description of this file. * * A polyfill for HTML Canvas features, including * Path2D support. */ if (CanvasRenderingContext2D.prototype.ellipse === undefined) { CanvasRenderingContext2D.prototype.ellipse = function(x, y, radiusX, radiusY, rotation, startAngle, endAngle, antiClockwise) { this.save(); this.translate(x, y); this.rotate(rotation); this.scale(radiusX, radiusY); this.arc(0, 0, 1, startAngle, endAngle, antiClockwise); this.restore(); }; } var BM_Path2D; function BM_CanvasRenderingContext2D(renderer){ this.renderer = renderer; } (function() { var canvasPrototype = CanvasRenderingContext2D.prototype; var bm_canvasPrototype = BM_CanvasRenderingContext2D.prototype; function Path_(arg) { this.ops_ = []; if (arg === undefined) { return; } if (typeof arg == 'string') { try { this.ops_ = parser.parse(arg); } catch(e) { // Treat an invalid SVG path as an empty path. } } else if (arg.hasOwnProperty('ops_')) { this.ops_ = arg.ops_.slice(0); } else { throw 'Error: ' + typeof arg + 'is not a valid argument to Path'; } } // TODO(jcgregorio) test for arcTo and implement via something. // Path methods that map simply to the CanvasRenderingContext2D. var simple_mapping = [ 'closePath', 'moveTo', 'lineTo', 'quadraticCurveTo', 'bezierCurveTo', 'rect', 'arc', 'arcTo', 'ellipse' ]; function createFunction(name) { return function() { var i, len = arguments.length; var args = []; for(i=0;i<len;i+=1){ args.push(arguments[i]); } this.ops_.push({type: name, args: args}); }; } // Add simple_mapping methods to Path2D. for (var i=0; i<simple_mapping.length; i++) { var name = simple_mapping[i]; Path_.prototype[name] = createFunction(name); } Path_.prototype.addPath = function(path, tr) { var hasTx = false; if (tr && (tr[0] != 1 || tr[1] !== 0 || tr[2] !== 0 || tr[3] != 1 || tr[4] !== 0 || tr[5] !== 0)) { hasTx = true; this.ops_.push({type: 'save', args: []}); this.ops_.push({type: 'transform', args: [tr[0], tr[1], tr[2], tr[3], tr[4], tr[5]]}); } this.ops_ = this.ops_.concat(path.ops_); if (hasTx) { this.ops_.push({type: 'restore', args: []}); } }; var original_fill = canvasPrototype.fill; var original_stroke = canvasPrototype.stroke; var original_clip = canvasPrototype.clip; // Replace methods on CanvasRenderingContext2D with ones that understand Path2D. bm_canvasPrototype.fill = function(arg) { if (arg instanceof Path_) { this.renderer.canvasContext.beginPath(); for (var i = 0, len = arg.ops_.length; i < len; i++) { var op = arg.ops_[i]; if(op.type == 'transform'){ this.renderer.ctxTransform(op.args); }else if(op.type == 'save'){ this.renderer.save(); }else if(op.type == 'restore'){ this.renderer.restore(); }else{ this.renderer.canvasContext[op.type].apply(this.renderer.canvasContext, op.args); } } len = arguments.length; var args = []; for(i=1;i<len;i+=1){ args.push(arguments[i]); } original_fill.apply(this.renderer.canvasContext, args); } else { original_fill.apply(this.renderer.canvasContext, arguments); } }; bm_canvasPrototype.stroke = function(arg) { if (arg instanceof Path_) { this.renderer.canvasContext.beginPath(); for (var i = 0, len = arg.ops_.length; i < len; i++) { var op = arg.ops_[i]; this.renderer.canvasContext[op.type].apply(this.renderer.canvasContext, op.args); } original_stroke.call(this.renderer.canvasContext); } else { original_stroke.call(this.renderer.canvasContext); } }; bm_canvasPrototype.clip = function(arg) { if (arg instanceof Path_) { this.renderer.canvasContext.beginPath(); for (var i = 0, len = arg.ops_.length; i < len; i++) { var op = arg.ops_[i]; this.renderer.canvasContext[op.type].apply(this.renderer.canvasContext, op.args); } len = arguments.length; var args = []; for(i=1;i<len;i+=1){ args.push(arguments[i]); } original_clip.apply(this.renderer.canvasContext, args); } else { original_clip.apply(this.renderer.canvasContext, arguments); } }; // Set up externs. BM_Path2D = Path_; })();