Skip to main content
October 7, 2012
Question

newbie / how was this done? animated stroke

  • October 7, 2012
  • 2 replies
  • 3037 views

My favorite DPS magazine has this beautiful animated stroke that I am showing below in these iPad screen captures. The stroke starts from upper left corner and progresses up until to lower right. This is DPS and I presume this animation is made in Flash before becoming a DPS html overlay, so I drawed a couples of black lines in Flash with several white rectangle tweens progressively covering the line in order to recreate that effect. That does not work, my SWF ignores the timeline and triggers all tweens at the same time, ruins the effect.

I am not a Flash guy, but do you people know if Flash is the easiest to create this effect?

Many thanks,

This topic has been closed for replies.

2 replies

Inspiring
October 7, 2012

Although animated masks can offer some advantages, you can do that totally programmatically using Graphics class capabilities.

Below is an example that emulates what you want. It definitely need optimization - just a quick and dirty example.

Just place this code on the first frame of an empty FLA.

stop();

import flash.display.Graphics;

import flash.display.Shape;

import flash.display.Sprite;

import flash.events.Event;

import flash.geom.Point;

var animatedLineOverlay:Shape;

var overlayGraphics:Graphics;

var overlayPoints:Array;

var overlayMargin:Number = 30;

var currentPoints:Object;

var nextPoint:Point;

var sPoint:Point;

var ePoint:Point;

var angle:Number;

var speed:Number = 8;

var advanceX:Number;

var advanceY:Number;

init();

function init():void

{

    makeBackground();

    definePoints();

    makeOverlay();

    startAnimation();

}

function startAnimation():void

{

    addEventListener(Event.ENTER_FRAME, drawLine);

}

function drawLine(e:Event):void

{

    if (!currentPoints)

    {

        if (overlayPoints.length == 0)

        {

            removeEventListener(Event.ENTER_FRAME, drawLine);

            return;

        }

        currentPoints = overlayPoints.shift();

        if (currentPoints.lineColor)

        {

            overlayGraphics.lineStyle(1, currentPoints.lineColor, 1, true);

        }

        sPoint = currentPoints.start;

        ePoint = currentPoints.end;

        angle = Math.atan2(ePoint.x - sPoint.x, ePoint.y - sPoint.y);

        advanceX = speed * Math.sin(angle);

        advanceY = speed * Math.cos(angle);

        overlayGraphics.moveTo(sPoint.x, sPoint.y);

        nextPoint = new Point(sPoint.x, sPoint.y);

    }

    nextPoint.x += advanceX;

    nextPoint.y += advanceY;

   

    overlayGraphics.lineTo(nextPoint.x, nextPoint.y);

    if (Point.distance(ePoint, nextPoint) <= speed)

    {

        overlayGraphics.lineTo(ePoint.x, ePoint.y);

        currentPoints = null;

    }

}

function definePoints():void

{

    var overlayWidth:Number = stage.stageWidth - overlayMargin * 2;

    var overlayHeight:Number = stage.stageHeight - overlayMargin * 2;

    overlayPoints = [];

    overlayPoints.push({start: new Point(0, 0), end: new Point(0, overlayHeight / 6)});

    overlayPoints.push({start: new Point(0, overlayHeight * .5), end: new Point(0, overlayHeight)});

    overlayPoints.push({start: new Point(0, overlayHeight), end: new Point(overlayWidth / 8, overlayHeight)});

    overlayPoints.push({start: new Point(overlayWidth / 8, overlayHeight), end: new Point(overlayWidth / 6, overlayHeight - 50)});

    overlayPoints.push({start: new Point(overlayWidth / 6, overlayHeight - 50), end: new Point(overlayWidth * .5, overlayHeight - 50)});

    overlayPoints.push({start: new Point(overlayWidth * .5, overlayHeight - 50), end: new Point(overlayWidth - 20, overlayHeight - 50), lineColor: 0xFFFFFF});

    overlayPoints.push({start: new Point(overlayWidth - 20, overlayHeight - 50), end: new Point(overlayWidth - 20, overlayHeight - 100)});

    overlayPoints.push({start: new Point(overlayWidth - 20, overlayHeight - 100), end: new Point(overlayWidth, overlayHeight - 150)});

    overlayPoints.push({start: new Point(overlayWidth, overlayHeight - 150), end: new Point(overlayWidth, overlayHeight - 200)});

}

function makeOverlay():void

{

    animatedLineOverlay = new Shape();

    overlayGraphics = animatedLineOverlay.graphics;

    overlayGraphics.lineStyle(1, 0, 1, true);

    overlayGraphics.beginFill(0x000000);

    overlayGraphics.drawRect(0, 0, 80, 10);

    overlayGraphics.endFill();

    animatedLineOverlay.x = animatedLineOverlay.y = overlayMargin;

    addChild(animatedLineOverlay);

}

function makeBackground():void

{

    graphics.beginFill(0xFF8040);

    graphics.drawRect(0, 0, stage.stageWidth * .5, stage.stageHeight);

    graphics.endFill();

    graphics.beginFill(0x0070DF);

    graphics.drawRect(stage.stageWidth * .5, 0, stage.stageWidth * .5, stage.stageHeight);

    graphics.endFill();

}

October 7, 2012

I am totally impressed, many thanks for what you call quick and dirty.

The swf movie I get is perfect and ultra light, yet it does not work after I passed the FLA through Wallaby, do you have any clue? My timeline only has one frame, is this the reason?

All best,

Inspiring
October 7, 2012

Sorry, I am not familiar with Wallaby...

kglad
Community Expert
Community Expert
October 7, 2012

i didn't gather any info from your screen captures but generally animation that appears as cursive writing is done by using various animated masks.  each mask/animation should appear on a distinct layer.

October 7, 2012

Thank you, you mean all this Inside flash, correct? I am not super confident this travels Ok to DPS via Wallaby.

October 7, 2012

By the way my 3 screen captures show an appearing vertical black stroke on the left hand side of the page