on d9d1dfd help sign in
elk/core-js/Graphics/Render.js
277 lines 7.7 kB history raw
2var Render = function(){
4function newElement(elementType) {
5 var e = document.createElement(elementType);
6 e.style.padding = "0";
7 e.style.margin = "0";
8 return e;
9};
11function addTo(container, elem) {
12 container.appendChild(elem);
13};
15function makeText(pos,txt) {
16 var e = newElement('div');
17 e.innerHTML = txt;
18 e.style.textAlign = pos;
19 return e;
20};
22function image(src) {
23 var img = newElement('img');
24 img.src = src;
25 img.name = src;
26 img.style.display = "block";
27 return img;
30function fittedImage(w,h,src) {
31 var e = newElement('div');
32 e.style.width = w + 'px';
33 e.style.height = h + 'px';
34 e.style.position = "relative";
35 e.style.overflow = "hidden";
37 var img = newElement('img');
38 img.onload = function() {
39 img.style.position = 'absolute';
40 img.style.margin = 'auto';
42 var sw = w, sh = h;
43 if (w / h > this.width / this.height) {
44 sh = Math.round(this.height * w / this.width);
45 } else {
46 sw = Math.round(this.width * h / this.height);
47 }
48 img.style.width = sw + 'px';
49 img.style.height = sh + 'px';
50 img.style.left = ((w - sw) / 2) + 'px';
51 img.style.top = ((h - sh) / 2) + 'px';
52 };
53 img.src = src;
54 img.name = src;
55 addTo(e,img);
56 return e;
57};
59var video = function(src) {
60 var e = newElement('video');
61 e.controls = "controls";
62 var source = newElement('source');
63 source.src = src;
64 var segs = src.split('.');
65 source.type = "video/" + segs[segs.length-1];
66 addTo(e, source);
67 e.style.display = "block";
68 return e;
69};
71function divify(e) {
72 var div = newElement('div');
73 addTo(div, e);
74 return div;
75};
76function goDown(e) {
77 return e //.tagName === "DIV" ? e : divify(e);
78};
79function goRight(e) {
80 e.style.styleFloat = "left";
81 e.style.cssFloat = "left";
82 return e;
83};
84function goIn(e) {
85 e.style.position = 'absolute';
86 return e;
87};
88function flowWith(f, prep, elist) {
89 var container = newElement('div');
90 for (var i = elist.length; i--; ) {
91 addTo(container, f(prep(elist[i])));
92 }
93 return container;
94};
96function flow(dir,elist) {
97 switch(dir) {
98 case "DDown": elist = elist.slice(0).reverse();
99 case "DUp": return flowWith(goDown,render,elist);
100 case "DRight": elist = elist.slice(0).reverse();
101 case "DLeft": return flowWith(goRight,render,elist);
102 case "DOut": elist = elist.slice(0).reverse();
103 case "DIn": return flowWith(goIn,render,elist);
104 };
105};
107function toPos(pos) {
108 switch(pos[0]) {
109 case "Absolute": return pos[1] + "px";
110 case "Relative": return (pos[1] * 100) + "%";
111 }
114function setPos(pos,e) {
115 e.style.position = 'absolute';
116 e.style.margin = 'auto';
117 switch(pos[0]) {
118 case "Position":
119 if (pos[1][0] !== "Far") e.style.left = 0;
120 if (pos[1][0] !== "Near") e.style.right = 0;
121 if (pos[2][0] !== "Far") e.style.top = 0;
122 if (pos[2][0] !== "Near") e.style.bottom = 0;
123 break;
124 case "PositionAt":
125 e.style.top = toPos(pos[2]);
126 e.style.left = toPos(pos[1]);
127 var shift = "translate(" + ~~(-e.style.width.slice(0,-2) / 2) + "px," + ~~(-e.style.height.slice(0,-2) / 2) + "px)";
128 e.style.transform = shift;
129 e.style.msTransform = shift;
130 e.style.MozTransform = shift;
131 e.style.webkitTransform = shift;
132 e.style.OTransform = shift;
133 break;
134 default:
135 var p = pos[0].slice(-2);
136 e.style[p[0] === "T" ? 'top' : 'bottom'] = toPos(pos[2]);
137 e.style[p[1] === "L" ? 'left' : 'right'] = toPos(pos[1]);
138 }
141function container(pos,elem) {
142 var e = render(elem);
143 setPos(pos,e);
144 var div = newElement('div');
145 div.style.position = "relative";
146 div.style.overflow = "hidden";
147 addTo(div,e);
148 return div;
149};
151function render(elem) {
152 var e = {};
153 switch(elem[2][0]) {
154 case "EText": e = makeText(elem[2][1],elem[2][2]); break;
155 case "EImage": e = image(elem[2][1]); break;
156 case "EVideo": e = video(elem[2][1]); break;
157 case "EFittedImage": e = fittedImage(elem[3],elem[4],elem[2][1]); break;
158 case "EFlow": e = flow(elem[2][1][0],elem[2][2]); break;
159 case "ECollage": e = Collage.collage(elem[2][1],elem[2][2],elem[2][3]); break;
160 case "EEmpty": e = newElement('div'); break;
161 case "EContainer": e = container(elem[2][1],elem[2][2]); break;
162 case "EHtml":
163 e = elem[2][1];
164 if (e.type !== 'button') {
165 var p = Value.getExcess(e);
166 elem[3] -= p[0];
167 elem[4] -= p[1];
168 }
169 break;
170 case "EExternalHtml":
171 e = newElement('div');
172 addTo(e, elem[2][1]);
173 break;
174 }
175 e.id = elem[1];
176 e.style.width = (~~elem[3]) + 'px';
177 e.style.height = (~~elem[4]) + 'px';
178 if (elem[5] !== 1) { e.style.opacity = elem[5]; }
179 if (elem[6][0] === "Just") {
180 e.style.backgroundColor = Elm.Color.extract(elem[6][1]);
181 }
182 if (elem[7][0] === "Just") {
183 var a = newElement('a');
184 a.href = elem[7][1];
185 addTo(a,e);
186 return a;
187 }
188 return e;
189};
191function update(node,curr,next) {
192 if (node.tagName === 'A') { node = node.firstChild; }
193 if (curr[1] === next[1]) return;
194 if (curr[2][0] !== next[2][0]) {
195 return node.parentNode.replaceChild(render(next),node);
196 }
197 var nextE = next[2], currE = curr[2];
198 switch(nextE[0]) {
199 case "EText":
200 if (nextE[1] !== currE[1]) node.style.textAlign = nextE[1];
201 if (nextE[2] !== currE[2]) node.innerHTML = nextE[2];
202 break;
203 case "EImage":
204 if (nextE[1] !== currE[1]) node.src = nextE[1];
205 break;
206 case "EVideo":
207 case "EFittedImage":
208 if (!Value.eq(nextE,currE) || next[3]!==curr[3] || next[4]!==curr[4]) {
209 return node.parentNode.replaceChild(render(next),node);
210 }
211 break;
212 case "ECollage":
213 if (nextE[1] !== currE[1] || nextE[2] !== currE[2] || nextE[3].length !== currE[3].length) {
214 return node.parentNode.replaceChild(render(next),node);
215 }
216 Collage.updateCollage(node,currE[3],nextE[3]);
217 break;
218 case "EFlow":
219 if (nextE[1] !== currE[1]) {
220 return node.parentNode.replaceChild(render(next),node);
221 }
222 var nexts = nextE[2];
223 var kids = node.childNodes;
224 if (nexts.length !== kids.length) {
225 return node.parentNode.replaceChild(render(next),node);
226 }
227 var currs = currE[2];
228 var goDir = function(x) { return x; };
229 switch(nextE[1][0]) {
230 case "DDown": case "DUp": goDir = goDown; break;
231 case "DRight": case "DLeft": goDir = goRight; break;
232 case "DOut": case "DIn": goDir = goIn; break;
233 }
234 for (var i = kids.length; i-- ;) {
235 update(kids[i],currs[i],nexts[i]);
236 goDir(kids[i]);
237 }
238 break;
239 case "EContainer":
240 update(node.childNodes[0],currE[2],nextE[2]);
241 setPos(nextE[1],node.childNodes[0]);
242 break;
243 case "EEmpty":
244 break;
245 case "EHtml":
246 if (next[1] !== curr[1]) {
247 var e = render(next);
248 node.parentNode.replaceChild(e,node);
249 node = e;
250 }
251 if (e.type !== 'button') {
252 var p = Value.getExcess(node);
253 next[3] -= p[0];
254 next[4] -= p[1];
255 }
256 break;
257 case "EExternalHtml":
258 if (next[1] !== curr[1])
259 node.parentNode.replaceChild(render(next),node);
260 break;
261 }
262 if (next[3] !== curr[3]) node.style.width = (~~next[3]) + 'px';
263 if (next[4] !== curr[4]) node.style.height = (~~next[4]) + 'px';
264 if (next[5] !== curr[5]) node.style.opacity = next[5];
265 if (next[6].length === 2) {
266 var clr = Elm.Color.extract(next[6][1]);
267 if (clr !== node.style.backgroundColor) node.style.backgroundColor = clr;
268 }
269 if (next[7].length === 2) {
270 if (curr[7].length === 1 || next[7][1] !== curr[7][1]) node.parentNode.href = next[7][1];
271 }
272 next[1] = curr[1];
275return {render:render,update:update,addTo:addTo,newElement:newElement,flowWith:flowWith,goIn:goIn};
277}();