Home | History | Annotate | Download | only in docs
      1 var canvas;
      2 var ctx;
      3 var canvasGradients = {};
      4 
      5 function 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 
     13 function canvas_opacity(color) {
     14     var a = (color >> 24) & 0xFF;
     15     return a / 255.;
     16 }
     17 
     18 function 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 
     27 function 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 
     89 function keyframeCanvasInit(displayList, first) {
     90     if ('canvas' in first && 'clear' == first.canvas) {
     91         displayList.clear = true;
     92     }
     93 }
     94 
     95 function 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 
    153 function 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