spin.js not showing up on iPhone/iPad - html

I use spin.js for showing a spinner when loading a new page. Because IE had problems with animating a gif I use this library. Now I found out that it doesn't work on iOS. The spinner is not showing up at all. Tested with:
iPhone with iOS 6.1.3
iPad with iOS 5.1.1
It is working on every browser for Windows (even Safari for Windows).
Header:
<script type="text/javascript" src="../js/spin.min.js"></script>
before closing body:
<div id ="center" style="position:fixed;top:50%;left:50%"></div>
<script>
var opts = {
lines: 13, // The number of lines to draw
length: 8, // The length of each line
width: 4, // The line thickness
radius: 11, // The radius of the inner circle
corners: 1, // Corner roundness (0..1)
rotate: 0, // The rotation offset
direction: 1, // 1: clockwise, -1: counterclockwise
color: '#000', // #rgb or #rrggbb or array of colors
speed: 1, // Rounds per second
trail: 60, // Afterglow percentage
shadow: false, // Whether to render a shadow
hwaccel: false, // Whether to use hardware acceleration
className: 'spinner', // The CSS class to assign to the spinner
zIndex: 2e9, // The z-index (defaults to 2000000000)
top: 'auto', // Top position relative to parent in px
left: 'auto' // Left position relative to parent in px
};
var target = document.getElementById('center');
var spinner = new Spinner(opts);
$("#select-place input").click(function(){
spinner.spin(target);
});
$(window).bind("load", function() {
spinner.stop();
});
</script>
I tried to use another element. Here it works. The problem is position:fixed. I read that iOS 5 does support this. How do I center the spinner in the middle of the screen even on iOS? The page is not expliciitely build for mobile devices. It's mainly a desktop version but it should work for iOS too.

Because the other solution didn't worked and I won't use a framework I came up with a JS solution. Simply calculate the middle of the screen with JS:
jQuery.fn.center = function () {
this.css("position","absolute");
this.css("top", Math.max(0, (($(window).height() - $(this).outerHeight()) / 2) +
$(window).scrollTop()) + "px");
this.css("left", Math.max(0, (($(window).width() - $(this).outerWidth()) / 2) +
$(window).scrollLeft()) + "px");
return this;
}
$('#center').center();
Taken from the answer from Tony in this post.
One disadvantage: The user can scroll away from the spinner. You'd need something which adapts on scrolling as e.g. shown in Fixed positioning in Mobile Safari.

Related

ExtJs: Draggable element without Region

