├── .gitignore ├── ReadMe.txt ├── build.template.properties ├── build.xml ├── build ├── android-resources │ └── template-air-app.xml ├── assets │ └── logo.png ├── bin-resources │ ├── images │ │ ├── icons │ │ │ ├── app-icon-36x36.png │ │ │ ├── app-icon-48x48.png │ │ │ └── app-icon-72x72.png │ │ ├── image1.jpg │ │ ├── image10.jpg │ │ ├── image11.jpg │ │ ├── image12.jpg │ │ ├── image13.jpg │ │ ├── image14.jpg │ │ ├── image15.jpg │ │ ├── image16.jpg │ │ ├── image17.jpg │ │ ├── image18.jpg │ │ ├── image19.jpg │ │ ├── image2.jpg │ │ ├── image20.jpg │ │ ├── image21.jpg │ │ ├── image22.jpg │ │ ├── image23.jpg │ │ ├── image24.jpg │ │ ├── image25.jpg │ │ ├── image26.jpg │ │ ├── image27.jpg │ │ ├── image28.jpg │ │ ├── image29.jpg │ │ ├── image3.jpg │ │ ├── image4.jpg │ │ ├── image5.jpg │ │ ├── image6.jpg │ │ ├── image7.jpg │ │ ├── image8.jpg │ │ └── image9.jpg │ └── js │ │ └── swfobject.js ├── build-includes │ ├── android.xml │ ├── asdoc.xml │ ├── chrome.xml │ ├── compile-swc.xml │ ├── compile-swf.xml │ ├── ios.xml │ ├── misc.xml │ └── test.xml ├── html-template │ ├── html.properties │ └── index.template.html ├── ios-resources │ └── template-air-app.xml ├── libs │ ├── FlexUnit4.swc │ ├── FlexUnit4CIListener.swc │ ├── ant-contrib.jar │ ├── flexUnit4UIRunner.swc │ └── flexUnitTasks.jar ├── playbook-resources │ └── blackberry-tablet.xml └── psds │ └── app-icon.psd ├── src ├── BitmapScrollerApp.as ├── Main.as ├── com │ └── flashartofwar │ │ ├── BitmapScroller.as │ │ ├── behaviors │ │ ├── EaseScrollBehavior.as │ │ ├── ISlider.as │ │ └── SliderBehavior.as │ │ └── ui │ │ └── Slider.as └── net │ └── hires │ └── debug │ └── Stats.as └── test ├── BitmapScrollerAppTestApp.mxml ├── BitmapScrollerTestSuite.as └── com └── flashartofwar └── BitmapScrollerTest.as /.gitignore: -------------------------------------------------------------------------------- 1 | /.settings/* 2 | 3 | /html-template/* 4 | /bin-debug/* 5 | /bin-release/* 6 | /libs/* 7 | /bin/* 8 | /doc/* 9 | /report/* 10 | /dist/* 11 | /ipas/* 12 | 13 | /.actionScriptProperties 14 | /.flexProperties 15 | /.flexLibProperties 16 | /.project 17 | /.as3_classpath 18 | /com.adobe.flexbuilder.project.prefs 19 | /org.eclipse.core.resources.prefs 20 | 21 | Icon 22 | Thumbs.db 23 | .DS_Store 24 | 25 | build.properties 26 | /tmp/* 27 | /*.iml 28 | *.mobileprovision 29 | *.p12 30 | *.cer -------------------------------------------------------------------------------- /ReadMe.txt: -------------------------------------------------------------------------------- 1 | Hello, 2 | 3 | Welcome to my Bitmap Scroller project. Once you have a look through the demo app 4 | it should be relatively easy to incorporate this into your own project. Here is 5 | a little info on how to get the demo up and running. 6 | 7 | Building Without Ant 8 | 9 | If you do not want to use ANT you must manually copy the build/bin-resources/images 10 | folder to your bin or bin-debug directory and compile the app like you normally 11 | would. The main class is called BitmapScrollerApp located in the src folder. This 12 | represents a demo class to show off how the BitmapScroller works. 13 | 14 | You will also have to set up a few extra lines of code in the advanced compiler area 15 | of your project’s settings: 16 | 17 | -use-network=false (If you are not testing this on a localhost or server) 18 | 19 | -define=CONFIG::mobile,false (If you are compiling for desktop. For mobile 20 | change this to true. This allows you to configure different logic for each 21 | platform which I will talk about later). 22 | 23 | -static-link-runtime-shared-libraries=true (This is important on any project 24 | that uses Flex 4 since it is set to false by default. This may not impact 25 | this project but if you begin embedding assets it is key). 26 | 27 | 28 | Building With ANT 29 | 30 | The build file is located in the root directory. It relies on a build.properties 31 | file to run. I provide a template file called build.template.properties which you 32 | can copy and rename to build.template. Once you do that open it up and lets change 33 | a few key properties. 34 | 35 | You will need to set the following paths: 36 | 37 | FLEX_HOME - path to your Flex SDK. If you have FlashBuilder installed it 38 | is located in the App’s dir under SDK 4.0. 39 | 40 | android.sdk - path to your Android SDK 41 | 42 | browser - On a PC you will want to use the path to the actual browser 43 | such as C:/Program Files/Mozilla Firefox/firefox.exe. On a mac the name 44 | of the browser will work such as Safari. 45 | 46 | Once you set these paths you should be able to run the ANT Build. The default build 47 | is compile swf. After running it, the build will create a bin folder for you and 48 | compile the swf in there. From there you can launch the index.html however you want. 49 | There is an ANT target for local-run located in the compile-swf include build or use 50 | the IDE to launch the index file and trigger the debugger, which is what I normally do. 51 | -------------------------------------------------------------------------------- /build.template.properties: -------------------------------------------------------------------------------- 1 | # IMPORTANT Change to your local system paths before using ANT 2 | 3 | #Toggle on/off specific targets 4 | run.test = false 5 | run.asdoc = false 6 | logging = false 7 | autolaunch.url = true 8 | mobile = false 9 | 10 | #compiler mode: debug, optimize 11 | compile.type = optimize 12 | 13 | # Build paths 14 | FLEX_HOME = /Applications/Adobe Flash Builder 4.5/sdks/4.5.0 15 | #android.sdk= 16 | 17 | #Properties file for build.xml 18 | project.name=BitmapScrollerApp 19 | 20 | #Version number 21 | ver.num=v1.5.2-beta 22 | project.name.versioned=${project.name}-${ver.num} 23 | deploy.name.versioned=${project.name}-${ver.num} 24 | 25 | #browser 26 | browser = "Google Chrome" 27 | report.url = ${report.loc}/html/index.html 28 | app.url = ${bin.loc}/index.html 29 | 30 | #Certificate 31 | certificate.name = Certificates.p12 32 | certificate.username = 33 | certificate.company = 34 | certificate.password = 35 | certificate.filename = Certificates.p12 36 | 37 | #provisioning 38 | ios.provision = BitmapScroller.mobileprovision 39 | ipa.package = com.flashartofwar.bitmapscroller 40 | ## Don't change these settings ### 41 | 42 | #build locations 43 | deploy.loc=${basedir}/bin 44 | asdoc.loc=${FLEX_HOME}/bin/asdoc 45 | main.src.loc=${basedir}/src 46 | test.src.loc=${basedir}/test 47 | doc.loc=${basedir}/doc 48 | lib.loc=${basedir}/build/libs 49 | bin.loc=${deploy.loc} 50 | report.loc=${basedir}/report 51 | template.loc=${basedir}/build/templates 52 | includes.loc=${basedir}/build/build-includes 53 | air.swcs=${FLEX_HOME}/frameworks/libs/air 54 | adb=${android.sdk}/platform-tools/adb.exe 55 | adt=${FLEX_HOME}/bin/adt.bat 56 | apks.loc=${deploy.loc}/apks 57 | ipas.loc=${deploy.loc}/ipas 58 | tmp.loc=${basedir}/tmp 59 | logs.loc=${report.loc}/logs -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /build/android-resources/template-air-app.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.flashartofwar.bitmapscroller 4 | BitmapScrollerApp 5 | BitmapScrollerApp 6 | 1.0.0 7 | 8 | swfs/@projectversion@.swf 9 | false 10 | true 11 | true 12 | landscape 13 | 14 | 15 | images/icons/app-icon-36x36.png 16 | images/icons/app-icon-48x48.png 17 | images/icons/app-icon-72x72.png 18 | 19 | 20 | 21 | UIDeviceFamily 23 | 24 | 1 25 | 2 26 | 27 | ]]> 28 | high 29 | 30 | 31 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 42 | 43 | 44 | 45 | 46 | 48 | 49 | 50 | 51 | 52 | ]]> 53 | 54 | 55 | -------------------------------------------------------------------------------- /build/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/assets/logo.png -------------------------------------------------------------------------------- /build/bin-resources/images/icons/app-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/icons/app-icon-36x36.png -------------------------------------------------------------------------------- /build/bin-resources/images/icons/app-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/icons/app-icon-48x48.png -------------------------------------------------------------------------------- /build/bin-resources/images/icons/app-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/icons/app-icon-72x72.png -------------------------------------------------------------------------------- /build/bin-resources/images/image1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image1.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image10.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image11.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image12.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image13.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image14.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image15.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image16.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image17.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image18.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image19.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image2.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image20.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image21.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image22.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image23.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image24.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image25.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image26.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image27.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image28.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image29.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image3.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image4.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image5.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image6.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image7.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image8.jpg -------------------------------------------------------------------------------- /build/bin-resources/images/image9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/bin-resources/images/image9.jpg -------------------------------------------------------------------------------- /build/bin-resources/js/swfobject.js: -------------------------------------------------------------------------------- 1 | /* SWFObject v2.1 2 | Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis 3 | This software is released under the MIT License 4 | */ 5 | var swfobject=function(){var b="undefined",Q="object",n="Shockwave Flash",p="ShockwaveFlash.ShockwaveFlash",P="application/x-shockwave-flash",m="SWFObjectExprInst",j=window,K=document,T=navigator,o=[],N=[],i=[],d=[],J,Z=null,M=null,l=null,e=false,A=false;var h=function(){var v=typeof K.getElementById!=b&&typeof K.getElementsByTagName!=b&&typeof K.createElement!=b,AC=[0,0,0],x=null;if(typeof T.plugins!=b&&typeof T.plugins[n]==Q){x=T.plugins[n].description;if(x&&!(typeof T.mimeTypes!=b&&T.mimeTypes[P]&&!T.mimeTypes[P].enabledPlugin)){x=x.replace(/^.*\s+(\S+\s+\S+$)/,"$1");AC[0]=parseInt(x.replace(/^(.*)\..*$/,"$1"),10);AC[1]=parseInt(x.replace(/^.*\.(.*)\s.*$/,"$1"),10);AC[2]=/r/.test(x)?parseInt(x.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof j.ActiveXObject!=b){var y=null,AB=false;try{y=new ActiveXObject(p+".7")}catch(t){try{y=new ActiveXObject(p+".6");AC=[6,0,21];y.AllowScriptAccess="always"}catch(t){if(AC[0]==6){AB=true}}if(!AB){try{y=new ActiveXObject(p)}catch(t){}}}if(!AB&&y){try{x=y.GetVariable("$version");if(x){x=x.split(" ")[1].split(",");AC=[parseInt(x[0],10),parseInt(x[1],10),parseInt(x[2],10)]}}catch(t){}}}}var AD=T.userAgent.toLowerCase(),r=T.platform.toLowerCase(),AA=/webkit/.test(AD)?parseFloat(AD.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,q=false,z=r?/win/.test(r):/win/.test(AD),w=r?/mac/.test(r):/mac/.test(AD);/*@cc_on q=true;@if(@_win32)z=true;@elif(@_mac)w=true;@end@*/return{w3cdom:v,pv:AC,webkit:AA,ie:q,win:z,mac:w}}();var L=function(){if(!h.w3cdom){return }f(H);if(h.ie&&h.win){try{K.write(" 23 | 26 | 27 | 28 | 29 |
30 |

You will need Flash Player 10+ to see this site.

31 |
32 | 33 | -------------------------------------------------------------------------------- /build/ios-resources/template-air-app.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | package@ 4 | @project@ 5 | @project@ 6 | @version@ 7 | mobileDevice 8 | 9 | swfs/@projectversion@.swf 10 | false 11 | true 12 | true 13 | landscape 14 | 15 | 16 | images/icons/app-icon-72x72.png 17 | images/icons/app-icon-48x48.png 18 | images/icons/app-icon-36x36.png 19 | 20 | 21 | -------------------------------------------------------------------------------- /build/libs/FlexUnit4.swc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/libs/FlexUnit4.swc -------------------------------------------------------------------------------- /build/libs/FlexUnit4CIListener.swc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/libs/FlexUnit4CIListener.swc -------------------------------------------------------------------------------- /build/libs/ant-contrib.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/libs/ant-contrib.jar -------------------------------------------------------------------------------- /build/libs/flexUnit4UIRunner.swc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/libs/flexUnit4UIRunner.swc -------------------------------------------------------------------------------- /build/libs/flexUnitTasks.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/libs/flexUnitTasks.jar -------------------------------------------------------------------------------- /build/playbook-resources/blackberry-tablet.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | images/icons/app-icon-72x72.png 7 | 8 | 9 | Jesse Freeman 10 | gYAAgLsHEomMibpniOjN3qG9_NE 11 | 1.0.0.0 12 | 13 | -------------------------------------------------------------------------------- /build/psds/app-icon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/theflashbum/BitmapScroller/a064036d71a46e94f369f2d06d7f4f0564cbeb4f/build/psds/app-icon.psd -------------------------------------------------------------------------------- /src/BitmapScrollerApp.as: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Original Author: Jesse Freeman of FlashArtOfWar.com 5 | * Copyright (c) 2010 6 | * Class File: BitmapScrollerApp.as 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | package 28 | { 29 | import com.flashartofwar.BitmapScroller; 30 | import com.flashartofwar.behaviors.EaseScrollBehavior; 31 | import com.flashartofwar.ui.Slider; 32 | 33 | import flash.display.Bitmap; 34 | import flash.display.Loader; 35 | import flash.display.Sprite; 36 | import flash.display.StageAlign; 37 | import flash.display.StageScaleMode; 38 | import flash.events.Event; 39 | import flash.events.IOErrorEvent; 40 | import flash.events.MouseEvent; 41 | import flash.events.SecurityErrorEvent; 42 | import flash.net.URLRequest; 43 | 44 | import flash.text.TextField; 45 | 46 | import flash.text.TextFieldAutoSize; 47 | 48 | import net.hires.debug.Stats; 49 | 50 | [SWF(width="800",height="480",backgroundColor="#333333",frameRate="60")] 51 | public class BitmapScrollerApp extends Sprite 52 | { 53 | 54 | private var preloadList:Array = ["image1.jpg","image2.jpg","image3.jpg","image4.jpg","image5.jpg","image6.jpg","image7.jpg","image8.jpg","image9.jpg","image10.jpg","image11.jpg","image12.jpg","image13.jpg","image14.jpg","image15.jpg","image16.jpg","image17.jpg","image18.jpg","image19.jpg","image20.jpg","image21.jpg","image22.jpg","image23.jpg","image24.jpg","image25.jpg","image26.jpg","image27.jpg","image28.jpg","image29.jpg"]; 55 | private var baseURL:String = "images/"; 56 | private var currentlyLoading:String; 57 | private var loader:Loader = new Loader(); 58 | private var bitmapScroller:BitmapScroller; 59 | private var images:Array = new Array(); 60 | private var easeScrollBehavior:EaseScrollBehavior; 61 | private var stats:Stats; 62 | private var isMouseDown:Boolean; 63 | private var slider:Slider; 64 | private var preloadStatus:TextField; 65 | 66 | /** 67 | * 68 | */ 69 | public function BitmapScrollerApp() 70 | { 71 | trace("Hello"); 72 | 73 | configureStage(); 74 | 75 | if (CONFIG::mobile) 76 | { 77 | baseURL = "/" + baseURL; 78 | } 79 | 80 | 81 | preloadStatus = new TextField(); 82 | preloadStatus.text = "Loading..."; 83 | preloadStatus.autoSize = TextFieldAutoSize.LEFT; 84 | preloadStatus.x = 10; 85 | preloadStatus.y = 10; 86 | preloadStatus.selectable = false; 87 | addChild(preloadStatus); 88 | 89 | preload(); 90 | 91 | } 92 | 93 | /** 94 | * 95 | */ 96 | private function configureStage():void 97 | { 98 | this.stage.align = StageAlign.TOP_LEFT; 99 | this.stage.scaleMode = StageScaleMode.NO_SCALE; 100 | } 101 | 102 | /** 103 | * 104 | */ 105 | protected function init():void 106 | { 107 | createBitmapScroller(); 108 | createScrubber(); 109 | createEaseScrollBehavior(); 110 | createStats(); 111 | 112 | if (!CONFIG::mobile) 113 | { 114 | // Once everything is set up add stage resize listeners 115 | this.stage.addEventListener(Event.RESIZE, onStageResize); 116 | 117 | // calls stage resize once to put everything in its correct place 118 | onStageResize(); 119 | } 120 | else 121 | { 122 | //fingerTouch(); 123 | } 124 | 125 | onStageResize(); 126 | activateLoop(); 127 | } 128 | 129 | /** 130 | * 131 | * @param event 132 | */ 133 | private function onStageResize(event:Event = null):void 134 | { 135 | var stageWidth:int = stage.stageWidth; 136 | var stageHeight:int = stage.stageHeight; 137 | 138 | /*if (!CONFIG::mobile) 139 | { 140 | stageWidth = stage.fullScreenWidth; 141 | stageHeight = stage.fullScreenHeight; 142 | }*/ 143 | 144 | bitmapScroller.width = slider.width = stageWidth; 145 | bitmapScroller.height = stageHeight; 146 | stats.x = (stageWidth - stats.width) - 10; 147 | slider.y = stage.stageHeight - slider.height - 20; 148 | if(slider.y > 770) 149 | slider.y = 770; 150 | slider.width -= 40; 151 | slider.x = 20; 152 | } 153 | 154 | /** 155 | * 156 | */ 157 | private function createStats():void 158 | { 159 | stats = addChild(new Stats({ bg: 0x000000 })) as Stats; 160 | stats.y = 10; 161 | } 162 | 163 | /** 164 | * 165 | */ 166 | private function activateLoop():void 167 | { 168 | addEventListener(Event.ENTER_FRAME, onEnterFrame); 169 | } 170 | 171 | /** 172 | * 173 | * @param event 174 | */ 175 | private function onEnterFrame(event:Event):void 176 | { 177 | loop(); 178 | } 179 | 180 | /** 181 | * 182 | */ 183 | private function createEaseScrollBehavior():void 184 | { 185 | easeScrollBehavior = new EaseScrollBehavior(bitmapScroller, 0); 186 | } 187 | 188 | /** 189 | * 190 | */ 191 | private function createScrubber():void 192 | { 193 | var sWidth:int = stage.stageWidth; 194 | var sHeight:int = 10; 195 | var dWidth:int = 40; 196 | var corners:int = 5; 197 | if (CONFIG::mobile) 198 | { 199 | sHeight = 20; 200 | dWidth = 60; 201 | corners = 10; 202 | } 203 | 204 | slider = new Slider(sWidth, sHeight, dWidth, corners, 0); 205 | slider.y = stage.stageHeight - slider.height - 20; 206 | 207 | slider.addEventListener(Event.CHANGE, onSliderValueChange) 208 | addChild(slider); 209 | 210 | } 211 | 212 | private function onSliderValueChange(event:Event):void 213 | { 214 | trace("Slider Changed", slider.value); 215 | } 216 | 217 | /** 218 | * 219 | */ 220 | private function createBitmapScroller():void 221 | { 222 | 223 | bitmapScroller = new BitmapScroller(); 224 | bitmapScroller.bitmapDataCollection = images; 225 | addChild(bitmapScroller); 226 | bitmapScroller.width = stage.stageWidth; 227 | bitmapScroller.height = stage.stageHeight; 228 | 229 | } 230 | 231 | /** 232 | * Handles preloading our images. Checks to see how many are left then 233 | * calls loadNext or compositeImage. 234 | */ 235 | protected function preload():void 236 | { 237 | 238 | if (preloadList.length == 0) 239 | { 240 | removeChild(preloadStatus); 241 | init(); 242 | } 243 | else 244 | { 245 | loadNext(); 246 | preloadStatus.text = preloadList.length + " Images Left To Load."; 247 | } 248 | } 249 | 250 | /** 251 | * Loads the next item in the prelaodList 252 | */ 253 | private function loadNext():void 254 | { 255 | currentlyLoading = preloadList.shift(); 256 | loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoad); 257 | loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError); 258 | loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError); 259 | 260 | loader.load(new URLRequest(baseURL + currentlyLoading)); 261 | } 262 | 263 | /** 264 | * 265 | * @param event 266 | */ 267 | private function onError(event:*):void 268 | { 269 | preloadStatus.text = event.text; 270 | } 271 | 272 | /** 273 | * Handles onLoad, saves the BitmapData then calls preload 274 | */ 275 | private function onLoad(event:Event):void 276 | { 277 | loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoad); 278 | 279 | images.push(Bitmap(event.target.content).bitmapData); 280 | 281 | currentlyLoading = null; 282 | 283 | preload(); 284 | } 285 | 286 | /** 287 | * 288 | */ 289 | public function loop():void 290 | { 291 | var percent:Number = slider.value / 100; 292 | var s:Number = bitmapScroller.totalWidth; 293 | var t:Number = bitmapScroller.width; 294 | 295 | easeScrollBehavior.targetX = percent * (s - t); 296 | // 297 | easeScrollBehavior.update(); 298 | // 299 | bitmapScroller.render(); 300 | } 301 | 302 | // This is for mobile touch support 303 | 304 | /** 305 | * 306 | */ 307 | private function fingerTouch():void 308 | { 309 | stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); 310 | stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); 311 | stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); 312 | } 313 | 314 | /** 315 | * 316 | * @param event 317 | */ 318 | private function onMouseDown(event:MouseEvent):void 319 | { 320 | isMouseDown = true; 321 | } 322 | 323 | /** 324 | * 325 | * @param event 326 | */ 327 | private function onMouseUp(event:MouseEvent):void 328 | { 329 | isMouseDown = false; 330 | } 331 | 332 | /** 333 | * 334 | * @param event 335 | */ 336 | private function onMouseMove(event:MouseEvent):void 337 | { 338 | if (isMouseDown) 339 | { 340 | var percent:Number = (event.localX) / (stage.stageWidth) * 100; 341 | slider.value = percent; 342 | } 343 | } 344 | } 345 | } -------------------------------------------------------------------------------- /src/Main.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | import flash.display.Sprite; 4 | 5 | public class Main extends Sprite 6 | { 7 | public function Main() 8 | { 9 | // Launch your application by right clicking within this class and select: Deubg As > FDT SWF Application 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/com/flashartofwar/BitmapScroller.as: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Original Author: Jesse Freeman of FlashArtOfWar.com 5 | * Copyright (c) 2010 6 | * Class File: BitmapScroller.as 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | * 26 | */ 27 | 28 | package com.flashartofwar 29 | { 30 | import flash.display.Bitmap; 31 | import flash.display.BitmapData; 32 | import flash.events.Event; 33 | import flash.geom.Point; 34 | import flash.geom.Rectangle; 35 | 36 | public class BitmapScroller extends Bitmap 37 | { 38 | protected const INVALID_SIZE:String = "size"; 39 | protected const INVALID_SCROLL:String = "scroll"; 40 | protected const INVALID_SIZE_SCROLL:String = "all"; 41 | protected const INVALID_VISUALS:String = "visuals"; 42 | 43 | protected var _bitmapDataCollection:Array; 44 | protected var collectionRects:Array = []; 45 | protected var _totalWidth:int = 0; 46 | protected var _maxHeight:Number = 0; 47 | protected var collectionTotal:int = 0; 48 | protected var copyPixelOffset:Point = new Point(); 49 | protected var internalSampleArea:Rectangle = new Rectangle(0, 0, 0, 0); 50 | protected var collectionID:int; 51 | protected var sourceRect:Rectangle; 52 | protected var sourceBitmapData:BitmapData; 53 | protected var leftOver:Number; 54 | protected var point:Point; 55 | protected var calculationPoint:Point = new Point(); 56 | protected var difference:Number; 57 | protected var sampleArea:Rectangle; 58 | protected var samplePositionPoint:Point = new Point(); 59 | protected var _invalid:Boolean; 60 | protected var invalidSize:Boolean; 61 | protected var invalidScroll:Boolean; 62 | protected var invalidVisuals:Boolean; 63 | 64 | 65 | public function BitmapScroller(bitmapData:BitmapData = null, pixelSnapping:String = "auto", smoothing:Boolean = false) 66 | { 67 | super(null, pixelSnapping, smoothing); 68 | addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 69 | } 70 | 71 | override public function get width():Number 72 | { 73 | return internalSampleArea.width; 74 | } 75 | 76 | override public function set width(value:Number):void 77 | { 78 | if (value == internalSampleArea.width) 79 | { 80 | return; 81 | } 82 | else 83 | { 84 | internalSampleArea.width = value; 85 | invalidate(INVALID_SIZE); 86 | } 87 | } 88 | 89 | override public function get height():Number 90 | { 91 | return internalSampleArea.height; 92 | } 93 | 94 | override public function set height(value:Number):void 95 | { 96 | if (value == internalSampleArea.height) 97 | { 98 | return; 99 | } 100 | else 101 | { 102 | internalSampleArea.height = value; 103 | invalidate(INVALID_SIZE); 104 | } 105 | } 106 | 107 | public function get scrollX():Number 108 | { 109 | return internalSampleArea.x; 110 | } 111 | 112 | public function set scrollX(value:Number):void 113 | { 114 | if (value == internalSampleArea.x) 115 | { 116 | return; 117 | } 118 | else 119 | { 120 | internalSampleArea.x = value; 121 | invalidate(INVALID_SCROLL); 122 | } 123 | } 124 | 125 | public function get totalWidth():int 126 | { 127 | return _totalWidth; 128 | } 129 | 130 | public function get maxHeight():Number 131 | { 132 | return _maxHeight; 133 | } 134 | 135 | public function render():void 136 | { 137 | 138 | if (_invalid) 139 | { 140 | // We check to see if the size has changed. If it has we create a new bitmap. If not we clear it with fillRect 141 | if (invalidSize) 142 | { 143 | bitmapData = new BitmapData(internalSampleArea.width, internalSampleArea.height, true, 0x000000); 144 | } 145 | else 146 | { 147 | bitmapData.fillRect(internalSampleArea, 0); 148 | } 149 | 150 | // Call sample to get the party started 151 | draw(internalSampleArea.clone()); 152 | 153 | // Clear any invalidation 154 | clearInvalidation(); 155 | } 156 | } 157 | 158 | private function clearInvalidation():void 159 | { 160 | _invalid = false; 161 | invalidSize = false; 162 | invalidScroll = false; 163 | invalidVisuals = false; 164 | } 165 | 166 | protected function indexCollection():void 167 | { 168 | var i:int; 169 | collectionTotal = _bitmapDataCollection.length; 170 | _totalWidth = 0; 171 | _maxHeight = 0; 172 | 173 | for (i = 0; i < collectionTotal; ++ i) 174 | { 175 | if (_bitmapDataCollection[i] is BitmapData) 176 | { 177 | indexBitmapData(_bitmapDataCollection[i]); 178 | } 179 | else 180 | { 181 | throw new Error("BitmapScroller can only process BitmapData."); 182 | } 183 | } 184 | 185 | } 186 | 187 | protected function indexBitmapData(bmd:BitmapData):void 188 | { 189 | var lastRect:Rectangle = collectionRects[collectionRects.length - 1]; 190 | 191 | var lastX:int = lastRect ? lastRect.x + lastRect.width + 1 : 0; 192 | 193 | // create a rect to represent the BitmapData 194 | var rect:Rectangle = new Rectangle(lastX, 0, bmd.width, bmd.height); 195 | 196 | collectionRects.push(rect); 197 | 198 | _totalWidth += rect.width; 199 | 200 | if (bmd.height > _maxHeight) 201 | { 202 | _maxHeight = bmd.height; 203 | } 204 | 205 | } 206 | 207 | /** 208 | * 209 | * @param sampleCoord 210 | * @return 211 | */ 212 | protected function calculateCollectionStartIndex(sampleCoord:Point):int 213 | { 214 | 215 | if (sampleCoord.x < 0) 216 | return -1; 217 | 218 | var i:int; 219 | 220 | for (i = 0; i < collectionTotal; ++ i) 221 | { 222 | if (collectionRects[i].containsPoint(sampleCoord)) 223 | { 224 | return i; 225 | } 226 | } 227 | 228 | return -1; 229 | } 230 | 231 | protected function draw(sampleArea:Rectangle, offset:Point = null):void 232 | { 233 | calculationPoint.x = sampleArea.x; 234 | calculationPoint.y = sampleArea.y; 235 | 236 | collectionID = calculateCollectionStartIndex(calculationPoint); 237 | 238 | if (collectionID != -1) 239 | { 240 | sourceRect = collectionRects[collectionID]; 241 | 242 | sourceBitmapData = _bitmapDataCollection[collectionID]; 243 | 244 | leftOver = Math.round(calculateLeftOverValue(sampleArea.x, sampleArea.width, sourceRect)); 245 | 246 | if (!offset) 247 | offset = copyPixelOffset; 248 | 249 | point = calculateSamplePosition(sampleArea, sourceRect); 250 | 251 | sampleArea.x = point.x; 252 | sampleArea.y = point.y; 253 | 254 | bitmapData.copyPixels(sourceBitmapData, sampleArea, offset); 255 | 256 | if (leftOver > 0) 257 | { 258 | offset = new Point(bitmapData.width - leftOver, 0); 259 | var leftOverSampleArea:Rectangle = calculateLeftOverSampleArea(sampleArea, leftOver, sourceRect); 260 | 261 | draw(leftOverSampleArea, offset); 262 | } 263 | 264 | } 265 | } 266 | 267 | 268 | protected function calculateLeftOverValue(offset:Number, sampleWidth:Number, sourceRect:Rectangle):Number 269 | { 270 | 271 | difference = (offset + sampleWidth) - (sourceRect.x + sourceRect.width); 272 | 273 | return (difference < 0) ? 0 : difference; 274 | } 275 | 276 | 277 | protected function calculateLeftoverOffset(sampleArea:Rectangle, leftOver:Number):Point 278 | { 279 | 280 | return new Point(sampleArea.width - leftOver, 0); 281 | } 282 | 283 | protected function calculateLeftOverSampleArea(sampleAreaSRC:Rectangle, leftOver:Number, sourceRect:Rectangle):Rectangle 284 | { 285 | sampleArea = sampleAreaSRC.clone(); 286 | sampleArea.width = leftOver + 1; 287 | sampleArea.x = sourceRect.x + sourceRect.width + 1; 288 | 289 | return sampleArea; 290 | } 291 | 292 | protected function calculateSamplePosition(sampleRect:Rectangle, sourceArea:Rectangle):Point 293 | { 294 | samplePositionPoint.x = sampleRect.x - sourceArea.x; 295 | 296 | return samplePositionPoint; 297 | } 298 | 299 | public function clear():void 300 | { 301 | 302 | } 303 | 304 | /** Invalidation Logic **/ 305 | 306 | protected function invalidate(type:String = "all"):void 307 | { 308 | if (!_invalid) 309 | { 310 | _invalid = true; 311 | 312 | switch (type) 313 | { 314 | case INVALID_VISUALS: 315 | invalidVisuals = true; 316 | break; 317 | case INVALID_SIZE: 318 | invalidSize = true; 319 | break; 320 | case INVALID_SCROLL: 321 | invalidScroll = true; 322 | break; 323 | case INVALID_SIZE_SCROLL: 324 | invalidScroll = true; 325 | invalidSize = true; 326 | break; 327 | } 328 | } 329 | } 330 | 331 | /** 332 | * 333 | * @param event 334 | */ 335 | protected function onAddedToStage(event:Event):void 336 | { 337 | removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 338 | addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage); 339 | render(); 340 | } 341 | 342 | /** 343 | * 344 | * @param event 345 | */ 346 | protected function onRemovedFromStage(event:Event):void 347 | { 348 | removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage); 349 | removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 350 | } 351 | 352 | public function set bitmapDataCollection(value:Array):void 353 | { 354 | _bitmapDataCollection = value; 355 | indexCollection(); 356 | } 357 | } 358 | } -------------------------------------------------------------------------------- /src/com/flashartofwar/behaviors/EaseScrollBehavior.as: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Original Author: Jesse Freeman of FlashArtOfWar.com 5 | * Copyright (c) 2010 6 | * Class File: EaseScrollBehavior.as 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | package com.flashartofwar.behaviors 28 | { 29 | import flash.events.EventDispatcher; 30 | 31 | public class EaseScrollBehavior extends EventDispatcher 32 | { 33 | 34 | public var targetX:Number; 35 | private var target:Object; 36 | 37 | public function EaseScrollBehavior(target:Object, targetX:Number = 0) 38 | { 39 | 40 | if (!target.hasOwnProperty("scrollX")) 41 | { 42 | throw new Error("Supplied target does not have a scrollX property."); 43 | } 44 | else 45 | { 46 | this.target = target; 47 | targetX = targetX; 48 | } 49 | 50 | } 51 | 52 | public function update():void 53 | { 54 | 55 | if ((target.scrollX == targetX)) 56 | { 57 | return; 58 | } 59 | else 60 | { 61 | var c:Number = targetX - target.scrollX; 62 | var b:Number = target.scrollX; 63 | target.scrollX = c * 25.0 / 256.0 + b; 64 | 65 | if (c < .01 && c > -.01) 66 | { 67 | target.scrollX = targetX; 68 | } 69 | } 70 | 71 | 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /src/com/flashartofwar/behaviors/ISlider.as: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Original Author: Jesse Freeman of FlashArtOfWar.com 5 | * Copyright (c) 2010 6 | * Class File: ISlider.as 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | package com.flashartofwar.behaviors 28 | { 29 | public interface ISlider 30 | { 31 | function get value():Number; 32 | 33 | function set value(value:Number):void; 34 | 35 | function get ticks():Number; 36 | } 37 | } -------------------------------------------------------------------------------- /src/com/flashartofwar/behaviors/SliderBehavior.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Modified Version of 3 | * Slider.as 4 | * Keith Peters 5 | * version 0.9.5 6 | * 7 | * Abstract base slider class for HSlider and VSlider. 8 | * 9 | * Copyright (c) 2010 Keith Peters 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy 12 | * of this software and associated documentation files (the "Software"), to deal 13 | * in the Software without restriction, including without limitation the rights 14 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | * copies of the Software, and to permit persons to whom the Software is 16 | * furnished to do so, subject to the following conditions: 17 | * 18 | * The above copyright notice and this permission notice shall be included in 19 | * all copies or substantial portions of the Software. 20 | * 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | * THE SOFTWARE. 28 | */ 29 | 30 | package com.flashartofwar.behaviors 31 | { 32 | import flash.display.Sprite; 33 | import flash.events.Event; 34 | import flash.events.EventDispatcher; 35 | import flash.events.MouseEvent; 36 | import flash.geom.Rectangle; 37 | 38 | public class SliderBehavior extends EventDispatcher implements ISlider 39 | { 40 | public static const HORIZONTAL:String = "horizontal"; 41 | public static const VERTICAL:String = "vertical"; 42 | public static const DRAGGER:String = "dragger"; 43 | public static const TRACK:String = "track"; 44 | 45 | private var target:Sprite; 46 | protected var dragger:Sprite; 47 | protected var track:Sprite; 48 | protected var _backClick:Boolean = true; 49 | protected var _value:Number = 0; 50 | protected var _max:Number = 100; 51 | protected var _min:Number = 0; 52 | protected var _orientation:String; 53 | //protected var _tick:Number = 1; 54 | //protected var _numTics:Number = 48; //total width of images / 480, rounded up. 55 | 56 | public function SliderBehavior(target:Sprite) 57 | { 58 | 59 | _orientation = HORIZONTAL; 60 | 61 | if (target is ISlider && target is Sprite) 62 | { 63 | this.target = target; 64 | } 65 | else 66 | { 67 | throw new Error("Target must implement ISlider and be a Sprite") 68 | } 69 | init(); 70 | } 71 | 72 | /** 73 | * Initializes the component. 74 | */ 75 | protected function init():void 76 | { 77 | 78 | dragger = target.getChildByName(DRAGGER) as Sprite; 79 | dragger.addEventListener(MouseEvent.MOUSE_DOWN, onDrag); 80 | 81 | track = target.getChildByName(TRACK) as Sprite; 82 | if (_backClick) 83 | { 84 | track.addEventListener(MouseEvent.MOUSE_DOWN, onBackClick); 85 | } 86 | else 87 | { 88 | track.removeEventListener(MouseEvent.MOUSE_DOWN, onBackClick); 89 | } 90 | } 91 | 92 | /** 93 | * Find position of nearest tick 94 | */ 95 | protected function nearestTick(tl:Number, nt:Number, rp:Number):Number 96 | { 97 | return (tl/nt)*Math.round(nt*rp/tl); 98 | } 99 | 100 | /** 101 | * Adjusts value to be within minimum and maximum. 102 | */ 103 | protected function correctValue():void 104 | { 105 | if (_max > _min) 106 | { 107 | _value = Math.min(_value, _max); 108 | _value = Math.max(_value, _min); 109 | } 110 | else 111 | { 112 | _value = Math.max(_value, _max); 113 | _value = Math.min(_value, _min); 114 | } 115 | } 116 | 117 | /** 118 | * Adjusts position of handle when value, maximum or minimum have changed. 119 | */ 120 | public function refresh():void 121 | { 122 | var range:Number; 123 | if (_orientation == HORIZONTAL) 124 | { 125 | range = track.width - dragger.width; 126 | dragger.x = (_value - _min) / (_max - _min) * range; 127 | } 128 | else 129 | { 130 | range = track.height - dragger.height; 131 | dragger.y = track.height - track.width - (_value - _min) / (_max - _min) * range; 132 | } 133 | } 134 | 135 | /////////////////////////////////// 136 | // event handlers 137 | /////////////////////////////////// 138 | 139 | /** 140 | * Handler called when user clicks the background of the slider, causing the handle to move to that point. Only active if backClick is true. 141 | * @param event The MouseEvent passed by the system. 142 | */ 143 | protected function onBackClick(event:MouseEvent):void 144 | { 145 | if (_orientation == HORIZONTAL) 146 | { 147 | dragger.x = target.mouseX - dragger.width / 2; 148 | dragger.x = Math.max(dragger.x, 0); 149 | dragger.x = Math.min(dragger.x, track.width - dragger.width); 150 | if(ticks > 0) 151 | { 152 | //this next line has a hilarious effect. 153 | dragger.x = nearestTick(track.width - dragger.width, ticks, dragger.x); 154 | } 155 | _value = dragger.x / (track.width - dragger.width) * (_max - _min) + _min; 156 | } 157 | else 158 | { 159 | dragger.y = target.mouseY - dragger.height / 2; 160 | dragger.y = Math.max(dragger.y, 0); 161 | dragger.y = Math.min(dragger.y, track.height - dragger.height); 162 | _value = (track.height - dragger.height - dragger.y) / (track.height - dragger.height) * (_max - _min) + _min; 163 | } 164 | dispatchEvent(new Event(Event.CHANGE)); 165 | 166 | } 167 | 168 | /** 169 | * Internal mouseDown handler. Starts dragging the handle. 170 | * @param event The MouseEvent passed by the system. 171 | */ 172 | protected function onDrag(event:MouseEvent):void 173 | { 174 | target.stage.addEventListener(MouseEvent.MOUSE_UP, onDrop); 175 | target.stage.addEventListener(MouseEvent.MOUSE_MOVE, onSlide); 176 | if (_orientation == HORIZONTAL) 177 | { 178 | dragger.startDrag(false, new Rectangle(0, 0, track.width - dragger.width, 0)); 179 | } 180 | else 181 | { 182 | dragger.startDrag(false, new Rectangle(0, 0, 0, track.height - dragger.height)); 183 | } 184 | } 185 | 186 | /** 187 | * Internal mouseUp handler. Stops dragging the handle. 188 | * @param event The MouseEvent passed by the system. 189 | */ 190 | protected function onDrop(event:MouseEvent):void 191 | { 192 | target.stage.removeEventListener(MouseEvent.MOUSE_UP, onDrop); 193 | target.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onSlide); 194 | 195 | if(ticks > 0) 196 | { 197 | var oldValue:Number = _value; 198 | if (_orientation == HORIZONTAL) 199 | { 200 | //this next line has a hilarious effect. 201 | dragger.x = nearestTick(track.width - dragger.width, ticks, dragger.x); 202 | _value = dragger.x / (track.width - dragger.width) * (_max - _min) + _min; 203 | } 204 | else 205 | { 206 | // _value = (track.height - dragger.height - dragger.y) / (track.height - dragger.height) * (_max - _min) + _min; 207 | } 208 | if (_value != oldValue) 209 | { 210 | dispatchEvent(new Event(Event.CHANGE)); 211 | } 212 | } 213 | 214 | target.stopDrag(); 215 | } 216 | 217 | /** 218 | * Internal mouseMove handler for when the handle is being moved. 219 | * @param event The MouseEvent passed by the system. 220 | */ 221 | protected function onSlide(event:MouseEvent):void 222 | { 223 | var oldValue:Number = _value; 224 | if (_orientation == HORIZONTAL) 225 | { 226 | _value = dragger.x / (track.width - dragger.width) * (_max - _min) + _min; 227 | } 228 | else 229 | { 230 | _value = (track.height - dragger.height - dragger.y) / (track.height - dragger.height) * (_max - _min) + _min; 231 | } 232 | if (_value != oldValue) 233 | { 234 | dispatchEvent(new Event(Event.CHANGE)); 235 | } 236 | } 237 | 238 | 239 | /////////////////////////////////// 240 | // getter/setters 241 | /////////////////////////////////// 242 | 243 | /** 244 | * Sets / gets whether or not a click on the background of the slider will move the handler to that position. 245 | */ 246 | public function set backClick(b:Boolean):void 247 | { 248 | _backClick = b; 249 | } 250 | 251 | public function get backClick():Boolean 252 | { 253 | return _backClick; 254 | } 255 | 256 | /** 257 | * Sets / gets the current value of this slider. 258 | */ 259 | public function set value(v:Number):void 260 | { 261 | _value = v; 262 | 263 | correctValue(); 264 | refresh(); 265 | 266 | } 267 | 268 | public function get value():Number 269 | { 270 | return _value;//( / _tick) * _tick; 271 | } 272 | 273 | /** 274 | * Gets / sets the maximum value of this slider. 275 | */ 276 | public function set maximum(m:Number):void 277 | { 278 | _max = m; 279 | correctValue(); 280 | refresh(); 281 | } 282 | 283 | public function get maximum():Number 284 | { 285 | return _max; 286 | } 287 | 288 | /** 289 | * Gets / sets the minimum value of this slider. 290 | */ 291 | public function set minimum(m:Number):void 292 | { 293 | _min = m; 294 | correctValue(); 295 | refresh(); 296 | } 297 | 298 | public function get minimum():Number 299 | { 300 | return _min; 301 | } 302 | 303 | /** 304 | * Gets / sets the tick value of this slider. This round the value to the nearest multiple of this number. 305 | */ 306 | /*public function set tick(t:Number):void 307 | { 308 | _tick = t; 309 | } 310 | 311 | public function get tick():Number 312 | { 313 | return _tick; 314 | }*/ 315 | 316 | public function get ticks():Number 317 | { 318 | return ISlider(target).ticks; 319 | } 320 | } 321 | } -------------------------------------------------------------------------------- /src/com/flashartofwar/ui/Slider.as: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Original Author: Jesse Freeman of FlashArtOfWar.com 5 | * Copyright (c) 2010 6 | * Class File: Slider.as 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | package com.flashartofwar.ui 28 | { 29 | import com.flashartofwar.behaviors.ISlider; 30 | import com.flashartofwar.behaviors.SliderBehavior; 31 | 32 | import flash.display.Sprite; 33 | import flash.events.Event; 34 | import flash.filters.DropShadowFilter; 35 | import flash.geom.Rectangle; 36 | 37 | public class Slider extends Sprite implements ISlider 38 | { 39 | 40 | private var behavior:SliderBehavior; 41 | private var track:Sprite; 42 | private var dragger:Sprite; 43 | private var _width:Number; 44 | private var _height:Number; 45 | private var draggerWidth:Number; 46 | private var roundedCorners:Number; 47 | private var maskShape:Sprite; 48 | private var _ticks:Number; 49 | 50 | public function Slider(width:Number = 100, height:Number = 10, draggerWidth:Number = 40, roundedCorners:Number = 5, ticks:Number = 10) 51 | { 52 | _width = width; 53 | _height = height; 54 | this.ticks = ticks; 55 | this.draggerWidth = draggerWidth; 56 | this.roundedCorners = roundedCorners; 57 | init(); 58 | } 59 | 60 | override public function set width(value:Number):void 61 | { 62 | track.width = mask.width = Math.round(value); 63 | if (behavior) behavior.refresh(); 64 | } 65 | 66 | override public function set height(value:Number):void 67 | { 68 | track.height = mask.height = Math.round(value); 69 | if (behavior) behavior.refresh(); 70 | } 71 | 72 | public function get value():Number 73 | { 74 | return behavior.value; 75 | } 76 | 77 | public function set value(value:Number):void 78 | { 79 | behavior.value = value; 80 | } 81 | 82 | private function init():void 83 | { 84 | track = addChild(createTrack()) as Sprite; 85 | dragger = addChild(createDragger()) as Sprite; 86 | 87 | maskShape = createTrack(); 88 | addChild(maskShape); 89 | mask = maskShape; 90 | 91 | addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 92 | } 93 | 94 | private function onAddedToStage(event:Event):void 95 | { 96 | behavior = new SliderBehavior(this); 97 | behavior.addEventListener(Event.CHANGE, onValueChange); 98 | removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 99 | addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage); 100 | } 101 | 102 | private function onValueChange(event:Event):void 103 | { 104 | dispatchEvent(event); 105 | } 106 | 107 | private function onRemovedFromStage(event:Event):void 108 | { 109 | addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 110 | removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage); 111 | } 112 | 113 | private function createDragger():Sprite 114 | { 115 | var sprite:Sprite = new Sprite(); 116 | sprite.name = SliderBehavior.DRAGGER; 117 | sprite.graphics.beginFill(0xffffff); 118 | sprite.graphics.drawRoundRect(0, 0, draggerWidth, _height, roundedCorners); 119 | sprite.graphics.endFill(); 120 | sprite.graphics.lineStyle(2, 0x666666, .6); 121 | 122 | sprite.graphics.moveTo(draggerWidth/2 , 2); 123 | sprite.graphics.lineTo(draggerWidth/2, _height - 2); 124 | 125 | sprite.graphics.moveTo(draggerWidth/2 + 3, 2); 126 | sprite.graphics.lineTo(draggerWidth/2 + 3, _height - 2); 127 | 128 | sprite.graphics.moveTo(draggerWidth/2 - 3, 2); 129 | sprite.graphics.lineTo(draggerWidth/2 - 3, _height - 2); 130 | 131 | sprite.buttonMode = true; 132 | sprite.useHandCursor = true; 133 | 134 | var dropShadow:DropShadowFilter = new DropShadowFilter(); 135 | dropShadow.color = 0x000000; 136 | dropShadow.blurX = 40; 137 | dropShadow.strength = 1; 138 | dropShadow.alpha = .7; 139 | dropShadow.distance = 0; 140 | 141 | var filtersArray:Array = new Array(dropShadow); 142 | sprite.filters = filtersArray; 143 | 144 | return sprite; 145 | } 146 | 147 | private function createTrack():Sprite 148 | { 149 | var sprite:Sprite = new Sprite(); 150 | sprite.name = SliderBehavior.TRACK; 151 | sprite.graphics.beginFill(0x000000, .4); 152 | sprite.graphics.drawRoundRect(0, 0, _width, _height, roundedCorners); 153 | sprite.graphics.endFill(); 154 | sprite.scale9Grid = new Rectangle(roundedCorners+2, _height/2 + 2, _width - (roundedCorners * 2 + 4), 2); 155 | 156 | /*if(ticks > 0) 157 | { 158 | var i:int; 159 | var tickWidth:int = _width / ticks; 160 | 161 | for (i = 0; i < ticks; ++i) 162 | { 163 | sprite.graphics.beginFill(0x10ffffff, i%2 * .3); 164 | sprite.graphics.drawRect(tickWidth * i, 0, tickWidth, _height); 165 | sprite.graphics.endFill(); 166 | } 167 | }*/ 168 | 169 | return sprite; 170 | } 171 | 172 | public function get ticks():Number 173 | { 174 | return _ticks; 175 | } 176 | 177 | public function set ticks(value:Number):void 178 | { 179 | _ticks = value < 0 ? 0 : value; 180 | } 181 | 182 | public function get currentTick():Number 183 | { 184 | return (value / _ticks) * _ticks; 185 | } 186 | } 187 | } 188 | 189 | -------------------------------------------------------------------------------- /src/net/hires/debug/Stats.as: -------------------------------------------------------------------------------- 1 | /** 2 | * Stats 3 | * 4 | * Released under MIT license: 5 | * http://www.opensource.org/licenses/mit-license.php 6 | * 7 | * How to use: 8 | * 9 | * addChild( new Stats() ); 10 | * 11 | * or 12 | * 13 | * addChild( new Stats( { bg: 0xffffff } ); 14 | * 15 | * version log: 16 | * 17 | * 09.10.22 2.2 Mr.doob + FlipX of graph to be more logic. 18 | * + Destroy on Event.REMOVED_FROM_STAGE (thx joshtynjala) 19 | * 09.03.28 2.1 Mr.doob + Theme support. 20 | * 09.02.21 2.0 Mr.doob + Removed Player version, until I know if it's really needed. 21 | * + Added MAX value (shows Max memory used, useful to spot memory leaks) 22 | * + Reworked text system / no memory leak (original reason unknown) 23 | * + Simplified 24 | * 09.02.07 1.5 Mr.doob + onRemovedFromStage() (thx huihuicn.xu) 25 | * 08.12.14 1.4 Mr.doob + Code optimisations and version info on MOUSE_OVER 26 | * 08.07.12 1.3 Mr.doob + Some speed and code optimisations 27 | * 08.02.15 1.2 Mr.doob + Class renamed to Stats (previously FPS) 28 | * 08.01.05 1.2 Mr.doob + Click changes the fps of flash (half up increases, half down decreases) 29 | * 08.01.04 1.1 Mr.doob + Shameless ripoff of Alternativa's FPS look :P 30 | * Theo + Log shape for MEM 31 | * + More room for MS 32 | * 07.12.13 1.0 Mr.doob + First version 33 | **/ 34 | 35 | package net.hires.debug 36 | { 37 | import flash.display.Bitmap; 38 | import flash.display.BitmapData; 39 | import flash.display.Sprite; 40 | import flash.events.Event; 41 | import flash.events.MouseEvent; 42 | import flash.geom.Rectangle; 43 | import flash.system.System; 44 | import flash.text.StyleSheet; 45 | import flash.text.TextField; 46 | import flash.utils.getTimer; 47 | 48 | public class Stats extends Sprite 49 | { 50 | protected const WIDTH:uint = 70; 51 | protected const HEIGHT:uint = 100; 52 | 53 | protected var xml:XML; 54 | 55 | protected var text:TextField; 56 | protected var style:StyleSheet; 57 | 58 | protected var timer:uint; 59 | protected var fps:uint; 60 | protected var ms:uint; 61 | protected var ms_prev:uint; 62 | protected var mem:Number; 63 | protected var mem_max:Number; 64 | 65 | protected var graph:Bitmap; 66 | protected var rectangle:Rectangle; 67 | 68 | protected var fps_graph:uint; 69 | protected var mem_graph:uint; 70 | protected var mem_max_graph:uint; 71 | 72 | protected var theme:Object = { bg: 0x000033, fps: 0xffff00, ms: 0x00ff00, mem: 0x00ffff, memmax: 0xff0070 }; 73 | 74 | /** 75 | * Stats FPS, MS and MEM, all in one. 76 | * 77 | * @param _theme Example: { bg: 0x202020, fps: 0xC0C0C0, ms: 0x505050, mem: 0x707070, memmax: 0xA0A0A0 } 78 | */ 79 | public function Stats(_theme:Object = null):void 80 | { 81 | if (_theme) 82 | { 83 | if (_theme.bg != null) theme.bg = _theme.bg; 84 | if (_theme.fps != null) theme.fps = _theme.fps; 85 | if (_theme.ms != null) theme.ms = _theme.ms; 86 | if (_theme.mem != null) theme.mem = _theme.mem; 87 | if (_theme.memmax != null) theme.memmax = _theme.memmax; 88 | } 89 | 90 | mem_max = 0; 91 | 92 | xml = 93 | FPS: 94 | MS: 95 | MEM: 96 | MAX: 97 | ; 98 | 99 | style = new StyleSheet(); 100 | style.setStyle("xml", {fontSize:'9px', fontFamily:'_sans', leading:'-2px'}); 101 | style.setStyle("fps", {color: hex2css(theme.fps)}); 102 | style.setStyle("ms", {color: hex2css(theme.ms)}); 103 | style.setStyle("mem", {color: hex2css(theme.mem)}); 104 | style.setStyle("memMax", {color: hex2css(theme.memmax)}); 105 | 106 | text = new TextField(); 107 | text.width = WIDTH; 108 | text.height = 50; 109 | text.styleSheet = style; 110 | text.condenseWhite = true; 111 | text.selectable = false; 112 | text.mouseEnabled = false; 113 | 114 | graph = new Bitmap(); 115 | graph.y = 50; 116 | 117 | rectangle = new Rectangle(WIDTH - 1, 0, 1, HEIGHT - 50); 118 | 119 | addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true); 120 | addEventListener(Event.REMOVED_FROM_STAGE, destroy, false, 0, true); 121 | } 122 | 123 | private function init(e:Event):void 124 | { 125 | graphics.beginFill(theme.bg); 126 | graphics.drawRect(0, 0, WIDTH, HEIGHT); 127 | graphics.endFill(); 128 | 129 | addChild(text); 130 | 131 | graph.bitmapData = new BitmapData(WIDTH, HEIGHT - 50, false, theme.bg); 132 | addChild(graph); 133 | 134 | addEventListener(MouseEvent.CLICK, onClick); 135 | addEventListener(Event.ENTER_FRAME, update); 136 | } 137 | 138 | private function destroy(e:Event):void 139 | { 140 | graphics.clear(); 141 | 142 | while (numChildren > 0) 143 | removeChildAt(0); 144 | 145 | graph.bitmapData.dispose(); 146 | 147 | removeEventListener(MouseEvent.CLICK, onClick); 148 | removeEventListener(Event.ENTER_FRAME, update); 149 | } 150 | 151 | private function update(e:Event):void 152 | { 153 | timer = getTimer(); 154 | 155 | if (timer - 1000 > ms_prev) 156 | { 157 | ms_prev = timer; 158 | mem = Number((System.totalMemory * 0.000000954).toFixed(3)); 159 | mem_max = mem_max > mem ? mem_max : mem; 160 | 161 | fps_graph = Math.min(graph.height, ( fps / stage.frameRate ) * graph.height); 162 | mem_graph = Math.min(graph.height, Math.sqrt(Math.sqrt(mem * 5000))) - 2; 163 | mem_max_graph = Math.min(graph.height, Math.sqrt(Math.sqrt(mem_max * 5000))) - 2; 164 | 165 | graph.bitmapData.scroll(-1, 0); 166 | 167 | graph.bitmapData.fillRect(rectangle, theme.bg); 168 | graph.bitmapData.setPixel(graph.width - 1, graph.height - fps_graph, theme.fps); 169 | graph.bitmapData.setPixel(graph.width - 1, graph.height - ( ( timer - ms ) >> 1 ), theme.ms); 170 | graph.bitmapData.setPixel(graph.width - 1, graph.height - mem_graph, theme.mem); 171 | graph.bitmapData.setPixel(graph.width - 1, graph.height - mem_max_graph, theme.memmax); 172 | 173 | xml.fps = "FPS: " + fps + " / " + stage.frameRate; 174 | xml.mem = "MEM: " + mem; 175 | xml.memMax = "MAX: " + mem_max; 176 | 177 | fps = 0; 178 | } 179 | 180 | fps++; 181 | 182 | xml.ms = "MS: " + (timer - ms); 183 | ms = timer; 184 | 185 | text.htmlText = xml; 186 | } 187 | 188 | private function onClick(e:MouseEvent):void 189 | { 190 | mouseY / height > .5 ? stage.frameRate-- : stage.frameRate++; 191 | xml.fps = "FPS: " + fps + " / " + stage.frameRate; 192 | text.htmlText = xml; 193 | } 194 | 195 | // .. Utils 196 | 197 | private function hex2css(color:int):String 198 | { 199 | return "#" + color.toString(16); 200 | } 201 | } 202 | } -------------------------------------------------------------------------------- /test/BitmapScrollerAppTestApp.mxml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /test/BitmapScrollerTestSuite.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | 4 | import com.flashartofwar.BitmapScrollerTest; 5 | 6 | [Suite] 7 | 8 | [RunWith("org.flexunit.runners.Suite")] 9 | 10 | public class BitmapScrollerTestSuite 11 | { 12 | 13 | public var test1 : BitmapScrollerTest; 14 | } 15 | } -------------------------------------------------------------------------------- /test/com/flashartofwar/BitmapScrollerTest.as: -------------------------------------------------------------------------------- 1 | package com.flashartofwar 2 | { 3 | import flash.display.Bitmap; 4 | import flash.display.BitmapData; 5 | import flash.geom.Point; 6 | import flash.geom.Rectangle; 7 | 8 | import org.flexunit.Assert; 9 | 10 | /** 11 | * @author jessefreeman 12 | */ 13 | public class BitmapScrollerTest extends BitmapScroller 14 | { 15 | 16 | private const demoImageHeight:int = 680; 17 | 18 | private var demoImageWidth:int = 1023; 19 | 20 | public function BitmapScrollerTest() 21 | { 22 | var collection:Array = []; 23 | 24 | for (var i:int; i < 3; i ++) 25 | { 26 | // Create dummy images 27 | collection.push(new BitmapData(demoImageWidth, demoImageHeight, false, 0x000000)); 28 | } 29 | 30 | super(); 31 | 32 | width = 500; 33 | height = 100; 34 | bitmapDataCollection = collection; 35 | 36 | render(); 37 | 38 | } 39 | 40 | [Test] 41 | public function testTotalWidth():void 42 | { 43 | Assert.assertEquals(totalWidth, demoImageWidth * 3); 44 | } 45 | 46 | [Test] 47 | public function testMaxHeight():void 48 | { 49 | Assert.assertEquals(maxHeight, demoImageHeight); 50 | } 51 | 52 | [Test] 53 | public function test1stCollectionRect():void 54 | { 55 | var rect:Rectangle = collectionRects[0]; 56 | Assert.assertEquals(rect.toString(), "(x=0, y=0, w=" + demoImageWidth + ", h=" + demoImageHeight + ")"); 57 | 58 | } 59 | 60 | [Test] 61 | public function test2ndCollectionRect():void 62 | { 63 | var rect:Rectangle = collectionRects[1]; 64 | Assert.assertEquals(rect.toString(), "(x=" + (demoImageWidth + 1) + ", y=0, w=" + demoImageWidth + ", h=" + demoImageHeight + ")"); 65 | } 66 | 67 | [Test] 68 | public function test3rdCollectionRect():void 69 | { 70 | var rect:Rectangle = collectionRects[2]; 71 | Assert.assertEquals(rect.toString(), "(x=" + (demoImageWidth * 2 + 2) + ", y=0, w=" + demoImageWidth + ", h=" + demoImageHeight + ")"); 72 | } 73 | 74 | [Test] 75 | public function testCalculateLeftoverForInRangeSample():void 76 | { 77 | var leftover:Number = calculateLeftOverValue(0, 200, collectionRects[0]); 78 | Assert.assertEquals(leftover, 0); 79 | } 80 | 81 | [Test] 82 | public function testCalculateLeftoverForOutOfRangeSample():void 83 | { 84 | var leftover:Number = calculateLeftOverValue(0, demoImageWidth + (demoImageWidth / 2), collectionRects[0]); 85 | Assert.assertEquals(leftover, demoImageWidth / 2); 86 | } 87 | 88 | [Test] 89 | public function testCalculateStartIndex0():void 90 | { 91 | Assert.assertEquals(calculateCollectionStartIndex(new Point(0, 0)), 0); 92 | } 93 | 94 | [Test] 95 | public function testCalculateStartIndex1():void 96 | { 97 | Assert.assertEquals(calculateCollectionStartIndex(new Point(demoImageWidth + 30, 0)), 1); 98 | } 99 | 100 | [Test] 101 | public function testCalculateStartIndex2():void 102 | { 103 | Assert.assertEquals(calculateCollectionStartIndex(new Point(demoImageWidth * 2 + 30, 0)), 2); 104 | } 105 | 106 | [Test] 107 | public function testCalculateStartIndexOutOfRange1():void 108 | { 109 | Assert.assertEquals(calculateCollectionStartIndex(new Point(-500, 0)), -1); 110 | } 111 | 112 | [Test] 113 | public function testCalculateStartIndexOutOfRange2():void 114 | { 115 | Assert.assertEquals(calculateCollectionStartIndex(new Point(demoImageWidth * (_bitmapDataCollection.length + 1), 0)), -1); 116 | } 117 | 118 | [Test] 119 | public function testCalculateSamplePosition():void 120 | { 121 | var sr:Rectangle = new Rectangle(20, 0, 50, 50); 122 | var sa:Rectangle = new Rectangle(0, 0, 100, 50); 123 | 124 | var point:Point = calculateSamplePosition(sr, sa); 125 | Assert.assertEquals(point.toString(), "(x=20, y=0)"); 126 | } 127 | 128 | [Test] 129 | public function testCalculateSamplePosition2():void 130 | { 131 | var sr:Rectangle = new Rectangle(150, 0, 100, 50); 132 | var sa:Rectangle = new Rectangle(100, 0, 100, 50); 133 | 134 | var point:Point = calculateSamplePosition(sr, sa); 135 | Assert.assertEquals(point.toString(), "(x=50, y=0)"); 136 | } 137 | 138 | [Ignore] 139 | public function testExternalSampleRectIsNotModified():void 140 | { 141 | 142 | render(); 143 | 144 | Assert.assertEquals(sampleArea.toString(), "(x=0, y=0, w=500, h=100)"); 145 | } 146 | 147 | [Test] 148 | public function testCalculateCollectionStartIndexOnRectStart():void 149 | { 150 | Assert.assertEquals(calculateCollectionStartIndex(new Point(demoImageWidth + 1, 0)), 1); 151 | } 152 | 153 | } 154 | } 155 | --------------------------------------------------------------------------------