ey-frame-svg-1.0.3.js 7.17 KB
/*!
 * VERSION: 1.0.3
 * DATE: 2016-05-04
 * 
 * Requires:
 *     GSAP TweenMax (import com.greensock.*;)
 *     GASP drawSVG Plugin ()
 *          This work is subject to the terms at http://greensock.com/standard-license or for
 *          Club GreenSock members, the software agreement that was issued with your membership.
 *
 * @license Copyright (c) 2016, Tenzing Communications Inc. All rights reserved.
 * 
 * @author: Dan Rempel, dan@gotenzing.com
 
 * Usage Example:
 *    var myEySvg = initEySvgFrame(10, 196, 193); // frame line weight, width, height
 *    document.getElementById("body").appendChild(myEySvg);
 *    animateEyFrame(2); // delay in seconds
 *    animateGradient(2); // delay in seconds
 *    animateFill(2); // delay in seconds
 * 
 * MINIFY:
 * http://esprima.org/demo/minify.html
 * 
 **/


var eySvg;
var eyStroke;
var eyDot1;
var eyDot2;
var eyDot3;
var eyGradient;
var eyFill;

var tl;
var eyStrokeWeight;
var eySvgHeight;
var eySvgWidth;
var eyAngleHeight;
var eyDotSpacing;
var eyDotDuration = .2; // seconds for animation
var eyFrameDuration = 1; // seconds for animation
var eyGradientDuration = 1; // seconds for animation
var eyFillDuration = 1; // seconds for animation
var eyColor = "#FFD400";
var svgNS = "http://www.w3.org/2000/svg"; 
var isForward = true; 

/**
myWeight:Number - the width of the line of the frame in pixels
myWidth:Number - width of the desired frame in pixels measured from the outside to the outside
myHeight:Number - height of the desired frame in pixels measured from the peak to the bottom
myDuration:Number - seconds the animation will take to elapse from start to finish

Returns: SVG element
**/
var initEySvgFrame = function (myWeight, myWidth, myHeight)
{
    //// calculate all the points and variables to assist in drawing ////
    
    tl = new TimelineMax({onStart:tlStart, onUpdate:tlUpdate, onComplete:tlComplete, onReverseComplete:tlReverseComplete });
    
    eyDotSpacing = Math.floor(myWeight*8.5/10); // EY ratio of weight to spacing
    eyStrokeWeight = myWeight;
    eySvgWidth = myWidth;
    eySvgHeight = myHeight;
    
    var myRadians = 10 * Math.PI / 180; // EY angles up at 10 degrees
    eyAngleHeight = Math.tan(myRadians)*(myWidth - myWeight); // height of the head (measured vertically from shoulder anchor pt to top of head anchor pt)
    
    //// create the properly sized svg container ////
    
    var eySvg = document.createElementNS(svgNS, "svg");
    eySvg.setAttribute("id", "ey-frame");
    eySvg.setAttribute("width", myWidth+"px");
    eySvg.setAttribute("height", myHeight+"px");
    eySvg.setAttribute("viewBox", "0 0 "+eySvgWidth + " " + eySvgHeight );
    var myDefs = document.createElementNS(svgNS, "defs");
    eySvg.appendChild(myDefs);
    
    
    //// draw the gradient for def ////
    
    var myLinearGradient = document.createElementNS(svgNS, "linearGradient");
    myLinearGradient.setAttribute("id", "linear-gradient");
    myLinearGradient.setAttribute("x1", "0%");
    myLinearGradient.setAttribute("x2", "0%");
    myLinearGradient.setAttribute("y1", "0%");
    myLinearGradient.setAttribute("y2", "100%");
    myDefs.appendChild(myLinearGradient);

    //stops

    var stop;
    stop = createStop ({id:"stop-1", offset:"0%", color:"Black", opacity:".7" });
    myLinearGradient.appendChild(stop);
    stop = createStop ({id:"stop-2", offset:"100%", color:"Black", opacity:"0" });
    myLinearGradient.appendChild(stop);
    
    // gradient shape
    
    eyGradient = createShape ("ey-gradient", "url(#linear-gradient)");
    eySvg.appendChild(eyGradient);

        
    //// create 3 dots ////
    
    eyDot1 = createDot(1);
    eySvg.appendChild(eyDot1);
    eyDot2 = createDot(2);
    eySvg.appendChild(eyDot2);
    eyDot3 = createDot(3);
    eySvg.appendChild(eyDot3);
    
    //// draw the rest of the path ////
    
    eyStroke = createPath("ey-stroke");
    eyStroke.setAttribute("d", 
        " M " + ((eyStrokeWeight + eyDotSpacing)*3) + " " + (eySvgHeight-myWeight/2) + 
        " H " + (myWidth-myWeight/2) +
        " V " + myWeight/1.5 +
        " L " + myWeight/2 + " " + (eyAngleHeight+myWeight/2) +
        " V " + (myHeight-myWeight-eyDotSpacing)
    );
    eySvg.appendChild(eyStroke);    

    return eySvg;
    
};

