iScroll 4 No Canvas click/tap events when zoomed in - javascript

I have an odd problem that I can't work out - I'm using iScroll 4 to scroll an HTML5 canvas (implemented as below):
mapScroll = new iScroll('td_map', {zoom: true, bounce: false,
hScrollbar: false, vScrollbar: false,
}, 100);
The zoom works brilliantly (tested on iPad 2/4), and the canvas items which have tap and click events are firing when the map is not zoomed in. However as soon as the zoom is used (so in iScroll the scale is changed from minZoom of 1) the click events aren't firing or they're not being reached. If I zoom out or double click to reset the zoom back to normal, the events will fire as expected again.
The click event:
trainGroup.on("click tap", function(evt) {
console.log("Hello train!");
});
Any ideas as to what's going on would be great :)
Thanks very much,
Becky
EDIT: After much debug logging to work out what was going on where, it looks like the mouse event has the wrong information. It seems that the CSS transform the zoom does on the canvas doesn't update the mouse clicks, so when I think I'm clicking on the object its actually clicking whatever would be on the non-zoomed canvas. I haven't figured out how to update the mouse events with the translated info yet, but at least thats progress :)

Related

How to prevent Pinch IN Zooming of Image using Pinchzoom.js

So I have this scenario where I am using Pinchzoom.js library for zooming images. It is perfectly working and the library is very good. But I have a scenario where the PINCH IN gesture (on mobile) also makes the image zoom OUT. To see a working demo, you can refer to their working demo link. When you will PINCH IN, you will observe that the image zooms OUT but after the gesture has ended, it retains its original size. I wanted to ask if there is a way to disable this zooming out effect? My PinchZoom settings are as:
Array.from(document.querySelectorAll('.myimages')).forEach(function (el) {
new PinchZoom.default(el, {
tapZoomFactor: 5,
maxZoom: 10,
use2d: true,
verticalPadding: 1,
draggableUnzoomed: false
});
});
Try setting the property minZoom to 1.
This effect happens because it allows you to zoom out to a size that is smaller than your screen, so the browser scale it back so it fits the whole phone width.
You need to add the property which will tell the minimum zoom size. In Pinchzoom.js library there is minZoom property for that.
So if you don't want your image to be zoomed out on pinch-in then set minZoom:1.
I tried this settings by adding minZoom property to the demo link and it was working correctly.
Array.from(document.querySelectorAll('.myimages-container')).forEach(function (el) {
new PinchZoom.default(el, {
tapZoomFactor: 5,
maxZoom: 10,
minZoom:1,
use2d: true,
verticalPadding: 1,
draggableUnzoomed: false
});
});
If this solution is not working for you then maybe this is the problem is with your element selection.
Use container <div> as the parent of your every image and then apply settings to that parent <div>.
<div class="myimages-container">
<img src="my_image.jpg"></img>
</div>

PDF.JS: Reloadeing/ re-rendering due to zoom stops JS events

When I execute the Pinch Zoom gesture (wipe 2 fingers apart or to each other on the display), on the PDF.JS viewer.html in an Cordova app on iOS 11.4.1, the document should be permanently zoomed in or out. But if the document is reloaded/ re-rendered (little loading spinner is shown in PDF.JS toolbar) from a zoom size of approx < 120%, the 'gesturechange' event is no longer fired. The fingers must first be removed from the display and the pinch zoom gesture must be executed again with 2 fingers to get the event fired again. I also tried the library Hammer.JS, but unfortunately here is exactly the same behavior. If the document is further enlarged at a zoom of approx. > 120%, no re-rendering takes place (no loading spinner is shown in PDF.JS toolbar) and the 'gesturechange' event is further fired and everything works. Now the question would be whether you can deactivate re-rendering if necessary and only execute it again at the end of the pinch zoom?
This is the JavaScript example code. PDFJS viewer.html is rendered in an iframe and ExtJS is used.
var viewer = Ext.dom.Query.select('iframe')[0].contentWindow.document.getElementById("viewer");
var pdfViewer = me.el.dom.contentWindow.PDFViewerApplication.pdfViewer;
viewer.addEventListener('gesturechange', function(e) {
if (e.scale < 1.0) {
console.log("PinchOut")
pdfViewer.currentScale = pdfViewer.currentScale - 0.01;
} else if (e.scale > 1.0) {
console.log("PinchIn");
pdfViewer.currentScale = pdfViewer.currentScale + 0.01;
}
})
Try to set the PDFJS.disableTextLayer in viewer.js to "false"
PDFJS.disableTextLayer: false,
then it should work

How to identify REAL mouse movement when entering fullscreen mode

