Programmation AS3

Lundi 5 septembre 2011 1 05 /09 /Sep /2011 14:52

Afin d'agrémenter un peu la palette de possibilité la fonction epitrochoide peut être réjoutée.

        private function epitrochoid( angle:Number, r:Number, k:int, d:int, equation:Boolean ):Number
        {
            var trochoid:Number;
           
            if( equation )
            {
                trochoid = ( (k * r) + r) * Math.cos(angle) - d * Math.cos( ( (k * r) + r ) / r * angle )
            }
            else
            {
                trochoid = ( (k * r) + r) * Math.sin(angle) - d * Math.sin( ( (k * r) + r ) / r * angle )
            }
           
            return trochoid
        }


 

Voici un aperçu d'un hypotrochoïd à gauche et d'un epitrochoide à droite:

Par Gilles De Truchis - Publié dans : Programmation AS3
Ecrire un commentaire - Voir les 0 commentaires
Lundi 5 septembre 2011 1 05 /09 /Sep /2011 09:49

La galerie de type carrousel est une animation flash plutôt répendue. De fait le manège circulaire devient vite banal. Voici une classe qui vous permettra d'explorer de nouvelles formes bien plus originales que le cercle. En effet, en jouant sur les valeurs des équations paramétriques dans la fonction hypotrochoïd, vous pourrez obtenir des effets vraiment originaux. En lisant attentivement le programme vous constaterez qu'il est également possible d'ajouter un effet de perspective.