var animateEyFrame = function (myDelay)
{
    isForward = true;
    tl.timeScale(1);
    var lastPt = 0;
    tl.fromTo(eyDot1, eyDotDuration, {drawSVG:"0"}, {drawSVG:"0 "+(lastPt+=(eyStrokeWeight+eyDotSpacing)), ease:Power1.easeInOut, delay:myDelay });
    tl.fromTo(eyDot2, eyDotDuration, {drawSVG:"0"}, {drawSVG:"0 "+(lastPt+=(eyStrokeWeight+eyDotSpacing)), ease:Power1.easeInOut });
    tl.fromTo(eyDot3, eyDotDuration, {drawSVG:"0"}, {drawSVG:"0 "+(lastPt+=(eyStrokeWeight+eyDotSpacing)), ease:Power1.easeInOut });
    tl.call(tlDotToLine, []);
    tl.fromTo(eyStroke, eyFrameDuration, {drawSVG:"0"}, {drawSVG:"0 100%", ease:Power1.easeIn});
};
var animateEyReverse = function (myDelay)
{
    TweenMax.delayedCall(myDelay, intAnimateEyReverse, [0]);
}

var animateGradient = function (myDelay)
{
    tl.fromTo(eyGradient, .5, {opacity:0}, {opacity:1, delay:myDelay});
};
var animateFill = function (myDelay)
{
    //// draw the fill shape for def ////
    if (typeof eyFill === 'undefined' || variable === null) {
        // variable is undefined or null
        eyFill = createShape ("ey-gradient", eyColor);
        eySvg.appendChild(eyFill);
    }
    tl.fromTo(eyFill, .5, {y:eySvgHeight}, {y:0, ease:Power2.easeIn, delay:myDelay});
};



////////// private functions
 
var createPath = function (myId)
{
    var myPath = document.createElementNS(svgNS,"path");
    myPath.setAttribute("id", myId);
    myPath.setAttribute("fill", "none");
    myPath.setAttribute("stroke", eyColor);
    myPath.setAttribute("stroke-width", eyStrokeWeight);
    myPath.setAttribute("stroke-miterlimit", "10");
    return myPath;
};

var createDot = function (dotNum)
{
    var myDot = createPath("ey-dot"+dotNum);
    myDot.setAttribute("d", 
        " M " + ((eyStrokeWeight + eyDotSpacing)*(dotNum-1)) + " " + (eySvgHeight-eyStrokeWeight/2) + 
        " h " + eyStrokeWeight
    );
    return myDot;
};


var createShape = function (myId, myFill)
{
    var myShape = document.createElementNS(svgNS,"path");
    myShape.setAttribute("id", myId);
    myShape.setAttribute("fill", myFill);
    myShape.setAttribute("d", 
        " M 0 " + (eySvgHeight) + 
        " H " + (eySvgWidth) +
        " V 2 " +
        " L 0 " + (eyAngleHeight+2) +
        " Z "
    );
    return myShape;
};

var createStop = function (myStopObj)
{
    var myStop = document.createElementNS(svgNS, "stop");
    myStop.setAttribute("id", myStopObj.id);
    myStop.setAttribute("offset", myStopObj.offset);
    myStop.setAttribute("stop-color", myStopObj.color);
    myStop.setAttribute("stop-opacity", myStopObj.opacity);
    return myStop;
};

var intAnimateEyReverse = function (time)
{
    isForward = false;
    tl.reverse(time);
    // need to timescale the last 3 dots bit
    tl.timeScale
//     tl.smoothChildTiming = true;
//isForward
}
var tlStart = function ()
{
    
};
var tlDotToLine = function ()
{
    if(!isForward)
    {
        tl.timeScale(4);
    }
};
var tlUpdate = function ()
{
    
};
var tlComplete = function ()
{
    
};
var tlReverseComplete = function ()
{
    
};