webkit translate3d issues (peek-thru) - ios

I'm building an iOS app with PhoneGap. I'm using translate3d CSS animations to create the 'flip' effect.
This works great on simpler elements...a DIV with front/back divs and maybe an extra span or two.
But when I attempt to flip a larger element...namely the entire screen, I get redraw glitches. What happens as soon as I swap the css class to start the transition, parts of the 'bottom' div pop-through the 'top' div, then the flip happens, then they pop-out again. And it's not the entire element that shows through...it's half of the element split along the axis that I'm doing the translate 3d rotation on.
Any ideas or theories as to what might be causing this? It happens the same both on the iPad as an app and on the desktop in Safari, so appears to be a webkit issue.
Could it be some CSS issues? Or is attempting to do a full-screen translate3d rotation with complex nested elements with large background images just more than Safari can handle?
UPDATE 1:
I've made progress in narrowing down the issue.
What's happening is that the elements that are 'peeking through' when I do the translate3d flip happen to be child elements that had been previously positioned via translate3d.
My 'page' structure that I want to transition with translate3d:
<div id="frontbackwrapper">
<div id="front">
</div><!--/front-->
<div id="back">
</div><!--/back-->
</div><!--/frontbackwrapper-->
This works on it's own. The front div is replaced with the back div with a card-flip effect.
The problem is that prior to doing the full page flip, I've already animated some elements within the #front div using translate3d:
<div id="frontbackwrapper">
<div id="front">
<div class="modal"></div>
</div><!--/front-->
<div id="back">
</div><!--/back-->
</div><!--/frontbackwrapper-->
Example CSS:
.modal {
width: 800px;
height: 568px;
position: absolute;
left: 112px;
z-index: 100;
-webkit-transition-duration: 1s;
-webkit-transform: translate3d(0,-618px,0); /* set off screen by default */
}
.modal.modalOn {
-webkit-transform: translate3d(0,80px,0); /* slides the div into place */
}
If--instead of using translate3d--I just reposition the div with a top style or transform the top property, I don't get the peek-through issue. Of course, that means I have to give up the slick animation or hardware acceleration, respectively.
At this point, it looks like a webkit bug. I'll keep doing some playing with it. If anyone has run into this before and found a workaround, I'm all ears!

solution! After a night of sleep, I mulled over the culprit and what to do with it. It's not necessarily the act of animating a child element with translate3d but rather the face that the element that was translated has that CSS property at the time it's parent is being animated with translate3d.
The fix is to first animate the child element, then remove the translate style all together.
The CSS structure is now:
/* default class for the start of your element */
.modal-startposition {
-webkit-transition-duration: 1s;
-webkit-transform: translate3d(0,-618px,0);
}
/* add this class via jQuery to then allow
webkit to animate the element into position */
.modal-animateposition {
-webkit-transform: translate3d(0,80px,0);
}
/* when animation is done, remove the above class
and replace it with this */
.modal-endposition {
top: 80px;
}
And some sample jQuery:
//[attach a click event to trigger and then...]
$myModal
.addClass("modal-animateposition")
.on('webkitTransitionEnd',function () {
$myModal
.removeClass('modal-startposition')
.removeClass('modal-animateposition')
.addClass('modal-endposition');
});
A little tedious, but it completely fixes the screen redrawing problem.
EDIT: Corrected a typo

DA,
I learned something from this, thanks. Also,
take note of the css attrbibutes, 'translate3d' and 'left'. Translating and positioning is a little different. Test it out, translate an element 100px in x-axis, set it's 'left' style attribute to 0px. Verify, it will be positioned at 0px on x-axis from the current translation point (starting from 100px on x-axis).
That produces mathematical errors in drag/drop and animation algorithms and easily noticed (redraw glitches, skips, position getting reset), and becomes a challenge because translate3d no longer updates the elements offsetLeft or 'left' style attribute (to prevent reflow, for optimization), so parsing the elements real left, is based on knowing if translate3d or left was being used. If you're a game developer, tracking the x,y in internal variables is the way to stay in synch with the elements position. Hope that helps out more.

Related