I want to create a GoogleMap like draggable div (as in this example http://tech.pro/tutorial/790/javascr...in-a-container).
But with ExtJs I did not find a way to achieve this without get rid of the Region...
I have a container which fit the screen and I have a huge div inside it (more than 10 000 px) which is centered (called it "area").
When I create an Ext.dd.DD class with this "area" element as a target, and start to drag... the DragDrop fonctionnality doesn't work as the div is stuck in the top-left corner.
Any idea on how to achieve this?
(Obviously, I don't want scoll, but drag and drop scroll).
Thanks in advance,
PsychoKrameur
PS: I'm using ExtJs 5.1
With ExtJS 5.1 you can use the TouchScroller, but be careful the class is private. That means it can change in further releases.
Example: https://fiddle.sencha.com/#fiddle/lmn
document.addEventListener("dragstart", function(e) {
e.preventDefault(); //This for the image otherwise it will dragged in IE
});
var panel = Ext.create("Ext.Panel", {
style: {
cursor: "move"
},
width: 400,
height: 400,
items: [{
xtype: "image",
width: 1019,
height: 1019,
src: "http://tech.pro/_sotc/sites/default/files/202/images/duck.jpg"
}],
renderTo: Ext.getBody()
});
Ext.defer(function() {
var childSize = panel.items.first().getSize();
var size = panel.getSize();
var scroller = Ext.scroll.TouchScroller.create({
element: panel.getOverflowEl()
});
scroller.scrollTo(size.width / 2 - childSize.width / 2, size.height / 2 - childSize.height / 2); //center the image
}, 1);

Chrome crops image in famo.us

I have a background (svg) image that I initially will view zoomed in and then on an event the image will zoom out to fit in the page. This works well in Firefox but in Chrome the picture was cropped when zoomed in and thus when it is supposed to fit the page it has white space around it. I believe this is part of Chrome's optimizer described here: http://famo.us/guides/pitfalls
My question is then, can I disable this optimization for this specific image? Or is there any other solution?
Edit: No need to look at the Chrome optimizer, solved by using better method for zooming (from correct answer below).
Athough we do not know your use case, here is an example using proportions.
Example jsBin (click on the image to resize)
var mainContext = Engine.createContext();
mainContext.setPerspective(1000);
var mod = new StateModifier();
var logo = new ImageSurface({
content: 'http://code.famo.us/assets/famous_logo.svg',
classes: ['double-sided']
});
logo._mod = new Modifier({
size: [undefined, undefined],
origin: [0.5, 0.5],
align: [0.5, 0.5],
transform: Transform.translate(0, 0, 0),
proportions: [1.5, 1.5]
});
var mainMod = new Modifier({
origin: [0.5, 0.5],
align: [0.5, 0.5]
});
var rootnode = mainContext.add(mainMod);
rootnode.add(logo._mod).add(logo);
//logo._mod.setProportions([1.5, 1.5], {duration: 2000});
logo.on('click', function(){
if (!logo.small)
logo._mod.setProportions([1,1], {duration: 1000});
else
logo._mod.setProportions([1.5, 1.5], {duration: 1000});
logo.small = !logo.small;
});

IOS 7 - css - html height - 100% = 692px

I have a weird bug on iPad iOS7 landscape mode.
What i was able to investigate is that in iOS7 window.outerHeight is 692px and
window.innerHeight 672px; while in previous versions both values are 672px.
Even though my <html> and <body> tags have height 100% there seems to be space for scrolling, and the weird thing is that this problem only shows up on landscpae
You can see what i am talking about by visiting t.cincodias.com, for example, in a iOS 7 iPad the footer bar (or the header sometimes) will be cut. But on previous iOS versions the content displays fine at fullscreen.
Even when i set the height of both tags to height: 672px !important and position:absolute; bottom: 0;, you can still scroll the content vertically by touching an iframe (the ads are iframes).
I'm running the release candidate version of iOS7
thanks for any help.
I used this JavaScript solution for solving that problem:
if (
navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i) &&
window.innerHeight != document.documentElement.clientHeight
) {
var fixViewportHeight = function() {
document.documentElement.style.height = window.innerHeight + "px";
if (document.body.scrollTop !== 0) {
window.scrollTo(0, 0);
}
};
window.addEventListener("scroll", fixViewportHeight, false);
window.addEventListener("orientationchange", fixViewportHeight, false);
fixViewportHeight();
document.body.style.webkitTransform = "translate3d(0,0,0)";
}
I believe this is a bug in iOS 7 - if you rotate it to portrait mode, it sets both (innerHeight/outerHeight) to the same value. If it isn't a bug, then portrait mode has one because the behavior isn't consistent.
You could detect iOS 7/mobile Safari and use window.innerHeight if iOS 7.
I'll combine the answers. Thanks all!
You can do something like this:
if (navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i)) {
$('#yourDivID').height(window.innerHeight);
window.scrollTo(0, 0);
}
The window.scrollTo solves the issue of the bar overlapping in landscape when rotating.
Cheers!
I reproduce the same problem in iOS 8.
Here is my solution.
I listened resize, scroll, orientationChange event, to ensure when user trigger screen size change, will call reset height function.
I wrote a debounce to prevent multiple call.
And It's in a closure and no dependent (no jQuery).
(function(){
var setViewportHeight = (function(){
function debounced(){
document.documentElement.style.height = window.innerHeight + "px";
if (document.body.scrollTop !== 0) {
window.scrollTo(0, 0);
}
}
var cancelable = null;
return function(){
cancelable && clearTimeout(cancelable);
cancelable = setTimeout(debounced, 100);
};
})();
//ipad safari
if(/iPad/.test(navigator.platform) && /Safari/i.test(navigator.userAgent)){
window.addEventListener("resize", setViewportHeight, false);
window.addEventListener("scroll", setViewportHeight, false);
window.addEventListener("orientationchange", setViewportHeight, false);
setViewportHeight();
}
})();