package fx.bidesign.controls
{
   
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.MovieClip;
   
    import flash.events.Event;
    import flash.events.MouseEvent;
   
    import flash.net.URLLoader;
    import flash.net.URLRequest;
   
    import flash.filters.BlurFilter;
    import flash.filters.GlowFilter;
    import flash.filters.BitmapFilterQuality;
   
    import fl.transitions.easing.*;
   
    import fx.gskinner.motion.GTween;
   
    import fx.bidesign.display.FxAlertDisplay;
   
    import fx.bidesign.utils.FxDisplayObjectPosition;
    import fx.bidesign.utils.FxDisplayObjectAlign;
   
    import fx.bidesign.filters.FxReflect;
    import fx.bidesign.desktop.FxSuperStage;

    public class FxTilesCarousel extends Sprite
    {
        private var loader:Loader;

        private var url:String;
       
        private var xml:XML;
        private var list:XMLList;
        private var urlLoader:URLLoader;
       
        private var array:Array;
        private var speed:Number;
        private var radiusX:Number;
        private var radiusY:Number;
        private var perspective:Number;
        private var angles:Vector.<Number>;
       
        private var isRunning:Boolean;
       
        private var tooltip:FxAlertDisplay;
        private var bigTip:FxAlertDisplay;
       
        private var pos:FxDisplayObjectPosition;
               
        public function FxTilesCarousel( pUrl:String )
        {
            url = pUrl;
           
            init();
           
            loadXML();
        }
       
        private function init():void
        {
            speed = 0.01;
            radiusX = 100;
            radiusY = 40;
            perspective = 1;
            array = [];
           
            isRunning = true;
           
            pos = new FxDisplayObjectPosition();
           
            //
            tooltip = new FxAlertDisplay( "no item", 200, 30 );
           
            tooltip.name = "0";
           
            //
            /*bigTip = new FxAlertDisplay( "Description du produit selectionné : ", 500, 150 );
           
            pos.push( bigTip, null, 200, FxDisplayObjectAlign.TOP );
           
            addChild( bigTip );*/
           
            //addEventListener( Event.REMOVED_FROM_STAGE, removeAll );
        }
       
        private function loadXML():void
        {
            urlLoader = new URLLoader( new URLRequest( url ) );
           
            urlLoader.addEventListener( Event.COMPLETE, xmlLoaded );
        }
       
        private function xmlLoaded( pEvt:Event ):void
        {
            xml = new XML( pEvt.target.data );
            list = xml.wine;
           
            angles = new Vector.<Number>( list.length(), true );
           
            for( var i:int = 0; i < list.length(); i++ )
            {
                loader = new Loader();
               
                loader.name = String( i );
                loader.mouseChildren = false;
               
                loader.addEventListener( Event.ENTER_FRAME, enterFrame );
                loader.addEventListener( MouseEvent.MOUSE_MOVE, mouseMove );
                loader.addEventListener( MouseEvent.MOUSE_OVER, mouseOver );
                loader.addEventListener( MouseEvent.MOUSE_DOWN, mouseDown );
               
                loader.load( new URLRequest( list[i].@source ) );
               
                addChild( loader );
               
                angles[i] = i * ( Math.PI * 2 ) / list.length();
               
                array.push( loader );
            }
           
            urlLoader.removeEventListener( Event.COMPLETE, xmlLoaded );
        }
       
        private function enterFrame( pEvt:Event ):void
        {
            tooltip.move( getChildByName( String( tooltip.id ) ).x - 30, getChildByName( String( tooltip.id ) ).y - 40 );
           
            if( isRunning )
            {
               
                pEvt.target.x = hypotrochoid( angles[int(pEvt.target.name)], radiusX, 3, radiusX, true)
                pEvt.target.y = hypotrochoid( angles[int(pEvt.target.name)], radiusY, 3, radiusY, false)
               
                var s:Number = (pEvt.target.y - perspective) / ( (FxSuperStage.STAGE.stageHeight / 2) + radiusY - perspective );
               
                //pEvt.target.scaleX = ( s + 1 ) / 2; // permet l'ajout d'un effet de perspective
                //pEvt.target.scaleY = ( s + 1 ) / 2;
// permet l'ajout d'un effet de perspective
                angles[int(pEvt.target.name)] += speed;
               
                pEvt.target.filters = [ new GlowFilter( 0x000000, 0.6, 4, 4, 2, BitmapFilterQuality.HIGH ) ];
                //pEvt.target.filters = [ new BlurFilter( 0.0,Math.abs(s/0.2), BitmapFilterQuality.HIGH )  ];
               
                array.sortOn( "scaleX", Array.NUMERIC );
   
                array.forEach( sortTiles );
            }
        }
       
        private function hypotrochoid( angle:Number, r:Number, k:int, d:int, equation:Boolean ):Number
        {
            var trochoid:Number;
           
            if( equation )
            {
                trochoid = ( (k * r) - r) * Math.cos(angle) + d * Math.cos( ( (k * r) - r ) / r * angle )
            }
            else
            {
                trochoid = ( (k * r) - r) * Math.sin(angle) - d * Math.sin( ( (k * r) - r ) / r * angle )
            }
           
            return trochoid
        }
       
        private function sortTiles( item:Loader, index:int, target:Array ):void
        {
            setChildIndex( item, index );
        }
       
        private function mouseMove( pEvt:MouseEvent ):void
        {
            speed = ( mouseX - ( FxSuperStage.STAGE.stageWidth / 2 ) ) / 60000;
        }
       
        private function mouseDown( pEvt:MouseEvent ):void
        {
            isRunning = !isRunning;
           
            var txt:String = list[int(pEvt.target.name)].@label + "\n\n" + list[int(pEvt.target.name)] + "\n\n" + list[int(pEvt.target.name)].@desc;
           
            //bigTip.text = txt;
        }
       
        private function mouseOver( pEvt:MouseEvent ):void
        {
            tooltip.id = int(pEvt.target.name);
            tooltip.text = list[int(pEvt.target.name)].@label;
           
            addChild( tooltip );
        }
       
        private function removeAll( pEvt:Event ):void
        {
            for( var j:int = 0; j < array.length; j++ )
            {
                var ld:Loader = array[j].getChildAt( 0 ) as Loader;
               
                ld.unload();
                ld.removeEventListener( Event.ENTER_FRAME, enterFrame );
                ld.removeEventListener( MouseEvent.MOUSE_MOVE, mouseMove );
                ld.removeEventListener( MouseEvent.MOUSE_OVER, mouseOver );
                ld.removeEventListener( MouseEvent.MOUSE_DOWN, mouseDown );
               
                removeChild( ld );
            }
           
            removeChild( bigTip );
            bigTip = null;
           
            removeChild( tooltip );
            tooltip = null;
        }
    }
}