FlexSlider with Woocommerce: prevent vertical swipe touch on horizontal sliders

with WooCommerce 4.2, on iOS, FlexSlider (v2.7.2) show a bug with a horizontal slider: when the focus is on the slider as the user swipes left or right, the vertical scroll is still active, there is some level of vertical movement. That makes the slider "rebound".
You can see the bug in this video: https://youtu.be/bM8zcv3ciTo
EDIT: My question is similar to this one, but related to Flexslider.
I have this in functions.php:
/*PRODUCT PAGE FlexSlider Options*/
add_filter( 'woocommerce_single_product_carousel_options', 'filter_single_product_carousel_options' );
function filter_single_product_carousel_options( $options ) {
if ( wp_is_mobile() ) {
$options['controlNav'] = true; // Option 'thumbnails' by default
$options['direction'] = "horizontal";
$options['slideshow'] = false; // Already "false" by default
}
return $options;
}
Any idea how to prevent this vertical scroll while the focus is on the Flexslider?
Anybody also has this bug?
I installed a test site with only Wordpress and WooCommerce, and the bug is here, so it's not plugin-related: http://woo.makemy.biz/produit/produit-de-test/
Edit: Adapting the owl carousel solution would result in code that looks like this:
//You should replace ".myFlexslider" with an appropriate class.
jQuery('.myFlexslider').data('flexslider').vars.before = function(){
jQuery('body').css('overflow', 'hidden');
};
jQuery('.myFlexslider').data('flexslider').vars.after = function(){
jQuery('body').css('overflow', '');
};
which should work. https://codepen.io/Terrafire123/pen/YzWRXOJ
It's not possible to do this via PHP, because PHP doesn't expose the API necessary to do this.
You should know, that preventing vertical scroll when the slider swipes is usually discouraged because this can result in the slider being annoyingly difficult to scroll past.
Original answer: The fact that the issue seems to occur with both Flickity and Flexsider seems to indicate that it isn't a problem with either one, but rather with the user.
A careful review of the Youtube video you have seems to indicate it's working correctly, and there is no real bug. Every time the slider doesn't move in your video, it's because
a. He's sliding vertically, not horizontally, or
b. He's sliding in a direction he can't slide because loop is disabled and he's at the first element.
The rebound effect is normal when you scroll to the top of the page in iOS. If desired, you can disable the bouncing effect with a workaround like this:
html {
position: fixed;
height: 100%;
overflow: hidden;
}
body {
width: 100vw;
height: 100vh;
position:relative;
overflow:auto;
-webkit-overflow-scrolling: touch;
}

Is there a known workaround for fixed elements rendering in the wrong place when the iOS virtual keyboard is on screen?

I've got an app which leverages a WKWebView for most of the content. In a few screens we have buttons in a div which leverages position: fixed; so that they're always in the same place as a long form scrolls underneath. When the virtual keyboard is shown I add a class to the document body that can be used to adjust other things, for example, tweaking the bottom property on the div containing these buttons so they move above the keyboard.
So far, so good, they're always visible. The problem arises when the form is then scrolled, the buttons visibly move up with the rest of the page (which they shouldn't), but the browser actually acts as if they're still position where they're supposed to be. The screen shot shows where the browser believes the buttons are, and if you touch those areas then the buttons get activated.
I'm happy to chalk this up as a bug with WebKit or specifically WKWebView, but is there a known workaround for this so that they render in the correct place? I read that adding a translation to trigger hardware rendering could help, but it doesn't seem to have done the job here. I also read that changing the position to absolute could solve this issue, but for me it just results in them being rendered off screen somewhere altogether.
You can add fixed position to button wrapper
.btn-bar-fixed {
position: fixed;
bottom: 0px;
right: 0px;
}

How to disable vertical scrolling while sliding ion slide in iOS?

