Path: blob/main/projects/HexGL/libs/Editor_files/CanvasRenderer.js
4627 views
var pgli = pgli || {};1pgli.render = pgli.render || {};23pgli.render.CanvasRenderer = gamecore.Base.extend('CanvasRenderer',4{ // static56SCOPE_KEYWORDS: {7'use': 0,8'repeat': 1,9'comment': 210},11SCOPE_XFORMS: {12'x': 1,13'y': 2,14'width': 3,15'height': 4,16'scale': 017},18REPEAT_TYPES: {19'none': 'no-repeat',20'x': 'repeat-x',21'y': 'repeat-y',22'xy': 'repeat'23}2425},26{ // instance2728dom: null,29container: null,30canvas: null,31context: null,32width: 1024,33height: 768,34project: null,35xform: [],36xseek: -1,37scope: [],38sseek: -1,39resources: {40images: []41},42variables: null,4344/**45* Bind a new renderer to given canvas46* @param jQuery.DOMElement domElement [description]47* @param Integer width [description]48* @param Integer height [description]49*/50init: function(domElement)51{52this.dom = domElement;53this.container = $('#'+this.dom);54this.canvas = document.createElement("Canvas");55this.container.append(this.canvas);5657this.resize();5859this.variables = new gamecore.Hashtable();60},6162draw: function()63{64clearTrace();6566if(!this.project)67{68trace("#Render failed: No project loaded");69return;70}71trace("#Starting renderer...");7273this.context.clearRect(0, 0, this.width, this.height);7475var ratio = this.getRenderRatio();76var root = this.project.getRootModule();77var w = root.width*ratio;78var h = root.height*ratio;79var x = Math.round((this.width - w)/2);80var y = Math.round((this.height - h)/2);8182this.sreset();83this.xreset(ratio, x, y, w, h);84this.walkModule(root);85},8687walkModule: function(module)88{89if(!module) return;9091trace("#Render: "+module.name);9293if("params" in module) for(p in module.params)94this.sset(p, module.params[p]);9596if("vars" in module)97this.actionVars(module.vars);9899if("fill" in module)100this.actionFill(module.fill);101102if("layers" in module) for(var i=0, len=module.layers.length; i<len; ++i)103{104var layer = module.layers[i];105if("use" in layer)106{107if("repeat" in layer)108{109var iterator;110111try {112iterator = pgli.lang.Parser.parseRepeat(layer.repeat, this.sget());113trace("# Found repeat layer ["+iterator.varname+" from "+iterator.start+" to "+iterator.end+"]");114} catch(e) {115trace("(!) Syntax error in repeat expression ["+layer.repeat+"]");116continue;117}118119while(iterator.loop())120{121this.sset(iterator.varname, iterator.step);122this.walkLayer(layer);123iterator.next();124}125}126else127{128this.walkLayer(layer);129}130}131}132},133134walkLayer: function(layer)135{136var static = pgli.render.CanvasRenderer;137138this.xpush();139this.spush();140141for(k in layer)142{143if(k in static.SCOPE_KEYWORDS)144continue;145else if(k in static.SCOPE_XFORMS)146{147var val = pgli.lang.Parser.parseExpression(layer[k], this.sget(), this.xget());148if(typeof(val) == "number")149{150val = Number(val)*this.xgetr();151}152else153{154var p = val.search("%");155if(p > 0)156val = (Number(val.substr(O, p))/100)*this.xget()[static.SCOPE_XFORMS[k]];157else continue;158}159if(k == "x" || k == "y")160{161val += this.xget()[static.SCOPE_XFORMS[k]];162}163this.xset(static.SCOPE_XFORMS[k], val);164}165else166this.sset(k, pgli.lang.Parser.parseExpression(layer[k], this.sget()), this.xget());167}168169this.walkModule(this.project.getModule(layer.use));170171this.spop();172this.xpop();173},174175actionVars: function(opts)176{177var static = pgli.render.CanvasRenderer;178179for(k in opts)180{181if(k in static.SCOPE_KEYWORDS || k in static.SCOPE_XFORMS)182continue;183else184this.sset(k, pgli.lang.Parser.parseExpression(opts[k], this.sget(), this.xget()));185}186},187188actionFill: function(opts)189{190var static = pgli.render.CanvasRenderer;191192if(opts.type == "image")193{194//trace("# Fill(image)...")195var image = this.loadImage(196pgli.lang.Parser.parseExpression(opts.value, this.sget(), this.xget())197);198199if("repeat" in opts && opts.repeat in static.REPEAT_TYPES)200{201var pattern = this.context.createPattern(image, static.REPEAT_TYPES[opts.repeat]);202203this.context.rect(this.xgetx(), this.xgety(), this.xgetw(), this.xgeth());204this.context.fillStyle = pattern;205this.context.fill();206207//pattern = null;208}209else210{211this.context.drawImage(image, this.xgetx(), this.xgety(), this.xgetw(), this.xgeth());212}213}214else if(opts.type == "color")215{216//trace("# Fill(color)...")217this.context.beginPath();218this.context.rect(this.xgetx(), this.xgety(), this.xgetw(), this.xgeth());219this.context.fillStyle = pgli.lang.Parser.parseExpression(opts.value, this.sget(), this.xget());220this.context.fill();221}222else if(opts.type == "line")223{224//trace("# Fill(line)...")225this.context.beginPath();226this.context.rect(this.xgetx(), this.xgety(), this.xgetw(), this.xgeth());227this.context.lineWidth = 1;228this.context.strokeStyle = pgli.lang.Parser.parseExpression(opts.value, this.sget(), this.xget());229this.context.stroke();230}231},232233loadImage: function(url)234{235var self = this;236if(url in this.resources.images)237{238return this.resources.images[url];239}240else241{242trace("/!\\ Image is loading, will redraw onload.");243var img = new Image();244img.onload = function(){245trace("#Image loaded, redrawing...");246self.draw();247};248img.src = url;249this.resources.images[url] = img;250return img;251}252},253254spush: function()255{256this.scope.push(this.cloneScope(this.sget()));257this.sseek++;258},259260spop: function()261{262this.sseek--;263return this.scope.pop();264},265266sreset: function()267{268this.scope = [{}];269this.sseek = 0;270},271272sget: function()273{274return this.scope[this.sseek];275},276277sset: function(key, value)278{279this.scope[this.sseek][key] = value;280},281282xpush: function(ratio, x, y, h, w)283{284if(ratio == undefined)285if(this.xseek == -1)286this.xform.push([1.0, 0, 0, this.width, this.height]);287else288this.xform.push(this.xget().slice(0))289else290this.xform.push([ratio, x, y, h, w]);291292this.xseek++;293},294295xpop: function()296{297this.xseek--;298return this.xform.pop();299},300301xget: function()302{303return this.xform[this.xseek];304},305306xset: function(key, value)307{308this.xform[this.xseek][key] = value;309},310311xreset: function(ratio, x, y, h, w)312{313this.xseek = -1;314this.xform = [];315this.xpush(ratio, x, y, h, w);316},317318xgetr: function()319{320return this.xform[this.xseek][0];321},322323xgetx: function()324{325return this.xform[this.xseek][1];326},327328xgety: function()329{330return this.xform[this.xseek][2];331},332333xgetw: function()334{335return this.xform[this.xseek][3];336},337338xgeth: function()339{340return this.xform[this.xseek][4];341},342343cloneScope: (function()344{345return function (obj) { Clone.prototype=obj; return new Clone() };346function Clone(){}347}()),348349bindProject: function(project)350{351this.project = project;352},353354resize: function()355{356var w = this.container.width();357var h = this.container.height();358359var size = 0.9*Math.min(w, h);360this.width = size;361this.height = size;362var $canvas = $(this.canvas);363$canvas.width(size);364$canvas.height(size);365this.canvas.width = size;366this.canvas.height = size;367$canvas.css('marginTop', this.container.height() / 2 - size / 2);368$canvas.css('marginLeft', this.container.width() / 2 - size / 2);369370this.context = this.canvas.getContext("2d");371372/*var ctx = this.canvas.getContext("2d");373ctx.clearRect(0, 0, size, size);374ctx.canvas.width = ctx.canvas.height = size;375ctx.font = 'bold 40px Arial';376ctx.textAlign = 'center';377ctx.fillStyle = '#444';378ctx.fillText("Preview", size/2, size/2);*/379},380381getRenderRatio: function()382{383var root = this.project.getRootModule();384if(!root) return;385return Math.min(this.width/root.width, this.height/root.height);386}387388});389390