Voici les autres classes nécessaires pour le fonctionnement de cette dernière ainsi qu'un exemple de la structure du fichier xml: sources

Par Gilles De Truchis - Publié dans : Programmation AS3
Ecrire un commentaire - Voir les 0 commentaires
Lundi 15 novembre 2010 1 15 /11 /Nov /2010 22:44

J'ai récemment posté sur Mediabox une galerie tout à fait standard mais qui j'éspère pourra servir à certain. Je détaille ci-dessous quelques classes qui la composent et bien évidement je mets à disposition les sources. Voici le résultat final: exemple

 

arborescence Afin que le projet semble claire, voici son arborescence. A la racine, (i.e. dans le fichier CLASS FxTilesInfinity), nous trouve le fichier wall.swf autour duquel s'organisent différents dossiers.

Dans le dossier xml nous trouvons le fichier wall3D.xml qui répertorie les chemins d'accès aux différentes images qui composeront la galerie. Chaque noeud contient deux adresses, l'une pour la miniature de l'image et l'autre pour l'image dans sa taille originelle.

Le dossier gal contient deux sous dossiers, thumbs et tiles, qui sont destinés à contenir respectivement les miniatures et images non modifiées.

Le dossier fx contient l'ensemble des classes nécessaires. Elles sont réparties en deux packages. Le package de Grant Skinner qui sert pour les Tweens et le package bidesign qui sert pour la galerie.

Le dossier control contient la classe FxTilesInfinity donc le constructeur admet deux paramètres, l'url du xml fournissant la liste des adresses des images et le nombre de lignes sur lesquels les miniatures sont à répartir. Cela peu permettre, par exemple, d'adapter la hauteur de la galerie en fonction de la taille de l'écran client.

 

Voici le contenu de la classe document qui montre comment instancier un objet FxTilesInfinity.

 

package fx.bidesign.document
{
   
    import fx.bidesign.utils.FxStats;
   
    import fx.bidesign.desktop.FxSuperStage;
   
    import fx.bidesign.controls.FxTilesInfinity;
   

    public class Document extends FxSuperStage
    {
       
        public function Document()
        {
            var line:int = Math.floor( FxSuperStage.STAGE.stageHeight / 300 );
           
            var wall:FxTilesInfinity;
           
            wall = new FxTilesInfinity( "xml/wall3D.xml", line );

            addChild( wall );
        }
       
    }
}

 

La classe FxTilesInfinity n'est pas spécialement compliquée et peut être améliorée pour intégrer de la 3D. Néanmoins, le contrôle des ressources utilisées devient plus compiqué dans ce cas.

 

