1. #1
    Sencha User
    Join Date
    May 2011
    Posts
    143
    Vote Rating
    0
    rockinthesixstring is on a distinguished road

      0  

    Default Embed Animation Within Sencha Touch App Without iFrame

    Embed Animation Within Sencha Touch App Without iFrame


    What is the best way to embed an Animation inside a Sencha Touch app without using an iFrame?

    This is what I'm trying, but unfortunately I don't see any animation.

    index-debug.html
    Code:
    <!DOCTYPE html>
    <head>
        <title></title>
    
        <!-- sencha css-->
        <link rel="stylesheet" type="text/css" href="http://cdn.sencha.io/touch/sencha-touch-2.0.0-pr1/resources/css/sencha-touch.css" />
        <!-- sencha library -->
        <script type="text/javascript" src="/lib/sencha-touch-all-debug-w-comments.js"></script>
        <!--<script type="text/javascript" src="http://cdn.sencha.io/touch/sencha-touch-2.0.0-pr1/sencha-touch-all-debug-w-comments.js"></script>-->
    
        <!-- rpc styling -->
        <link rel="stylesheet" type="text/css" href="css/site/overrides.css" />
        <link rel="stylesheet" type="text/css" href="css/site/elements.css" />
        <link rel="stylesheet" type="text/css" href="css/site/icons.css" />
        <link rel="stylesheet" type="text/css" href="css/site/containers.css" />
        <link rel="stylesheet" type="text/css" href="css/site/buttons.css" />
        <link rel="stylesheet" type="text/css" href="css/site/home-banner.css" />
    
    
        <!-- code -->
        <!-- HERE IS THE BANNER CODE-->
        <script type="text/javascript" src="app/code/home-banner.js"></script>
    
        <!-- app start -->
        <script type="text/javascript" src="app/index.js"></script>
    
        <!-- models -->
    
        <!-- stores -->
    
        <!-- partial views -->
        <script type="text/javascript" src="app/views/bible/_bibleInAYearView.js"></script>
        <script type="text/javascript" src="app/views/bible/_chapterADayView.js"></script>
    
        <!-- views -->
        <script type="text/javascript" src="app/views/home/indexView.js"></script>
        <script type="text/javascript" src="app/views/bible/indexView.js"></script>
        <script type="text/javascript" src="app/views/video/index.js"></script>
        <script type="text/javascript" src="app/views/contact/indexView.js"></script>
        <script type="text/javascript" src="app/views/more/indexView.js"></script>
    
        <!-- controllers -->
        <script type="text/javascript" src="app/controllers/homeController.js"></script>
        <script type="text/javascript" src="app/controllers/bibleController.js"></script>
        <script type="text/javascript" src="app/controllers/videoController.js"></script>
        <script type="text/javascript" src="app/controllers/contactController.js"></script>
        <script type="text/javascript" src="app/controllers/moreController.js"></script>
    
        
    </head>
    <body>
    
    </body>
    </html>
    HomeIndex View
    Code:
    Ext.define('rpc.view.home.indexView', {
        extend: 'Ext.Panel',
        alias: 'widget.home-indexView',
        config: {
            scrollable: true,
            items: [{
                xtype: 'toolbar',
                title: 'RockPointe Mobile',
                docked: 'top'
            }, {
                xtype: 'panel',
                items: [{
                   xtype: 'panel',
                   items: [{
                       html: '<div><ol id="AN-sObj-parentOl"><li id="AN-sObj-scene-0"><div class="AN-sObj-stage" id="ext-gen1760"><div class="AN-Object" id="AN-sObj-34"><div id="AN-sObj-val-34"><img src="img/banner-1.jpg"></div></div><div id="AN-sObj-35"><span>Relentlessly Focused On The Lost</span></div><div id="AN-sObj-36"><span>Passionately Devoted To God</span></div><div id="AN-sObj-37"><span>Deeply Committed To One Another</span></div></div></li></ol></div>'
                   }]
                }]
            }]
        },
        initialize: function () {
            console.log('rpc.view.home.indexView ~ initialize');
            loadHomeBanner(); // Call the Banner Load Function
            this.callParent();
        }
    });
    home-banner.css (as output by Sencha Animator)
    Code:
     #AN-sObj-scene-0 .AN-sObj-stage {
    border:0 !important;
    }
    
    .AN-sObj-stage {
     position: relative;
     overflow:hidden;
     -webkit-perspective: 600;
      }
    
     .AN-sObj-stage div {
     position: absolute;
     }
    
     .AN-sObj-stage a {
    color: inherit;
     text-decoration:none;
    }
    
     .AN-sObj-stage * {
    margin:0;
     padding:0;
     -webkit-font-smoothing: antialiased;
    }
    
     .AN-sObj-stage img {
    position: absolute;
     top:0;
     left:0;
    }
    
     body,.AN-sObj-stage,ol,li {
    margin:0;
     padding:0;
    }
    
     ol {
    list-style:none;
     position:relative;
    }
    
     li {
    position:absolute;
     top:0;
     left:0;
    }
    
     .AN-Scene-Description {
    display: none;
    }
    
     @-webkit-keyframes AN-ani-delay {
     0% {
    }
    
     100% {
    }
    
    }
    
    li {
     display:none;
     }
    
    li.run {
    display:block;
     }
    
    .restart * {
     -webkit-animation-name: none !important;
     }
    
    #AN-sObj-34{
     -webkit-transform: translate3d(0px, 0px, 0px);
    width: 600px;
    height: 150px;
    top:0;
     left:0;
     }
    
    #AN-sObj-35{
     -webkit-transform: translate3d(70px, 95px, 0px);
    width: 236px;
    height: 23px;
    top:0;
     left:0;
    font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
    font-size: 14px;
    font-weight: bold;
    text-shadow: rgba(255,255,255,0.5) 1px 1px 3px;
     }
    
    #AN-sObj-36{
     -webkit-transform: translate3d(140px, 63px, 0px);
    width: 211px;
    height: 19px;
    top:0;
     left:0;
    font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
    font-size: 14px;
    text-shadow: rgba(255,255,255,0.5) 1px 1px 3px;
    font-weight: bold;
     }
    
    #AN-sObj-37{
     -webkit-transform: translate3d(35px, 29px, 0px);
    width: 257px;
    height: 19px;
    top:0;
     left:0;
    font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
    font-size: 14px;
    font-weight: bold;
    text-shadow: rgba(255,255,255,0.5) 1px 1px 3px;
     }
    
     #AN-sObj-scene-0 .AN-sObj-stage {
    height: 150px;
    width: 600px;
    background-color: rgba(255,255,255,1);
    border:1px solid rgba(10,10,10,1);
    }
    
    @-webkit-keyframes AN-ani-38 {
    0% {
    -webkit-transform: translate3d(70px, 95px, 0px);
    opacity: 0;
    }
    81.9% {
    -webkit-transform: translate3d(70px, 95px, 0px);
    opacity: 0;
    }
    100% {
    -webkit-transform: translate3d(70px, 95px, 0px);
    opacity: 1;
    }
    }
    
    .run #AN-sObj-35 {
    -webkit-animation-name: AN-ani-38;
    -webkit-animation-duration: 11.170238095238094s;
    -webkit-animation-delay: 0s;
    -webkit-animation-fill-mode: both;
    }
    .restart #AN-sObj-35 {
    -webkit-transform: translate3d(70px, 95px, 0px);
    opacity: 0;
    }
    @-webkit-keyframes AN-ani-39 {
    0% {
    -webkit-transform: translate3d(140px, 63px, 0px);
    opacity: 0;
    }
    72.02% {
    -webkit-transform: translate3d(140px, 63px, 0px);
    opacity: 0;
    }
    100% {
    -webkit-transform: translate3d(140px, 63px, 0px);
    opacity: 1;
    }
    }
    
    .run #AN-sObj-36 {
    -webkit-animation-name: AN-ani-39;
    -webkit-animation-duration: 7.166883116883118s;
    -webkit-animation-delay: 0s;
    -webkit-animation-fill-mode: both;
    }
    .restart #AN-sObj-36 {
    -webkit-transform: translate3d(140px, 63px, 0px);
    opacity: 0;
    }
    @-webkit-keyframes AN-ani-40 {
    0% {
    -webkit-transform: translate3d(35px, 29px, 0px);
    opacity:0;
    -webkit-transform-origin: 50% 50%;
    }
    0.01% {
    -webkit-transform: translate3d(35px, 29px, 0px);
    opacity: 0;
    -webkit-transform-origin: 50% 50%;
    }
    100% {
    -webkit-transform: translate3d(35px, 29px, 0px);
    opacity: 1;
    -webkit-transform-origin: 50% 50%;
    }
    }
    
    .run #AN-sObj-37 {
    -webkit-animation-name: AN-ani-40;
    -webkit-animation-duration: 1.9545454545454553s;
    -webkit-animation-delay: 1.2s;
    -webkit-animation-fill-mode: both;
    }
    .restart #AN-sObj-37 {
    -webkit-transform: translate3d(35px, 29px, 0px);
    opacity: 0;
    -webkit-transform-origin: 50% 50%;
    }
    home-banner.js (as output by Animator)
    Code:
    function loadHomeBanner(){
        console.log('Loading Home Banner');
    
    if (typeof(AN) === 'undefined') {
       AN = {};
    }
    AN.Controller = {
    
        scenes: {},
        scenesArray: [],
        currentSceneID: -1,
        olElement: null,
        clickEvents: {},
        useOrmma: false,
    
        setConfig: function(configData) {
    
            this.clickEvents = configData.clickEvents
    
            this.olElement = document.getElementById(configData.parentId);
            var liElements = this.olElement.children;
    
            if (configData.ormma) {
                this.useOrmma = true;
            }
    
            var scene;
            for (var i=0; i < configData.scenes.length; i++) {
                scene = configData.scenes[i];
                scene.element = liElements[i];
                this.scenes[scene.id] = scene;
                this.scenesArray.push(scene);
            }
    
            this.setupListeners();
    
            this.startSceneByID(this.scenesArray[0].id);
    
    
    
        },
    
    
        runningAnimationCount: 0,
    
        setupListeners: function() {
            var me = this;
    
            this.olElement.addEventListener('webkitAnimationStart', function() {
    
            },false);
    
            this.olElement.addEventListener('webkitAnimationEnd', function() {
                me.onAnimationEnd();
            },false);
    
            function addMousemoveListenerTo(scene) {
                scene.element.addEventListener('mousemove', function(event){
                    scene.mousemoveAction(me, event);
                }, false);
            }
    
            var scene;
            for (var i=0; i < this.scenesArray.length; i++) {
                scene = this.scenesArray[i];
                if (scene.mousemoveAction) {
    
                    addMousemoveListenerTo(scene);
                }
            }
    
            function addListenerTo(element, event, aFunction) {
                element.addEventListener(event, function(event){
                    aFunction(me,event);
                }, false);
            }
    
            //add click events
            var element, clickEvent;
            for (var i=0; i < this.clickEvents.length; i++) {
                clickEvent = this.clickEvents[i];
                element = document.getElementById(clickEvent.id);
                addListenerTo(element, 'click', clickEvent.handler);
            }
    
        },
    
    
        onAnimationEnd: function() {
    
            this.runningAnimationCount--;
    
            if (this.runningAnimationCount === 0) {
                this.onSceneFinish();
            }
    
        },
    
        startSceneByID: function(sceneID) {
    
            var me = this;
    
            //restart current scene without flicker
            if (sceneID === this.currentSceneID) {
                this.scenes[sceneID].element.setAttribute('class','run restart');
    
                setTimeout(function(){
    
                    me.runningAnimationCount = me.scenes[sceneID].animationCount;
                    me.scenes[sceneID].element.setAttribute('class','run');
    
                    if (me.scenes[sceneID].startAction) {
                        me.scenes[sceneID].startAction(me);
                    }
                    if (me.scenes[sceneID].animationCount === 0 ) {
                        me.onSceneFinish();
                    }
    
                    },0);
                return;
            } else if (this.currentSceneID !== -1) {
                this.scenes[this.currentSceneID].element.setAttribute('class','');
            }
    
            this.runningAnimationCount = this.scenes[sceneID].animationCount;
    
            this.currentSceneID = sceneID;
            var nextScene = this.scenes[sceneID];
            nextScene.element.setAttribute('class','run');
    
    
            if (this.useOrmma) {
    
               this.ormmaNextScene(nextScene);
            }
    
    
            if (nextScene.startAction) {
                nextScene.startAction(this);
            }
            if (nextScene.animationCount === 0 ) {
                this.onSceneFinish();
            }
    
    
        },
    
        replayScene: function() {
            this.startSceneByID(this.currentSceneID);
        },
    
        onSceneFinish: function() {
    
            if (this.scenes[this.currentSceneID].endAction) {
                this.scenes[this.currentSceneID].endAction(this);
            }
    
        },
    
        goToNextScene: function() {
            var nextIndex = this.scenesArray.indexOf(this.scenes[this.currentSceneID]) + 1;
            var nextScene;
            if (nextScene = this.scenesArray[nextIndex]) {
                this.startSceneByID(nextScene.id);
            }
        },
    
        goToURL: function(aURL) {
            document.location.href = aURL;
        },
    
        ormmaNextScene: function(nextScene) {
            var currentState = ormma.getState();
    
            if (nextScene.dimensions.expanded) {
                //expanded state
                //check if we're expanded
                var maxSize = ormma.getMaxSize()
                if (currentState !== 'expanded') {
                    ormma.expand({
                        x:0,
                        y:0,
                        width: maxSize.width,
                        height: maxSize.height
                    })
                }
    
                var transform = "";
                var elementHeight = nextScene.element.offsetHeight;
                var elementWidth = nextScene.element.offsetWidth;
                var y = (maxSize.height - elementHeight) / 2;
                var x = (maxSize.width - elementWidth) / 2;
                transform += " translate3d("+Math.round(x)+"px,"+Math.round(y)+"px,0)";
    
    
                if (nextScene.dimensions.fit) {
                    var scaleFactor = Math.min(maxSize.width/elementWidth, maxSize.height/elementHeight);
                    transform += " scale3d("+scaleFactor+","+scaleFactor+",1)";
                }
                nextScene.element.style.webkitTransform = transform;
    
            } else {
    
                if (currentState === 'expanded') {
                    ormma.close();
                }
                ormma.resize(nextScene.dimensions.width,nextScene.dimensions.height);
            }
    
    
        }
    
    }
    
    
    
    
    window.addEventListener('load', function(){
        var configData = {
            parentId: 'AN-sObj-parentOl',
            ormma: false,
            scenes: [{id: 0,animationCount: 3,duration: 11170.238095238094,dimensions: {height: 150,width: 600,expanded: false,fit: false},startAction: function(controller,event) {
    //set your scene dimensions
    var sceneWidth = 600;
    var sceneHeight = 150;
    
    //get container for all scenes
    var scenesContainer = document.querySelector('#AN-sObj-parentOl');
    
    //get the parent of the scene container and it's size
    var parentElement = scenesContainer.parentElement;
    var pageWidth = parentElement.clientWidth;
    var pageHeight = parentElement.clientHeight;
    
    //calculate the scaling factor
    var scaleFactor = Math.min(pageWidth/sceneWidth, pageHeight/sceneHeight);
    var transform = " scale3d("+scaleFactor+", "+scaleFactor+", 1)";
    
    //apply the scaling
    scenesContainer.style.webkitTransformOrigin = "0 0";
    scenesContainer.style.webkitTransform = transform;
    
    }}],
            clickEvents: []
        };
        AN.Controller.setConfig(configData);
    }, false);
    };

  2. #2
    Sencha User arnebech's Avatar
    Join Date
    Jun 2010
    Posts
    498
    Vote Rating
    10
    arnebech will become famous soon enough

      0  

    Default


    Normally the animation listens for the window load event, but since you put it into a function that your are calling after the window load event the animation will never initialize.

    so you could try moving out of the load event e.g. something like this
    Code:
    //this is what you have at the end of your home-banner.js
    window.addEventListener('load', function(){
         var configData = {.....};
         AN.Controller.setConfig(configData);
    },false);
    
    
    //try removing the listener wrapper
    //so you end up with something like this     
    var configData = {.....};
    AN.Controller.setConfig(configData);

  3. #3
    Sencha User
    Join Date
    May 2011
    Posts
    143
    Vote Rating
    0
    rockinthesixstring is on a distinguished road

      0  

    Default


    Quote Originally Posted by arnebech View Post
    Normally the animation listens for the window load event, but since you put it into a function that your are calling after the window load event the animation will never initialize.

    so you could try moving out of the load event e.g. something like this
    Code:
    //this is what you have at the end of your home-banner.js
    window.addEventListener('load', function(){
         var configData = {.....};
         AN.Controller.setConfig(configData);
    },false);
    
    
    //try removing the listener wrapper
    //so you end up with something like this     
    var configData = {.....};
    AN.Controller.setConfig(configData);
    Now since I'm calling it from the `initialize` method, it's being called before the html section is rendered. What are the other methods other than initialize? I'm looking in the docs, but am not being very successful.

    Code:
    Ext.define('rpc.view.home.indexView', {
        extend: 'Ext.Panel',
        alias: 'widget.home-indexView',
        config: {},
        initialize: function () {
            loadHomeBanner();
        }
    });

  4. #4
    Sencha User
    Join Date
    May 2011
    Posts
    143
    Vote Rating
    0
    rockinthesixstring is on a distinguished road

      0  

    Default


    Sorry, this part of the question probably belongs in the ST2 forum.

  5. #5
    Sencha User
    Join Date
    May 2011
    Posts
    143
    Vote Rating
    0
    rockinthesixstring is on a distinguished road

      0  

    Default


    Your answers worked as needed. Now all I need to do is figure out how to execute the function after the DOM is painted. Working through it in the ST2 forum.

  6. #6
    Sencha User arnebech's Avatar
    Join Date
    Jun 2010
    Posts
    498
    Vote Rating
    10
    arnebech will become famous soon enough

      0  

    Default


    Sounds good. When you figure it out, feel free to post that tidbit here so other forum users can benefit from it as well. Thanks.

  7. #7
    Sencha User
    Join Date
    Nov 2011
    Posts
    14
    Vote Rating
    0
    rayman1900 is on a distinguished road

      0  

    Cool I found the solution to your problem

    I found the solution to your problem


    I was able to control the animation by doing this:

    Code:
    items: [			{
    				xtype:'panel',
    				id:'square',
    				fullscreen:true,
    				html:'<ol id="AN-sObj-parentOl"><li id="AN-sObj-scene-0"><div class="AN-sObj-stage" id="ext-gen3864"><div id="AN-sObj-5"></div></div></li></ol>',
    				listeners:{
    					afterRender:function(){
    						
    						var configData = {
    					        parentId: 'AN-sObj-parentOl',
    					        ormma: false,
    					        scenes: [{id: 0,animationCount: 1,duration: 4256.753246753247,dimensions: {height: 248,width: 300,expanded: false,fit: false}}],
    					        clickEvents: []
    					    };
    					    AN.Controller.setConfig(configData);	
    						
    					}
    				},
    				items:[
    				{
    					xtype:'button',
    					listeners:{
    						el:{
    							tap:function(){
    							AN.Controller.replayScene();
    							
    							}
    						}
    					}
    					
    				}
    				],

    ----So as you can see, no need to encapsulate your export js file into a loadHomeBanner() founction.

    What you can do is to implement the configData variable with all his content into a listeners that listen when the panel has finished rendering, then call your variable configData, and voila !

    Then if you want, like proposed in my code, you can create inside that panel a button and listen for a tap that will trigger one of the function linked to the animation, like the replayScene() function !

    Hope this code will come handy for all those people who want to insert their animations without an iframe tag !

    Sincerely, I was excited to try this software, but I found so little documentation on the sencha animator help page regarding alternatives to import your animation into sencha's other products, like sencha touch or Ext.js...this is a great letdown for me...

    Well, better share my knowledge with other sencha devs, since there is almost no documentation available on this kind of problem... Enjoy

    Best regards,
    Ray


  8. #8
    Sencha User
    Join Date
    May 2011
    Posts
    143
    Vote Rating
    0
    rockinthesixstring is on a distinguished road

      0  

    Exclamation


    Thanks Ray
    I've already got a similar bit working, however my problem lies in the fact that I cannot get the width to change properly.

    If I go from portrait to landscape, then my 100% width animation expands to fill the screen properly.

    If I go from landscape to portrait, then my 100% width animation stays the width of landscape mode... thus leaving all of the rest of the objects in the view to overflow off the right hand side of my screen.

  9. #9
    Sencha User
    Join Date
    Nov 2011
    Posts
    14
    Vote Rating
    0
    rayman1900 is on a distinguished road

      0  

    Default


    What kind of animation are you making? an ad or simply an animated image over some sort of panel ?

  10. #10
    Sencha User
    Join Date
    May 2011
    Posts
    143
    Vote Rating
    0
    rockinthesixstring is on a distinguished road

      0  

    Default


    Quote Originally Posted by rayman1900 View Post
    What kind of animation are you making? an ad or simply an animated image over some sort of panel ?
    I figured out my problem. The suggestion made to me in order to dynamically adjust the width was to use

    Code:
    var pageHeight = parentElement.clientWidth;
    After setting the smoke alarm off from my brain churning away, I changed that line to this

    Code:
    var pageWidth = Ext.viewport.getWidth();
    Works like a champ.