├── feffects ├── Easing.hx ├── easing │ ├── LICENCE.txt │ ├── Sine.hx │ ├── Quad.hx │ ├── Linear.hx │ ├── Cubic.hx │ ├── Quart.hx │ ├── Quint.hx │ ├── Circ.hx │ ├── Back.hx │ ├── Expo.hx │ ├── Bounce.hx │ ├── easing_readme.txt │ └── Elastic.hx ├── TweenRgb.hx └── Tween.hx ├── samples ├── export │ ├── flash │ │ ├── flash8.swf │ │ └── flash9+.swf │ ├── js │ │ ├── index.html │ │ └── js.js │ └── html5 │ │ ├── haxe │ │ ├── release.hxml │ │ ├── debug.hxml │ │ ├── nme │ │ │ └── AssetData.hx │ │ ├── NMEPreloader.hx │ │ └── ApplicationMain.hx │ │ └── bin │ │ ├── index.html │ │ └── webgl-debug.js ├── buildNME.bat ├── buildFLASH8_FLASH9_JS.hxml ├── NMESamples.nmml └── Main.hx ├── haxelib.xml └── readme.txt /feffects/Easing.hx: -------------------------------------------------------------------------------- 1 | package feffects; 2 | 3 | typedef Easing = Float->Float->Float->Float->Float; 4 | -------------------------------------------------------------------------------- /feffects/easing/LICENCE.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stereobooster/feffects/master/feffects/easing/LICENCE.txt -------------------------------------------------------------------------------- /samples/export/flash/flash8.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stereobooster/feffects/master/samples/export/flash/flash8.swf -------------------------------------------------------------------------------- /samples/export/flash/flash9+.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stereobooster/feffects/master/samples/export/flash/flash9+.swf -------------------------------------------------------------------------------- /samples/export/js/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FEffectsSample 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /samples/export/html5/haxe/release.hxml: -------------------------------------------------------------------------------- 1 | -main ApplicationMain 2 | -lib nme 3 | -lib feffects 4 | -cp D:\workspace\SDK\haxe\lib\nme/git/ 5 | -D nme4=1 6 | -D nme_ver=4.0.0 7 | -D nme_install_tool=1 8 | -D html5 9 | -D web 10 | -js export/html5/bin/FEffectsSample.js 11 | -cp export/html5/haxe 12 | -D html5 13 | -D html 14 | --remap flash:nme 15 | --remap native:browser -------------------------------------------------------------------------------- /samples/export/html5/haxe/debug.hxml: -------------------------------------------------------------------------------- 1 | -main ApplicationMain 2 | -lib nme 3 | -lib feffects 4 | -cp D:\workspace\SDK\haxe\lib\nme/git/ 5 | -D nme4=1 6 | -D nme_ver=4.0.0 7 | -D nme_install_tool=1 8 | -D html5 9 | -D web 10 | -js export/html5/bin/FEffectsSample.js 11 | -cp export/html5/haxe 12 | -D html5 13 | -D html 14 | --remap flash:nme 15 | --remap native:browser 16 | -debug -------------------------------------------------------------------------------- /samples/buildNME.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | haxelib run nme build NMESamples.nmml html5 3 | haxelib run nme build NMESamples.nmml neko 4 | REM haxelib run nme build NMESamples.nmml cpp 5 | REM haxelib run nme build NMESamples.nmml android 6 | REM haxelib run nme build NMESamples.nmml ios 7 | REM haxelib run nme build NMESamples.nmml webos 8 | REM haxelib run nme build NMESamples.nmml blackberry 9 | -------------------------------------------------------------------------------- /samples/buildFLASH8_FLASH9_JS.hxml: -------------------------------------------------------------------------------- 1 | # flash8 2 | -swf export/flash/flash8.swf 3 | -swf-header 600:800:30:FFFFFF 4 | -swf-version 8 5 | -main Main 6 | -lib feffects 7 | 8 | --next 9 | 10 | # flash9+ 11 | -swf export/flash/flash9+.swf 12 | -swf-header 600:800:30:FFFFFF 13 | -swf-version 9 14 | -main Main 15 | -lib feffects 16 | 17 | --next 18 | 19 | # js 20 | -js export/js/js.js 21 | -main Main 22 | -lib feffects -------------------------------------------------------------------------------- /haxelib.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Set of effects (tweens, sineloops...) targeting Flash / JS / NME (Neko, C++, Windows, Linux, OSX, Android, iOS, webOS, BlackBerry, HTML5) 12 | Full Haxe 3 Support 13 | -------------------------------------------------------------------------------- /samples/NMESamples.nmml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /feffects/easing/Sine.hx: -------------------------------------------------------------------------------- 1 | package feffects.easing; 2 | 3 | @:publicFields class Sine #if !haxe3 implements haxe.Public #end { 4 | inline static function easeIn ( t : Float, b : Float, c : Float, d : Float ) : Float { 5 | return -c * Math.cos ( t / d * ( Math.PI * 0.5 ) ) + c + b; 6 | } 7 | 8 | inline static function easeOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 9 | return c * Math.sin( t / d * ( Math.PI * 0.5 ) ) + b; 10 | } 11 | 12 | inline static function easeInOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 13 | return -c * 0.5 * ( Math.cos( Math.PI * t / d ) - 1 ) + b; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /feffects/easing/Quad.hx: -------------------------------------------------------------------------------- 1 | package feffects.easing; 2 | 3 | @:publicFields class Quad #if !haxe3 implements haxe.Public #end { 4 | inline static function easeIn ( t : Float, b : Float, c : Float, d : Float ) : Float { 5 | return c * ( t /= d ) * t + b; 6 | } 7 | 8 | inline static function easeOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 9 | return -c * ( t /= d ) * ( t - 2 ) + b; 10 | } 11 | 12 | inline static function easeInOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 13 | if ( ( t /= d * 0.5 ) < 1 ) 14 | return c * 0.5 * t * t + b; 15 | else 16 | return -c * 0.5 * ( ( --t ) * ( t - 2 ) - 1 ) + b; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /feffects/easing/Linear.hx: -------------------------------------------------------------------------------- 1 | package feffects.easing; 2 | 3 | @:publicFields class Linear #if !haxe3 implements haxe.Public #end { 4 | inline static function easeNone ( t : Float, b : Float, c : Float, d : Float ) : Float { 5 | return c * t / d + b; 6 | } 7 | 8 | inline static function easeIn ( t : Float, b : Float, c : Float, d : Float ) : Float { 9 | return c * t / d + b; 10 | } 11 | 12 | inline static function easeOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 13 | return c * t / d + b; 14 | } 15 | 16 | inline static function easeInOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 17 | return c * t / d + b; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /samples/export/html5/haxe/nme/AssetData.hx: -------------------------------------------------------------------------------- 1 | package nme; 2 | 3 | 4 | import nme.Assets; 5 | 6 | 7 | class AssetData { 8 | 9 | 10 | public static var className = new Map (); 11 | public static var library = new Map (); 12 | public static var path = new Map (); 13 | public static var type = new Map (); 14 | 15 | private static var initialized:Bool = false; 16 | 17 | 18 | public static function initialize ():Void { 19 | 20 | if (!initialized) { 21 | 22 | 23 | 24 | initialized = true; 25 | 26 | } 27 | 28 | } 29 | 30 | 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /feffects/easing/Cubic.hx: -------------------------------------------------------------------------------- 1 | package feffects.easing; 2 | 3 | @:publicFields class Cubic #if !haxe3 implements haxe.Public #end { 4 | inline static function easeIn ( t : Float, b : Float, c : Float, d : Float ) : Float { 5 | return c * ( t /= d ) * t * t + b; 6 | } 7 | 8 | inline static function easeOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 9 | return c * ( ( t = t / d - 1 ) * t * t + 1 ) + b; 10 | } 11 | 12 | inline static function easeInOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 13 | if ( ( t /= d * 0.5 ) < 1 ) 14 | return c * 0.5 * t * t * t + b; 15 | else 16 | return c * 0.5 * ( ( t -= 2 ) * t * t + 2 ) + b; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /feffects/easing/Quart.hx: -------------------------------------------------------------------------------- 1 | package feffects.easing; 2 | 3 | @:publicFields class Quart #if !haxe3 implements haxe.Public #end { 4 | inline static function easeIn ( t : Float, b : Float, c : Float, d : Float ) : Float { 5 | return c * ( t /= d ) * t * t * t + b; 6 | } 7 | 8 | inline static function easeOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 9 | return -c * ( ( t = t / d - 1 ) * t * t * t - 1 ) + b; 10 | } 11 | 12 | inline static function easeInOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 13 | if ( ( t /= d * 0.5 ) < 1 ) 14 | return c * 0.5 * t * t * t * t + b; 15 | else 16 | return -c * 0.5 * ( ( t -= 2 ) * t * t * t - 2) + b; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /feffects/easing/Quint.hx: -------------------------------------------------------------------------------- 1 | package feffects.easing; 2 | 3 | @:publicFields class Quint #if !haxe3 implements haxe.Public #end { 4 | inline static function easeIn ( t : Float, b : Float, c : Float, d : Float ) : Float { 5 | return c * ( t /= d ) * t * t * t * t + b; 6 | } 7 | 8 | inline static function easeOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 9 | return c * ( ( t = t / d - 1 ) * t * t * t * t + 1 ) + b; 10 | } 11 | 12 | inline static function easeInOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 13 | if ( ( t /= d * 0.5 ) < 1 ) 14 | return c * 0.5 * t * t * t * t * t + b; 15 | else 16 | return c * 0.5 * ( ( t -= 2 ) * t * t * t * t + 2 ) + b; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /feffects/easing/Circ.hx: -------------------------------------------------------------------------------- 1 | package feffects.easing; 2 | 3 | @:publicFields class Circ #if !haxe3 implements haxe.Public #end { 4 | inline static function easeIn ( t : Float, b : Float, c : Float, d : Float ) : Float { 5 | return -c * ( Math.sqrt( 1 - ( t /= d ) * t ) - 1 ) + b; 6 | } 7 | 8 | inline static function easeOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 9 | return c * Math.sqrt( 1 - ( t = t / d - 1 ) * t ) + b; 10 | } 11 | 12 | inline static function easeInOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 13 | if ( ( t /= d * 0.5 ) < 1 ) 14 | return -c * 0.5 * ( Math.sqrt( 1 - t * t ) - 1 ) + b; 15 | else 16 | return c * 0.5 * ( Math.sqrt( 1 - ( t -= 2 ) * t ) + 1 ) + b; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /samples/export/html5/bin/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | FEffects sample 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /feffects/easing/Back.hx: -------------------------------------------------------------------------------- 1 | package feffects.easing; 2 | 3 | @:publicFields class Back #if !haxe3 implements haxe.Public #end { 4 | inline static function easeIn ( t : Float, b : Float, c : Float, d : Float ) : Float { 5 | return c * ( t /= d ) * t * ( ( 1.70158 + 1 ) * t - 1.70158 ) + b; 6 | } 7 | 8 | inline static function easeOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 9 | return c * ( ( t = t / d - 1 ) * t * ( ( 1.70158 + 1 ) * t + 1.70158 ) + 1 ) + b; 10 | } 11 | 12 | inline static function easeInOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 13 | var s = 1.70158; 14 | if ( ( t /= d * 0.5 ) < 1 ) 15 | return c * 0.5 * ( t * t * ( ( ( s *= ( 1.525 ) ) + 1 ) * t - s ) ) + b; 16 | else 17 | return c * 0.5 * ( ( t -= 2 ) * t * ( ( ( s *= ( 1.525 ) ) + 1 ) * t + s ) + 2 ) + b; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /feffects/easing/Expo.hx: -------------------------------------------------------------------------------- 1 | package feffects.easing; 2 | 3 | @:publicFields class Expo #if !haxe3 implements haxe.Public #end { 4 | inline static function easeIn ( t : Float, b : Float, c : Float, d : Float ) : Float { 5 | return ( t == 0 ) ? b : c * Math.pow( 2, 10 * ( t / d - 1 ) ) + b; 6 | } 7 | 8 | inline static function easeOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 9 | return ( t == d ) ? b + c : c * ( -Math.pow( 2, -10 * t / d ) + 1 ) + b; 10 | } 11 | 12 | inline static function easeInOut ( t : Float, b : Float, c : Float, d : Float) : Float { 13 | if ( t == 0 ) 14 | return b; 15 | else if ( t == d ) 16 | return b + c; 17 | else if ( ( t /= d / 2 ) < 1 ) 18 | return c * 0.5 * Math.pow( 2, 10 * ( t - 1 ) ) + b; 19 | else 20 | return c * 0.5 * ( -Math.pow( 2, -10 * --t ) + 2 ) + b; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /feffects/easing/Bounce.hx: -------------------------------------------------------------------------------- 1 | package feffects.easing; 2 | 3 | @:publicFields class Bounce #if !haxe3 implements haxe.Public #end { 4 | inline static function easeOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 5 | if ( ( t /= d ) < ( 1 / 2.75 ) ) 6 | return c * ( 7.5625 * t * t ) + b; 7 | else if ( t < ( 2 / 2.75 ) ) 8 | return c * ( 7.5625 * ( t -= ( 1.5 / 2.75 ) ) * t + .75 ) + b; 9 | else if ( t < ( 2.5 / 2.75 ) ) 10 | return c * ( 7.5625 * ( t -= ( 2.25 / 2.75 ) ) * t + .9375 ) + b; 11 | else 12 | return c * ( 7.5625 * ( t -= ( 2.625 / 2.75 ) ) * t + .984375 ) + b; 13 | } 14 | 15 | inline static function easeIn ( t : Float, b : Float, c : Float, d : Float ) : Float { 16 | return c - easeOut ( d - t, 0, c, d ) + b; 17 | } 18 | 19 | inline static function easeInOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 20 | if ( t < d * 0.5 ) 21 | return easeIn ( t * 2, 0, c, d ) * .5 + b; 22 | else 23 | return easeOut ( t * 2 - d, 0, c, d ) * .5 + c *.5 + b; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | 3.0.0 : Full Haxe 3 support 2 | 1.4.0 : Haxe 3 Ready + speedup 3 | 1.3.3 : Based on ENTER_FRAME instead of Timer on NME & Flash 4 | 1.3.2 : Start tween bug fixed + synthax added 5 | 1.3.1 : Haxe 2.10 compatible (fields/properies fixed) 6 | 1.3.0 : new user-friendly synthax 7 | 1.2.0 : flash/flash9+/js/neko/cpp full support, global optimizations done + easing optimizations (thx Andy;) 8 | 1.1.3 : C++ added, minor bug fixed and some optimizations done 9 | 1.1.2 : haXe 2.03 compatible 10 | 1.1.1 : Easing function in constructor support added 11 | 1.1.0 : Object properties supported, pause(), resume(), reverse(), seek( n : Int ), duration, position, reversed, isPlaying added, main loop inlined 12 | 1.0.2 : easing functions inlined 13 | 1.0.1 : haXe 2.0 compatible 14 | 1.0.0 : haXe 2.0 compatible 15 | 0.1.3 : Flash/JS Tween, Tween::stop & Tween::endTween fixed 16 | 0.1.2 : Tween::stop fixed 17 | 0.1.1 : "end" function for tween handlers is now optional + default handlers removed 18 | 0.1.0 : Tween + easing equations 19 | 20 | TODO : 21 | -sineloops 22 | 23 | More samples, contact : filt3r@free.fr -------------------------------------------------------------------------------- /feffects/TweenRgb.hx: -------------------------------------------------------------------------------- 1 | package feffects; 2 | 3 | import feffects.Tween; 4 | 5 | class TweenRgb extends Tween { 6 | 7 | var _initVals : Dynamic; 8 | var _endVals : Dynamic; 9 | 10 | public function intToRgb(c: Int): Dynamic { 11 | return { 12 | r: ( (c >> 16) & 0xFF ), 13 | g: ( (c >> 8) & 0xFF ), 14 | b: ( c & 0xFF ) 15 | }; 16 | } 17 | 18 | public function RgbToInt(c: Dynamic): Int { 19 | return ( ( c.r << 16 ) | ( c.g << 8 ) | c.b ); 20 | } 21 | 22 | public function new( init : Float, end : Float, dur : Int, ?easing : Easing, autoStart = false, ?onUpdate : Float->Void, ?onFinish : Void->Void ) { 23 | super(init, end, dur, easing, autoStart, onUpdate, onFinish); 24 | 25 | _initVals = intToRgb( Std.int(init) ); 26 | _endVals = intToRgb( Std.int(end) ); 27 | } 28 | 29 | override function getCurVal( curTime : Int ) : Float { 30 | var c = { 31 | r: Math.floor(_easingF( curTime, _initVals.r, _endVals.r - _initVals.r, duration )), 32 | g: Math.floor(_easingF( curTime, _initVals.g, _endVals.g - _initVals.g, duration )), 33 | b: Math.floor(_easingF( curTime, _initVals.b, _endVals.b - _initVals.b, duration )) 34 | }; 35 | return RgbToInt(c); 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /feffects/easing/easing_readme.txt: -------------------------------------------------------------------------------- 1 | -Ported to haXe by Michel Romecki (filt3r@free.fr) 2 | 3 | ============================================================================================ 4 | Easing Equations v2.0 5 | September 1, 2003 6 | (c) 2003 Robert Penner, all rights reserved. 7 | This work is subject to the terms in http://www.robertpenner.com/easing_terms_of_use.html. 8 | ============================================================================================ 9 | 10 | These tweening functions provide different flavors of 11 | math-based motion under a consistent API. 12 | 13 | Types of easing: 14 | 15 | Linear 16 | Quadratic 17 | Cubic 18 | Quartic 19 | Quintic 20 | Sinusoidal 21 | Exponential 22 | Circular 23 | Elastic 24 | Back 25 | Bounce 26 | 27 | Changes: 28 | 2.0 - ported to ActionScript 2.0; functions now in packages and use strong typing 29 | 1.5 - added bounce easing 30 | 1.4 - added elastic and back easing 31 | 1.3 - tweaked the exponential easing functions to make endpoints exact 32 | 1.2 - inline optimizations (changing t and multiplying in one step)--thanks to Tatsuo Kato for the idea 33 | 34 | Discussed in Chapter 7 of 35 | Robert Penner's Programming Macromedia Flash MX 36 | (including graphs of the easing equations) 37 | 38 | http://www.robertpenner.com/profmx 39 | http://www.amazon.com/exec/obidos/ASIN/0072223561/robertpennerc-20 40 | -------------------------------------------------------------------------------- /feffects/easing/Elastic.hx: -------------------------------------------------------------------------------- 1 | package feffects.easing; 2 | 3 | @:publicFields class Elastic #if !haxe3 implements haxe.Public #end { 4 | inline static function easeIn ( t : Float, b : Float, c : Float, d : Float ) : Float { 5 | if ( t == 0 ) { 6 | return b; 7 | } if ( ( t /= d ) == 1 ) { 8 | return b + c; 9 | } else { 10 | var p = d * .3; 11 | var s = p * 0.25; 12 | return -( c * Math.pow( 2, 10 * ( t -= 1 ) ) * Math.sin( ( t * d - s ) * ( 2 * Math.PI ) / p ) ) + b; 13 | } 14 | } 15 | 16 | inline static function easeOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 17 | if ( t == 0 ) { 18 | return b; 19 | } else if ( ( t /= d ) == 1 ) { 20 | return b + c; 21 | } else { 22 | var p = d * .3; 23 | var s = p * 0.25; 24 | return ( c * Math.pow( 2, -10 * t ) * Math.sin( ( t * d - s ) * ( 2 * Math.PI ) / p ) + c + b ); 25 | } 26 | } 27 | 28 | inline static function easeInOut ( t : Float, b : Float, c : Float, d : Float ) : Float { 29 | if ( t == 0 ){ 30 | return b; 31 | } else if ( ( t /= d / 2 ) == 2 ) { 32 | return b + c; 33 | } else { 34 | var p = d * ( .3 * 1.5 ); 35 | var s = p * 0.25; 36 | if ( t < 1 ) 37 | return -.5 * ( c * Math.pow( 2, 10 * ( t -= 1 ) ) * Math.sin( ( t * d - s ) * ( 2 * Math.PI ) / p ) ) + b; 38 | else 39 | return c * Math.pow( 2, -10 * ( t -= 1 ) ) * Math.sin( ( t * d - s ) * ( 2 * Math.PI ) / p ) * .5 + c + b; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /samples/export/html5/haxe/NMEPreloader.hx: -------------------------------------------------------------------------------- 1 | import nme.display.Sprite; 2 | import nme.events.Event; 3 | 4 | 5 | class NMEPreloader extends Sprite 6 | { 7 | private var outline:Sprite; 8 | private var progress:Sprite; 9 | 10 | 11 | public function new() 12 | { 13 | super(); 14 | 15 | var backgroundColor = getBackgroundColor (); 16 | var r = backgroundColor >> 16 & 0xFF; 17 | var g = backgroundColor >> 8 & 0xFF; 18 | var b = backgroundColor & 0xFF; 19 | var perceivedLuminosity = (0.299 * r + 0.587 * g + 0.114 * b); 20 | var color = 0x000000; 21 | 22 | if (perceivedLuminosity < 70) { 23 | 24 | color = 0xFFFFFF; 25 | 26 | } 27 | 28 | var x = 30; 29 | var height = 9; 30 | var y = getHeight () / 2 - height / 2; 31 | var width = getWidth () - x * 2; 32 | 33 | var padding = 3; 34 | 35 | outline = new Sprite (); 36 | outline.graphics.lineStyle (1, color, 0.15, true); 37 | outline.graphics.drawRoundRect (0, 0, width, height, padding * 2, padding * 2); 38 | outline.x = x; 39 | outline.y = y; 40 | addChild (outline); 41 | 42 | progress = new Sprite (); 43 | progress.graphics.beginFill (color, 0.35); 44 | progress.graphics.drawRect (0, 0, width - padding * 2, height - padding * 2); 45 | progress.x = x + padding; 46 | progress.y = y + padding; 47 | progress.scaleX = 0; 48 | addChild (progress); 49 | } 50 | 51 | 52 | public function getBackgroundColor():Int 53 | { 54 | return 16777215; 55 | } 56 | 57 | 58 | public function getHeight():Float 59 | { 60 | var height = 480; 61 | 62 | if (height > 0) { 63 | 64 | return height; 65 | 66 | } else { 67 | 68 | return nme.Lib.current.stage.stageHeight; 69 | 70 | } 71 | } 72 | 73 | 74 | public function getWidth():Float 75 | { 76 | var width = 640; 77 | 78 | if (width > 0) { 79 | 80 | return width; 81 | 82 | } else { 83 | 84 | return nme.Lib.current.stage.stageWidth; 85 | 86 | } 87 | } 88 | 89 | 90 | public function onInit() 91 | { 92 | 93 | } 94 | 95 | 96 | public function onLoaded() 97 | { 98 | dispatchEvent (new Event (Event.COMPLETE)); 99 | } 100 | 101 | 102 | public function onUpdate(bytesLoaded:Int, bytesTotal:Int) 103 | { 104 | var percentLoaded = bytesLoaded / bytesTotal; 105 | 106 | if (percentLoaded > 1) 107 | { 108 | percentLoaded == 1; 109 | } 110 | 111 | progress.scaleX = percentLoaded; 112 | } 113 | 114 | 115 | } -------------------------------------------------------------------------------- /samples/Main.hx: -------------------------------------------------------------------------------- 1 | import feffects.Tween; 2 | import feffects.easing.Quint; 3 | import feffects.easing.Sine; 4 | import feffects.easing.Back; 5 | import feffects.easing.Bounce; 6 | import feffects.easing.Circ; 7 | import feffects.easing.Cubic; 8 | import feffects.easing.Elastic; 9 | import feffects.easing.Expo; 10 | import feffects.easing.Linear; 11 | import feffects.easing.Quad; 12 | import feffects.easing.Quart; 13 | 14 | #if flash9 15 | import flash.display.MovieClip; 16 | import flash.Lib; 17 | #elseif flash8 18 | import flash.MovieClip; 19 | import flash.Lib; 20 | #elseif (js && !nme) 21 | #if haxe3 22 | import js.Browser; 23 | #else 24 | import js.Dom; 25 | #end 26 | import js.Lib; 27 | #elseif nme 28 | import nme.display.MovieClip; 29 | import nme.Lib; 30 | #end 31 | 32 | using feffects.Tween.TweenObject; 33 | 34 | class Main { 35 | public function new() { 36 | var effects = 37 | [ 38 | Quint.easeIn, Quint.easeOut, Quint.easeInOut, 39 | Sine.easeIn, Sine.easeOut, Sine.easeInOut, 40 | Back.easeIn, Back.easeOut, Back.easeInOut, 41 | Bounce.easeIn, Bounce.easeOut, Bounce.easeInOut, 42 | Circ.easeIn, Circ.easeOut, Circ.easeInOut, 43 | Cubic.easeIn, Cubic.easeOut, Cubic.easeInOut, 44 | Elastic.easeIn, Elastic.easeOut, Elastic.easeInOut, 45 | Expo.easeIn, Expo.easeOut, Expo.easeInOut, 46 | Linear.easeIn, Linear.easeOut, Linear.easeInOut, Linear.easeNone, 47 | Quad.easeIn, Quad.easeOut, Quad.easeInOut, 48 | Quart.easeIn, Quart.easeOut, Quad.easeInOut 49 | ]; 50 | 51 | var i = 0; 52 | var sprite = null; 53 | var gfx = null; 54 | var t = null; 55 | while ( i < effects.length ) { 56 | #if (flash9||nme) 57 | sprite = new MovieClip(); 58 | sprite.x = i * 10 + 30; 59 | gfx = sprite.graphics; 60 | gfx.beginFill( 0x000000, 1 ); 61 | Lib.current.addChild( sprite ); 62 | #elseif js 63 | // new local var sprite needed...js bug ??? 64 | #if haxe3 65 | var sprite = Browser.document.createElement( "div" ); 66 | Browser.document.body.appendChild( sprite ); 67 | #else 68 | var sprite = Lib.document.createElement( "div" ); 69 | Lib.document.body.appendChild( sprite ); 70 | #end 71 | sprite.style.position = "absolute"; 72 | sprite.style.backgroundColor = "#000000"; 73 | sprite.style.padding = "5px"; 74 | sprite.style.left = i * 10 + 30 + "px"; 75 | #elseif flash8 76 | sprite = Lib.current.createEmptyMovieClip( "sprite" + i, i ); 77 | sprite._x = i * 10 + 30; 78 | gfx = sprite; 79 | gfx.beginFill( 0x000000, 100 ); 80 | #end 81 | 82 | #if (flash||nme) 83 | gfx.lineTo( 10, 0 ); 84 | gfx.lineTo( 10, 10 ); 85 | gfx.lineTo( 0, 10 ); 86 | gfx.lineTo( 0, 0 ); 87 | gfx.endFill(); 88 | #if flash8 89 | t = sprite.tween( { _y : 150 }, 2000, effects[ i ] ); 90 | #else 91 | t = sprite.tween( { y : 150 }, 2000, effects[ i ] ); 92 | #end 93 | #elseif js 94 | t = new Tween( 50, 150, 2000, effects[ i ] ); 95 | t.onUpdate( function ( e ) sprite.style.top = e + "px" ); 96 | #end 97 | 98 | t.start(); 99 | t.seek( 350 ); 100 | 101 | haxe.Timer.delay( t.pause, 250 ); 102 | haxe.Timer.delay( t.resume, 500 ); 103 | haxe.Timer.delay( t.reverse, 750 ); 104 | haxe.Timer.delay( t.reverse, 1000 ); 105 | haxe.Timer.delay( t.reverse, 1250 ); 106 | haxe.Timer.delay( t.reverse, 1500 ); 107 | haxe.Timer.delay( t.pause, 1750 ); 108 | haxe.Timer.delay( t.resume, 2000 ); 109 | i++; 110 | } 111 | 112 | trace( "start for 2000ms tweening" ); 113 | trace( "seek at 350ms" ); 114 | haxe.Timer.delay( function() trace( "pause" ), 250 ); 115 | haxe.Timer.delay( function() trace( "resume" ), 500 ); 116 | haxe.Timer.delay( function() trace( "reverse" ), 750 ); 117 | haxe.Timer.delay( function() trace( "reverse" ), 1000 ); 118 | haxe.Timer.delay( function() trace( "reverse" ), 1250 ); 119 | haxe.Timer.delay( function() trace( "reverse" ), 1500 ); 120 | haxe.Timer.delay( function() trace( "pause" ), 1750 ); 121 | haxe.Timer.delay( function() trace( "resume" ), 2000 ); 122 | } 123 | 124 | public static function main() { 125 | new Main(); 126 | } 127 | } -------------------------------------------------------------------------------- /samples/export/html5/haxe/ApplicationMain.hx: -------------------------------------------------------------------------------- 1 | #if !macro 2 | #if (nme && !flambe) 3 | 4 | import Main; 5 | import haxe.Resource; 6 | import nme.display.Bitmap; 7 | import nme.display.BitmapData; 8 | import nme.display.Loader; 9 | import nme.events.Event; 10 | import nme.media.Sound; 11 | import nme.net.URLLoader; 12 | import nme.net.URLRequest; 13 | import nme.net.URLLoaderDataFormat; 14 | import nme.Assets; 15 | import nme.Lib; 16 | 17 | #if haxe3 18 | import haxe.ds.StringMap; 19 | #else 20 | typedef StringMap = Hash; 21 | #end 22 | 23 | class ApplicationMain { 24 | 25 | private static var completed:Int; 26 | private static var preloader:NMEPreloader; 27 | private static var total:Int; 28 | 29 | public static var loaders:StringMap ; 30 | public static var urlLoaders:StringMap ; 31 | 32 | public static function main() { 33 | completed = 0; 34 | loaders = new StringMap (); 35 | urlLoaders = new StringMap (); 36 | total = 0; 37 | 38 | nme.Lib.setPackage("filt3rek", "FEffectsSample", "com.filt3rek.FEffectsSample", "1.0.0"); 39 | nme.Lib.current.loaderInfo = nme.display.LoaderInfo.create (null); 40 | 41 | 42 | 43 | 44 | preloader = new NMEPreloader(); 45 | 46 | Lib.current.addChild(preloader); 47 | preloader.onInit(); 48 | 49 | 50 | 51 | var resourcePrefix = "NME_:bitmap_"; 52 | for (resourceName in Resource.listNames()) { 53 | if (StringTools.startsWith (resourceName, resourcePrefix)) { 54 | var type = Type.resolveClass(StringTools.replace (resourceName.substring(resourcePrefix.length), "_", ".")); 55 | if (type != null) { 56 | total++; 57 | var instance = Type.createInstance (type, [ 0, 0, true, 0x00FFFFFF, bitmapClass_onComplete ]); 58 | } 59 | } 60 | } 61 | 62 | if (total == 0) { 63 | begin(); 64 | } else { 65 | for (path in loaders.keys()) { 66 | var loader:Loader = loaders.get(path); 67 | loader.contentLoaderInfo.addEventListener("complete", 68 | loader_onComplete); 69 | loader.load (new URLRequest (path)); 70 | } 71 | 72 | for (path in urlLoaders.keys()) { 73 | var urlLoader:URLLoader = urlLoaders.get(path); 74 | urlLoader.addEventListener("complete", loader_onComplete); 75 | urlLoader.load(new URLRequest (path)); 76 | } 77 | } 78 | } 79 | 80 | private static function begin():Void { 81 | preloader.addEventListener(Event.COMPLETE, preloader_onComplete); 82 | preloader.onLoaded (); 83 | } 84 | 85 | private static function bitmapClass_onComplete(instance:BitmapData):Void { 86 | completed++; 87 | var classType = Type.getClass (instance); 88 | Reflect.setField (classType, "preload", instance); 89 | if (completed == total) { 90 | begin (); 91 | } 92 | } 93 | 94 | private static function loader_onComplete(event:Event):Void { 95 | completed ++; 96 | preloader.onUpdate (completed, total); 97 | if (completed == total) { 98 | begin (); 99 | } 100 | } 101 | 102 | private static function preloader_onComplete(event:Event):Void { 103 | preloader.removeEventListener(Event.COMPLETE, preloader_onComplete); 104 | Lib.current.removeChild(preloader); 105 | preloader = null; 106 | if (Reflect.field(Main, "main") == null) 107 | { 108 | var mainDisplayObj = Type.createInstance(DocumentClass, []); 109 | if (Std.is(mainDisplayObj, browser.display.DisplayObject)) 110 | nme.Lib.current.addChild(cast mainDisplayObj); 111 | } 112 | else 113 | { 114 | Reflect.callMethod(Main, Reflect.field (Main, "main"), []); 115 | } 116 | } 117 | } 118 | 119 | @:build(DocumentClass.build()) 120 | class DocumentClass extends Main {} 121 | 122 | #else 123 | 124 | import Main; 125 | 126 | class ApplicationMain { 127 | 128 | public static function main() { 129 | if (Reflect.field(Main, "main") == null) { 130 | Type.createInstance(Main, []); 131 | } else { 132 | Reflect.callMethod(Main, Reflect.field(Main, "main"), []); 133 | } 134 | } 135 | } 136 | 137 | #end 138 | #else 139 | 140 | import haxe.macro.Context; 141 | import haxe.macro.Expr; 142 | 143 | class DocumentClass { 144 | 145 | macro public static function build ():Array { 146 | var classType = Context.getLocalClass().get(); 147 | var searchTypes = classType; 148 | while (searchTypes.superClass != null) { 149 | if (searchTypes.pack.length == 2 && searchTypes.pack[1] == "display" && searchTypes.name == "DisplayObject") { 150 | var fields = Context.getBuildFields(); 151 | var method = macro { 152 | return nme.Lib.current.stage; 153 | } 154 | fields.push ({ name: "get_stage", access: [ APrivate, AOverride ], kind: FFun({ args: [], expr: method, params: [], ret: macro :nme.display.Stage }), pos: Context.currentPos() }); 155 | return fields; 156 | } 157 | searchTypes = searchTypes.superClass.t.get(); 158 | } 159 | return null; 160 | } 161 | 162 | } 163 | #end -------------------------------------------------------------------------------- /feffects/Tween.hx: -------------------------------------------------------------------------------- 1 | package feffects; 2 | 3 | #if haxe3 4 | import haxe.ds.GenericStack in FastList; 5 | #else 6 | import haxe.FastList; 7 | #end 8 | 9 | #if nme 10 | import nme.Lib; 11 | import nme.events.Event; 12 | #elseif flash9 13 | import flash.Lib; 14 | import flash.events.Event; 15 | #elseif ( js ||flash8 ) 16 | import haxe.Timer; 17 | #end 18 | 19 | import feffects.Easing; 20 | 21 | /** 22 | * Class that allows tweening properties of an object.
23 | * Version 3.0.0 24 | * Compatible haxe 3 - flash/js/NME 25 | * Usage :
26 | * import feffects.easing.Elastic;
27 | * 28 | * using feffects.Tween.TweenObject; 29 | * ...
30 | * var mySprite = new Sprite(); 31 | * mySprite.graphics.beginFill( 0 ); 32 | * mySprite.graphics.drawCircle( 0, 0, 20 ); 33 | * mySprite.graphics.endFill(); 34 | * 35 | * Lib.current.addChild( mySprite ); 36 | * 37 | * function foo() { 38 | * trace( "end" ); 39 | * } 40 | * 41 | * mySprite.tween( { x : 100, y : 200 }, 1000 ).onFinish( foo ).start(); 42 | * 43 | * OR 44 | * 45 | * mySprite.tween( { x : 100, y : 200 }, 1000, foo, true ); 46 | * 47 | * @author : M.Romecki 48 | * 49 | */ 50 | 51 | class TweenObject { 52 | 53 | public var tweens (default, null) : FastList; 54 | public var target (default, null) : Dynamic; 55 | public var properties (default, null) : Dynamic; 56 | public var duration (default, null) : Int; 57 | public var easing (default, null) : Easing; 58 | public var isPlaying (get_isPlaying, null) : Bool; 59 | function get_isPlaying() { 60 | for ( tween in tweens ) { 61 | if ( tween.isPlaying ) 62 | return true; 63 | } 64 | return false; 65 | } 66 | 67 | var __onFinish : Void->Void; 68 | var _nbFinished : Int; 69 | var _nbTotal : Int; 70 | 71 | public static function tween( target : Dynamic, properties : Dynamic, duration : Int, ?easing : Easing, autoStart = false, ?onFinish : Void->Void ) { 72 | return new TweenObject( target, properties, duration, easing, autoStart, onFinish ); 73 | } 74 | 75 | public function new( target : Dynamic, properties : Dynamic, duration : Int, ?easing : Easing, autoStart = false, ?onFinish : Void->Void ) { 76 | this.target = target; 77 | this.properties = properties; 78 | this.duration = duration; 79 | this.easing = easing; 80 | 81 | this.onFinish( onFinish ); 82 | 83 | tweens = new FastList(); 84 | _nbTotal = 0; 85 | for ( key in Reflect.fields( properties ) ) { 86 | var tp = new TweenProperty( target, key, Reflect.field( properties, key ), duration, easing, false ); 87 | tp.onFinish( _onFinish ); 88 | tweens.add( tp ); 89 | _nbTotal++; 90 | } 91 | 92 | if ( autoStart ) 93 | start(); 94 | } 95 | 96 | public function setEasing( easing : Easing ) : TweenObject { 97 | for ( tweenProp in tweens ) 98 | tweenProp.setEasing( easing ); 99 | return this; 100 | } 101 | 102 | public function start() : FastList { 103 | _nbFinished = 0; 104 | for ( tweenProp in tweens ) 105 | tweenProp.start(); 106 | return tweens; 107 | } 108 | 109 | public function pause() { 110 | for ( tweenProp in tweens ) 111 | tweenProp.pause(); 112 | } 113 | 114 | public function resume() { 115 | for ( tweenProp in tweens ) 116 | tweenProp.resume(); 117 | } 118 | 119 | public function seek( n : Int ) : TweenObject { 120 | for ( tweenProp in tweens ) 121 | tweenProp.seek( n ); 122 | return this; 123 | } 124 | 125 | public function reverse(){ 126 | for ( tweenProp in tweens ) 127 | tweenProp.reverse(); 128 | } 129 | 130 | public function stop( ?finish : Bool ) { 131 | for ( tweenProp in tweens ) 132 | tweenProp.stop( finish ); 133 | } 134 | 135 | public function onFinish( f : Void->Void ) : TweenObject { 136 | __onFinish = f != null ? f : function(){}; 137 | return this; 138 | } 139 | 140 | function _onFinish() { 141 | _nbFinished++; 142 | if ( _nbFinished == _nbTotal ) 143 | __onFinish(); 144 | } 145 | } 146 | 147 | class TweenProperty extends Tween{ 148 | 149 | public var target (default, null) : Dynamic; 150 | public var property (default, null) : String; 151 | 152 | #if ( flash9 || nme ) 153 | var _doTarget : flash.display.DisplayObject; 154 | #end 155 | 156 | public function new( target : Dynamic, prop : String, value : Float, duration : Int, ?easing : Easing, autostart = false, ?onFinish : Void->Void ) { 157 | this.target = target; 158 | this.property = prop; 159 | 160 | #if ( flash9 || nme ) 161 | if ( Std.is( target, flash.display.DisplayObject ) ) { 162 | _doTarget = target; 163 | super( Reflect.getProperty( target, property ), value, duration, easing, autostart, switch( prop ) { 164 | case 'x' : __onUpdateX; 165 | case 'y' : __onUpdateY; 166 | case 'width' : __onUpdateWidth; 167 | case 'height' : __onUpdateHeight; 168 | case 'alpha' : __onUpdateAlpha; 169 | case 'rotation' : __onUpdateRotation; 170 | case 'scaleX' : __onUpdateScaleX; 171 | case 'scaleY' : __onUpdateScaleY; 172 | #if flash10 173 | case 'z' : __onUpdateZ; 174 | case 'scaleZ' : __onUpdateScaleZ; 175 | case 'rotationX' : __onUpdateRotationX; 176 | case 'rotationY' : __onUpdateRotationY; 177 | case 'rotationZ' : __onUpdateRotationZ; 178 | #end 179 | default: __onUpdate; 180 | }, onFinish ); 181 | }else 182 | super( Reflect.getProperty( target, property ), value, duration, easing, autostart, __onUpdate, onFinish ); 183 | #else 184 | super( Reflect.getProperty( target, property ), value, duration, easing, autostart, __onUpdate, onFinish ); 185 | #end 186 | } 187 | 188 | function __onUpdate( n : Float ) { 189 | Reflect.setProperty( target, property, n ); 190 | } 191 | 192 | #if ( flash9 || nme ) 193 | function __onUpdateX( n : Float ) { _doTarget.x = n; } 194 | function __onUpdateY( n : Float ) { _doTarget.y = n; } 195 | function __onUpdateWidth( n : Float ) { _doTarget.width = n; } 196 | function __onUpdateHeight( n : Float ) { _doTarget.height = n; } 197 | function __onUpdateAlpha( n : Float ) { _doTarget.alpha = n; } 198 | function __onUpdateRotation( n : Float ) { _doTarget.rotation = n; } 199 | function __onUpdateScaleX( n : Float ) { _doTarget.scaleX = n; } 200 | function __onUpdateScaleY( n : Float ) { _doTarget.scaleY = n; } 201 | #if flash10 202 | function __onUpdateZ( n : Float ) { _doTarget.z = n; } 203 | function __onUpdateScaleZ( n : Float ) { _doTarget.scaleZ = n; } 204 | function __onUpdateRotationX( n : Float ) { _doTarget.rotationX = n; } 205 | function __onUpdateRotationY( n : Float ) { _doTarget.rotationY = n; } 206 | function __onUpdateRotationZ( n : Float ) { _doTarget.rotationZ = n; } 207 | #end 208 | #end 209 | } 210 | 211 | /** 212 | * Class that allows tweening numerical values of an object.
213 | * Version 3.0.0 214 | * Compatible haxe 3 - flash/js/NME 215 | * Usage :
216 | * import feffects.Tween;
217 | * import feffects.easing.Elastic;
218 | * ...
219 | * function foo ( n : Float ){ 220 | * mySprite.x = n; 221 | * } 222 | * var t = new Tween( 0, 100, 2000 ); // create a new tween
223 | * t.onUpdate( foo ); 224 | * t.start(); // start the tween
225 | * 226 | * You can add : 227 | * * 228 | * t.setEasing( Elastic.easeIn ); // set the easing function used to compute values
229 | * t.seek( 1000 ); // go to the specified position (in ms)
230 | * t.pause();
231 | * t.resume();
232 | * t.reverse(); // reverse the tween from the current position
233 | * t.stop(); 234 | * 235 | * OR combinated sythax : 236 | * 237 | * new Tween( 0, 100, 2000 ).setEasing( Elastic.easeIn ).seek( 1000 ).onUpdate( foo ).onFinish( foo2 ).start(); 238 | * 239 | * OR fastest one : 240 | * 241 | * new Tween( 0, 100, 2000, Elastic.easeIn, foo, foo2, true ).seek( 1000 ); 242 | * 243 | * @author : M.Romecki 244 | * 245 | */ 246 | 247 | class Tween { 248 | static var _aTweens = new FastList(); 249 | static var _aPaused = new FastList(); 250 | 251 | #if ( !nme && js || flash8 ) 252 | static var _timer : haxe.Timer; 253 | public static var INTERVAL = 10; 254 | #end 255 | 256 | public static var DEFAULT_EASING = easingEquation; 257 | 258 | public var duration (default, null) : Int; 259 | public var position (default, null) : Int; 260 | public var isReversed (default, null) : Bool; 261 | public var isPlaying (default, null) : Bool; 262 | public var isPaused (default, null) : Bool; 263 | 264 | static var _isTweening : Bool; 265 | 266 | var _initVal : Float; 267 | var _endVal : Float; 268 | var _startTime : Float; 269 | var _pauseTime : Float; 270 | var _offsetTime : Float; 271 | var _reverseTime : Float; 272 | 273 | var _easingF : Easing; 274 | var _onUpdate : Float->Void; 275 | var _onFinish : Void->Void; 276 | 277 | static function addTween( tween : Tween ) : Void { 278 | if ( !_isTweening ) 279 | { 280 | #if ( !nme && js || flash8 ) 281 | _timer = new haxe.Timer( INTERVAL ) ; 282 | _timer.run = cb_tick; 283 | #else 284 | Lib.current.stage.addEventListener( Event.ENTER_FRAME, cb_tick ); 285 | #end 286 | _isTweening = true; 287 | cb_tick(); 288 | } 289 | 290 | _aTweens.add( tween ); 291 | } 292 | 293 | static function removeActiveTween( tween : Tween ) : Void { 294 | _aTweens.remove( tween ); 295 | checkActiveTweens(); 296 | } 297 | 298 | static function removePausedTween( tween : Tween ) : Void { 299 | _aPaused.remove( tween ); 300 | checkActiveTweens(); 301 | } 302 | 303 | static function checkActiveTweens() { 304 | if ( _aTweens.isEmpty() ) { 305 | #if ( !nme && js || flash8 ) 306 | if ( _timer != null ) { 307 | _timer.stop() ; 308 | _timer = null ; 309 | } 310 | #else 311 | Lib.current.stage.removeEventListener( Event.ENTER_FRAME, cb_tick ); 312 | #end 313 | _isTweening = false; 314 | } 315 | } 316 | 317 | public static function getActiveTweens() { 318 | return _aTweens; 319 | } 320 | 321 | public static function getPausedTweens() { 322 | return _aPaused; 323 | } 324 | 325 | static function setTweenPaused( tween : Tween ) : Void { 326 | _aPaused.add( tween ); 327 | _aTweens.remove( tween ); 328 | 329 | checkActiveTweens(); 330 | } 331 | 332 | static function setTweenActive( tween : Tween ) : Void { 333 | _aTweens.add( tween ); 334 | _aPaused.remove( tween ); 335 | 336 | if ( !_isTweening ) { 337 | #if ( !nme && js || flash8 ) 338 | _timer = new haxe.Timer( INTERVAL ) ; 339 | _timer.run = cb_tick; 340 | #else 341 | Lib.current.stage.addEventListener( Event.ENTER_FRAME, cb_tick ); 342 | #end 343 | _isTweening = true; 344 | cb_tick(); 345 | } 346 | } 347 | 348 | static function cb_tick( #if ( nme || flash9 ) ?_ #end ) : Void { 349 | for ( i in _aTweens ) 350 | i.doInterval(); 351 | } 352 | 353 | /** 354 | * Create a tween from the [init] value, to the [end] value, while [dur] (in ms)
355 | * There is a default easing equation. 356 | */ 357 | 358 | public function new( init : Float, end : Float, dur : Int, ?easing : Easing, autoStart = false, ?onUpdate : Float->Void, ?onFinish : Void->Void ) { 359 | 360 | _initVal = init; 361 | _endVal = end; 362 | duration = dur; 363 | 364 | _offsetTime = 0; 365 | position = 0; 366 | isPlaying = false; 367 | isPaused = false; 368 | isReversed = false; 369 | 370 | this.onUpdate( onUpdate ); 371 | this.onFinish( onFinish ); 372 | setEasing( easing ); 373 | 374 | if ( autoStart ) 375 | start(); 376 | } 377 | 378 | public function start( position = 0 ) : Void { 379 | _startTime = getStamp(); 380 | _reverseTime = getStamp(); 381 | 382 | seek( position ); 383 | 384 | if ( isPaused ) 385 | removePausedTween( this ); 386 | 387 | isPlaying = true; 388 | isPaused = false; 389 | 390 | addTween( this ); 391 | 392 | if ( duration == 0 || position >= duration ) 393 | stop( true ); 394 | } 395 | 396 | public function pause() : Void { 397 | if ( !isPlaying || isPaused ) 398 | return; 399 | _pauseTime = getStamp(); 400 | 401 | isPlaying = false; 402 | isPaused = true; 403 | 404 | setTweenPaused( this ); 405 | } 406 | 407 | public function resume() : Void { 408 | if ( !isPaused || isPlaying ) 409 | return; 410 | 411 | _startTime += getStamp() - _pauseTime; 412 | _reverseTime += getStamp() - _pauseTime; 413 | 414 | isPlaying = true; 415 | isPaused = false; 416 | 417 | setTweenActive( this ); 418 | } 419 | 420 | /** 421 | * Go to the specified position [ms] (in ms) 422 | */ 423 | public function seek( ms : Int ) : Tween { 424 | _offsetTime = ms < duration ? ms : duration; 425 | return this; 426 | } 427 | 428 | /** 429 | * Reverse the tweeen from the current position 430 | */ 431 | public function reverse() { 432 | if ( !isPlaying ) 433 | return; 434 | 435 | isReversed = !isReversed; 436 | if ( !isReversed ) 437 | _startTime += ( getStamp() - _reverseTime ) * 2; 438 | 439 | _reverseTime = getStamp(); 440 | } 441 | 442 | public function stop( doFinish = false ) : Void { 443 | if( isPaused ) 444 | removePausedTween( this ); 445 | else 446 | if( isPlaying ) 447 | removeActiveTween( this ); 448 | 449 | isPaused = false; 450 | isPlaying = false; 451 | 452 | if ( doFinish ) 453 | finish(); 454 | } 455 | 456 | function finish() : Void { 457 | _onUpdate( isReversed ? _initVal : _endVal ); 458 | _onFinish(); 459 | } 460 | 461 | 462 | public function onUpdate( f : Float->Void ) { 463 | _onUpdate = f != null ? f : function(_){}; 464 | return this; 465 | } 466 | 467 | public function onFinish( f : Void->Void ) { 468 | _onFinish = f != null ? f : function(){}; 469 | return this; 470 | } 471 | 472 | /** 473 | * Set the [easingFunc] equation to use for tweening 474 | */ 475 | public function setEasing( f : Easing ) : Tween { 476 | _easingF = f != null ? f : easingEquation; 477 | return this; 478 | } 479 | 480 | function doInterval() : Void { 481 | var stamp = getStamp(); 482 | 483 | var curTime = 0; 484 | untyped{ 485 | if ( isReversed ) 486 | curTime = ( _reverseTime * 2 ) - stamp - _startTime + _offsetTime; 487 | else 488 | curTime = stamp - _startTime + _offsetTime; 489 | } 490 | 491 | var curVal = getCurVal( curTime ); 492 | if ( curTime >= duration || curTime < 0 ) 493 | stop( true ); 494 | else { 495 | _onUpdate( curVal ); 496 | } 497 | position = curTime; 498 | } 499 | 500 | function getCurVal( curTime : Int ) : Float { 501 | return _easingF( curTime, _initVal, _endVal - _initVal, duration ); 502 | } 503 | 504 | inline function getStamp() { 505 | #if sys 506 | return Sys.time() * 1000; 507 | #elseif js 508 | return Date.now().getTime(); 509 | #elseif flash 510 | return flash.Lib.getTimer(); 511 | #end 512 | } 513 | 514 | static inline function easingEquation( t : Float, b : Float, c : Float, d : Float ) : Float { 515 | return c / 2 * ( Math.sin( Math.PI * ( t / d - 0.5 ) ) + 1 ) + b; 516 | } 517 | } 518 | 519 | -------------------------------------------------------------------------------- /samples/export/js/js.js: -------------------------------------------------------------------------------- 1 | (function () { "use strict"; 2 | function $extend(from, fields) { 3 | function inherit() {}; inherit.prototype = from; var proto = new inherit(); 4 | for (var name in fields) proto[name] = fields[name]; 5 | return proto; 6 | } 7 | var Main = function() { 8 | var effects = [feffects.easing.Quint.easeIn,feffects.easing.Quint.easeOut,feffects.easing.Quint.easeInOut,feffects.easing.Sine.easeIn,feffects.easing.Sine.easeOut,feffects.easing.Sine.easeInOut,feffects.easing.Back.easeIn,feffects.easing.Back.easeOut,feffects.easing.Back.easeInOut,feffects.easing.Bounce.easeIn,feffects.easing.Bounce.easeOut,feffects.easing.Bounce.easeInOut,feffects.easing.Circ.easeIn,feffects.easing.Circ.easeOut,feffects.easing.Circ.easeInOut,feffects.easing.Cubic.easeIn,feffects.easing.Cubic.easeOut,feffects.easing.Cubic.easeInOut,feffects.easing.Elastic.easeIn,feffects.easing.Elastic.easeOut,feffects.easing.Elastic.easeInOut,feffects.easing.Expo.easeIn,feffects.easing.Expo.easeOut,feffects.easing.Expo.easeInOut,feffects.easing.Linear.easeIn,feffects.easing.Linear.easeOut,feffects.easing.Linear.easeInOut,feffects.easing.Linear.easeNone,feffects.easing.Quad.easeIn,feffects.easing.Quad.easeOut,feffects.easing.Quad.easeInOut,feffects.easing.Quart.easeIn,feffects.easing.Quart.easeOut,feffects.easing.Quad.easeInOut]; 9 | var i = 0; 10 | var sprite = null; 11 | var gfx = null; 12 | var t = null; 13 | while(i < effects.length) { 14 | var sprite1 = [js.Browser.document.createElement("div")]; 15 | js.Browser.document.body.appendChild(sprite1[0]); 16 | sprite1[0].style.position = "absolute"; 17 | sprite1[0].style.backgroundColor = "#000000"; 18 | sprite1[0].style.padding = "5px"; 19 | sprite1[0].style.left = i * 10 + 30 + "px"; 20 | t = new feffects.Tween(50,150,2000,effects[i]); 21 | t.onUpdate((function(sprite1) { 22 | return function(e) { 23 | sprite1[0].style.top = e + "px"; 24 | }; 25 | })(sprite1)); 26 | t.start(); 27 | t.seek(350); 28 | haxe.Timer.delay($bind(t,t.pause),250); 29 | haxe.Timer.delay($bind(t,t.resume),500); 30 | haxe.Timer.delay($bind(t,t.reverse),750); 31 | haxe.Timer.delay($bind(t,t.reverse),1000); 32 | haxe.Timer.delay($bind(t,t.reverse),1250); 33 | haxe.Timer.delay($bind(t,t.reverse),1500); 34 | haxe.Timer.delay($bind(t,t.pause),1750); 35 | haxe.Timer.delay($bind(t,t.resume),2000); 36 | i++; 37 | } 38 | console.log("start for 2000ms tweening"); 39 | console.log("seek at 350ms"); 40 | haxe.Timer.delay(function() { 41 | console.log("pause"); 42 | },250); 43 | haxe.Timer.delay(function() { 44 | console.log("resume"); 45 | },500); 46 | haxe.Timer.delay(function() { 47 | console.log("reverse"); 48 | },750); 49 | haxe.Timer.delay(function() { 50 | console.log("reverse"); 51 | },1000); 52 | haxe.Timer.delay(function() { 53 | console.log("reverse"); 54 | },1250); 55 | haxe.Timer.delay(function() { 56 | console.log("reverse"); 57 | },1500); 58 | haxe.Timer.delay(function() { 59 | console.log("pause"); 60 | },1750); 61 | haxe.Timer.delay(function() { 62 | console.log("resume"); 63 | },2000); 64 | }; 65 | Main.main = function() { 66 | new Main(); 67 | } 68 | var Reflect = function() { } 69 | Reflect.field = function(o,field) { 70 | var v = null; 71 | try { 72 | v = o[field]; 73 | } catch( e ) { 74 | } 75 | return v; 76 | } 77 | Reflect.getProperty = function(o,field) { 78 | var tmp; 79 | return o == null?null:o.__properties__ && (tmp = o.__properties__["get_" + field])?o[tmp]():o[field]; 80 | } 81 | Reflect.setProperty = function(o,field,value) { 82 | var tmp; 83 | if(o.__properties__ && (tmp = o.__properties__["set_" + field])) o[tmp](value); else o[field] = value; 84 | } 85 | Reflect.fields = function(o) { 86 | var a = []; 87 | if(o != null) { 88 | var hasOwnProperty = Object.prototype.hasOwnProperty; 89 | for( var f in o ) { 90 | if(f != "__id__" && hasOwnProperty.call(o,f)) a.push(f); 91 | } 92 | } 93 | return a; 94 | } 95 | var feffects = {} 96 | feffects.TweenObject = function(target,properties,duration,easing,autoStart,onFinish) { 97 | if(autoStart == null) autoStart = false; 98 | this.target = target; 99 | this.properties = properties; 100 | this.duration = duration; 101 | this.easing = easing; 102 | this.onFinish(onFinish); 103 | this.tweens = new haxe.ds.GenericStack(); 104 | this._nbTotal = 0; 105 | var _g = 0, _g1 = Reflect.fields(properties); 106 | while(_g < _g1.length) { 107 | var key = _g1[_g]; 108 | ++_g; 109 | var tp = new feffects.TweenProperty(target,key,Reflect.field(properties,key),duration,easing,false); 110 | tp.onFinish($bind(this,this._onFinish)); 111 | this.tweens.add(tp); 112 | this._nbTotal++; 113 | } 114 | if(autoStart) this.start(); 115 | }; 116 | feffects.TweenObject.tween = function(target,properties,duration,easing,autoStart,onFinish) { 117 | if(autoStart == null) autoStart = false; 118 | return new feffects.TweenObject(target,properties,duration,easing,autoStart,onFinish); 119 | } 120 | feffects.TweenObject.prototype = { 121 | _onFinish: function() { 122 | this._nbFinished++; 123 | if(this._nbFinished == this._nbTotal) this.__onFinish(); 124 | } 125 | ,onFinish: function(f) { 126 | this.__onFinish = f != null?f:function() { 127 | }; 128 | return this; 129 | } 130 | ,stop: function(finish) { 131 | var $it0 = this.tweens.iterator(); 132 | while( $it0.hasNext() ) { 133 | var tweenProp = $it0.next(); 134 | tweenProp.stop(finish); 135 | } 136 | } 137 | ,reverse: function() { 138 | var $it0 = this.tweens.iterator(); 139 | while( $it0.hasNext() ) { 140 | var tweenProp = $it0.next(); 141 | tweenProp.reverse(); 142 | } 143 | } 144 | ,seek: function(n) { 145 | var $it0 = this.tweens.iterator(); 146 | while( $it0.hasNext() ) { 147 | var tweenProp = $it0.next(); 148 | tweenProp.seek(n); 149 | } 150 | return this; 151 | } 152 | ,resume: function() { 153 | var $it0 = this.tweens.iterator(); 154 | while( $it0.hasNext() ) { 155 | var tweenProp = $it0.next(); 156 | tweenProp.resume(); 157 | } 158 | } 159 | ,pause: function() { 160 | var $it0 = this.tweens.iterator(); 161 | while( $it0.hasNext() ) { 162 | var tweenProp = $it0.next(); 163 | tweenProp.pause(); 164 | } 165 | } 166 | ,start: function() { 167 | this._nbFinished = 0; 168 | var $it0 = this.tweens.iterator(); 169 | while( $it0.hasNext() ) { 170 | var tweenProp = $it0.next(); 171 | tweenProp.start(); 172 | } 173 | return this.tweens; 174 | } 175 | ,setEasing: function(easing) { 176 | var $it0 = this.tweens.iterator(); 177 | while( $it0.hasNext() ) { 178 | var tweenProp = $it0.next(); 179 | tweenProp.setEasing(easing); 180 | } 181 | return this; 182 | } 183 | ,get_isPlaying: function() { 184 | var $it0 = this.tweens.iterator(); 185 | while( $it0.hasNext() ) { 186 | var tween = $it0.next(); 187 | if(tween.isPlaying) return true; 188 | } 189 | return false; 190 | } 191 | ,__properties__: {get_isPlaying:"get_isPlaying"} 192 | } 193 | var haxe = {} 194 | haxe.ds = {} 195 | haxe.ds.GenericStack = function() { 196 | }; 197 | haxe.ds.GenericStack.prototype = { 198 | iterator: function() { 199 | var l = this.head; 200 | return { hasNext : function() { 201 | return l != null; 202 | }, next : function() { 203 | var k = l; 204 | l = k.next; 205 | return k.elt; 206 | }}; 207 | } 208 | ,remove: function(v) { 209 | var prev = null; 210 | var l = this.head; 211 | while(l != null) { 212 | if(l.elt == v) { 213 | if(prev == null) this.head = l.next; else prev.next = l.next; 214 | break; 215 | } 216 | prev = l; 217 | l = l.next; 218 | } 219 | return l != null; 220 | } 221 | ,add: function(item) { 222 | this.head = new haxe.ds.FastCell(item,this.head); 223 | } 224 | } 225 | feffects.Tween = function(init,end,dur,easing,autoStart,onUpdate,onFinish) { 226 | if(autoStart == null) autoStart = false; 227 | this._initVal = init; 228 | this._endVal = end; 229 | this.duration = dur; 230 | this._offsetTime = 0; 231 | this.position = 0; 232 | this.isPlaying = false; 233 | this.isPaused = false; 234 | this.isReversed = false; 235 | this.onUpdate(onUpdate); 236 | this.onFinish(onFinish); 237 | this.setEasing(easing); 238 | if(autoStart) this.start(); 239 | }; 240 | feffects.Tween.addTween = function(tween) { 241 | if(!feffects.Tween._isTweening) { 242 | feffects.Tween._timer = new haxe.Timer(feffects.Tween.INTERVAL); 243 | feffects.Tween._timer.run = feffects.Tween.cb_tick; 244 | feffects.Tween._isTweening = true; 245 | feffects.Tween.cb_tick(); 246 | } 247 | feffects.Tween._aTweens.add(tween); 248 | } 249 | feffects.Tween.removeActiveTween = function(tween) { 250 | feffects.Tween._aTweens.remove(tween); 251 | feffects.Tween.checkActiveTweens(); 252 | } 253 | feffects.Tween.removePausedTween = function(tween) { 254 | feffects.Tween._aPaused.remove(tween); 255 | feffects.Tween.checkActiveTweens(); 256 | } 257 | feffects.Tween.checkActiveTweens = function() { 258 | if(feffects.Tween._aTweens.head == null) { 259 | if(feffects.Tween._timer != null) { 260 | feffects.Tween._timer.stop(); 261 | feffects.Tween._timer = null; 262 | } 263 | feffects.Tween._isTweening = false; 264 | } 265 | } 266 | feffects.Tween.getActiveTweens = function() { 267 | return feffects.Tween._aTweens; 268 | } 269 | feffects.Tween.getPausedTweens = function() { 270 | return feffects.Tween._aPaused; 271 | } 272 | feffects.Tween.setTweenPaused = function(tween) { 273 | feffects.Tween._aPaused.add(tween); 274 | feffects.Tween._aTweens.remove(tween); 275 | feffects.Tween.checkActiveTweens(); 276 | } 277 | feffects.Tween.setTweenActive = function(tween) { 278 | feffects.Tween._aTweens.add(tween); 279 | feffects.Tween._aPaused.remove(tween); 280 | if(!feffects.Tween._isTweening) { 281 | feffects.Tween._timer = new haxe.Timer(feffects.Tween.INTERVAL); 282 | feffects.Tween._timer.run = feffects.Tween.cb_tick; 283 | feffects.Tween._isTweening = true; 284 | feffects.Tween.cb_tick(); 285 | } 286 | } 287 | feffects.Tween.cb_tick = function() { 288 | var $it0 = feffects.Tween._aTweens.iterator(); 289 | while( $it0.hasNext() ) { 290 | var i = $it0.next(); 291 | i.doInterval(); 292 | } 293 | } 294 | feffects.Tween.easingEquation = function(t,b,c,d) { 295 | return c / 2 * (Math.sin(Math.PI * (t / d - 0.5)) + 1) + b; 296 | } 297 | feffects.Tween.prototype = { 298 | getStamp: function() { 299 | return new Date().getTime(); 300 | } 301 | ,getCurVal: function(curTime) { 302 | return this._easingF(curTime,this._initVal,this._endVal - this._initVal,this.duration); 303 | } 304 | ,doInterval: function() { 305 | var stamp = new Date().getTime(); 306 | var curTime = 0; 307 | if(this.isReversed) curTime = this._reverseTime * 2 - stamp - this._startTime + this._offsetTime; else curTime = stamp - this._startTime + this._offsetTime; 308 | var curVal = this._easingF(curTime,this._initVal,this._endVal - this._initVal,this.duration); 309 | if(curTime >= this.duration || curTime < 0) this.stop(true); else this._onUpdate(curVal); 310 | this.position = curTime; 311 | } 312 | ,setEasing: function(f) { 313 | this._easingF = f != null?f:feffects.Tween.easingEquation; 314 | return this; 315 | } 316 | ,onFinish: function(f) { 317 | this._onFinish = f != null?f:function() { 318 | }; 319 | return this; 320 | } 321 | ,onUpdate: function(f) { 322 | this._onUpdate = f != null?f:function(_) { 323 | }; 324 | return this; 325 | } 326 | ,finish: function() { 327 | this._onUpdate(this.isReversed?this._initVal:this._endVal); 328 | this._onFinish(); 329 | } 330 | ,stop: function(doFinish) { 331 | if(doFinish == null) doFinish = false; 332 | if(this.isPaused) feffects.Tween.removePausedTween(this); else if(this.isPlaying) feffects.Tween.removeActiveTween(this); 333 | this.isPaused = false; 334 | this.isPlaying = false; 335 | if(doFinish) this.finish(); 336 | } 337 | ,reverse: function() { 338 | if(!this.isPlaying) return; 339 | this.isReversed = !this.isReversed; 340 | if(!this.isReversed) this._startTime += (new Date().getTime() - this._reverseTime) * 2; 341 | this._reverseTime = new Date().getTime(); 342 | } 343 | ,seek: function(ms) { 344 | this._offsetTime = ms < this.duration?ms:this.duration; 345 | return this; 346 | } 347 | ,resume: function() { 348 | if(!this.isPaused || this.isPlaying) return; 349 | this._startTime += new Date().getTime() - this._pauseTime; 350 | this._reverseTime += new Date().getTime() - this._pauseTime; 351 | this.isPlaying = true; 352 | this.isPaused = false; 353 | feffects.Tween.setTweenActive(this); 354 | } 355 | ,pause: function() { 356 | if(!this.isPlaying || this.isPaused) return; 357 | this._pauseTime = new Date().getTime(); 358 | this.isPlaying = false; 359 | this.isPaused = true; 360 | feffects.Tween.setTweenPaused(this); 361 | } 362 | ,start: function(position) { 363 | if(position == null) position = 0; 364 | this._startTime = new Date().getTime(); 365 | this._reverseTime = new Date().getTime(); 366 | this.seek(position); 367 | if(this.isPaused) feffects.Tween.removePausedTween(this); 368 | this.isPlaying = true; 369 | this.isPaused = false; 370 | feffects.Tween.addTween(this); 371 | if(this.duration == 0 || position >= this.duration) this.stop(true); 372 | } 373 | } 374 | feffects.TweenProperty = function(target,prop,value,duration,easing,autostart,onFinish) { 375 | if(autostart == null) autostart = false; 376 | this.target = target; 377 | this.property = prop; 378 | feffects.Tween.call(this,Reflect.getProperty(target,this.property),value,duration,easing,autostart,$bind(this,this.__onUpdate),onFinish); 379 | }; 380 | feffects.TweenProperty.__super__ = feffects.Tween; 381 | feffects.TweenProperty.prototype = $extend(feffects.Tween.prototype,{ 382 | __onUpdate: function(n) { 383 | Reflect.setProperty(this.target,this.property,n); 384 | } 385 | }); 386 | feffects.easing = {} 387 | feffects.easing.Back = function() { } 388 | feffects.easing.Back.easeIn = function(t,b,c,d) { 389 | return c * (t /= d) * t * (2.70158 * t - 1.70158) + b; 390 | } 391 | feffects.easing.Back.easeOut = function(t,b,c,d) { 392 | return c * ((t = t / d - 1) * t * (2.70158 * t + 1.70158) + 1) + b; 393 | } 394 | feffects.easing.Back.easeInOut = function(t,b,c,d) { 395 | var s = 1.70158; 396 | if((t /= d * 0.5) < 1) return c * 0.5 * (t * t * (((s *= 1.525) + 1) * t - s)) + b; else return c * 0.5 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b; 397 | } 398 | feffects.easing.Bounce = function() { } 399 | feffects.easing.Bounce.easeOut = function(t,b,c,d) { 400 | if((t /= d) < 1 / 2.75) return c * (7.5625 * t * t) + b; else if(t < 2 / 2.75) return c * (7.5625 * (t -= 1.5 / 2.75) * t + .75) + b; else if(t < 2.5 / 2.75) return c * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) + b; else return c * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) + b; 401 | } 402 | feffects.easing.Bounce.easeIn = function(t,b,c,d) { 403 | return c - feffects.easing.Bounce.easeOut(d - t,0,c,d) + b; 404 | } 405 | feffects.easing.Bounce.easeInOut = function(t,b,c,d) { 406 | if(t < d * 0.5) return (c - feffects.easing.Bounce.easeOut(d - t * 2,0,c,d)) * .5 + b; else return feffects.easing.Bounce.easeOut(t * 2 - d,0,c,d) * .5 + c * .5 + b; 407 | } 408 | feffects.easing.Circ = function() { } 409 | feffects.easing.Circ.easeIn = function(t,b,c,d) { 410 | return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b; 411 | } 412 | feffects.easing.Circ.easeOut = function(t,b,c,d) { 413 | return c * Math.sqrt(1 - (t = t / d - 1) * t) + b; 414 | } 415 | feffects.easing.Circ.easeInOut = function(t,b,c,d) { 416 | if((t /= d * 0.5) < 1) return -c * 0.5 * (Math.sqrt(1 - t * t) - 1) + b; else return c * 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b; 417 | } 418 | feffects.easing.Cubic = function() { } 419 | feffects.easing.Cubic.easeIn = function(t,b,c,d) { 420 | return c * (t /= d) * t * t + b; 421 | } 422 | feffects.easing.Cubic.easeOut = function(t,b,c,d) { 423 | return c * ((t = t / d - 1) * t * t + 1) + b; 424 | } 425 | feffects.easing.Cubic.easeInOut = function(t,b,c,d) { 426 | if((t /= d * 0.5) < 1) return c * 0.5 * t * t * t + b; else return c * 0.5 * ((t -= 2) * t * t + 2) + b; 427 | } 428 | feffects.easing.Elastic = function() { } 429 | feffects.easing.Elastic.easeIn = function(t,b,c,d) { 430 | if(t == 0) return b; 431 | if((t /= d) == 1) return b + c; else { 432 | var p = d * .3; 433 | var s = p * 0.25; 434 | return -(c * Math.pow(2,10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; 435 | } 436 | } 437 | feffects.easing.Elastic.easeOut = function(t,b,c,d) { 438 | if(t == 0) return b; else if((t /= d) == 1) return b + c; else { 439 | var p = d * .3; 440 | var s = p * 0.25; 441 | return c * Math.pow(2,-10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b; 442 | } 443 | } 444 | feffects.easing.Elastic.easeInOut = function(t,b,c,d) { 445 | if(t == 0) return b; else if((t /= d / 2) == 2) return b + c; else { 446 | var p = d * (.3 * 1.5); 447 | var s = p * 0.25; 448 | if(t < 1) return -0.5 * (c * Math.pow(2,10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; else return c * Math.pow(2,-10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b; 449 | } 450 | } 451 | feffects.easing.Expo = function() { } 452 | feffects.easing.Expo.easeIn = function(t,b,c,d) { 453 | return t == 0?b:c * Math.pow(2,10 * (t / d - 1)) + b; 454 | } 455 | feffects.easing.Expo.easeOut = function(t,b,c,d) { 456 | return t == d?b + c:c * (-Math.pow(2,-10 * t / d) + 1) + b; 457 | } 458 | feffects.easing.Expo.easeInOut = function(t,b,c,d) { 459 | if(t == 0) return b; else if(t == d) return b + c; else if((t /= d / 2) < 1) return c * 0.5 * Math.pow(2,10 * (t - 1)) + b; else return c * 0.5 * (-Math.pow(2,-10 * --t) + 2) + b; 460 | } 461 | feffects.easing.Linear = function() { } 462 | feffects.easing.Linear.easeNone = function(t,b,c,d) { 463 | return c * t / d + b; 464 | } 465 | feffects.easing.Linear.easeIn = function(t,b,c,d) { 466 | return c * t / d + b; 467 | } 468 | feffects.easing.Linear.easeOut = function(t,b,c,d) { 469 | return c * t / d + b; 470 | } 471 | feffects.easing.Linear.easeInOut = function(t,b,c,d) { 472 | return c * t / d + b; 473 | } 474 | feffects.easing.Quad = function() { } 475 | feffects.easing.Quad.easeIn = function(t,b,c,d) { 476 | return c * (t /= d) * t + b; 477 | } 478 | feffects.easing.Quad.easeOut = function(t,b,c,d) { 479 | return -c * (t /= d) * (t - 2) + b; 480 | } 481 | feffects.easing.Quad.easeInOut = function(t,b,c,d) { 482 | if((t /= d * 0.5) < 1) return c * 0.5 * t * t + b; else return -c * 0.5 * (--t * (t - 2) - 1) + b; 483 | } 484 | feffects.easing.Quart = function() { } 485 | feffects.easing.Quart.easeIn = function(t,b,c,d) { 486 | return c * (t /= d) * t * t * t + b; 487 | } 488 | feffects.easing.Quart.easeOut = function(t,b,c,d) { 489 | return -c * ((t = t / d - 1) * t * t * t - 1) + b; 490 | } 491 | feffects.easing.Quart.easeInOut = function(t,b,c,d) { 492 | if((t /= d * 0.5) < 1) return c * 0.5 * t * t * t * t + b; else return -c * 0.5 * ((t -= 2) * t * t * t - 2) + b; 493 | } 494 | feffects.easing.Quint = function() { } 495 | feffects.easing.Quint.easeIn = function(t,b,c,d) { 496 | return c * (t /= d) * t * t * t * t + b; 497 | } 498 | feffects.easing.Quint.easeOut = function(t,b,c,d) { 499 | return c * ((t = t / d - 1) * t * t * t * t + 1) + b; 500 | } 501 | feffects.easing.Quint.easeInOut = function(t,b,c,d) { 502 | if((t /= d * 0.5) < 1) return c * 0.5 * t * t * t * t * t + b; else return c * 0.5 * ((t -= 2) * t * t * t * t + 2) + b; 503 | } 504 | feffects.easing.Sine = function() { } 505 | feffects.easing.Sine.easeIn = function(t,b,c,d) { 506 | return -c * Math.cos(t / d * (Math.PI * 0.5)) + c + b; 507 | } 508 | feffects.easing.Sine.easeOut = function(t,b,c,d) { 509 | return c * Math.sin(t / d * (Math.PI * 0.5)) + b; 510 | } 511 | feffects.easing.Sine.easeInOut = function(t,b,c,d) { 512 | return -c * 0.5 * (Math.cos(Math.PI * t / d) - 1) + b; 513 | } 514 | haxe.Timer = function(time_ms) { 515 | var me = this; 516 | this.id = setInterval(function() { 517 | me.run(); 518 | },time_ms); 519 | }; 520 | haxe.Timer.delay = function(f,time_ms) { 521 | var t = new haxe.Timer(time_ms); 522 | t.run = function() { 523 | t.stop(); 524 | f(); 525 | }; 526 | return t; 527 | } 528 | haxe.Timer.prototype = { 529 | run: function() { 530 | console.log("run"); 531 | } 532 | ,stop: function() { 533 | if(this.id == null) return; 534 | clearInterval(this.id); 535 | this.id = null; 536 | } 537 | } 538 | haxe.ds.FastCell = function(elt,next) { 539 | this.elt = elt; 540 | this.next = next; 541 | }; 542 | var js = {} 543 | js.Browser = function() { } 544 | var $_; 545 | function $bind(o,m) { var f = function(){ return f.method.apply(f.scope, arguments); }; f.scope = o; f.method = m; return f; }; 546 | Math.__name__ = ["Math"]; 547 | Math.NaN = Number.NaN; 548 | Math.NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY; 549 | Math.POSITIVE_INFINITY = Number.POSITIVE_INFINITY; 550 | Math.isFinite = function(i) { 551 | return isFinite(i); 552 | }; 553 | Math.isNaN = function(i) { 554 | return isNaN(i); 555 | }; 556 | feffects.Tween._aTweens = new haxe.ds.GenericStack(); 557 | feffects.Tween._aPaused = new haxe.ds.GenericStack(); 558 | feffects.Tween.INTERVAL = 10; 559 | feffects.Tween.DEFAULT_EASING = feffects.Tween.easingEquation; 560 | js.Browser.document = typeof window != "undefined" ? window.document : null; 561 | Main.main(); 562 | })(); 563 | -------------------------------------------------------------------------------- /samples/export/html5/bin/webgl-debug.js: -------------------------------------------------------------------------------- 1 | //Copyright (c) 2009 The Chromium Authors. All rights reserved. 2 | //Use of this source code is governed by a BSD-style license that can be 3 | //found in the LICENSE file. 4 | 5 | // Various functions for helping debug WebGL apps. 6 | 7 | WebGLDebugUtils = function() { 8 | 9 | /** 10 | * Wrapped logging function. 11 | * @param {string} msg Message to log. 12 | */ 13 | var log = function(msg) { 14 | if (window.console && window.console.log) { 15 | window.console.log(msg); 16 | } 17 | }; 18 | 19 | /** 20 | * Which arguements are enums. 21 | * @type {!Object.} 22 | */ 23 | var glValidEnumContexts = { 24 | 25 | // Generic setters and getters 26 | 27 | 'enable': { 0:true }, 28 | 'disable': { 0:true }, 29 | 'getParameter': { 0:true }, 30 | 31 | // Rendering 32 | 33 | 'drawArrays': { 0:true }, 34 | 'drawElements': { 0:true, 2:true }, 35 | 36 | // Shaders 37 | 38 | 'createShader': { 0:true }, 39 | 'getShaderParameter': { 1:true }, 40 | 'getProgramParameter': { 1:true }, 41 | 42 | // Vertex attributes 43 | 44 | 'getVertexAttrib': { 1:true }, 45 | 'vertexAttribPointer': { 2:true }, 46 | 47 | // Textures 48 | 49 | 'bindTexture': { 0:true }, 50 | 'activeTexture': { 0:true }, 51 | 'getTexParameter': { 0:true, 1:true }, 52 | 'texParameterf': { 0:true, 1:true }, 53 | 'texParameteri': { 0:true, 1:true, 2:true }, 54 | 'texImage2D': { 0:true, 2:true, 6:true, 7:true }, 55 | 'texSubImage2D': { 0:true, 6:true, 7:true }, 56 | 'copyTexImage2D': { 0:true, 2:true }, 57 | 'copyTexSubImage2D': { 0:true }, 58 | 'generateMipmap': { 0:true }, 59 | 60 | // Buffer objects 61 | 62 | 'bindBuffer': { 0:true }, 63 | 'bufferData': { 0:true, 2:true }, 64 | 'bufferSubData': { 0:true }, 65 | 'getBufferParameter': { 0:true, 1:true }, 66 | 67 | // Renderbuffers and framebuffers 68 | 69 | 'pixelStorei': { 0:true, 1:true }, 70 | 'readPixels': { 4:true, 5:true }, 71 | 'bindRenderbuffer': { 0:true }, 72 | 'bindFramebuffer': { 0:true }, 73 | 'checkFramebufferStatus': { 0:true }, 74 | 'framebufferRenderbuffer': { 0:true, 1:true, 2:true }, 75 | 'framebufferTexture2D': { 0:true, 1:true, 2:true }, 76 | 'getFramebufferAttachmentParameter': { 0:true, 1:true, 2:true }, 77 | 'getRenderbufferParameter': { 0:true, 1:true }, 78 | 'renderbufferStorage': { 0:true, 1:true }, 79 | 80 | // Frame buffer operations (clear, blend, depth test, stencil) 81 | 82 | 'clear': { 0:true }, 83 | 'depthFunc': { 0:true }, 84 | 'blendFunc': { 0:true, 1:true }, 85 | 'blendFuncSeparate': { 0:true, 1:true, 2:true, 3:true }, 86 | 'blendEquation': { 0:true }, 87 | 'blendEquationSeparate': { 0:true, 1:true }, 88 | 'stencilFunc': { 0:true }, 89 | 'stencilFuncSeparate': { 0:true, 1:true }, 90 | 'stencilMaskSeparate': { 0:true }, 91 | 'stencilOp': { 0:true, 1:true, 2:true }, 92 | 'stencilOpSeparate': { 0:true, 1:true, 2:true, 3:true }, 93 | 94 | // Culling 95 | 96 | 'cullFace': { 0:true }, 97 | 'frontFace': { 0:true }, 98 | }; 99 | 100 | /** 101 | * Map of numbers to names. 102 | * @type {Object} 103 | */ 104 | var glEnums = null; 105 | 106 | /** 107 | * Initializes this module. Safe to call more than once. 108 | * @param {!WebGLRenderingContext} ctx A WebGL context. If 109 | * you have more than one context it doesn't matter which one 110 | * you pass in, it is only used to pull out constants. 111 | */ 112 | function init(ctx) { 113 | if (glEnums == null) { 114 | glEnums = { }; 115 | for (var propertyName in ctx) { 116 | if (typeof ctx[propertyName] == 'number') { 117 | glEnums[ctx[propertyName]] = propertyName; 118 | } 119 | } 120 | } 121 | } 122 | 123 | /** 124 | * Checks the utils have been initialized. 125 | */ 126 | function checkInit() { 127 | if (glEnums == null) { 128 | throw 'WebGLDebugUtils.init(ctx) not called'; 129 | } 130 | } 131 | 132 | /** 133 | * Returns true or false if value matches any WebGL enum 134 | * @param {*} value Value to check if it might be an enum. 135 | * @return {boolean} True if value matches one of the WebGL defined enums 136 | */ 137 | function mightBeEnum(value) { 138 | checkInit(); 139 | return (glEnums[value] !== undefined); 140 | } 141 | 142 | /** 143 | * Gets an string version of an WebGL enum. 144 | * 145 | * Example: 146 | * var str = WebGLDebugUtil.glEnumToString(ctx.getError()); 147 | * 148 | * @param {number} value Value to return an enum for 149 | * @return {string} The string version of the enum. 150 | */ 151 | function glEnumToString(value) { 152 | checkInit(); 153 | var name = glEnums[value]; 154 | return (name !== undefined) ? name : 155 | ("*UNKNOWN WebGL ENUM (0x" + value.toString(16) + ")"); 156 | } 157 | 158 | /** 159 | * Returns the string version of a WebGL argument. 160 | * Attempts to convert enum arguments to strings. 161 | * @param {string} functionName the name of the WebGL function. 162 | * @param {number} argumentIndx the index of the argument. 163 | * @param {*} value The value of the argument. 164 | * @return {string} The value as a string. 165 | */ 166 | function glFunctionArgToString(functionName, argumentIndex, value) { 167 | var funcInfo = glValidEnumContexts[functionName]; 168 | if (funcInfo !== undefined) { 169 | if (funcInfo[argumentIndex]) { 170 | return glEnumToString(value); 171 | } 172 | } 173 | return value.toString(); 174 | } 175 | 176 | function makePropertyWrapper(wrapper, original, propertyName) { 177 | //log("wrap prop: " + propertyName); 178 | wrapper.__defineGetter__(propertyName, function() { 179 | return original[propertyName]; 180 | }); 181 | // TODO(gmane): this needs to handle properties that take more than 182 | // one value? 183 | wrapper.__defineSetter__(propertyName, function(value) { 184 | //log("set: " + propertyName); 185 | original[propertyName] = value; 186 | }); 187 | } 188 | 189 | // Makes a function that calls a function on another object. 190 | function makeFunctionWrapper(original, functionName) { 191 | //log("wrap fn: " + functionName); 192 | var f = original[functionName]; 193 | return function() { 194 | //log("call: " + functionName); 195 | var result = f.apply(original, arguments); 196 | return result; 197 | }; 198 | } 199 | 200 | /** 201 | * Given a WebGL context returns a wrapped context that calls 202 | * gl.getError after every command and calls a function if the 203 | * result is not gl.NO_ERROR. 204 | * 205 | * @param {!WebGLRenderingContext} ctx The webgl context to 206 | * wrap. 207 | * @param {!function(err, funcName, args): void} opt_onErrorFunc 208 | * The function to call when gl.getError returns an 209 | * error. If not specified the default function calls 210 | * console.log with a message. 211 | */ 212 | function makeDebugContext(ctx, opt_onErrorFunc) { 213 | init(ctx); 214 | opt_onErrorFunc = opt_onErrorFunc || function(err, functionName, args) { 215 | // apparently we can't do args.join(","); 216 | var argStr = ""; 217 | for (var ii = 0; ii < args.length; ++ii) { 218 | argStr += ((ii == 0) ? '' : ', ') + 219 | glFunctionArgToString(functionName, ii, args[ii]); 220 | } 221 | log("WebGL error "+ glEnumToString(err) + " in "+ functionName + 222 | "(" + argStr + ")"); 223 | }; 224 | 225 | // Holds booleans for each GL error so after we get the error ourselves 226 | // we can still return it to the client app. 227 | var glErrorShadow = { }; 228 | 229 | // Makes a function that calls a WebGL function and then calls getError. 230 | function makeErrorWrapper(ctx, functionName) { 231 | return function() { 232 | var result = ctx[functionName].apply(ctx, arguments); 233 | var err = ctx.getError(); 234 | if (err != 0) { 235 | glErrorShadow[err] = true; 236 | opt_onErrorFunc(err, functionName, arguments); 237 | } 238 | return result; 239 | }; 240 | } 241 | 242 | // Make a an object that has a copy of every property of the WebGL context 243 | // but wraps all functions. 244 | var wrapper = {}; 245 | for (var propertyName in ctx) { 246 | if (typeof ctx[propertyName] == 'function') { 247 | wrapper[propertyName] = makeErrorWrapper(ctx, propertyName); 248 | } else { 249 | makePropertyWrapper(wrapper, ctx, propertyName); 250 | } 251 | } 252 | 253 | // Override the getError function with one that returns our saved results. 254 | wrapper.getError = function() { 255 | for (var err in glErrorShadow) { 256 | if (glErrorShadow[err]) { 257 | glErrorShadow[err] = false; 258 | return err; 259 | } 260 | } 261 | return ctx.NO_ERROR; 262 | }; 263 | 264 | return wrapper; 265 | } 266 | 267 | function resetToInitialState(ctx) { 268 | var numAttribs = ctx.getParameter(ctx.MAX_VERTEX_ATTRIBS); 269 | var tmp = ctx.createBuffer(); 270 | ctx.bindBuffer(ctx.ARRAY_BUFFER, tmp); 271 | for (var ii = 0; ii < numAttribs; ++ii) { 272 | ctx.disableVertexAttribArray(ii); 273 | ctx.vertexAttribPointer(ii, 4, ctx.FLOAT, false, 0, 0); 274 | ctx.vertexAttrib1f(ii, 0); 275 | } 276 | ctx.deleteBuffer(tmp); 277 | 278 | var numTextureUnits = ctx.getParameter(ctx.MAX_TEXTURE_IMAGE_UNITS); 279 | for (var ii = 0; ii < numTextureUnits; ++ii) { 280 | ctx.activeTexture(ctx.TEXTURE0 + ii); 281 | ctx.bindTexture(ctx.TEXTURE_CUBE_MAP, null); 282 | ctx.bindTexture(ctx.TEXTURE_2D, null); 283 | } 284 | 285 | ctx.activeTexture(ctx.TEXTURE0); 286 | ctx.useProgram(null); 287 | ctx.bindBuffer(ctx.ARRAY_BUFFER, null); 288 | ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, null); 289 | ctx.bindFramebuffer(ctx.FRAMEBUFFER, null); 290 | ctx.bindRenderbuffer(ctx.RENDERBUFFER, null); 291 | ctx.disable(ctx.BLEND); 292 | ctx.disable(ctx.CULL_FACE); 293 | ctx.disable(ctx.DEPTH_TEST); 294 | ctx.disable(ctx.DITHER); 295 | ctx.disable(ctx.SCISSOR_TEST); 296 | ctx.blendColor(0, 0, 0, 0); 297 | ctx.blendEquation(ctx.FUNC_ADD); 298 | ctx.blendFunc(ctx.ONE, ctx.ZERO); 299 | ctx.clearColor(0, 0, 0, 0); 300 | ctx.clearDepth(1); 301 | ctx.clearStencil(-1); 302 | ctx.colorMask(true, true, true, true); 303 | ctx.cullFace(ctx.BACK); 304 | ctx.depthFunc(ctx.LESS); 305 | ctx.depthMask(true); 306 | ctx.depthRange(0, 1); 307 | ctx.frontFace(ctx.CCW); 308 | ctx.hint(ctx.GENERATE_MIPMAP_HINT, ctx.DONT_CARE); 309 | ctx.lineWidth(1); 310 | ctx.pixelStorei(ctx.PACK_ALIGNMENT, 4); 311 | ctx.pixelStorei(ctx.UNPACK_ALIGNMENT, 4); 312 | ctx.pixelStorei(ctx.UNPACK_FLIP_Y_WEBGL, false); 313 | ctx.pixelStorei(ctx.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); 314 | // TODO: Delete this IF. 315 | if (ctx.UNPACK_COLORSPACE_CONVERSION_WEBGL) { 316 | ctx.pixelStorei(ctx.UNPACK_COLORSPACE_CONVERSION_WEBGL, ctx.BROWSER_DEFAULT_WEBGL); 317 | } 318 | ctx.polygonOffset(0, 0); 319 | ctx.sampleCoverage(1, false); 320 | ctx.scissor(0, 0, ctx.canvas.width, ctx.canvas.height); 321 | ctx.stencilFunc(ctx.ALWAYS, 0, 0xFFFFFFFF); 322 | ctx.stencilMask(0xFFFFFFFF); 323 | ctx.stencilOp(ctx.KEEP, ctx.KEEP, ctx.KEEP); 324 | ctx.viewport(0, 0, ctx.canvas.width, ctx.canvas.height); 325 | ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT); 326 | 327 | // TODO: This should NOT be needed but Firefox fails with 'hint' 328 | while(ctx.getError()); 329 | } 330 | 331 | function makeLostContextSimulatingCanvas(canvas) { 332 | var unwrappedContext_; 333 | var wrappedContext_; 334 | var onLost_ = []; 335 | var onRestored_ = []; 336 | var wrappedContext_ = {}; 337 | var contextId_ = 1; 338 | var contextLost_ = false; 339 | var resourceId_ = 0; 340 | var resourceDb_ = []; 341 | var numCallsToLoseContext_ = 0; 342 | var numCalls_ = 0; 343 | var canRestore_ = false; 344 | var restoreTimeout_ = 0; 345 | 346 | // Holds booleans for each GL error so can simulate errors. 347 | var glErrorShadow_ = { }; 348 | 349 | canvas.getContext = function(f) { 350 | return function() { 351 | var ctx = f.apply(canvas, arguments); 352 | // Did we get a context and is it a WebGL context? 353 | if (ctx instanceof WebGLRenderingContext) { 354 | if (ctx != unwrappedContext_) { 355 | if (unwrappedContext_) { 356 | throw "got different context" 357 | } 358 | unwrappedContext_ = ctx; 359 | wrappedContext_ = makeLostContextSimulatingContext(unwrappedContext_); 360 | } 361 | return wrappedContext_; 362 | } 363 | return ctx; 364 | } 365 | }(canvas.getContext); 366 | 367 | function wrapEvent(listener) { 368 | if (typeof(listener) == "function") { 369 | return listener; 370 | } else { 371 | return function(info) { 372 | listener.handleEvent(info); 373 | } 374 | } 375 | } 376 | 377 | var addOnContextLostListener = function(listener) { 378 | onLost_.push(wrapEvent(listener)); 379 | }; 380 | 381 | var addOnContextRestoredListener = function(listener) { 382 | onRestored_.push(wrapEvent(listener)); 383 | }; 384 | 385 | 386 | function wrapAddEventListener(canvas) { 387 | var f = canvas.addEventListener; 388 | canvas.addEventListener = function(type, listener, bubble) { 389 | switch (type) { 390 | case 'webglcontextlost': 391 | addOnContextLostListener(listener); 392 | break; 393 | case 'webglcontextrestored': 394 | addOnContextRestoredListener(listener); 395 | break; 396 | default: 397 | f.apply(canvas, arguments); 398 | } 399 | }; 400 | } 401 | 402 | wrapAddEventListener(canvas); 403 | 404 | canvas.loseContext = function() { 405 | if (!contextLost_) { 406 | contextLost_ = true; 407 | numCallsToLoseContext_ = 0; 408 | ++contextId_; 409 | while (unwrappedContext_.getError()); 410 | clearErrors(); 411 | glErrorShadow_[unwrappedContext_.CONTEXT_LOST_WEBGL] = true; 412 | var event = makeWebGLContextEvent("context lost"); 413 | var callbacks = onLost_.slice(); 414 | setTimeout(function() { 415 | //log("numCallbacks:" + callbacks.length); 416 | for (var ii = 0; ii < callbacks.length; ++ii) { 417 | //log("calling callback:" + ii); 418 | callbacks[ii](event); 419 | } 420 | if (restoreTimeout_ >= 0) { 421 | setTimeout(function() { 422 | canvas.restoreContext(); 423 | }, restoreTimeout_); 424 | } 425 | }, 0); 426 | } 427 | }; 428 | 429 | canvas.restoreContext = function() { 430 | if (contextLost_) { 431 | if (onRestored_.length) { 432 | setTimeout(function() { 433 | if (!canRestore_) { 434 | throw "can not restore. webglcontestlost listener did not call event.preventDefault"; 435 | } 436 | freeResources(); 437 | resetToInitialState(unwrappedContext_); 438 | contextLost_ = false; 439 | numCalls_ = 0; 440 | canRestore_ = false; 441 | var callbacks = onRestored_.slice(); 442 | var event = makeWebGLContextEvent("context restored"); 443 | for (var ii = 0; ii < callbacks.length; ++ii) { 444 | callbacks[ii](event); 445 | } 446 | }, 0); 447 | } 448 | } 449 | }; 450 | 451 | canvas.loseContextInNCalls = function(numCalls) { 452 | if (contextLost_) { 453 | throw "You can not ask a lost contet to be lost"; 454 | } 455 | numCallsToLoseContext_ = numCalls_ + numCalls; 456 | }; 457 | 458 | canvas.getNumCalls = function() { 459 | return numCalls_; 460 | }; 461 | 462 | canvas.setRestoreTimeout = function(timeout) { 463 | restoreTimeout_ = timeout; 464 | }; 465 | 466 | function isWebGLObject(obj) { 467 | //return false; 468 | return (obj instanceof WebGLBuffer || 469 | obj instanceof WebGLFramebuffer || 470 | obj instanceof WebGLProgram || 471 | obj instanceof WebGLRenderbuffer || 472 | obj instanceof WebGLShader || 473 | obj instanceof WebGLTexture); 474 | } 475 | 476 | function checkResources(args) { 477 | for (var ii = 0; ii < args.length; ++ii) { 478 | var arg = args[ii]; 479 | if (isWebGLObject(arg)) { 480 | return arg.__webglDebugContextLostId__ == contextId_; 481 | } 482 | } 483 | return true; 484 | } 485 | 486 | function clearErrors() { 487 | var k = Object.keys(glErrorShadow_); 488 | for (var ii = 0; ii < k.length; ++ii) { 489 | delete glErrorShadow_[k]; 490 | } 491 | } 492 | 493 | function loseContextIfTime() { 494 | ++numCalls_; 495 | if (!contextLost_) { 496 | if (numCallsToLoseContext_ == numCalls_) { 497 | canvas.loseContext(); 498 | } 499 | } 500 | } 501 | 502 | // Makes a function that simulates WebGL when out of context. 503 | function makeLostContextFunctionWrapper(ctx, functionName) { 504 | var f = ctx[functionName]; 505 | return function() { 506 | // log("calling:" + functionName); 507 | // Only call the functions if the context is not lost. 508 | loseContextIfTime(); 509 | if (!contextLost_) { 510 | //if (!checkResources(arguments)) { 511 | // glErrorShadow_[wrappedContext_.INVALID_OPERATION] = true; 512 | // return; 513 | //} 514 | var result = f.apply(ctx, arguments); 515 | return result; 516 | } 517 | }; 518 | } 519 | 520 | function freeResources() { 521 | for (var ii = 0; ii < resourceDb_.length; ++ii) { 522 | var resource = resourceDb_[ii]; 523 | if (resource instanceof WebGLBuffer) { 524 | unwrappedContext_.deleteBuffer(resource); 525 | } else if (resource instanceof WebGLFramebuffer) { 526 | unwrappedContext_.deleteFramebuffer(resource); 527 | } else if (resource instanceof WebGLProgram) { 528 | unwrappedContext_.deleteProgram(resource); 529 | } else if (resource instanceof WebGLRenderbuffer) { 530 | unwrappedContext_.deleteRenderbuffer(resource); 531 | } else if (resource instanceof WebGLShader) { 532 | unwrappedContext_.deleteShader(resource); 533 | } else if (resource instanceof WebGLTexture) { 534 | unwrappedContext_.deleteTexture(resource); 535 | } 536 | } 537 | } 538 | 539 | function makeWebGLContextEvent(statusMessage) { 540 | return { 541 | statusMessage: statusMessage, 542 | preventDefault: function() { 543 | canRestore_ = true; 544 | } 545 | }; 546 | } 547 | 548 | return canvas; 549 | 550 | function makeLostContextSimulatingContext(ctx) { 551 | // copy all functions and properties to wrapper 552 | for (var propertyName in ctx) { 553 | if (typeof ctx[propertyName] == 'function') { 554 | wrappedContext_[propertyName] = makeLostContextFunctionWrapper( 555 | ctx, propertyName); 556 | } else { 557 | makePropertyWrapper(wrappedContext_, ctx, propertyName); 558 | } 559 | } 560 | 561 | // Wrap a few functions specially. 562 | wrappedContext_.getError = function() { 563 | loseContextIfTime(); 564 | if (!contextLost_) { 565 | var err; 566 | while (err = unwrappedContext_.getError()) { 567 | glErrorShadow_[err] = true; 568 | } 569 | } 570 | for (var err in glErrorShadow_) { 571 | if (glErrorShadow_[err]) { 572 | delete glErrorShadow_[err]; 573 | return err; 574 | } 575 | } 576 | return wrappedContext_.NO_ERROR; 577 | }; 578 | 579 | var creationFunctions = [ 580 | "createBuffer", 581 | "createFramebuffer", 582 | "createProgram", 583 | "createRenderbuffer", 584 | "createShader", 585 | "createTexture" 586 | ]; 587 | for (var ii = 0; ii < creationFunctions.length; ++ii) { 588 | var functionName = creationFunctions[ii]; 589 | wrappedContext_[functionName] = function(f) { 590 | return function() { 591 | loseContextIfTime(); 592 | if (contextLost_) { 593 | return null; 594 | } 595 | var obj = f.apply(ctx, arguments); 596 | obj.__webglDebugContextLostId__ = contextId_; 597 | resourceDb_.push(obj); 598 | return obj; 599 | }; 600 | }(ctx[functionName]); 601 | } 602 | 603 | var functionsThatShouldReturnNull = [ 604 | "getActiveAttrib", 605 | "getActiveUniform", 606 | "getBufferParameter", 607 | "getContextAttributes", 608 | "getAttachedShaders", 609 | "getFramebufferAttachmentParameter", 610 | "getParameter", 611 | "getProgramParameter", 612 | "getProgramInfoLog", 613 | "getRenderbufferParameter", 614 | "getShaderParameter", 615 | "getShaderInfoLog", 616 | "getShaderSource", 617 | "getTexParameter", 618 | "getUniform", 619 | "getUniformLocation", 620 | "getVertexAttrib" 621 | ]; 622 | for (var ii = 0; ii < functionsThatShouldReturnNull.length; ++ii) { 623 | var functionName = functionsThatShouldReturnNull[ii]; 624 | wrappedContext_[functionName] = function(f) { 625 | return function() { 626 | loseContextIfTime(); 627 | if (contextLost_) { 628 | return null; 629 | } 630 | return f.apply(ctx, arguments); 631 | } 632 | }(wrappedContext_[functionName]); 633 | } 634 | 635 | var isFunctions = [ 636 | "isBuffer", 637 | "isEnabled", 638 | "isFramebuffer", 639 | "isProgram", 640 | "isRenderbuffer", 641 | "isShader", 642 | "isTexture" 643 | ]; 644 | for (var ii = 0; ii < isFunctions.length; ++ii) { 645 | var functionName = isFunctions[ii]; 646 | wrappedContext_[functionName] = function(f) { 647 | return function() { 648 | loseContextIfTime(); 649 | if (contextLost_) { 650 | return false; 651 | } 652 | return f.apply(ctx, arguments); 653 | } 654 | }(wrappedContext_[functionName]); 655 | } 656 | 657 | wrappedContext_.checkFramebufferStatus = function(f) { 658 | return function() { 659 | loseContextIfTime(); 660 | if (contextLost_) { 661 | return wrappedContext_.FRAMEBUFFER_UNSUPPORTED; 662 | } 663 | return f.apply(ctx, arguments); 664 | }; 665 | }(wrappedContext_.checkFramebufferStatus); 666 | 667 | wrappedContext_.getAttribLocation = function(f) { 668 | return function() { 669 | loseContextIfTime(); 670 | if (contextLost_) { 671 | return -1; 672 | } 673 | return f.apply(ctx, arguments); 674 | }; 675 | }(wrappedContext_.getAttribLocation); 676 | 677 | wrappedContext_.getVertexAttribOffset = function(f) { 678 | return function() { 679 | loseContextIfTime(); 680 | if (contextLost_) { 681 | return 0; 682 | } 683 | return f.apply(ctx, arguments); 684 | }; 685 | }(wrappedContext_.getVertexAttribOffset); 686 | 687 | wrappedContext_.isContextLost = function() { 688 | return contextLost_; 689 | }; 690 | 691 | return wrappedContext_; 692 | } 693 | } 694 | 695 | return { 696 | /** 697 | * Initializes this module. Safe to call more than once. 698 | * @param {!WebGLRenderingContext} ctx A WebGL context. If 699 | } 700 | * you have more than one context it doesn't matter which one 701 | * you pass in, it is only used to pull out constants. 702 | */ 703 | 'init': init, 704 | 705 | /** 706 | * Returns true or false if value matches any WebGL enum 707 | * @param {*} value Value to check if it might be an enum. 708 | * @return {boolean} True if value matches one of the WebGL defined enums 709 | */ 710 | 'mightBeEnum': mightBeEnum, 711 | 712 | /** 713 | * Gets an string version of an WebGL enum. 714 | * 715 | * Example: 716 | * WebGLDebugUtil.init(ctx); 717 | * var str = WebGLDebugUtil.glEnumToString(ctx.getError()); 718 | * 719 | * @param {number} value Value to return an enum for 720 | * @return {string} The string version of the enum. 721 | */ 722 | 'glEnumToString': glEnumToString, 723 | 724 | /** 725 | * Converts the argument of a WebGL function to a string. 726 | * Attempts to convert enum arguments to strings. 727 | * 728 | * Example: 729 | * WebGLDebugUtil.init(ctx); 730 | * var str = WebGLDebugUtil.glFunctionArgToString('bindTexture', 0, gl.TEXTURE_2D); 731 | * 732 | * would return 'TEXTURE_2D' 733 | * 734 | * @param {string} functionName the name of the WebGL function. 735 | * @param {number} argumentIndx the index of the argument. 736 | * @param {*} value The value of the argument. 737 | * @return {string} The value as a string. 738 | */ 739 | 'glFunctionArgToString': glFunctionArgToString, 740 | 741 | /** 742 | * Given a WebGL context returns a wrapped context that calls 743 | * gl.getError after every command and calls a function if the 744 | * result is not NO_ERROR. 745 | * 746 | * You can supply your own function if you want. For example, if you'd like 747 | * an exception thrown on any GL error you could do this 748 | * 749 | * function throwOnGLError(err, funcName, args) { 750 | * throw WebGLDebugUtils.glEnumToString(err) + " was caused by call to" + 751 | * funcName; 752 | * }; 753 | * 754 | * ctx = WebGLDebugUtils.makeDebugContext( 755 | * canvas.getContext("webgl"), throwOnGLError); 756 | * 757 | * @param {!WebGLRenderingContext} ctx The webgl context to wrap. 758 | * @param {!function(err, funcName, args): void} opt_onErrorFunc The function 759 | * to call when gl.getError returns an error. If not specified the default 760 | * function calls console.log with a message. 761 | */ 762 | 'makeDebugContext': makeDebugContext, 763 | 764 | /** 765 | * Given a canvas element returns a wrapped canvas element that will 766 | * simulate lost context. The canvas returned adds the following functions. 767 | * 768 | * loseContext: 769 | * simulates a lost context event. 770 | * 771 | * restoreContext: 772 | * simulates the context being restored. 773 | * 774 | * lostContextInNCalls: 775 | * loses the context after N gl calls. 776 | * 777 | * getNumCalls: 778 | * tells you how many gl calls there have been so far. 779 | * 780 | * setRestoreTimeout: 781 | * sets the number of milliseconds until the context is restored 782 | * after it has been lost. Defaults to 0. Pass -1 to prevent 783 | * automatic restoring. 784 | * 785 | * @param {!Canvas} canvas The canvas element to wrap. 786 | */ 787 | 'makeLostContextSimulatingCanvas': makeLostContextSimulatingCanvas, 788 | 789 | /** 790 | * Resets a context to the initial state. 791 | * @param {!WebGLRenderingContext} ctx The webgl context to 792 | * reset. 793 | */ 794 | 'resetToInitialState': resetToInitialState 795 | }; 796 | 797 | }(); 798 | 799 | --------------------------------------------------------------------------------