package fx.bidesign.controls
{
    import flash.events.Event;
    import flash.events.MouseEvent;
    
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
   
    import flash.net.URLLoader;
    import flash.net.URLRequest;
   
    import flash.geom.Point;
    import flash.geom.PerspectiveProjection;
   
    import fl.transitions.easing.*;
    import fl.motion.easing.Exponential;
   
    import fx.gskinner.motion.GTween;
   
    import fx.bidesign.controls.FxTile;
    import fx.bidesign.controls.FxTileDisplay;
   
    import fx.bidesign.events.FxTileEvent;
   
    import fx.bidesign.desktop.FxSuperStage;

    public class FxTilesInfinity extends Sprite
    {
        private var tile:FxTile;
        private var screen:FxTileDisplay;
       
        //
        private var end:int;
        private var tileMax:int;
        private var celerity:int;
       
        private var rows:int;
        private var spread:Number;

        private var tileW:Number;
        private var tileH:Number;
       
        private var filter:Boolean;
        private var reflect:Boolean;
        private var smoothing:Boolean;
        private var dimension:Boolean;
       
        private var zoom:Number;
        private var zoomMax:Number;
        private var zoomMin:Number;
       
        //
        private var offset:Number;
        private var allowMove:Boolean;
       
        //
        private var xml:XML;
        private var list:XMLList;
        private var loader:URLLoader;
       
        //
        private var url:String;

        public function FxTilesInfinity( pUrl:String, pRows:int = 3 )
        {
           
            url = pUrl;
            rows = pRows;
           
            //
            FxSuperStage.STAGE.align = StageAlign.TOP_LEFT;
            FxSuperStage.STAGE.scaleMode = StageScaleMode.NO_SCALE;
           
            //
            open();
        }
       
        private function open():void
        {
            //
            loader = new URLLoader( new URLRequest( url ) );
           
            loader.addEventListener( Event.COMPLETE, complete );
        }
       
        private function params():void
        {
            /*
            /
            / Let you modify params
            /
            */
           
            //rows = 3;
            spread = 10;
           
            celerity = 3500;
            end = list.length();

            tileW = 200;
            tileH = 200;
           
            filter = true;
            reflect = true;
            smoothing = true;
            dimension = false;
           
            zoom = 0;
            zoomMax = -500;
            zoomMin = 1500;
           
            /*
            /
            / end params
            /
            */
           
            //
            draw();
        }
       
        private function draw():void
        {
            //
            tileMax = Math.ceil( ( FxSuperStage.STAGE.stageWidth ) / ( tileW + spread ) ) * rows;
           
            for( var i:int = 0; i < tileMax; i++ )
            {
                tile = new FxTile( i, rows, tileW, tileH, spread, list[i].@src, list[i].@url, filter, reflect, smoothing );
               
                tile.addEventListener( FxTileEvent.LEFT, outByLeft );
                tile.addEventListener( FxTileEvent.RIGHT, outByRight );
               
                addChild( tile );
            }
           
            //
            this.transform.perspectiveProjection = new PerspectiveProjection();
            this.transform.perspectiveProjection.projectionCenter = new Point ( this.width / 2, this.height / 2 );
           
            //
            move();
        }
       
        private function drawNow( index:int ):void
        {
            tile = new FxTile( index, rows, tileW, tileH, spread, list[index].@src, list[index].@url, filter, reflect, smoothing );
               
            tile.addEventListener( FxTileEvent.LEFT, outByLeft );
            tile.addEventListener( FxTileEvent.RIGHT, outByRight );
           
            addChild( tile );
        }
       
        private function move():void
        {
            this.allowMove = true;
            this.doubleClickEnabled = true;
            this.addEventListener( Event.REMOVED_FROM_STAGE, removeAll );
           
            FxSuperStage.STAGE.addEventListener( MouseEvent.DOUBLE_CLICK, click );
            FxSuperStage.STAGE.addEventListener( MouseEvent.MOUSE_DOWN, mouseDown );
        }
       
        /*
        /
        / Event
        /
        */
       
        private function removeAll( pEvt:Event ):void
        {
            for( var j:int = 0; j < numChildren - 1; j++ )
            {
                 ( getChildAt( j ) as FxTile ).removeAll();
            }
        }
       
        private function complete( pEvt:Event ):void
        {
            //
            xml = new XML( pEvt.target.data );
           
            list = xml.item;
           
            //
            params();
           
            //
            loader.removeEventListener( Event.COMPLETE, complete );
        }
       
        private function outByLeft( pEvt:FxTileEvent ):void
        {
            //
            drawNow( pEvt.id + tileMax );
           
            //
            pEvt.target.removeEventListener( FxTileEvent.LEFT, outByLeft );
            pEvt.target.removeEventListener( FxTileEvent.RIGHT, outByRight );
           
            pEvt.target.removeAll();
        }
       
        private function outByRight( pEvt:FxTileEvent ):void
        {
            //
            drawNow( pEvt.id - tileMax );
           
            //
            pEvt.target.removeEventListener( FxTileEvent.LEFT, outByLeft );
            pEvt.target.removeEventListener( FxTileEvent.RIGHT, outByRight );
           
            pEvt.target.removeAll();
        }
       
        private function click( pEvt:MouseEvent ):void
        {
            if( pEvt.target is FxTile && allowMove )
            {
                allowMove = !allowMove;
               
                //
                screen = new FxTileDisplay( pEvt.target.source, FxSuperStage.STAGE.stageWidth, FxSuperStage.STAGE.stageHeight, false, false, true );
               
                addChild( screen );
               
                addEventListener( MouseEvent.CLICK, click );
            }
            else
            {
                allowMove = !allowMove;
               
                //
                removeChild( screen );
               
                removeEventListener( MouseEvent.CLICK, click );
            }
        }
       
        private function mouseDown( pEvt:MouseEvent ):void
        {
            offset = mouseX;
           
            if( allowMove ) FxSuperStage.STAGE.addEventListener( MouseEvent.MOUSE_UP, mouseUp );
            if( allowMove ) FxSuperStage.STAGE.addEventListener( MouseEvent.MOUSE_MOVE, mouseMove );
        }
       
        private function mouseUp( pEvt:MouseEvent ):void
        {
            //
            FxSuperStage.STAGE.removeEventListener( MouseEvent.MOUSE_UP, mouseUp );
            FxSuperStage.STAGE.removeEventListener( MouseEvent.MOUSE_MOVE, mouseMove );
           
            //
            if( dimension ) var rotateY:GTween = new GTween( this, 5, { rotationY: 0 },{ ease:Exponential.easeOut } );
        }
       
        private function mouseMove( pEvt:MouseEvent ):void
        {
            //
            var speed:Number = ( mouseX - offset ) / FxSuperStage.STAGE.stageWidth;
           
            /*if( speed < 0 ) speed = ( speed > - 0.7 ) ? speed : - 0.7;
            else speed = ( speed < 0.7 ) ? speed : 0.7;*/

            var moveX:GTween = new GTween( this, 5, { x: this.x + ( speed * celerity ) },{ ease:Exponential.easeOut } );
           
            moveX.addEventListener( Event.INIT, check );
           
            //
            if( dimension ) var rotateY:GTween = new GTween( this, 1, { rotationY: this.rotationY + ( speed * 10 ) },{ ease:Elastic.easeOut } );
           
            pEvt.updateAfterEvent();
        }
       
        private function check( pEvt:Event ):void
        {
            var pos:Number = ( end - tileMax ) * ( tileW + spread ) / 3;
           
            if( pEvt.target.getProperty( "x" ) > - 10 ) pEvt.target.setProperty( "x", 10 );
            else if( pEvt.target.getProperty( "x" ) < - pos ) pEvt.target.setProperty( "x", - pos );
           
            pEvt.target.removeEventListener( Event.INIT, check );
        }
    }
}

 

