on 0064813 help sign in
elk/runtime/Render/Collage.js
186 lines 5.2 kB history raw
2ElmRuntime.Render.Collage = function() {
3'use strict';
5var Render = ElmRuntime.use(ElmRuntime.Render.Element);
6var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
7var newElement = Utils.newElement, addTo = Utils.addTo,
8 extract = Utils.extract, fromList = Utils.fromList,
9 fromString = Utils.fromString, addTransform = Utils.addTransform;
11function trace(ctx, path) {
12 var points = fromList(path);
13 console.log(points);
14 var i = points.length - 1;
15 if (i <= 0) return;
16 ctx.moveTo(points[i]._0, points[i]._1);
17 while (i--) { ctx.lineTo(points[i]._0, points[i]._1); }
18 if (path.closed) {
19 i = points.length - 1;
20 ctx.lineTo(points[i]._0, points[i]._1);
21 }
24function line(ctx,style,path) {
25 var isSolid = style.dashing.ctor === 'Nil';
26 isSolid ? trace(ctx, path) : customLineHelp(ctx, style, path);
27 ctx.stroke();
30function customLineHelp(ctx, pattern, points) {
31 var i = points.length - 1;
32 if (i <= 0) return;
33 var x0 = points[i][1], y0 = points[i][2];
34 var x1=0, y1=0, dx=0, dy=0, remaining=0, nx=0, ny=0;
35 var pindex = 0, plen = pattern.length;
36 var draw = true, segmentLength = pattern[0];
37 ctx.moveTo(x0,y0);
38 while (i--) {
39 x1 = points[i][1]; y1 = points[i][2];
40 dx = x1 - x0; dy = y1 - y0;
41 remaining = Math.sqrt(dx * dx + dy * dy);
42 while (segmentLength <= remaining) {
43 x0 += dx * segmentLength / remaining;
44 y0 += dy * segmentLength / remaining;
45 ctx[draw ? 'lineTo' : 'moveTo'](x0, y0);
46 // update starting position
47 dx = x1 - x0; dy = y1 - y0;
48 remaining = Math.sqrt(dx * dx + dy * dy);
49 // update pattern
50 draw = !draw;
51 pindex = (pindex + 1) % plen;
52 segmentLength = pattern[pindex];
53 }
54 if (remaining > 0) {
55 ctx[draw ? 'lineTo' : 'moveTo'](x1, y1);
56 segmentLength -= remaining;
57 }
58 x0 = x1; y0 = y1;
59 }
62function drawLine(ctx, style, path) {
63 ctx.lineWidth = style.width;
64 ctx.lineCap = style.cap.ctor.toLowerCase();
65 ctx.lineJoin = style.join.ctor.toLowerCase();
66 ctx.miterLimit = style.miterLimit;
67 ctx.strokeStyle = extract(style.color);
68 return line(ctx, style, path);
71function texture(redo, ctx, src) {
72 var img = new Image();
73 img.src = fromString(src);
74 img.onload = redo;
75 return ctx.createPattern(img, 'repeat');
78function gradient(ctx, grad) {
79 var g;
80 if (grad.ctor === 'Linear') {
81 var p1 = grad._1, p2 = grad._2;
82 g = ctx.createLinearGradient(p1._0, p1._1, p2._0, p2._1);
83 } else {
84 var p1 = grad._1, p2 = grad._3;
85 g = ctx.createRadialGradient(p1._0, p1._1, grad._2, p2._0, p2._1, grad._4);
86 }
87 var stops = fromList(grad._0);
88 for (var i = stops.length; i--; ) {
89 var stop = stops[i];
90 g.addColorStop(stop._0, extract(stop._1));
91 }
92 return g;
95function drawShape(redo, ctx, style, path) {
96 console.log(style, path);
97 trace(ctx, path);
98 var sty = style.ctor;
99 ctx.fillStyle =
100 sty === 'Solid' ? extract(style._0) :
101 sty === 'Texture' ? texture(redo, ctx, style._0) : gradient(ctx, style._0);
102 ctx.fill();
105function drawImage(redo, ctx, form) {
106 var img = new Image();
107 img.onload = redo;
108 img.src = fromString(form._3);
109 var w = form._0, h = form._1, pos = form._2;
110 console.log(w,h,pos);
111 ctx.drawImage(img, pos._0, pos._1, w, h, -w/2, -h/2, w, h);
114function renderForm(redo,ctx,form) {
115 ctx.save();
116 if (form.x !== 0 || form.y !== 0) ctx.translate(form.x, form.y);
117 if (form.theta !== 0) ctx.rotate(form.theta);
118 if (form.scale !== 1) ctx.scale(form.scale, form.scale);
119 ctx.beginPath();
120 var f = form.form;
121 console.log(f);
122 switch(f.ctor) {
123 case 'FPath' : drawLine(ctx, f._0, f._1); break;
124 case 'FShape':
125 if (f._0.ctor === 'Left') {
126 f._1.closed = true;
127 drawLine(ctx, f._0._0, f._1);
128 } else {
129 drawShape(redo, ctx, f._0._0, f._1);
130 }
131 break;
132 case 'FImage': drawImage(redo, ctx, f); break;
133 case 'FGroup': renderForms(redo, ctx, f._0); break;
134 }
135 ctx.restore();
138function renderForms(redo, ctx, forms) {
139 var fs = fromList(forms);
140 console.log(fs);
141 for (var i = 0, len = fs.length; i < len; ++i) {
142 renderForm(redo,ctx,fs[i]);
143 }
146function collageForms(w,h,forms) {
147 var canvas = newElement('canvas');
148 w = w|0;
149 h = h|0;
150 canvas.style.width = w + 'px';
151 canvas.style.height = h + 'px';
152 canvas.style.display = "block";
153 canvas.width = w;
154 canvas.height = h;
155 function redo() { renderForms(this,ctx,forms); }
156 if (canvas.getContext) {
157 var ctx = canvas.getContext('2d');
158 console.log(forms);
159 renderForms(redo,ctx,forms);
160 return canvas;
161 }
162 canvas.innerHTML = "Your browser does not support canvas.";
163 return canvas;
166function collageElement(w, h, m, elem) {
167 var e = Render.render(elem);
168 var matrix = 'matrix(' + m[0] + ',' + m[3] + ',' + m[1] + ',' +
169 m[4] + ',' + m[2] + ',' + m[5] + ')';
170 addTransform(e.style, matrix);
171 var div = newElement('div');
172 addTo(div,e);
173 div.style.width = (w|0) + "px";
174 div.style.height = (h|0) + "px";
175 div.style.overflow = "hidden";
176 return div;
179function render(model) {
180 console.log(model);
181 return collageForms(model.w, model.h, model.forms);
184return { render:render };
186};