elm/core-js/Graphics/Render.js

177 lines
4.9 KiB
JavaScript
Raw Normal View History

2012-08-31 06:42:33 +00:00
var Render = function(){
function newElement(elementType) {
var e = document.createElement(elementType);
e.style.padding = "0";
e.style.margin = "0";
return e;
};
function addTo(container, elem) {
container.appendChild(elem);
};
function makeText(pos,txt) {
var e = newElement('div');
e.innerHTML = txt;
e.style.textAlign = pos;
return e;
};
function image(src) {
var img = newElement('img');
img.src = Value.toText(src);
img.name = img.src;
return img;
}
function fittedImage(w,h,src) {
var canvas = newElement('canvas');
canvas.style.width = w + 'px';
canvas.style.height = h + 'px';
canvas.width = w;
canvas.height = h;
canvas.innerHTML = "Your browser does not support the canvas element.";
var img = newElement('img');
img.onload = function() {
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
var sx = 0, sy = 0, sWidth = this.width, sHeight = this.height;
if (w / h > this.width / this.height) {
sHeight = this.width * h / w;
sy = (this.height - sHeight) / 2;
} else {
sWidth = this.height * w / h;
sx = (this.width - sWidth) / 2;
}
ctx.drawImage(img, sx, sy, sWidth, sHeight,
0,0, canvas.width, canvas.height);
}
};
img.src = Value.toText(src);
return canvas;
};
var video = function(src) {
src = Value.toText(src);
var e = newElement('video');
e.controls = "controls";
var source = newElement('source');
source.src = src;
var segs = src.split('.');
source.type = "video/" + segs[segs.length-1];
addTo(e, source);
return e;
};
function divify(e) {
var div = newElement('div');
addTo(div, e);
return div;
};
function goDown(e) {
return e //.tagName === "DIV" ? e : divify(e);
};
function goRight(e) {
e.style.styleFloat = "left";
e.style.cssFloat = "left";
return e;
};
function goIn(e) {
e.style.position = 'absolute';
return e;
};
function flowWith(f, prep, elist) {
var container = newElement('div');
for (var i = elist.length; i--; ) {
addTo(container, f(prep(elist[i])));
}
return container;
};
function flow(dir,elist) {
switch(dir) {
case "DDown": elist = elist.slice(0).reverse();
case "DUp": return flowWith(goDown,render,elist);
case "DRight": elist = elist.slice(0).reverse();
case "DLeft": return flowWith(goRight,render,elist);
case "DOut": elist = elist.slice(0).reverse();
case "DIn": return flowWith(goIn,render,elist);
};
};
function render(elem) {
var e = {};
switch(elem[2][0]) {
case "EText": e = makeText(elem[2][1],elem[2][2]); break;
case "EImage": e = image(elem[2][1]); break;
case "EVideo": e = video(elem[2][1]); break;
case "EFittedImage": e = fittedImage(elem[3],elem[4],elem[2][1]); break;
case "EFlow": e = flow(elem[2][1][0],elem[2][2]); break;
case "ECollage": e = Collage.collage(elem[2][1],elem[2][2],elem[2][3]); break;
case "EEmpty": e = newElement('div'); break;
case "EContainer":
e = newElement('div');
}
e.id = elem[1];
e.style.width = (~~elem[3]) + 'px';
e.style.height = (~~elem[4]) + 'px';
if (elem[5] !== 1) { e.style.opacity = elem[5]; }
if (elem[6][0] === "Just") {
e.style.color = ElmCode.Graphics.Color.extract(elem[6][1]);
}
return e;
};
function update(node,curr,next) {
if (curr[1] === next[1]) return;
if (curr[2][0] !== next[2][0]) {
node.parentNode.replaceChild(render(next),node);
}
var nextE = next[2], currE = curr[2];
switch(nextE[0]) {
case "EText":
if (nextE[1] !== currE[1]) node.innerHTML = Value.toText(nextE[1]);
break;
case "EImage":
if (nextE[1] !== currE[1]) node.src = nextE[1];
break;
case "EVideo":
case "EFittedImage":
if (Value.eq(nextE,currE)) break;
return node.parentNode.replaceChild(render(next),node);
case "ECollage":
if (nextE[1] !== currE[1] || nextE[2] !== currE[2]) {
return node.parentNode.replaceChild(render(nextE),node);
}
Collage.updateCollage(node,currE[3],nextE[3]);
break;
case "EFlow":
if (nextE[1] !== currE[1])
return node.parentNode.replaceChild(render(next),node);
var nexts = nextE[2];
var kids = node.childNodes;
if (nexts.length !== kids.length)
return node.parentNode.replaceChild(render(next),node);
var currs = currE[2];
for (var i = kids.length ; i-- ; ) {
update(kids[i],currs[i],nexts[i]);
}
case "EContainer":
case "EEmpty":
}
if (next[3] !== curr[3]) node.style.width = (~~next[3]) + 'px';
if (next[4] !== curr[4]) node.style.height = (~~next[4]) + 'px';
if (next[5] !== curr[5]) node.style.opacity = next[5];
if (next[6].length === 2) {
var clr = ElmCode.Graphics.Color.extract(next[6][1]);
if (clr !== node.style.color) node.style.color = clr;
}
next[1] = curr[1];
}
return {render:render,update:update,addTo:addTo,newElement:newElement,flowWith:flowWith,goIn:goIn};
}();