strange droppable() bug on iPad, works on iPhone - ios

I've tried various web searches, but I can't seem to find anything that relates to my problem.
To quickly delineate the problem:
HTML5 Cordova iOS app (7.1 -> 8.1)
uses draggable elements
I only have issues on the iPad, not on the iPhone
The HTML5 app itself works flawlessly in a web-browser
The app itself is a biology app that teaches translation - decoding RNA into a amino acid sequence, i.e. a protein.
For this, the user sees the sequence and drags the correct amino acid onto it. The amino acid is a draggable element and the target div is a droppable. One amino acid at a time a chain is built. Please refer to the screenshot to get an idea (can't embed yet).
http://i.stack.imgur.com/S4UpF.png
In order to fit all screens, I "transform: scale" the app accordingly (fixed size is ~850x550). And to get rid of the associated jQuery bug with draggable (object movement would also change with the scaling factor), I've followed the instructions at http://gungfoo.wordpress.com/2013/02/15/jquery-ui-resizabledraggable-with-transform-scale-set/
// scaling to fit viewport
// sizing the page
var myPage = $('.page');
var pageWidth=myPage.width();
var pageHeight=myPage.height();
// sizing the iFrame
var myFrame = $('.container');
var frameWidth=myFrame.width();
var frameHeight=myFrame.height();
// scaleFactor horizontal
var horizontalScale=pageWidth/frameWidth;
// scaleFactor vertiacal
var verticalScale=pageHeight/frameHeight;
// global zoomScale variable
var zoomScale = 1; // default, required for draggable debug
// if page fits vertically - scale horizontally
if ((frameHeight * horizontalScale) <= pageHeight) {
myFrame.css({
'transform': 'scale('+horizontalScale+')',
'transform-origin': 'top',
});
// adding vertical margin, if possible
if (pageHeight > frameHeight*horizontalScale) {
var heightDifference = pageHeight - frameHeight*horizontalScale;
myPage.css({
'margin-top': heightDifference/2,
'height': pageHeight - heightDifference/2,
});
}
zoomScale = horizontalScale;
// else scale vertically
} else {
myFrame.css({
'transform': 'scale('+verticalScale+')',
'transform-origin': 'top',
});
zoomScale = verticalScale;
}
// draggable + scale transform fixes (http://gungfoo.wordpress.com/2013/02/15/jquery-ui-resizabledraggable-with-transform-scale-set/)
function startFix(event, ui) {
ui.position.left = 0;
ui.position.top = 0;
}
function dragFix(event, ui) {
var changeLeft = ui.position.left - ui.originalPosition.left; // find change in left
var newLeft = ui.originalPosition.left + changeLeft / zoomScale; // adjust new left by our zoomScale
var changeTop = ui.position.top - ui.originalPosition.top; // find change in top
var newTop = ui.originalPosition.top + changeTop / zoomScale; // adjust new top by our zoomScale
ui.position.left = newLeft;
ui.position.top = newTop;
}
I've already got a beta version on iTunes connect and it works great on an iPhone. On iPads, however, the droppable area is oddly small and shifted. That is, the div seems to be properly rendered - it is the box with the dashed border.
Has anyone else encountered a similar bug? I really have no idea how to fix it.

I have managed to solve the problem.
The issue was probably based on the viewport meta tag (0.5 scaling) interacting badly with the transform:scale resizing.
Simply removing all viewport meta arguments have solved the problem.

Related

KonvaJS - Attach fixed scrollbar to element with dynamic height

Please assist, i have created dynamic content and i need attach scrollbar to it.
Main goal: when scroller reach to bottom my dynamic content bottom must be synchronized with it. (bottom of color boxes must be inline with the scroller)
Scroller size must be the same and don't change height.
How it will be work: if we have 12 boxes for example, slow speed will be used while scroller reach from top to bottom. if 30 boxes for example, it will be faster and so on...
i think so...
Maybe you provide a better solution.
"create dynamic elements layer" section creates color boxes, please check with different quantity
Thank you
jsFiddle
/* move scrollbar and dynamic elements */
verticalBar.on('dragmove', function (e) {
if (verticalBar.x() != verticalBarBottom.x()) {
verticalBar.x(verticalBarBottom.x())
}
if (verticalBar.y() < verticalBarBottom.y()) {
verticalBar.y(verticalBarBottom.y());
}
if (verticalBar.y() > verticalBarBottom.y() + verticalBarBottom.height() - verticalBar.height()) {
verticalBar.y(verticalBarBottom.y() + verticalBarBottom.height() - verticalBar.height());
}
productsOffset = verticalBar.y() - verticalBarBottom.y();
productsStep = products.getClientRect().height / verticalBarBottom.height();
productsStep = products.getClientRect().height / (verticalBarBottom.y() + verticalBarBottom.height());
newYpos = verticalBarBottom.y() - productPadding;
newYpos -= productsOffset * productsStep;
products.y(newYpos);
products.draw();
})
First, you may need to identify how far your left scrollbar is scrolled. I used progress variable (0 <= progress <= 1):
var progress = (verticalBar.y() - verticalBarBottom.y()) / (verticalBarBottom.height() - verticalBar.height());
Then you may need to identify what is min y and max y that layer may take to fit into you required view:
var minY = verticalBarBottom.y() + verticalBarBottom.height() - products.getClientRect().height;
var maxY = verticalBarBottom.y();
You may need to adjust these variables of your use case.
So real y is just somewhere between minY and maxY adjusted by progress:
var y = minY + (1 - progress) * (maxY - minY);
products.y(y);
Demo: https://jsfiddle.net/ehtro20j/

Unity to ios Notch And Safe Are Problems

I have tried creating a game in unity and build it on ios on any apple devices there were no problem except on iphone x. Screenshot is below.enter image description here. It was covered by the iphone x notch and then when when the character is on the left or the right side it was cut it half.Is there any other solution or a plugin we can use to solve the issue ?. Is there a unity settins or xcode settings to that ? .Thank You
About the iPhone X notch, you can use this:
Screen.safeArea
It is a convenient way to determine the screen actual "Safe Area". Read more about it in this thread.
About the character cutting in half, this is probably something you need to take care of manually based on your game logic. By getting the Screen.width - you should be able to either adjust the Camera (zoom out) or limit the character movement in a way that it will not get past the screen edge.
For the iPhone X and other notched phones you can use the generic Screen.safeArea provided by Unity 2017.2.1+. Attach the script below to a full screen UI panel (Anchor 0,0 to 1,1; Pivot 0.5,0.5) and it will shape itself to the screen safe.
Also recommended to have your Canvas set to "Scale With Screen Size" and "Match (Width-Height)" = 0.5.
public class SafeArea : MonoBehaviour
{
RectTransform Panel;
Rect LastSafeArea = new Rect (0, 0, 0, 0);
void Awake ()
{
Panel = GetComponent<RectTransform> ();
Refresh ();
}
void Update ()
{
Refresh ();
}
void Refresh ()
{
Rect safeArea = GetSafeArea ();
if (safeArea != LastSafeArea)
ApplySafeArea (safeArea);
}
Rect GetSafeArea ()
{
return Screen.safeArea;
}
void ApplySafeArea (Rect r)
{
LastSafeArea = r;
Vector2 anchorMin = r.position;
Vector2 anchorMax = r.position + r.size;
anchorMin.x /= Screen.width;
anchorMin.y /= Screen.height;
anchorMax.x /= Screen.width;
anchorMax.y /= Screen.height;
Panel.anchorMin = anchorMin;
Panel.anchorMax = anchorMax;
}
}
For a more in depth breakdown, I've written a detailed article with screenshots here: https://connect.unity.com/p/updating-your-gui-for-the-iphone-x-and-other-notched-devices. Hope it helps!
Sorry for the late answer but I have adjusted the camera's viewport rectangle for iOS devices and it works correctly. Check if it works for your camera as well.
I have tried safeArea and other script based solutions which do not seem to work.
#if UNITY_IPHONE
mainCamera.rect = new Rect(0.06f, 0.06f, 0.88f, 1);
#endif

React-Native iOS accurate active input position

I have tried to use some the existing solution for iOS keyboard avoiding but none of the existing solutions seems to be working properly with some of my rather complicated views and I am now having to implement my own system. Thus far I have managed to come up with the following which works quite good:
_keyboardDidShow(e) {
const keyboardHeight = e.endCoordinates.height;
const windowHeight = Dimensions.get('window').height;
const keyboardTop = windowHeight - keyboardHeight;
const margin = 10;
const currentlyFocusedField = TextInput.State.currentlyFocusedField();
UIManager.measureInWindow(currentlyFocusedField, (x, y, width, height) => {
const fieldBottom = y + height;
const offset = fieldBottom - keyboardTop + 10;
if (offset > 0) {
this.setState({ offsetY: -1 * offset, offsettingKeyboard: true });
}
});
}
I should mention that these inputs are inside ScrollViews which are themselves in a bunch of other stuff.
The problem is that when the handler is called for a TextInput that has not been scrolled up inside its view, the proper "fieldBottom" position is obtained without adding the height while the height addition is needed for the real position of a field inside a view that has been scrolled.
I cannot decide if this is a bug or if I am missing something. Is there perhaps a way I can check if the input's parent has been scrolled?

Enable rotation of Highcharts 3D scatter chart on touch devices

In my web application I utilize this beautiful 3D scatter chart rendered using Highcharts.
It does rotate nicely using the mouse by clicking on it and dragging around.
However, on neither my phone nor my tablet it does rotate also.
The code for enabling rotation looks as follows (adopted from the Highcharts sample page):
// Add mouse events for rotation
$(chart.container).on('mousedown.hc touchstart.hc', function (eStart) {
eStart = chart.pointer.normalize(eStart);
var posX = eStart.pageX,
posY = eStart.pageY,
alpha = chart.options.chart.options3d.alpha,
beta = chart.options.chart.options3d.beta,
newAlpha,
newBeta,
sensitivity = 5; // lower is more sensitive
$(document).on({
'mousemove.hc touchdrag.hc': function (e) {
// Run beta
newBeta = beta + (posX - e.pageX) / sensitivity;
chart.options.chart.options3d.beta = newBeta;
// Run alpha
newAlpha = alpha + (e.pageY - posY) / sensitivity;
chart.options.chart.options3d.alpha = newAlpha;
chart.redraw(false);
},
'mouseup touchend': function () {
$(document).off('.hc');
}
});
});
I assume that the events where this logic is registered are not available on my devices (recent Samsung Galaxy Tab and Samsung Galaxy S5).
Any ideas?
The problem is, a touch event doesn't have pageX or pageY. Instead of using event.pagePosition, you should use event.chartPosition. And chartPositions are only available after normalized by chart.pointer.normalize.
Also, there is no touchdrag event, it should be touchmove

Scaling Image Causes Crash In AS3 Flex AIR Mobile App

Problem:
Zooming in on image by scaling and moving using matrix causes the app to run out of memory and crash.
Additional Libraries used:
Gestouch - https://github.com/fljot/Gestouch
Description:
In my Flex Mobile app I have an Image inside a Group with pan/zoom enabled using the Gestouch library. The zoom works to an extent but causes the app to die (not freeze, just exit) with no error message after a certain zoom level.
This would be manageable except I can’t figure out how to implement a threshold to stop the zoom at, as it crashes at a different zoom level almost every time. I also use dynamic images so the source of the image could be any size or resolution.
They are usually JPEGS ranging from about 800x600 - 9000x6000 and are downloaded from a server so cannot be packaged with the app.
As of the AS3 docs there is no longer a limit to the size of the BitmapData object so that shouldn't be the issue.
“Starting with AIR 3 and Flash player 11, the size limits for a BitmapData object have been removed. The maximum size of a bitmap is now dependent on the operating system.”
The group is used as a marker layer for overlaying pins on.
The crash mainly happens on iPad Mini and older Android devices.
Things I have tried already tried:
1.Using Adobe Scout to pin point when the memory leak occurs.
2.Debugging to find the exact height and width of the marker layer and image at the time of crash.
3.Setting a max zoom variable based on the size of the image.
4.Cropping the image on zoom to only show the visible area. ( crashes on copyPixels function and BitmapData.draw() function )
5.Using imagemagick to make lower quality images ( small images still crash )
6.Using imagemagick to make very low res image and make a grid of smaller images . Displaying in the mobile app using a List and Tile layout.
7.Using weak references when adding event listeners.
Any suggestions would be appreciated.
Thanks
private function layoutImageResized(e: Event):void
{
markerLayer.scaleX = markerLayer.scaleY = 1;
markerLayer.x = markerLayer.y = 0;
var scale: Number = Math.min(width / image.sourceWidth , height / image.sourceHeight);
image.scaleX = image.scaleY = scale;
_imageIsWide = (image.sourceWidth / image.sourceHeight) > (width / height);
// centre image
if(_imageIsWide)
{
markerLayer.y = (height - image.sourceHeight * image.scaleY ) / 2 ;
}
else
{
markerLayer.x = (width -image.sourceWidth * image.scaleX ) / 2 ;
}
// set max scale
_maxScale = scale*_maxZoom;
}
private function onGesture(event:org.gestouch.events.GestureEvent):void
{
trace("Gesture start");
// if the user starts moving around while the add Pin option is up
// the state will be changed and the menu will disappear
if(currentState == "addPin")
{
return;
}
const gesture:TransformGesture = event.target as TransformGesture;
////trace("gesture state is ", gesture.state);
if(gesture.state == GestureState.BEGAN)
{
currentState = "zooming";
imgOldX = image.x;
imgOldY = image.y;
oldImgWidth = markerLayer.width;
oldImgHeight = markerLayer.height;
if(!_hidePins)
{
showHidePins(false);
}
}
var matrix:Matrix = markerLayer.transform.matrix;
// Pan
matrix.translate(gesture.offsetX, gesture.offsetY);
markerLayer.transform.matrix = matrix;
if ( (gesture.scale != 1 || gesture.rotation != 0) && ( (markerLayer.scaleX < _maxScale && markerLayer.scaleY < _maxScale) || gesture.scale < 1 ) && gesture.scale < 1.4 )
{
storedScale = gesture.scale;
// Zoom
var transformPoint:Point = matrix.transformPoint(markerLayer.globalToLocal(gesture.location));
matrix.translate(-transformPoint.x, -transformPoint.y);
matrix.scale(gesture.scale, gesture.scale);
/** THIS IS WHERE THE CRASH HAPPENS **/
matrix.translate(transformPoint.x, transformPoint.y);
markerLayer.transform.matrix = matrix;
}
}
I would say that's not a good idea to work with such a large image like (9000x6000) on mobile devices.
I suppose you are trying to implement some sort of map navigation so you need to zoom some areas hugely.
My solution would be to split that 9000x6000 into 2048x2048 pieces, then compress it using png2atf utility with mipmaps enabled.
Then you can use Starling to easily load these atf images and add it to stage3d and easily manage it.
In case you are dealing with 9000x6000 image - you'll get about 15 2048x2048 pieces, having them all added on the stage at one time you might think it would be heavy, but mipmaps will make it so that there are only tiny thumbnails of image are in memory until they are not zoomed - so you'll never run out of memory in case you remove invisible pieces from stage from time to time while zooming in, and return it back on zoom out

Resources