In ionic 3 ,Using iPhone when sliding ionic slider the vertical scrolling occur, it causes app ui experience. it’s serious bug I have tried many ideas in googling no one works. please help me any one aware of this issue
We had the same problem with some sliders on our project. The first slide was ok, you could slide left & right without any vertical scroll, however any further slides would scroll the whole page up & down. What fixed it for us was to add the following css:
.swiper-wrapper{
width:auto !important;
}
The .swiper-wrapper was width: 100%, and then being pushed to the left (and off screen) when scrolled. So any further swipes on the slider were outwith the swiper-wrapper thus causing the whole page to move.
i have the solution!
ionSlideDrag Emitted when a slide moves. When the slide moves i call a function which add a class to my content which add
overflow-y: hidden.
ionSlideDidChange Emitted when a slide change ends. it means that when slide change ends i call a function which remove the class and my content is again scrollable.
For add and remove class i have implemented jquery. ( How can I use jQuery with Ionic 2?)
this is an example of my code:
in my view.html
<ion-slides slidesPerView="4" spaceBetween="20" (ionSlideDrag)="dragging()" (ionSlideDidChange)="endDragging()">
<ion-slide *ngFor="let action of actionPages">
<img [src]="url + action.imgSmall">
<h1></h1>
</ion-slide>
</ion-slides>
in my view.ts
dragging(){
$("#contenitore").addClass("no-scroll")
}
endDragging(){
$("#contenitore").removeClass("no-scroll")
}
no-scroll class in app.scss:
.no-scroll {
div.scroll-content {
overflow-y: hidden;
}
}

jQuery UI - Rotate, drag, resize DIV like in image editor

I need "user-friendly" rotate, drag and resizable DIV. But, when this DIV is rotated, RESIZE function works very wierd. Not like in image editor. User can not handle resize properly. How to make it ?
jsFiddle Example
HTML :
<div id="blue"></div>
CSS :
#blue {
top: 100px;
left: 100px;
width:200px;
height:200px;
background-color:blue;
-ms-transform: rotate(120deg); /* IE 9 */
-webkit-transform: rotate(120deg); /* Safari */
transform: rotate(120deg);
}
jQuery
$("#blue").resizable({
aspectRatio: false,
handles: 'ne, se, sw, nw'
});
$("#blue").draggable();
Worked on a similar Question: How to get four corners rotate handle for a rotatable div..?
In this, OP wanted to add rotation handles to each corner. But it's a good example of what you're reporting too.
Take a look at: https://jsfiddle.net/Twisty/7zc36sug/
HTML
<div class="box-wrapper">
<div class="box">
</div>
</div>
Wrapping the box helps out for Draggable.
jQuery
$(function() {
// Assign Draggable
$('.box-wrapper').draggable({
cancel: ".ui-rotatable-handle"
});
// Assign Rotatable
$('.box').resizable().rotatable();
});
Resizing when at a rotated angle changes the location of the box, it's width and height, and causes it to move in a sort of weird way. This is why it does not work like it might in some graphics programs.
Since you did not indicate what you would prefer the behaivor to be like, I cannot properly answer your question: User can not handle resize properly. How to make it?
I hope this helps explain the issue.

-webkit-overflow-scrolling Problems With Objects Inserted Into DOM

I'm using -webkit-overflow-scrolling:touch for native scrolling capabilities on my iPad. But I've come into quite an odd problem:
I have one div with various children. If these children are big enough to create the need for scrolling, the device properly scrolls correctly, with momentum and all. However, if this div is not big enough to require scrolling, and suddenly has elements inserted into it and now does require scrolling, you will not be able to scroll the element at all.
I hope that wasn't too incredibly confusing, but if someone could shed some light on what to do in this situation, that would be fantastic. There isn't much documentation about this property out there.
EDIT: Tried testing this a lot, and it seems now it's just a generally intermittent problem. Every 1 out of 5 times or so, scrolling just fails for my entire web app, no matter the contents.
I had the same issue and it seems like assigning the CSS class after the new DOM element is added seems to work fine:
// your code to add a div to the DOM
// the div contains a scrollable div with the content class
setTimeout(function(){
// this is using JQuery
div.find(".content").addClass("overflowScroll");
}, 1);
// CSS class
.overflowScroll {
overflow: hidden;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
// The HTML for the div
// I am adding a dynamic list to the content div
// which should use the overflow scroll
<div class="panel">
<div class="header">
</div>
<div class="content"></div>
</div>

Resources