Jump to content

Gary Griswold

  • Posts

  • Joined

  • Last visited

Everything posted by Gary Griswold

  1. Thanks guys. The solution turned out to be easier than I imagined. My Tween needed autoKill: false. Reading your suggestions reminded me that I was using a plugin, and reading the plugin's documentation was what I needed. TweenMax.killTweensOf(window); TweenMax.to(window, 0.7, {scrollTo: { y: rect.top + window.scrollY - that.headerHeight, autoKill: false }}); I don't know if the .killTweensOf(window) is really needed. I will test that shortly.
  2. I am trying to animate scrolling of text, while the user is listening to the text being read, using the following JS with Greensock calls. document.body.addEventListener(BIBLE.SCROLL_TEXT, function(event) { var nodeId = event.detail.id; var verse = document.getElementById(nodeId); if (verse) { var rect = verse.getBoundingClientRect(); TweenMax.killTweensOf(window); TweenMax.to(window, 1.2, {scrollTo: { y: rect.top + window.scrollY - that.headerHeight}}); } }); This solution works some of the time. Actually it works almost all of the time if I change it to a TweenMax.set. The problem seems to be that text is dynamically added while scrolling occurs. Currently the program checks for the need for text to be added every 0.25 seconds. Even adding text at the end of the document is making the above animation not work. I tried to add a condition to the logic that adds text to prevent it from executing while scrolling was continuing. But, this did not improve the reliability of the animated scrolling. if (!TweenMax.isTweening(window)) { .... code that executes every 0.25 seconds, and sometimes adds text. var rootNode = document.createElement('div'); rootNode.setAttribute('id', 'top' + this.nodeId); rootNode.innerHTML = html; parent.appendChild(rootNode); } The text being added is chapters of the Bible, one chapter at a time, so it is not a small amount of text. Does anyone have any ideas? Given the complexity of the infinite scroll, and the fact that I read text from a sqlite database I don't know if I could produce a codepen. Thanks for any help.
  3. I am using TweenMax to animate the appearance and scaling of a Popup. It works fine in one view, but in another it occasionally does not appear until after the user starts to scroll the page beneath the Popup. The popup is just a div with three lines of text in three p elements. The animation of the popup is done as follows: var clickPos = String(event.detail.x) + 'px ' + String(event.detail.y) + 'px'; that.rootNode.appendChild(that.viewRoot); TweenMax.set(that.viewRoot, { scale: 0 }); TweenMax.to(that.viewRoot, 0.7, { scale: 1, transformOrigin: clickPos, immediateRender: true }); The css for the popup is as follows: #attribution { position: fixed; width: 80%; top: 10%; margin-top: 7%; margin-left: 7%; margin-right: 7%; padding: 3%; text-align: center; z-index: 200; background-color: rgba(255, 246, 233, 0.9); border-radius: 25px; border: solid; border-width: thin; box-shadow: 4px 4px 4px #777; -webkit-box-shadow: 4px 4px 4px #777; } Any ideas what could cause the delay in drawing, which sometimes occurs? When the program first starts, it will work fine, but after a while each popup does not appear unless one starts to scroll. Thanks for any help.
  4. Both of these solutions work great, but I do like using the function better, and I was able to move code that I had inside the onDrag function into the snap function. However, when I used the 'liveSnap' property as you show here, the toggle would snap instantly from one side to the other. But, when I used the 'snap' property it does glide gracefully. Thanks so much.
  5. Hi, I have written a toggle switch using draggable with the snap property set to the dimensions of the slider. For example: snap:[0,47] works just fine. But because I am developing for mobile I cannot use hardcoded dimensions. So, I have tried setting the snap after Draggable.create as follows: var drag0 = draggable[0]; drag0.snap = [drag0.minX, drag0.maxX]; But, this does not seem to work. Is there a way to make this work? P.S. This is my first code pen.
  6. Thanks Diaco. You really nailed it.
  7. Hello, I have been able to use Draggable to create a very nice slider control that controls font-size. There is one div, which is the slider bar, and another the thumb. My only problem is that I need to set a starting X position for the thumb, that is computed from the current fontSize. The math is working, except that I do not know how to get the this.minX and this.minY values before the slider is used. The documentation mentions translation.transform, but I have no idea how that would be used in my javascript code. The javascript is as follow: If needed, I will add a code pen: function startDraggable(fontSize, ptMin, ptMax) { var sampleNode = document.getElementById('sampleText'); var ptRange = ptMax - ptMin; var startPos = initialPosition(fontSize); TweenMax.set('#thumb', {x:startPos}); Draggable.create('#thumb', {type:'x', bounds:'#slider', onDrag:function() { console.log('x', this.x, this.minX, this.maxX); resizeText(this.x, this.minX, this.maxX); }}); function initialPosition(fontSize) { var slider = document.getElementById('slider'); console.log('local left', slider.offsetLeft); var bounds = slider.getBoundingClientRect(); var minX = bounds.left; var maxX = bounds.right; console.log('found bounds', minX, maxX); var x = (fontSize - ptMin) / ptRange * (maxX - minX) + minX; resizeText(x, minX, maxX); return(x); } function resizeText(x, min, max) { var size = (x - min) / (max - min) * ptRange + ptMin; sampleNode.style.fontSize = size + 'px'; } }
  8. Jonathan, Thanks so much for your input. The opacity and/or autoAlpha did help, and I also found scaleY to be better than height. The row shrinks nicely, but the rows below remain still until the row is removed, and then they jump up. The result is a little jarring. I guess the row removal looks better not animated. Thanks for the help.
  9. Thanks so much for fixing my silly error. My only excuse is that I am accustomed to strongly typed compiled languages. I still have a problem with the animation of the row being dropped. I am trying to animate the height of the one cell in the row to height: 0, and then delete the row, but the tween isn't working.
  10. I have a row (TR) in a table that contains only one cell (TD). I would like to animate change the height of the cell to zero, before removing the row. But I have not been able to get this to work. I would also do the corresponding animation when a new row is inserted. My apologies that the code-pen is not very good. It is my first try. I know this might be easier with divs, but I am using table in this application for rows and columns of data and I need the easy grouping capability that "rowspan" and "colspan" provide
  11. Hello, I am trying to get a small scrollable body of text (the table of contents) to appear starting from under the button that is clicked to present the table of contents. Then I want the table of contents to disappear by a reverse animation back under the button when the user has selected a place in the table of contents. I have a solution that partially works, but if the user has scrolled to the bottom half of the table of contents, the tween to remove the table of contents is happening twice. Or maybe it is starting, getting interrupted by something, and then finishing. This is a 'single page' mobile app. So pages of text are being removed from the DOM when the TOC is shown, and added to the DOM when the TOC is removed. I don't know if I could fit the essential ingredients into a codepen, but these are the two tween calls that I am using. Show: TweenMax.fromTo(this.rootNode, 0.7, { css: {scale:0} }, { css: {scale:1, transformOrigin:"left top"}, ease:Power4.easeOut}); Hide: TweenMax.fromTo(this.rootNode, 0.7, { css: {scale:1} }, { css: {scale:0}}); Thanks for any help you can provide.
  12. Jack, Thanks. The update() function call does help, and it seems that I need to do the Draggable create after I have added the starting content. But there is still a problem that is caused by a weakness in Cordova. It appears that Cordova is linked to the older (pre ios 8) UIWebView, not the new WKWebView. So, even using Draggable with Cordova I get the pre iOS 8 behavior of no Javascript updates and no screen painting while the view UIWebKit is scrolling. With this limitation in Cordova, I will not be able to add and remove content dynamically unless I wait till scrolling stops at the end of the viewport. The following link describes the problem with Cordova at the end of the writeup. Thanks for your help. http://developer.telerik.com/featured/scroll-event-change-ios-8-big-deal/ Gary
  13. Hello, I am developing a cordova/phonegap application for iOS and Android, and I am trying to use Draggable for scrolling to overcome some problems with iOS native scrolling in cordova. I am not seeing any movement when pressing and dragging the screen even though the onPress and onDrag are firing. I have noticed in the documentation that height must be set somewhere, but please be specific about where and with what javascript (not jquery) functions. I can verify that offsetHeight has already been set on the div you added and the value looks correct. Is there something else to set? If that is not the problem, other things that might be a cause are that I am doing an infinite scroll of text, and since the user can jump around, the Draggable is created when there is no content, because the parts being presented in the scrolling viewport are frequently deleted and other pages added. Plus as the user scrolls forward or back new pages are added to the beginning or end. To date I am seeing Draggable work with my application running under Node/Webkit, but when I move the same code to a cordova (phonegap) application nothing moves. If Draggable scrolling is known to work with Cordova, please let me know and I will try to put together a test that could be presented in codepen. Gary
  14. Hi, I have written a very basic class using the VideoLoader for a mobile application in AS3 (not Flex), and it works very well when I run it in the emulator. But, when I run it on the device, it fails with a NetStream.Play.Failed error. I am pretty new to video, any idea what could be wrong. The code, and a log of errors follows. package lib.view.student { import com.greensock.events.LoaderEvent; import com.greensock.loading.VideoLoader; import flash.display.Sprite; import flash.events.Event; import flash.utils.getTimer; public class VideoPlayerGS extends Sprite { private var _sourceURL:String; private var _video:VideoLoader; public function VideoPlayerGS(sourceURL:String) { super(); _sourceURL = sourceURL; trace('VIDEO URL', _sourceURL); addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); } private function addedToStageHandler(event:Event) : void { _video = new VideoLoader(_sourceURL, {autoPlay: true, container: this, width: stage.fullScreenWidth, height: stage.fullScreenHeight, scaleMode: 'proportionalInside', hAlign: 'center', vAlign: 'center', bgColor: 0x000000, onOpen: onOpenHandler, onInit: onInitHandler, onProgress: onProgressHandler, onComplete: onCompleteHandler, onCancel: onCancelHandler, onError: onErrorHandler, onFail: onFailHandler, onIOError: onIOErrorHandler }); _video.load(); } private function onOpenHandler(event:LoaderEvent) : void { trace('LoaderEvent', event.type, event.text, getTimer()); } private function onInitHandler(event:Event) : void { trace('InitEvent', event.type, getTimer()); } private function onProgressHandler(event:LoaderEvent) : void { //trace('ProgressEvent', event.toString(), getTimer()); } private function onCompleteHandler(event:LoaderEvent) : void { trace('CompleteEvent', event.type, event.text, getTimer()); } private function onCancelHandler(event:LoaderEvent) : void { trace('CancelEvent', event.type, event.text, getTimer()); } private function onErrorHandler(event:LoaderEvent) : void { trace('ErrorEvent', event.type, event.text, getTimer()); } private function onFailHandler(event:LoaderEvent) : void { trace('FailEvent', event.type, event.text, getTimer()); } private function onIOErrorHandler(event:LoaderEvent) : void { trace('IOErrorEvent', event.type, event.text, getTimer()); } } } The console output is as follows: [trace] VIDEO URL http://s3.amazonaws.com/ecs.media.us/Vickie_Weaving_sm.f4v [trace] LoaderEvent open 2514 [trace] InitEvent init 2952 [trace] ---- [trace] Error on VideoLoader 'loader0' (http://s3.amazonaws.com/ecs.media.us/Vickie_Weaving_sm.f4v): NetStream.Play.Failed [trace] ---- [trace] ErrorEvent error VideoLoader 'loader0' (http://s3.amazonaws.com/ecs.media.us/Vickie_Weaving_sm.f4v) > NetStream.Play.Failed 2979 [trace] FailEvent fail VideoLoader 'loader0' (http://s3.amazonaws.com/ecs.media.us/Vickie_Weaving_sm.f4v) > NetStream.Play.Failed 2980 [trace] CancelEvent cancel 2980
  15. I have found some code on SnorkleTV that performed a 3D Flip of a page, and I was trying to use it. But in my use of it the object is being rotated from the left margin, but what I need is for it to be rotated by the x axis center of the object. The following is the code that I am using for the first step in the Flip. var flipSpeed:Number = 0.5; var tl:TimelineMax = new TimelineMax({paused:true}); tl.append(TweenMax.to(currentView, flipSpeed, {rotationY:90, visible:false, ease:Linear.easeNone})) The example given on SnorkleTV was extraordinary. I hope to get it right. Gary
  16. I have just discovered a simple solution. Changing panels to visible=false when they are not on stage corrects the performance problem. Amazing. I had used the visible property before to make things appear or disappear, but also seems that the renderer is able to ignore those things that are not visible.
  17. The panel scrolling example works great and by comparing it to my code, I have been able to fix the problem that I had. Thanks very much. But, I am running into another problem using it and hope you have some advice on what would be the best solution. My panels are a mixture of text, images with some interactive objects. When I put three or more of them side by side, all of the performance degrades significantly. My panels are much too large to be cached as bitmap. Blitmask doesn't work well because there are too many interactive components whose change would require recreation of the Blitmask. I am guessing that the problem is that flash is spending time rendering the panels that are not in view. The only other solution that I can think might work would be to keep only one panel on the stage, and add a second panel only when I have an event that indicates the user is scrolling horizontally. I think this would fix the problem, but it would introduce a slight delay in the start of scrolling. Do you have any other ideas that you think might be better?
  18. Hello, The prior website contained an excellent example of horizontal panel scrolling (or dragging) with the panels going back to alignment with the edge of the display when released. I believe it was on the ThrowProps page, but this example did not use ThrowProps. I can't seem to find it in the new website. My modifications of the code seem to have messed it up somewhere along the line and I need to get back to the original. The JS Draggable looks extraordinary, and exactly the kind of thing I need. Is there any plan to get it running in ActionScript? Gary
  19. The ThrowPropsPlugin API page contained an example of using it for scrolling a page vertically, and the throw props web page contained an example for doing horizontal panel transitions that animate entire panel movements right and left. Both of these work extremely well. But when I combine them, I run into problems that both of them are acting on mouse up and mouse down events, which means neither is working as intended. Add some interactive objects to the scrolling page, and it only gets more complicated. I think the solution is to write a singleton class that interprets mouse down, mouse move and mouse up events on the stage and infers user intent so that is can dispatch an event to either the scroller, or the panel slider, or the interactive object in the scroller viewport. My past experience with mouse events is limited to listening for clicks. So, if there is any example code that would point me in the right direction, I would be very happy to know about it.
  20. I notice that your examples of scrolling using ThrowProps pretty consistently listens for mouse events on mc.stage.add…. where mc is the container being scrolled. And I notice that listening on the stage makes the listeners very responsive. This works fine if the entire stage is being scrolled, but usually this is not the case. The performance of the scroller seems to be very much affected by how quickly the listener receives the event. Two possibilities of how to deal with this come to mind. One approach would be to find the display object that is the correct bounds and closest to the stage. In some cases this might be the scroller itself. In my case the parent of the scroller is always the correct size. The other option would be to listen on the stage, and check the target to see if the scroller is an ancestor. Do you recommend one approach over another? Or, do you have another to suggest? I apologize if this question is too general, and understand if you would prefer to pass on it.
  21. Your analysis of the problem is correct, but I am still puzzled about how to fix it. Consider the following: 1) Class A uses the Scroller class. 2) Class A contains its own mouse up and mouse down handlers to execute when the mouse has been clicked. 3) When Class A senses a mouse click, it calls scrollToY in the scroller class, which executes a tween to scroll. 4) The Scroller class gets the mouse up event immediately after Class A has finished the processing described above. 5) The mouse up event in the scroller executes the ThrowPropsPlugin, which appears to stop the other tween. What would be the best way to resolve the duplicate handling of the mouse up in two classes?
  22. I have written a scroller class that is very closely based upon the example given on the ThrowProps api doc page. One of the things that I have added is a scrollToY(num) function, which works fine. But it does not work if called as a result of a mouse click. The viewport being scrolled is a list of words, and when a word is clicked, I would like to scroll that word to the center of the viewport. But, TweenLite.to is not working unless I comment out the ThrowPropsPlugin.to call in the same class. It appears that the ThrowPropsPlugin is doing something with the mouse clicks that interferes with the TweenLite.to Any help would be greatly appreciated. The scrolling animation that I am getting is gorgeous. package views.base { import com.greensock.TweenLite; import com.greensock.easing.Strong; import com.greensock.plugins.ThrowPropsPlugin; import com.greensock.plugins.TweenPlugin; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Rectangle; import flash.utils.getTimer; import lib.data.IDisposable; public class Scroller extends Sprite implements IDisposable { TweenPlugin.activate([ThrowPropsPlugin]); private var _viewport:Sprite; private var _bounds:Rectangle; private var _relativeYPosition:Number; public function Scroller() { super(); } public function setViewPort(sprite:Sprite, dimensions:Rectangle) : void { _viewport = sprite; _bounds = dimensions; _viewport.x = _bounds.x; _viewport.y = _bounds.y; addChild(_viewport); ThrowPropsPlugin.track(_viewport, "y"); //track the "y" property's velocity automatically addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler); } public function beforeResizeViewport() : void { if (_viewport) { _relativeYPosition = Math.max(0, _viewport.y * -1 / _viewport.height); } } public function resizeViewport(dimensions:Rectangle) : void { _bounds = dimensions; if (_viewport) { var yPos:Number = Math.min(_relativeYPosition * _viewport.height, _viewport.height - dimensions.height); _viewport.y = yPos * -1; } } public function scrollToY(position:Number) : void { var duration:Number = Math.abs(_viewport.y - position) / _viewport.height * 20; duration = Math.max(1, duration); TweenLite.to(_viewport, duration, {y:position}); // _viewport.y = position; } public function dispose() : void { removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler); if (_viewport && _viewport is IDisposable) { (_viewport as IDisposable).dispose(); _viewport = null; } } private function addedToStageHandler(event:Event) : void { stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); } private function mouseDownHandler(event:MouseEvent):void { TweenLite.killTweensOf(_viewport); _viewport.startDrag(false, new Rectangle(_bounds.x, -99999, 0, 99999999)); stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); } private function mouseUpHandler(event:MouseEvent):void { _viewport.stopDrag(); stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); var yOverlap:Number = Math.max(0, _viewport.height - _bounds.height); ThrowPropsPlugin.to(_viewport, {ease:Strong.easeOut, throwProps:{y:{max:_bounds.top, min:_bounds.top - yOverlap, resistance:200}}}, 10, 0.25, 1); } private function removedFromStageHandler(event:Event) : void { stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); } } }