Cocoon JS and Kinetic JS

I am developing an educational game for children (D&D, colors, shapes, numbers, etc) and I am using KineticJS for that purpose. It runs fine on Ipad 4 and Iphone 5, but on Android devices it runs with a very low framerate (Galaxy Tab 2 and Galaxy S2). I tried to compile the app with Cocoon JS to enable canvas acceleration, but it gets stuck on launch screeen (with phonegap build it runs fine).
Do I have to make any changes in the Kinetic source code to build on CocoonJS? Are there any alternatives to improve Kinetic performance on android devices?
Cocoonjs cannot render the parent container (its a div). You need to overwrite the prototype of Kinetic.
Kinetic.Stage.prototype._buildDOM = function() {
this.content = this.attrs.container;
this.hitCanvas = new Kinetic.Canvas(0, 0, true);
this.bufferCanvas = new Kinetic.SceneCanvas({
pixelRatio: 1
});
this.bufferHitCanvas = new Kinetic.HitCanvas();
this._resizeDOM();
};
Kinetic.Stage.prototype._getContentPosition = function() {
var rect = this.content.getBoundingClientRect ? this.content.getBoundingClientRect() : { top : 0, left : 0 };
return { top: rect.top, left: rect.left };
};
Then build your main stage as this.
this.stage = new Kinetic.Stage({width: 960, height: 500, container: document.body});

dragging and dropping onto a jquery slider - posting position to server

I'm trying to implement dragging an item onto a jquery slider. For example, if the item is dropped onto 86% of the slider I would like to POST this position to the server so the item can be place 86% along the result set on the server.
How do you detect dropping onto a jQuery slider and the percentage POSTed to the server?
Since I'm not so good at explaining things, I made a jsFiddle for you. Although this might not be exactly what your looking for, it should be a good starting point!
Here's the code :
$(function () {
//the draggable object
$("#dragobject").draggable();
//Prepare the slider
var range = 100,
sliderDiv = $("#slider");
// Activate the UI slider
sliderDiv.slider({
min: 0,
max: range,
create : function(){
$(this).find(".ui-slider-handle").hide();
}
});
// Number of tick marks on slider
var position = sliderDiv.position(),
sliderWidth = sliderDiv.width(),
minX = position.left,
maxX = minX + sliderWidth,
tickSize = sliderWidth / range;
//Set slider as droppable
sliderDiv.droppable({
//on drop
drop: function (e, ui) {
var finalMidPosition = $(ui.draggable).position().left + Math.round($("#dragobject").width() / 2);
//If within the slider's width, follow it along
if (finalMidPosition >= minX && finalMidPosition <= maxX) {
var val = Math.round((finalMidPosition - minX) / tickSize);
sliderDiv.slider("value", val);
alert(val + "%");
//do ajax update here to set the position
/*$.ajax({
type: "POST",
url: url,
data: val,
success: function () {
//congrats
},
dataType: dataType
});*/
}
}
});
});
And here's the jsFiddle link : jsFiddle example
Hope it helps,
Marc.
SOURCES :
Jquery slider that slides while mouse move,
jQuery UI slider
Since you are using jQuery, lets assume you are using jQuery UI for your drag and drop. First read this: http://api.jqueryui.com/droppable/#event-drop
Then realize that you get the offset position of the dropped element relative to the droppable container as part of the event. This would be where you could compute that into percentage if you needed.
For example, dropped at position left -> 90px of a container that you know to be 100px wide means 90% is your magic number.
Or if you are using native drag and drop, check out this simple edit: http://jsbin.com/ezuke/3283/edit . If you pop a console log on the event in the drop event, you will see that it also exposes the offset of where you dropped it and you could again consume that in your calculation of %.