I have the problem, that I need to know if the user actually moved his mouse for real when entering fullscreen, or if it just is a programatically side effect of entering the fullscreen.
Because, when entering fullscreen, the mouse Y coordinates change automatically because the mouse moves upwards on the absolute screen position (since the top navigation of the browser disappears). And since every browser brings a notification in fullscreen mode, this very notification triggers a mousemove event.
So, this makes it very painful to find out, whether the user acually move the mouse, or not.
Is there a solution to identify REAL mouse movement?
$(document).on('mousemove', function(event){
/* gets also triggered when just entering fullscreen,
but without actual movement of the physical mouse..
how can this be identified/ignored?
*/
});
JS Fiddle
What I've tried so far
I tried already relativating the mouse position by using something like window.screen.top - but this seems not to be implemented yet by any browser so far.
I don't think there's anything formally implemented as yet to detect full screen. There's a fullscreenchange as part of the Fullscreen API but it's still experimental and requires vendor-specific prefixes.
So, basically you'll have to get around that limitation with some tricks, like intersecting the resize event and skipping whatever logic you are running on mousemove. Here's an example...
var resizing = false;
$(document).on('mousemove', function(event){
if(resizing == false){
$('p').text(event.pageX + ':' + event.pageY);
console.log("moving");
}
});
$(window).resize(function(){
resizing = true;
setTimeout(function(){
resizing = false;
}, 4000);
});
This example simply defines a flag that determines whether the window is resizing or not, if resizing the onmousemove logic is skipped. Particularly I hate to use setTimeout with an arbitrary time to switch off the resizing flag, but if your requirements are not so strict it can get the job done beautifully
Why don't you incorporate a delay (for example 0.5 seconds) where you ignore all mouse inputs. After the delay, any mouse movements are likely to be from the user...
I solved it now by saving the mouse coordinates, and check if they change - while I force one mousemove event after fullscreen in order to update the coordinates once.
$(document).on('mousemove', function(event){
if(event.pageX == $(this).data('mouseX') && event.pageY == $(this).data('mouseY'))
return;
$(this)
.data('mouseX', event.pageX)
.data('mouseY', event.pageY)
;
});
$(document).mousemove();

d3-js mouse wheel problems when activating and deactivating zoom behavior

I activate and deactivate the zoom behavior as seen in http://bl.ocks.org/benzguo/4370043 :
var zoom = d3.behavior.zoom().on("zoom", rescale)
// after adding the handler, the mouse wheel will still scroll the page
// activate
svg_g_element.call(zoom)
// now, the mouse wheel zoom
// desactivate
svg_g_element.call(d3.behavior.zoom().on("zoom")
// now, the mouse wheel will neither zoom nor scroll while over the svg_g_element
How can a establish the default mouse wheel behavior to scroll the page? Or is the way show in the examples not the best way to deactivate the zoom behavior?
This code will disable mousewheel zoom on Firefox as well.
svg_g_element
.on("mousewheel.zoom", null)
.on("DOMMouseScroll.zoom", null) // disables older versions of Firefox
.on("wheel.zoom", null) // disables newer versions of Firefox
You might want to disable the zoom mousewheel event specifically with this.
svg_g_element.on("mousewheel.zoom", null);

How can I react when a user touches an HTML element on an iPhone?

I'm displaying some HTML content in my iPhone app using a UIWebView. I have an image link, and I want it to change when the user touches it - at the moment the user puts a finger on the screen, rather than waiting until they lift their finger back off.
What CSS or JavaScript concept could accomplish this? I've looked at the hover and active states in CSS, but they don't seem to be what I'm after: hover relates to touch-up rather than touch-down, while active seems to have no effect at all.
You could try this.
I think it should be what you are looking for!
http://articles.sitepoint.com/article/iphone-development-12-tips/2
8: Touch Events
Of course, you use your iPhone with a
finger instead of a mouse; rather than
clicking, you tap. What’s more, you
can use several fingers to touch and
tap. On the iPhone, mouse events are
replaced by touch events. They are:
touchstart
touchend
touchmove
touchcancel (when the system cancels the touch)
When you subscribe to any of those
events, your event listener will
receive an event object. The event
object has some important properties,
such as:
touches — a collection of touch objects, one for each finger that
touches the screen. The touch objects
have, for example, pageX and pageY
properties containing the coordinates
of the touch within the page.
targetTouches — works like touches, but only registers touches on
a target element as opposed to the
whole page.
The next example is a simple
implementation of drag and drop. Let’s
put a box on a blank page and drag it
around. All you need to do is
subscribe to the touchmove event and
update the position of the box as the
finger moves around, like so:
window.addEventListener('load', function() {
var b = document.getElementById('box'),
xbox = b.offsetWidth / 2, // half the box width
ybox = b.offsetHeight / 2, // half the box height
bstyle = b.style; // cached access to the style object
b.addEventListener('touchmove', function(event) {
event.preventDefault(); // the default behaviour is scrolling
bstyle.left = event.targetTouches[0].pageX - xbox + 'px';
bstyle.top = event.targetTouches[0].pageY - ybox + 'px';
}, false);
}, false);
The touchmove event listener first cancels the default behavior of the finger move—otherwise Safari will scroll the page. The collection event.targetTouches contains a list of data for each finger currently on the target div element.
We only care about one finger, so we use event.targetTouches[0]. Then pageX gives us the X coordinate of the finger. From this value we subtract half the width of the div so that the finger stays in the center of the box.
Hope it helps!
Try the Javascript "onMouseDown", hopefully the mobile Safari will fire the event.
Link

Categories

Resources