Les paramètres utiles à la gestions de la galerie sont regroupés dans la fonction params() et sont essentiellement les à la vitesse de défilement (celerity), l'écart entre les miniatures (spread), la dimension des miniatures (tileW et tileH) et le rendu. Du rendu, va dépendre la fluidité de l'animation. Ainsi, si chaque miniature est lissée (smoothing), encadré (filter) et embarque un effet de reflet (reflect) l'animation pourra ne pas être fluide sur tout les postes clients.

 

Télécharger les sources

Par Gilles De Truchis - Publié dans : Programmation AS3
Ecrire un commentaire - Voir les 0 commentaires
Mardi 9 juin 2009 2 09 /06 /Juin /2009 12:25

On m'a récemment demandé de ressortir un vieil algorithme de cryptage RSA que je n'ai pas retrouvé. J'ai donc entrepris de réécrive ma classe RSA. Quelques jours plus tard je découvre qu'une classe RSA existe déjà au sein du package AS3crypto (dont je me sers mais j'étais passé à coté de cet classe "RSAKey"). L'extrême faiblesse de ma classe RSA venait du fait que je ne parvenais pas à effectuer des calcules d'arithmétique modulaire avec des puissances importantes du type: m = cd mod n. En effet l'efficacité des clés de chiffrements du cryptage RSA repose sur la grandeur des nombres et si d doit rester petit, l'intérêt du procédé disparaît.
Pour ceux qui ne connaissent pas le RSA, il ne s'agit pas du Revenu de Solidarité Active vous l'aurez compris. C'est une technique de chiffrement mis au point par Rivest Shamir Adleman. Mais le sujet n'est pas là... Il s'agit de parvenir à calculer des opérations du type cd mod n avec de grandes valeurs. Voici une implémentation d'exponentiation modulaire basée sur de l'exponentiation binaire qui donne des résultats intéressants:

// Modular Exponentiation
var st:int = getTimer();
trace( mod( 1026, 649, 1073 ) );
trace( "Time elapsed: ", getTimer() -
st );

/* Math.pow( a, b ) % c */
function mod( a:int, b:int, c:int ):int
{
    var d:Number = 1;
    var e:Number = a;
    
    while( b > 0 )
    {
        if( b % 2 == 1 ) d = ( d * e ) % c;

        e = ( e * e ) % c;
        b /= 2;
    }
    return d % c;
}


Voici une mise en pratique basique du code précédent:



Application pour le PGCD (Plus grand commun diviseur)... Je sais ça remonte à loin tout ça



Par Gilles De Truchis - Publié dans : Programmation AS3
Ecrire un commentaire - Voir les 0 commentaires
Lundi 20 avril 2009 1 20 /04 /Avr /2009 00:40

Voici une classe qui permet de calculer la prime (spread) d'un CDS mono-support sur obligation et une application flash de pricing des CDS en question. La méthode utilisée est celle du démantèlement, présentée précédemment.

 

package fx.bidesign.maths
{
    import fx.bidesign.maths.Factorial;
    
    public class CDS
    {

        public function CDS()
        {

        }
        public static function evaluate( n:Number, s:Number, a:Number, r:Array, rc:Array ):Array
        {
            var phi:Array = [];
            var spreads:Array = [];
            var gamma:Array = [];
           
            var leg1:Number = 0;
            var leg2:Number = 0;
           
            var value:Number = 0;
           
            a = a / 100;
            s = s / 100;
           
            for( var i:int = 0; i < r.length; i++ )
            {
                r[i] = Number( r[i] ) / 100;
                rc[i] = Number( rc[i] ) / 100;
               
                spreads.push( rc[i] - r[i] );
               
                phi.push( (i+1) * 1 / ( 1 - a ) * spreads[i] );
               
                gamma.push( 1 - phi[i] );
               
                if( i == 0 ) leg1 += 1 / Math.pow( 1 + r[i], i+1 ) * phi[i];
                else leg1 += 1 / Math.pow( 1 + r[i], i+1 ) * ( gamma[i-1] - gamma[i] );
               
                leg2 += 1 / Math.pow( 1 + r[i], i+1 ) * gamma[i];
            }
           
            leg1 *= ( 1 - a ) * n;
            leg2 *= s * n;
           
            value = leg1 - leg2;
           
            return [value, leg1, leg2, phi, spreads];
        }
    }
}



Télécharger les sources (.rar)

Par Gilles De Truchis - Publié dans : Programmation AS3
Ecrire un commentaire - Voir les 1 commentaires

Un problème d'affichage...?

Certaines pages de ce site contiennent des animations Flash qui nécessitent la dernière version du flash player.

haut de page

Varennes EcoFin

Mon site internet migre vers une nouvelle adresse: Varennes EcoFin. Il s'agit d'un site en flash recentré sur mes travaux de recherches, ma thèse et des resources pour les étudiants (programmes, bases de données etc.). Pour accéder à la version sans flash (HTML5): Varennes EcoFin Sky.

Présentation

Recherche

Music Player

 
Créer un blog gratuit sur over-blog.com - Contact - C.G.U. - Signaler un abus - Articles les plus commentés