@@ -2,10 +2,11 @@
2ElmRuntime.Render.Collage = function() {
2ElmRuntime.Render.Collage = function() {
3'use strict';
3'use strict';
5+var Render = ElmRuntime.use(ElmRuntime.Render.Element);
5var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
6var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
6var newElement = Utils.newElement, addTo = Utils.addTo,
7var newElement = Utils.newElement, addTo = Utils.addTo,
7 extract = Utils.extract, fromList = Utils.fromList,
8 extract = Utils.extract, fromList = Utils.fromList,
8− fromString = Utils.fromString;
9+ fromString = Utils.fromString, addTransform = Utils.addTransform;
10function trace(ctx, path) {
11function trace(ctx, path) {
11 var points = fromList(path);
12 var points = fromList(path);
@@ -129,9 +130,9 @@ function renderForms(redo, ctx, forms) {
131function collageForms(w,h,forms) {
132function collageForms(w,h,forms) {
132− var canvas = Render.newElement('canvas');
133+ var canvas = newElement('canvas');
133− w = ~~w;
134+ w = w|0;
134− h = ~~h;
135+ h = h|0;
135 canvas.style.width = w + 'px';
136 canvas.style.width = w + 'px';
136 canvas.style.height = h + 'px';
137 canvas.style.height = h + 'px';
137 canvas.style.display = "block";
138 canvas.style.display = "block";
@@ -143,183 +144,27 @@ function collageForms(w,h,forms) {
143 renderForms(redo,ctx,w,h,forms);
144 renderForms(redo,ctx,w,h,forms);
144 return canvas;
145 return canvas;
146− canvas.innerHTML = "Your browser does not support the canvas element.";
147+ canvas.innerHTML = "Your browser does not support canvas.";
147 return canvas;
148 return canvas;
150−function applyTransforms(theta,scale,x,y,w,h,e) {
151+function collageElement(w, h, m, elem) {
151− var t = "translate(" + (x - w / 2) + "px,"+ (y - h / 2) + "px)";
152+ var e = Render.render(elem);
152− var r = theta === (~~theta) ? "" : "rotate(" + theta*360 + "deg)";
153+ var matrix = 'matrix(' + m[0] + ',' + m[3] + ',' + m[1] + ',' +
153− var s = scale === 1 ? "" : "scale(" + scale + "," + scale + ")";
154+ m[4] + ',' + m[2] + ',' + m[5] + ')';
154− var transforms = t + " " + s + " " + r;
155+ addTransform(e.style, matrix);
155− e.style.transform = transforms;
156+ var div = newElement('div');
156− e.style.msTransform = transforms;
157+ addTo(div,e);
157− e.style.MozTransform = transforms;
158+ div.style.width = (w|0) + "px";
158− e.style.webkitTransform = transforms;
159+ div.style.height = (h|0) + "px";
159− e.style.OTransform = transforms;
160+ div.style.overflow = "hidden";
162−function collageElement(w,h,theta,scale,x,y,elem) {
164+function render(model) {
163− var e = Render.render(elem);
165+ return collageForms(model.w, model.h, model.forms);
164− applyTransforms(theta,scale,x,y,elem[3],elem[4],e);
165− var div = Render.newElement('div');
166− Render.addTo(div,e);
167− div.style.width = (~~w) + "px";
168− div.style.height = (~~h) + "px";
169− div.style.overflow = "hidden";
173−function collage(w,h,formss) {
168+return { render:render };
174− if (formss.length === 0) { return collageForms(w,h,[]); }
175− var elems = new Array(formss.length);
176− for (var i = formss.length; i--; ) {
178− if (typeof f[0] === "string") {
179− elems[i] = collageElement(w,h,f[1],f[2],f[3][1],f[3][2],f[4][1]);
181− elems[i] = collageForms(w,h,f);
184− if (formss.length === 1) { return elems[0]; }
185− return Render.flowWith(Render.goIn,function(x){return x},elems);
188−function updateFormSet(node,currSet,nextSet) {
189− if (Value.eq(nextSet,currSet)) return;
190− var w = node.style.width.slice(0,-2) - 0;
191− var h = node.style.height.slice(0,-2) - 0;
192− if (typeof nextSet[0] === "object") {
193− if (typeof currSet[0] === "object") {
194− if (node.getContext) {
195− var ctx = node.getContext('2d');
196− function redo() { renderForms(this,ctx,w,h,nextSet); }
197− return renderForms(redo,ctx,w,h,nextSet);
200− var newNode = collageForms(w,h,nextSet);
201− newNode.style.position = 'absolute';
202− return node.parentNode.replaceChild(newNode,node);
204− node.style.width = (~~w) + "px";
205− node.style.height = (~~h) + "px";
207− var next = nextSet[4][1];
208− Render.update(node.firstChild, currSet[4][1], next);
209− applyTransforms(f[1],f[2],f[3][1],f[3][2],next[3],next[4],node.firstChild);
212−// assumes that the form sets are the same length.
213−function updateCollage(node,currs,nexts) {
214− if (nexts.length === 1) {
215− return updateFormSet(node,currs[0],nexts[0]);
217− var kids = node.childNodes;
218− var len = kids.length;
219− for (var i = len; i--; ) {
220− updateFormSet(kids[len-i-1], currs[i], nexts[i]);
224−function style(clr,n,list) {
226− '<span style="font-size:100%;color:' + clr + ';">' + n + '</span>',
230−function insideForm(point) { return function(form) {
231− if (!inBoundsOf(point[1],point[2],form)) return false;
233− switch (form[4][0]) {
234− case "FShape": return insideShape(point,form[1],form[2],form[3],form[4][3][1]);
235− case "FLine": return false;
237− hw = form[4][1] / 2;
238− hh = form[4][2] / 2;
241− hw = form[4][1][3] / 2;
242− hh = form[4][1][4] / 2;
245− return insideShape(point,form[1],form[2],form[3],
254−function inBoundsOf(px,py,form) {
255− if (form.length < 6) {
256− var fx = form[3][1], fy = form[3][2];
257− var radiusSquared = 0;
258− var scale = form[2];
259− switch (form[4][0]) {
261− var points = form[4][3][1];
262− for (var i = points.length; --i; ) {
264− radiusSquared = Math.max(radiusSquared, p[1]*p[1] + p[2]*p[2]);
266− radiusSquared *= scale * scale;
271− var x = scale * form[4][1] / 2;
272− var y = scale * form[4][2] / 2;
273− radiusSquared = x*x + y*y;
276− var x = scale * form[4][1][3] / 2;
277− var y = scale * form[4][1][4] / 2;
278− radiusSquared = x*x + y*y;
281− form.push(function(px,py) {
284− return dx*dx + dy*dy < radiusSquared + 1;
287− return form[5](px,py);
290−function insideShape(point,theta,scale,pos,points) {
295− var x = (point[1] - pos[1]) / scale;
296− var y = (point[2] - pos[2]) / scale;
298− var t = -2 * Math.PI * theta;
299− var nx = x * Math.cos(t) - y * Math.sin(t);
300− y = x * Math.sin(t) + y * Math.cos(t);
304− if (points.length === 0) { return false; }
306− for (var i = points.length - 1; i--; ) {
308− var p1x = p1[1], p1y = p1[2], p2x = p2[1], p2y = p2[2];
310− if (p1y < p2y) {var ymin=p1y, ymax=p2y;} else {var ymin=p2y, ymax=p1y;}
311− if (p1x < p2x) {var xmin=p1x, xmax=p2x;} else {var xmin=p2x, xmax=p1x;}
313− if (ymin < y && y <= ymax && x <= xmax) {
314− if (x <= xmin || x <= ((y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x)) {
320− return (counter % 2) === 1;
323−return {collage:collage, updateCollage:updateCollage, insideForm:insideForm};