Wilen_HeadUpload

E-greeting Card System for Online Gifting

April 26, 2012

Tasked with creating an online system for exchanging animated e-greetings and creating dynamic content to accompany an e-gifting site using Actionscript and HTML5 with Javascript, working with back-end e-commerce system in .NET/C#, I designed a flexible architecture that evolved to include a wide variety of features:

  • customizable animations
  • precisely controlled and calibrated color printing onto paper forms utilizing advanced math for scaling, placement and transformations like size/rotation/distortions when users print their own custom bar-coded giftcards
  • uploaded photos that could be silhouetted/outlined using bezier curves
  • stored library of user uploaded/outlined photos
  • user interface for changing custom fields and modular image area modification
  • dynamic scaling of text and images for ‘smart’ fitting of images and text into designated areas
  • animation of uploaded images (e.g. ‘flying head’ e-greetings, similar to JibJab’s)
  • database interaction for all user-defined element storage and retrieval

E-cards:

I was responsible for production of the individual e-cards as well, including storyboarding, green-screen studio videography, and even starred in a number of the mini-productions myself (I acted on camera as the “mummy”, both “gladiators” and the “fisherman” in the samples below).  Used a combination of camera work, Adobe After Effects, Flash ActionScripting, Javascript and  HTML5 techniques to produce online e-greeting animations to accompany the printed pieces, complete with uploaded faces and other content from the user.

I personally created the artwork as well for all of the examples on this page and directed other workers to create additional e-greetings to fill out the library available to gift-card senders.

CLICK THUMBNAILS BELOW TO SEE SAMPLE ANIMATIONS FROM SYSTEM

Note: the gray heads in the animations show where the user’s uploaded photos would go — for this portfolio I chose not to recreate a whole back-end system with database or re-engineer it to work on this demo site, but if you like I am happy to relate all details of how the dynamic aspects of the site work in the original context.  Right now the unpopulated data fields for sender, message, recipient, gift, etc. simply display “undefined”.

.
Dog Track
Mummy.
Mummy
.
Showgirls
.
Piano
title.
Gladiator
title.
Shark
title.
Office Party
title.
Road Trip
title.
Birthday Suit

 

Print Forms:

I created the Actionscript-based printing functionality that inserted custom content like sender name and message and user-controlled color and formatting option onto pre-created printed forms that users could print out either on ordinary printer paper at home, or designed to fit onto pre-perforated and folded giftcard forms.  Scaling and rotations and so forth were handled by custom mathematical functions I created to automate the process for each user.

The artwork for each printed form I adapted from the source material from each animated version of the e-greeting that I had created, either using content from the original Flash animation, video, or other image content like photographs.

CLICK THUMBNAILS BELOW TO SEE SAMPLE PRINT FORMS FROM SYSTEM

 

.
Dog Track
.
Gladiator
.
Showgirls
Mummy.
Mummy
title.
Shark

Gift system could be skinned to conform to various client websites.  This is an example entry page with NY Islanders skin.

Here is a sample code snippet showing one of the classes I created to handle auto-scaling and other transformations on images created through the system:


package { import flash.display.*; import flash.events.*; import flash.net.URLRequest; public class SwfObj extends MovieClipXtended // or should this extend sprite or nothing at all? { public var mySwfs:Array = new (Array); public var imageWid:Number; public var imageHei:Number; public var panelWid:Number; public var panelHei:Number; public var picRatio:Number; public var panelRatio:Number; public var imageXML:XML; public var i:uint; public var myI:uint; //Ken New Content Here re: Mask/upload head data public var hasMask:Boolean; // if this particular SWF has mask var currHeadNum:String = ""; var pcount:int; public function SwfObj() { } public function PopulateSwfObj(myXML, i):void { var updata = myXML.swfs.swf[i].uploadphoto; // this is the attribute (XML string) holding all the upload info for all photos/heads/etc var numUploads:Number = updata.length(); // NOTE: in this system, with one head per SWF this should always = 1, but play it safe with multi-capability var currUpload:XML = new XML; var count:int; for (count=1;countpanelRatio) { loader.x = 0; loader.width = Number(imageXML.@width); loader.height = Number(imageXML.@width)/picRatio; loader.y = ( Number(imageXML.@height)-loader.height)/2; } else { loader.y = 0; loader.height = Number(imageXML.@height); loader.width = Number(imageXML.@height)/picRatio; loader.x = (Number(imageXML.@width)-loader.width)/2; } break; case "fill": //scale proportional to barely fill panel picRatio = Number(imageXML.swfs.swf[myI].@width)/ Number(imageXML.swfs.swf[myI].@height); panelRatio = Number(imageXML.@width)/ Number(imageXML.@height); if (picRatio>panelRatio) { loader.y = 0; loader.height = Number(imageXML.@height); loader.width = Number(imageXML.@height)*picRatio; loader.x = -( Number(imageXML.@width)-loader.width)/2; } else { loader.x = 0; loader.width = Number(imageXML.@width); loader.height = Number(imageXML.@height)*picRatio; loader.y = -(Number(imageXML.@height)-loader.height)/2; } break; case "percentage": //using wid and hei as PERCENTAGE number, then offset x and y loader.width = Number(imageXML.swfs.swf[myI].@width)/100*Number(imageXML.@width); loader.height = Number(imageXML.swfs.swf[myI].@height)/100*Number(imageXML.@height); break; default: //defaults to "Manual" mode loader.width = Number(imageXML.swfs.swf[myI].@width); loader.height = Number(imageXML.swfs.swf[myI].@height); } LoadComplete.arg = "test"; LoadComplete.caller = this; SelfLoaded = true; dispatchEvent(LoadComplete); } private function ioErrorHandler(event:IOErrorEvent):void { //trace("ioErrorHandler: " + event); } } }

Leave a Comment