1var canvas; 2var ctx; 3var canvasGradients = {}; 4 5function canvas_rbga(color) { 6 var a = canvas_opacity(color); 7 var r = (color >> 16) & 0xFF; 8 var g = (color >> 8) & 0xFF; 9 var b = (color >> 0) & 0xFF; 10 return "rgba(" + r + "," + g + "," + b + "," + a + ")"; 11} 12 13function canvas_opacity(color) { 14 var a = (color >> 24) & 0xFF; 15 return a / 255.; 16} 17 18function displayCanvas(displayList) { 19 if (displayList.clear) { 20 ctx.clearRect(0, 0, canvas.width, canvas.height); 21 } 22 for (var index = 0; index < displayList.length; ++index) { 23 drawToCanvas(displayList[index]); 24 } 25} 26 27function drawToCanvas(action) { 28 ctx.save(); 29 var paint = paintToCanvas(action.paint); 30 var draw = action.draw; 31 if ('string' == typeof(draw)) { 32 draw = (new Function("return " + draw))(); 33 } 34 if (isArray(draw)) { 35 assert(draw.length > 0); 36 var picture = 'draw' in draw[0]; 37 if (picture) { 38 for (var index = 0; index < draw.length; ++index) { 39 drawToCanvas(draw[index]); 40 } 41 return; 42 } 43 ctx.beginPath(); 44 for (var index = 0; index < draw.length; ++index) { 45 for (var prop in draw[index]) { 46 var v = draw[index][prop]; 47 switch (prop) { 48 case 'arcTo': 49 ctx.arcTo(v[0], v[1], v[2], v[3], v[4]); 50 break; 51 case 'close': 52 ctx.closePath(); 53 break; 54 case 'cubic': 55 ctx.moveTo(v[0], v[1]); 56 ctx.bezierCurveTo(v[2], v[3], v[4], v[5], v[6], v[7]); 57 break; 58 case 'line': 59 ctx.moveTo(v[0], v[1]); 60 ctx.lineTo(v[2], v[3]); 61 break; 62 case 'quad': 63 ctx.moveTo(v[0], v[1]); 64 ctx.quadraticCurveTo(v[2], v[3], v[4], v[5]); 65 break; 66 default: 67 assert(0); 68 } 69 } 70 } 71 if ('fill' == paint.style) { 72 ctx.fill(); 73 } else { 74 assert('stroke' == paint.style); 75 ctx.stroke(); 76 } 77 } else { 78 assert('string' in draw); 79 if ('fill' == paint.style) { 80 ctx.fillText(draw.string, draw.x, draw.y); 81 } else { 82 assert('stroke' == paint.style); 83 ctx.strokeText(draw.string, draw.x, draw.y); 84 } 85 } 86 ctx.restore(); 87} 88 89function keyframeCanvasInit(displayList, first) { 90 if ('canvas' in first && 'clear' == first.canvas) { 91 displayList.clear = true; 92 } 93} 94 95function paintToCanvas(paint) { 96 var color; 97 var inPicture = 'string' == typeof(paint); 98 if (inPicture) { 99 paint = (new Function("return " + paint))(); 100 assert('object' == typeof(paint) && !isArray(paint)); 101 } 102 if ('gradient' in paint) { 103 var gradient = paint.gradient.split('.'); 104 var gradName = gradient[1]; 105 if (!canvasGradients[gradName]) { 106 var g = window[gradient[0]][gradient[1]]; 107 var grad = ctx.createRadialGradient(g.cx, g.cy, 0, g.cx, g.cy, g.r); 108 var stopLen = g.stops.length; 109 for (var index = 0; index < stopLen; ++index) { 110 var stop = g.stops[index]; 111 var color = canvas_rbga(stop.color); 112 grad.addColorStop(index, color); 113 } 114 canvasGradients[gradName] = grad; 115 } 116 color = canvasGradients[gradName]; 117 if (!inPicture) { 118 ctx.globalAlpha = canvas_opacity(paint.color); 119 } 120 } else { 121 color = canvas_rbga(paint.color); 122 } 123 if ('fill' == paint.style) { 124 ctx.fillStyle = color; 125 } else if ('stroke' == paint.style) { 126 ctx.strokeStyle = color; 127 } else { 128 ctx.globalAlpha = canvas_opacity(paint.color); 129 } 130 if ('strokeWidth' in paint) { 131 ctx.lineWidth = paint.strokeWidth; 132 } 133 if ('typeface' in paint) { 134 var typeface = typefaces[paint.typeface]; 135 var font = typeface.style; 136 if ('textSize' in paint) { 137 font += " " + paint.textSize; 138 } 139 if ('family' in typeface) { 140 font += " " + typeface.family; 141 } 142 ctx.font = font; 143 if ('textAlign' in paint) { 144 ctx.textAlign = paint.textAlign; 145 } 146 if ('textBaseline' in paint) { 147 ctx.textBaseline = paint.textBaseline; 148 } 149 } 150 return paint; 151} 152 153function setupCanvas() { 154 canvas = document.getElementById("canvas"); 155 ctx = canvas ? canvas.getContext("2d") : null; 156 assert(ctx); 157 var resScale = window.devicePixelRatio ? window.devicePixelRatio : 1; 158 var unscaledWidth = canvas.width; 159 var unscaledHeight = canvas.height; 160 canvas.width = unscaledWidth * resScale; 161 canvas.height = unscaledHeight * resScale; 162 canvas.style.width = unscaledWidth + 'px'; 163 canvas.style.height = unscaledHeight + 'px'; 164 if (resScale != 1) { 165 ctx.scale(resScale, resScale); 166 } 167} 168