I think this is a long shot, but worth asking. I've got something similar to the left menu in many mobile apps (e.g. Facebook), that opens smoothly (in my case, using CSS transitions) when you press the 'open' button, but I've also implemented a drag-out feature where you can swipe from the left of the screen to drag the menu out. In this scenario, it's driven by javascript and is too rapid (seemingly) for the CSS transitions to know what to do. It gets confused, stutters, goes backwards etc. So I've simply shut off the transition while the user is dragging the menu out. This works very well on iOS where ti's perfectly smooth, and while Android and Blackberry both try their best, it would be great if it could be smoother.
Here is my CSS for the open/closed menu states
#view_wrap {
position: absolute;
top: 0px;
right: -100%;
left: 100%;
bottom: 0px;
-webkit-transition: all .2s 0s;
-webkit-transform: translate(-100%);
background-color: #fff;
}
#menu.open + #view_wrap {
-webkit-transform: translate(-3.125em);
box-shadow: 0px 0px .3125em rgba(0,0,0,.5);
overflow: hidden;
}
#view_wrap.animating {
-webkit-transition: none;
}
and the drag functionality just changes the translate
value with each touchmove
Do you know of any tricks to get such rapid changes to be applied more smoothly with or without CSS transition?
I managed to get this to work, not entirely sure it will work in your situation but I have a slideshow which slides images horizontally both through next & back buttons and through dragging with a finger.
I was in a similar situation to you in that the sliding with the buttons was powered by 3d transitions so very smooth on any device that supported it however the dragging was done with just plane old javascript and stuttered a lot.
I have significantly more code than this but just extracted the bits to do with the transition for clarity.
On the element being dragged I began by adding a transition with a small duration on the touchstart event using jquery, 100ms seemed to work nicely for me.
// inside the touchstart event
$('#my-element').on('touchstart', function(e) {
$(this).css('transition','100ms');
});
While the touchmove event was firing, where I was previously doing a calculation to work out the left hand position and setting the left position of the element, I replaced this by applying a 3d transition and updating the X coordinate as the user moved their finger.
NOTE: translate3d apparently is 'hardware accelerated' on iOS devises where 'translate' isn't so its better to do a 3d translate with Y & Z set to 0.
// Inside the touchmove event, -10px will change as the user drags
$('#my-element').on('touchmove', function(e) {
var newLeft = /** A calculation of the new left hand position **/
$(this).css('transform','translate3d('+newLeft +'px,0px,0px);
});
Finally, on the touchend event I removed the CSS transition and re-set the left hand position of the element to the correct position.
// Inside the touchend event
$('#my-element').on('touchend', function(e) {
var endLeft = /** A calculation of the new left hand position **/
$('#sliding-element').css('transition','');
$('#sliding-element').css('transform','');
$('#sliding-element').css('left', endLeft /** Whatever the new left hand position is **/);
});
Hope this helps