/* * Xorax AS2 Player - Action Script 2 flash class for designer * * Copyright (c) 2008 Martin Panel (contact@xorax.info) * licensed under the MIT (MIT-LICENSE.txt) */ /** * @see flash mp3 player as2 * @author Xorax * @license http://www.opensource.org/licenses/mit-license.php copyright Martin PANEL : MIT license * @version 20080523 * @description aide l'assignation de fonctions et d'événements sur des objets graphique. */ class xorax.player.template extends xorax.player.base { /** * assigne l'action qui permet au bouton btn de démarrer la lecture lorsqu'il est cliqué. * @param btn MovieClip : référence du bouton * @param src String source du son à jouer (optionnel) */ public function addPlay (btn, src:String):Void{ var th = this; var lastonRelease = btn.onRelease; btn.onRelease = function(){ th.play(src); lastonRelease(); } } /** * assigne l'action qui permet au bouton btn de mettre la lecture en pause lorsqu'il est cliqué. * @param btn référence du bouton */ public function addPause (btn):Void{ var th = this; var lastonRelease = btn.onRelease; btn.onRelease = function(){ th.pause(); lastonRelease(); } } /** * assigne l'action à un bouton. Lorsque le bouton sera pressé, si le son est en pause ou stoppé, on reprend au niveau de la tête de lecture, sinon on le met en pause. * @param btn référence du bouton * @param src source du son à jouer lors quand l'action est appelé (optionnel) */ public function addPlayPause(btn, src):Void{ var th = this; var lastonRelease = btn.onRelease; btn.onRelease = function(){ if(th.isOnPlaying()){ th.pause(); } else { th.play(src); } lastonRelease(); } } /** * assigne l'action "arrèter le son et rembobiner la tête de lecture" à un bouton * @param btn référence du bouton */ public function addStop (btn):Void{ var th = this; var lastonRelease = btn.onRelease; btn.onRelease = function(){ th.stop(); lastonRelease(); } } /** * assigne l'action "augmenter le volume" à un bouton * @param btn référence du bouton */ public function addVolumeInc (btn):Void{ var th = this; var lastonRelease = btn.onRelease; btn.onRelease = function(){ th.volumeInc(); lastonRelease(); } } /** * assigne l'action "diminuer le volume" à un bouton * @param btn référence du bouton */ public function addVolumeDec (btn):Void{ var th = this; var lastonRelease = btn.onRelease; btn.onRelease = function(){ th.volumeDec(); lastonRelease(); } } function addDraggable (btn:MovieClip, onDrag:Function, onStop:Function, lockCenter:Boolean):Void{ //ondrag(x,y,btn): [x,y] | false ; onStop():Void var th = this; var lastOnPress = btn.onPress; var lastOnMouseMove:Function; btn.onPress = function(){ this.onDragging = true; var off_x = 0, off_y = 0; lockCenter = true; if(!lockCenter){ off_x = this._parent._xmouse - this._x; off_y = this._parent._ymouse - this._y; } var setPosition:Function = function (target:Object) { target._x = target._parent._xmouse - off_x; target._y = target._parent._ymouse - off_y; }; lastOnMouseMove = btn.onMouseMove; setPosition(this); lastOnPress(); if(lockCenter){ onDrag(this); lastOnMouseMove(); } this.onMouseMove = function () { setPosition(this); onDrag(this); lastOnMouseMove(); updateAfterEvent(); }; }; var lastOnRelease = btn.onRelease; btn.onRelease = btn.onReleaseOutside = function(){ this.onDragging = false; //this.onMouseMove(); onStop(this); this.onMouseMove = lastOnMouseMove; } lastOnRelease(); } /** * permet de se servir d'un élément graphique comme d'une bar de chargement. * Lors du chargement, le clip changera de taille en fonction des paramêtres pLeft et pRight et du nombre de byte chargé * exemple : * //btnId est une reference à un clip * myPlayer.addBarBytesLoaded(btnId, {_width:0}, {_width: 100}); * @param clip référence du clip * @param pLeft object contenant (au minimum) le _width ou le _left de la taille minimum que doit avoir le clip * @param pLeft object contenant (au minimum) le _width ou le _left de la taille maximum que doit avoir le clip */ public function addBarBytesLoaded (clip, pLeft, pRight){ if(!pLeft) var pLeft = {}; if(!pRight) var pRight = {}; var pRef = this.defRefPropertyScale(clip, pLeft, pRight); clip[pRef] = pLeft[pRef]; var th = this; var listen = { onLoading: function(success) { if(success) clip[pRef] = pRight[pRef]; else { clip[pRef] = pLeft[pRef] + ((pRight[pRef]-pLeft[pRef]) * th.position()/th.duration() ); } }}; this.addListener(listen); } function createMaskClip (bar){ var but = bar._parent.createEmptyMovieClip('__'+bar._name+'_but',bar._parent.getNextHighestDepth()); but._alpha = 0; var tp = bar.getBounds(bar._parent); but._x = tp.xMin; but._y = tp.yMin; but.beginFill(0xFF0000); but.moveTo(0,0); but.lineTo(bar._width,0); but.lineTo(bar._width,bar._height); but.lineTo(0,bar._height || 1); but.lineTo(0,0); but.endFill(); //bar.hitArea(but); but.useHandCursor = true; return but; } function addResizable (bar, onResize, onStop, pRef){ var but = this.createMaskClip(bar, pRef); var mRef = (pRef == '_height') ? '_ymouse': '_xmouse'; var sRef = (pRef == '_height') ? '_yscale': '_xscale'; var th = this; var lastOnPress = but.onPress; var lastOnMouseMove:Function; but.onPress = function(){ this.onResizing = true; lastOnPress(); lastOnMouseMove = but.onMouseMove; this.onMouseMove = function () { bar[pRef] = this[mRef]*this[sRef]/100; onResize(this); lastOnMouseMove(); updateAfterEvent(); }; }; var lastOnRelease = but.onRelease; but.onRelease = but.onReleaseOutside = function(){ bar[pRef] = this[mRef]*this[sRef]/100; onStop(this); this.onMouseMove = lastOnMouseMove; lastOnRelease(); this.onResizing = false; } return but; } /** * permet de se servir d'un élément graphique comme d'une bar de volume. * L'utilisateur pourra alor augmenté ou diminué le volume en augmentant ou en diminuant la taille du clip. * exemple : * //btnId est une reference à un clip * myPlayer.addBarVolume(btnId, {_height:0}, {_height: 100}); * @param clip référence du clip * @param pLeft object contenant (au minimum) le _width ou le _left de la taille minimum que doit avoir le clip * @param pLeft object contenant (au minimum) le _width ou le _left de la taille maximum que doit avoir le clip * @param onMoveFunc fonction appelé à chaque modification du volume */ public function addBarVolume(clip, pLeft:Object, pRight:Object, onMoveFunc:Function) :Void{ var pRef = this.defRefPropertyScale(clip, pLeft, pRight); var th = this; var onResize = function(){ var rap = th.setPropAccording(clip, pLeft, pRight, pRef); th.volumeSet(rap*100); } onResize(); this.addListener({ onStart: onResize, onVolumeChange: function(){ clip[pRef] = pLeft[pRef] + ((pRight[pRef]-pLeft[pRef]) * th.volume/100 ); th.setPropAccording(clip, pLeft, pRight, pRef); } }); this.addResizable (clip, onResize, onResize, pRef); } /** * permet de se servir d'un élément graphique comme d'un bouton de volume. * L'utilisateur pourra alor augmenté ou diminué le volume en déplçant le clip * exemple : * //btnId est une reference à un clip * myPlayer.addBarVolume(btnId, {_x:0}, {_x: 100}); * @param clip référence du clip * @param pLeft object contenant (au minimum) le _width ou le _left de la position minimum que doit avoir le clip * @param pLeft object contenant (au minimum) le _width ou le _left de la position maximum que doit avoir le clip * @param onDragFunc fonction appelé à chaque modification du volume */ public function addDragVolume (clip, pLeft:Object, pRight:Object, onDragFunc:Function) :Void{ var pRef = this.defRefPropertyPosition(clip, pLeft, pRight); var th = this; var onDrag = function(){ var rap = th.setPropAccording(clip, pLeft, pRight, pRef)*100; th.volumeSet(rap); } this.addListener({ onStart: onDrag, onVolumeChange: function(){ clip[pRef] = pLeft[pRef] + ((pRight[pRef]-pLeft[pRef]) * th.volume/100 ); th.setPropAccording(clip, pLeft, pRight, pRef); } }); this.addDraggable(clip, onDrag); } /** * permet de se servir d'un élément graphique comme d'une bar de position de la tête de lecture. * L'utilisateur pourra alor déplacer la tête de lecture en modifiant la taille clip. * exemple : * //btnId est une reference à un clip * myPlayer.addBarVolume(btnId, {_width:0}, {_width: 100}); * @param clip référence du clip * @param pLeft object contenant (au minimum) le _width ou le _left de la taille minimum que doit avoir le clip * @param pLeft object contenant (au minimum) le _width ou le _left de la taille maximum que doit avoir le clip * @param onMoveFunc fonction appelé à chaque changement de position de la tête de lecture */ public function addBarPosition(clip, pLeft:Object, pRight:Object, onMoveFunc:Function) :Void{ var pRef = this.defRefPropertyScale(clip, pLeft, pRight); var th = this; var onResize = function(){ var rap = th.setPropAccording(clip, pLeft, pRight, pRef); var pos = th.sound.duration/1000; var t = rap*pos; if(Math.round(th.sound.position/1000) != Math.round(t)) { if(th.isOnPause()) { th.pausedAt = t; } else { th.position(t*1000); } } onMoveFunc(rap); } //onResize(); var but = this.addResizable (clip, onResize, onResize, pRef); clip[pRef] = pLeft[pRef]; th.setPropAccording(clip, pLeft, pRight, pRef); var oldpRef = pRight[pRef]; var posOnload = function(){ if(th.sound.getBytesTotal() > 0){ pRight[pRef] = pLeft[pRef] + ((oldpRef - pLeft[pRef]) * th.sound.duration / th.duration()); } } var listen = { onPlaying: function(){ if(!clip.onResizing){ if(th.isOnLoading()) posOnload(); clip[pRef] = pLeft[pRef] + ((pRight[pRef]-pLeft[pRef]) * th.sound.position/th.sound.duration ); th.setPropAccording(clip, pLeft, pRight, pRef); } }, onLoading:function(success){ if(success) return pRight[pRef] = oldpRef; posOnload(); but[pRef] = pRight[pRef]; } }; this.addListener(listen); } /** * permet de se servir d'un élément graphique comme d'un bouton position de la tête de lecture. * le déplacement du clip bouton déplacera la tête de lecture. * exemple : * //btnId est une reference à un clip * myPlayer.addDragPosition(btnId, {_x:0, _y:0}, {_x:100, _y: 100}); * L'utilisateur pourra alor déplacer la tête de lecture en déplaçant le clip * @param clip référence du clip * @param pLeft object contenant (au minimum) le _width ou le _left de la taille minimum que doit avoir le clip * @param pLeft object contenant (au minimum) le _width ou le _left de la taille maximum que doit avoir le clip * @param onMoveFunc fonction appelé à chaque changement de position de la tête de lecture */ public function addDragPosition (btn, pLeft:Object, pRight:Object, onDragFunc:Function):Void{ var pRef = this.defRefPropertyPosition(btn, pLeft, pRight); btn[pRef] = pLeft[pRef]; var th = this; var onDrag = function(){ var rap = th.setPropAccording(btn, pLeft, pRight, pRef); var pos = (th.sound.duration || 0)/1000; var t = Math.round(rap*pos); if(Math.round((th.sound.position || 0)/1000) != t) { if(th.isOnPause()) { th.pausedAt = t; } else { th.sound.start(t); th.startPlaying(); } } onDragFunc(rap); } //onDrag(); th.setPropAccording(btn, pLeft, pRight, pRef); this.addDraggable(btn, onDrag); var oldpRef = pRight[pRef]; var posOnload = function(){ if(th.sound.getBytesTotal() > 0){ pRight[pRef] = pLeft[pRef] + ((oldpRef - pLeft[pRef]) * (th.sound.getBytesLoaded() || 0)/th.sound.getBytesTotal()); } } var listen = { onPlaying: function(){ if(!btn.onDragging){ if(th.isOnLoading()) posOnload(); btn[pRef] = pLeft[pRef] + ((pRight[pRef]-pLeft[pRef]) * th.sound.position/th.sound.duration); th.setPropAccording(btn, pLeft, pRight, pRef); } }, onLoading:function(success){ if(success) return pRight[pRef] = oldpRef; posOnload(); th.setPropAccording(btn, pLeft, pRight, pRef); } }; this.addListener(listen); } private function defRefPropertyPosition (target:MovieClip, pLeft:Object, pRight:Object){ var x = '_x', y = '_y'; var pRef;//, pRefInv; /* for(var p in pRight){ if(!(pLeft[p] instanceof Number)) pLeft[p] = target[p]; }*/ for(var p in pLeft){ if(isNaN(pRight[p])){ if(!isNaN(pLeft[p])){ target[p] = pLeft[p]; pRight[p] = pLeft[p]; } } } if(isNaN(pLeft[x]) || pLeft[x] == pRight[x]){ if(isNaN(pLeft[y])){ pRef = x; pLeft[x] = target[x] - (target._width/2); pRight[x] = target[x] + (target._width/2); } else pRef = y; } else pRef = x; /* Pour les concepteurs de flash, 3 n'est pas un nombre (false === 3 instanceof Number) et !isNaN(true) === true. Y en a qui doivent avoir des ampoules aux pieds à force de coder avec. pRefInv = (pRef == x) ? y : x; if(!(pLeft[pRefInv] instanceof Number)) pLeft[pRefInv] = pRight[pRefInv] = target[pRefInv]; */ return pRef; } private function defRefPropertyScale (target:MovieClip, pLeft:Object, pRight:Object){ var h = '_height', w = '_width'; var pRef; for(var p in pRight){ if(isNaN(pLeft[p])) pLeft[p] = 0; } for(var p in pLeft){ if(isNaN(pRight[p])){ target[p] = pLeft[p]; delete pLeft[p]; } } if(isNaN(pLeft[w])){ if(isNaN(pLeft[h])){ pRef = w; pLeft[w] = 0; pRight[w] = target[w]; } else pRef = h; } else pRef = w; return pRef; } private function setPropAccording (target:MovieClip, pLeft:Object, pRight:Object, pRef:String):Number { var rap = (target[pRef]-pLeft[pRef])/(pRight[pRef]-pLeft[pRef]); if(rap <= 0) rap = 0; if(rap > 1) rap = 1; for(var p in pLeft){ if(typeof(pLeft[p]) == 'function'){ pLeft[p](target, rap); } else { target[p] = pLeft[p] + rap*(pRight[p]-pLeft[p]); } } return rap; } private function addClipToMove (target:MovieClip, pLeft:Object, pRight:Object, funcSet:Function):Function{ var pRef = this.defRefPropertyPosition(target, pLeft, pRight); /*for(var p in pLeft) if(pRight[p] == undefined){ btn[p] = pLeft[p]; delete pLeft[p]; }*/ var th = this; var onMove = function(){ var rap = th.setPropAccording(target, pLeft, pRight, pRef); funcSet(rap, pLeft, pRight); } onMove(); return onMove; } }