on fa9d3bf help sign in
elk/runtime/Render/Collage.js
178 lines 5.1 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); }
20function line(ctx,style,path) {
21 var isSolid = style.dashing.ctor === 'Nil';
22 isSolid ? trace(ctx, path) : customLineHelp(ctx, style, path);
23 ctx.stroke();
26function customLineHelp(ctx, pattern, points) {
27 var i = points.length - 1;
28 if (i <= 0) return;
29 var x0 = points[i][1], y0 = points[i][2];
30 var x1=0, y1=0, dx=0, dy=0, remaining=0, nx=0, ny=0;
31 var pindex = 0, plen = pattern.length;
32 var draw = true, segmentLength = pattern[0];
33 ctx.moveTo(x0,y0);
34 while (i--) {
35 x1 = points[i][1]; y1 = points[i][2];
36 dx = x1 - x0; dy = y1 - y0;
37 remaining = Math.sqrt(dx * dx + dy * dy);
38 while (segmentLength <= remaining) {
39 x0 += dx * segmentLength / remaining;
40 y0 += dy * segmentLength / remaining;
41 ctx[draw ? 'lineTo' : 'moveTo'](x0, y0);
42 // update starting position
43 dx = x1 - x0; dy = y1 - y0;
44 remaining = Math.sqrt(dx * dx + dy * dy);
45 // update pattern
46 draw = !draw;
47 pindex = (pindex + 1) % plen;
48 segmentLength = pattern[pindex];
49 }
50 if (remaining > 0) {
51 ctx[draw ? 'lineTo' : 'moveTo'](x1, y1);
52 segmentLength -= remaining;
53 }
54 x0 = x1; y0 = y1;
55 }
58function drawLine(ctx, style, path) {
59 ctx.lineWidth = style.width;
60 ctx.lineCap = style.cap.ctor.toLowerCase();
61 ctx.lineJoin = style.join.ctor.toLowerCase();
62 ctx.miterLimit = style.miterLimit;
63 ctx.strokeStyle = extract(style.color);
64 return line(ctx, style, path);
67function texture(redo, ctx, src) {
68 var img = new Image();
69 img.src = fromString(src);
70 img.onload = redo;
71 return ctx.createPattern(img, 'repeat');
74function gradient(ctx, grad) {
75 var g;
76 if (grad.ctor === 'Linear') {
77 var p1 = grad._1, p2 = grad._2;
78 g = ctx.createLinearGradient(p1._0, p1._1, p2._0, p2._1);
79 } else {
80 var p1 = grad._1, p2 = grad._3;
81 g = ctx.createRadialGradient(p1._0, p1._1, grad._2, p2._0, p2._1, grad._4);
82 }
83 var stops = fromList(grad._0);
84 for (var i = stops.length; i--; ) {
85 var stop = stops[i];
86 g.addColorStop(stop._0, extract(stop._1));
87 }
88 return g;
91function drawShape(redo, ctx, style, path) {
92 console.log(style, path);
93 trace(ctx, path);
94 var sty = style.ctor;
95 ctx.fillStyle =
96 sty === 'Solid' ? extract(style._0) :
97 sty === 'Texture' ? texture(redo, ctx, style._0) : gradient(ctx, style._0);
98 ctx.fill();
101function drawImage(redo, ctx, form) {
102 var img = new Image();
103 img.onload = redo;
104 img.src = fromString(form._3);
105 var w = form._0, h = form._1, pos = form._2;
106 console.log(w,h,pos);
107 ctx.drawImage(img, pos._0, pos._1, w, h, -w/2, -h/2, w, h);
110function renderForm(redo,ctx,form) {
111 ctx.save();
112 if (form.x !== 0 || form.y !== 0) ctx.translate(form.x, form.y);
113 if (form.theta !== 0) ctx.rotate(form.theta);
114 if (form.scale !== 1) ctx.scale(form.scale, form.scale);
115 ctx.beginPath();
116 var f = form.form;
117 console.log(f);
118 switch(f.ctor) {
119 case 'FPath' : drawLine(ctx, f._0, f._1); break;
120 case 'FShape':
121 if (form.form._0.ctor === 'Left') drawLine(ctx, f._0._0, f._1);
122 else drawShape(redo, ctx, f._0._0, f._1);
123 break;
124 case 'FImage': drawImage(redo, ctx, f); break;
125 case 'FGroup': renderForms(redo, ctx, f._0); break;
126 }
127 ctx.restore();
130function renderForms(redo, ctx, forms) {
131 var fs = fromList(forms);
132 console.log(fs);
133 for (var i = 0, len = fs.length; i < len; ++i) {
134 renderForm(redo,ctx,fs[i]);
135 }
138function collageForms(w,h,forms) {
139 var canvas = newElement('canvas');
140 w = w|0;
141 h = h|0;
142 canvas.style.width = w + 'px';
143 canvas.style.height = h + 'px';
144 canvas.style.display = "block";
145 canvas.width = w;
146 canvas.height = h;
147 function redo() { renderForms(this,ctx,forms); }
148 if (canvas.getContext) {
149 var ctx = canvas.getContext('2d');
150 console.log(forms);
151 renderForms(redo,ctx,forms);
152 return canvas;
153 }
154 canvas.innerHTML = "Your browser does not support canvas.";
155 return canvas;
158function collageElement(w, h, m, elem) {
159 var e = Render.render(elem);
160 var matrix = 'matrix(' + m[0] + ',' + m[3] + ',' + m[1] + ',' +
161 m[4] + ',' + m[2] + ',' + m[5] + ')';
162 addTransform(e.style, matrix);
163 var div = newElement('div');
164 addTo(div,e);
165 div.style.width = (w|0) + "px";
166 div.style.height = (h|0) + "px";
167 div.style.overflow = "hidden";
168 return div;
171function render(model) {
172 console.log(model);
173 return collageForms(model.w, model.h, model.forms);
176return { render:render };
178};