Musings of a Fondue

SVG X Khan Academy - Part 2

A tweak to my previous approach.

This time the relative to absolute conversion is done within the JavaScript code itself. This results in less manual work and a more scalable approach.

It’s not quite a raw SVG to JavaScript conversion, but I’m pretty happy with it.

Here it is in action,

A walkthrough of the code

Scrubbed coordinate data,


var coordStuff = [

    [["label", "tailspikes"],
    ["m", 398.0549,366.73333],
    ["c", 11.04661,-5.40725,19.08374,-3.87834,19.82746,-3.01176,3.59971,4.19437,7.78039,13.80392,-1.25491,12.54902,-9.03529,-1.2549,-18.57255,-9.53726,-18.57255,-9.53726]],
    
    [["label", "tailspikes"],
    ["m", 434.19608,374.26274],
    ["c", 1.2549,-7.02745,0.12396,-17.83873,6.02353,-17.06666,7.68555,1.0058,11.79608,5.27059,11.79608,5.27059,-2.5098,5.77254,-17.81961,11.79607,-17.81961,11.79607]],

    [["label", "eyeball"],
    ["ellipse", 308.583328,148.3695146,19.617,19.617]],
    
    [["label", "pupil"],
    ["ellipse", 308.226998,149.08218,8.5519633,8.5519633]],

    [["label", "bodyline"],
    ["m", 532.32942,120.52157],
    ["c", 2.74817,-4.27928,7.02745,-4.51765,7.02745,-4.51765]],

    ...
];

Style attributes,


var styleStuff = {
    // fill, stroke, strokeWeight
    "tailspikes" : [color(163, 173, 133), color(94, 90, 66), null],
    "bodyfill" : [color(112, 202, 235), color(24, 53, 64), null],
    "spot" : [color(106, 87, 217, 100), null, null],
    "eyeball" : [color(255), color(71, 71, 50), null],
    "pupil" : [color(28, 28, 28), null, null],
    ...
};

var lines = ["bodyline", "bellyline", "face_whisker",
    "HornLine", "noseline", "teethline", "mouthline",
    "lowerlip_line"
];

Draw functions,


var drawEllipses = function(info){
    //draw
    ellipse( info[1][1], info[1][2], info[1][3], info[1][4] );
};

var drawBezierShape = function(info){
    var x1 = info[1][1], y1 = info[1][2];
    var pts = info[2];  //relative coords
    var p = [];         //absolute coords
    
    //convert relative coords to absolute coords
    for ( var i = 1; i < pts.length; i += 6 ){
        p.push( x1 + pts[i] );
        p.push( y1 + pts[i+1] );
        p.push( x1 + pts[i+2] );
        p.push( y1 + pts[i+3] );
        p.push( x1 + pts[i+4] );
        p.push( y1 + pts[i+5] );
        
        x1 += pts[i+4];
        y1 += pts[i+5];
    }
    
    //draw
    beginShape();
    vertex(info[1][1], info[1][2]);
    for (var i = 0; i < p.length; i += 6){
        bezierVertex(
            p[i], p[i+1],
            p[i+2], p[i+3],
            p[i+4], p[i+5]
        );
    }
    if ( lines.indexOf( info[0][1] ) > -1 ){  
        endShape(); //it's a line
    }
    else{
       endShape(CLOSE); //it's a shape
    }
};

var drawShape = function(info){
    //style
    var s = styleStuff[ info[0][1] ];
    
    noFill();
    if (s[0]){
        fill(s[0]);
    }
    
    noStroke();
    if (s[1]){
        strokeWeight(1);
        if(s[2]){
            strokeWeight(s[2]);
        }
        stroke(s[1]);
    }
    
    //draw
    if( info[1][0] === "m" ){
        drawBezierShape(info);
    }
    else if( info[1][0] === "ellipse" ){
        drawEllipses(info);
    }
};

The init code,


for( var i in coordStuff){
    drawShape( coordStuff[i] );
}

Comments