iOS: Animated scroll position jumps on long touch gestures - ios

Based on TweenMax, the ScrollTo Plugin and ScrollMagic (this is probably not where the problem came from):
I wanna have a hero section on top of a page, only tweening downwards if the user is scrolling from the very beginning. Everything works as expected on my laptop (MBP). Following problem: If I use a touch-device (iPhone SE, iOS 12.4.1) and use a short touch gesture, the window is tweening to the destination withouth any issue. But if I keep my finger on the screen, the page starts to flicker and jumps back to the top after the tween finished.
Codepen
Since it's not working with Codepen on my mobile device:
Reduced test
Is there any way to fix this behaviour? Already tried to toggle preventDefault with eventListeners on Callbacks as well as setting the position again onComplete.
var vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
// assume the feature isn't supported
var supportsPassive = false;
// create options object with a getter to see if its passive property is accessed
var opts = Object.defineProperty && Object.defineProperty({}, 'passive', { get: function(){ supportsPassive = true }});
// create a throwaway element & event and (synchronously) test out our options
document.addEventListener('test', function() {}, opts);
// var allowScroll = true;
function preventDefault(e) {
e = e || window.event;
if (e.preventDefault) {
e.preventDefault();
}
// if (e.stopImmediatePropagation) {
// e.stopImmediatePropagation();
// }
if (e.stopPropagation) {
e.stopPropagation();
}
e.returnValue = false;
}
function getBodyScrollTop() {
var el = document.scrollingElement || document.documentElement;
return el.scrollTop;
// return window.pageYOffset
}
function setBodyScrollTop(scrollTop) {
var el = document.scrollingElement || document.documentElement;
el.scrollTop = scrollTop;
// window.pageYOffset = scrollTop;
}
function addMousewheelListener() {
if (e.addEventListener)
{
// IE9, Chrome, Safari, Opera
e.addEventListener("mousewheel", preventScroll, supportsPassive ? { passive: false } : false);
// Firefox
e.addEventListener("DOMMouseScroll", preventScroll, supportsPassive ? { passive: false } : false);
}
// IE 6/7/8
else
{
e.attachEvent("onmousewheel", preventScroll);
}
}
function removeMousewheelListener() {
if (e.removeEventListener)
{
// IE9, Chrome, Safari, Opera
e.removeEventListener("mousewheel", preventScroll, supportsPassive ? { passive: false } : false);
// Firefox
e.removeEventListener("DOMMouseScroll", preventScroll, supportsPassive ? { passive: false } : false);
}
// IE 6/7/8
else
{
e.detachEvent("onmousewheel", preventScroll);
}
}
function removeTouchListeners(e) {
window.removeEventListener("touchmove", preventScroll);
window.removeEventListener("touchstart", removeTouchListeners);
window.removeEventListener("touchend", removeTouchListeners);
}
function preventScroll(e) {
// if(TweenMax.isTweening(window) || !allowScroll) {
// e.preventDefault();
// e.stopImmediatePropagation();
preventDefault(e)
// }
}
function deactivateScroll() {
// allowScroll = false;
console.log('fired 1');
// window.addEventListener("touchstart", preventScroll, { passive: false });
window.addEventListener("touchmove", preventScroll, { passive: false });
addMousewheelListener();
}
function activateScroll() {
// allowScroll = true;
removeMousewheelListener();
// var scrollTop = y;
// var scrollTop = getBodyScrollTop;
// setBodyScrollTop(scrollTop);
window.addEventListener("touchstart", removeTouchListeners, { passive: false });
window.addEventListener("touchend", removeTouchListeners, { passive: false });
// var event1 = new Event('touchstart');
// var event2 = new Event('touchmove');
// var event3 = new Event('touchend');
// window.dispatchEvent(event1);
// window.dispatchEvent(event2);
// window.dispatchEvent(event3);
}
var ctrl = new ScrollMagic.Controller();
var sceneLeave = new ScrollMagic.Scene({
triggerElement: "#content",
triggerHook: "onEnter",
offset: 1
})
.addTo(ctrl)
.on("enter", function(event) {
TweenMax.to(window, 1, {
scrollTo: {
y: "#content",
autoKill: false
},
onStart: deactivateScroll,
onComplete: activateScroll
});
});

Related

$(window).scroll(function () {}) is not working

I'm trying to perform some action on window scroll event but it is not working.
Here is my code
$(window).scroll(function () {
// var limit = 7; //The number of records to display per request
var lastID = $newsfeed_start;
if (($(window).scrollTop() == $(document).height() - $(window).height()&& (lastID != 0)) {
// increment strat value
$newsfeed_start = $newsfeed_start + $newsfeed_limit;
get_timeline_post('');
}
});
even $(window).scroll(function () { } ) function is not working
Your CSS is actually setting the rest of the document to not show overflow therefore the document itself isn't scrolling. The easiest fix for this is bind the event to the thing that is scrolling, which in your case is div#page.
So its easy as changing:
$(document).scroll(function() { // OR $(window).scroll(function() {
didScroll = true;
});
to
$('div#page').scroll(function() {
didScroll = true;
});

How to Render Webcam/Live video in WebGL without Library

I have been following this tutorial and it succesfully renders video on to a cube using webGL.
Is it possible for instead of using a video I would like to use a live feed from a webcam without using frameworks like Three.js?
The code below reads from the webcam into HTMLVideoElement how to convert it into texture so I can map it to my vertices in raw WebGL?
function setupVideo(url) {
const video = document.createElement('video');
var playing = false;
var timeupdate = false;
video.autoplay = true;
video.muted = true;
video.loop = true;
// Waiting for these 2 events ensures
// there is data in the video
video.addEventListener('playing', function() {
playing = true;
checkReady();
}, true);
video.addEventListener('timeupdate', function() {
timeupdate = true;
checkReady();
}, true);
navigator.getUserMedia = ( navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
var hasUserMedia = navigator.getUserMedia ? true : false;
console.log(hasUserMedia);
// Prefer camera resolution nearest to 1280x720.
var constraints = { audio: true, video: { width: 640, height: 360 } };
navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStream) {
video.srcObject = mediaStream;
video.onloadedmetadata = function(e) {
};
})
.catch(function(err) { console.log(err.name + ": " + err.message); }); // always check for errors at the end.
video.play();
function checkReady() {
if (playing && timeupdate) {
copyVideo = true;
}
}
return video;
}

Setting Context Item position in Firefox addons SDK

I'm writing an extension that involving adding an item to Firefox's context menu, but it appends to the end of the menu and I couldn't find any pointers customizing item's position using Addon SDK (insertBefore/insertAfter), I know how this can be done using XUL, but I'm trying to do it using Addon SDK or some sort of Addon SDK/XUL combination
This is the code snippet related to context menu
main.js
var pageMod = require("sdk/page-mod");
var data = require("sdk/self").data;
var tabs = require("sdk/tabs");
var cm = require("sdk/context-menu");
pageMod.PageMod({
include: "*.youtube.com",
contentScriptFile: data.url("page.js"),
onAttach: function (worker) {
worker.port.emit('link', data.url('convertbutton.png'));
}});
cm.Item({
label: "Convert File",
image: data.url("bighdconverterlogo128png.png"),
context: [
cm.URLContext(["*.youtube.com"]),
cm.PageContext()
],
contentScriptFile: data.url("menu.js"),
onMessage: function(vUrl){
tabs.open(vUrl);
}
});
data/menu.js
self.on("click", function(){
self.postMessage('http://hdconverter.co/' + 'c.php?url=' + window.location.href);
});
Thanks
i dont know about sdk but for non-sdk addons its easy. but because you dont have the boiler plate setup its going to look long. add this code to your addon at the bottom:
var positionToInsertMenu = 0; //set the position you want it at here
var myLabelText = 'Convert File';
const {interfaces: Ci,utils: Cu} = Components;
Cu.import('resource://gre/modules/Services.jsm');
/*start - windowlistener*/
var windowListener = {
//DO NOT EDIT HERE
onOpenWindow: function (aXULWindow) {
// Wait for the window to finish loading
let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
aDOMWindow.addEventListener("load", function () {
aDOMWindow.removeEventListener("load", arguments.callee, false);
windowListener.loadIntoWindow(aDOMWindow, aXULWindow);
}, false);
},
onCloseWindow: function (aXULWindow) {},
onWindowTitleChange: function (aXULWindow, aNewTitle) {},
register: function () {
// Load into any existing windows
let XULWindows = Services.wm.getXULWindowEnumerator(null);
while (XULWindows.hasMoreElements()) {
let aXULWindow = XULWindows.getNext();
let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
windowListener.loadIntoWindow(aDOMWindow, aXULWindow);
}
// Listen to new windows
Services.wm.addListener(windowListener);
},
unregister: function () {
// Unload from any existing windows
let XULWindows = Services.wm.getXULWindowEnumerator(null);
while (XULWindows.hasMoreElements()) {
let aXULWindow = XULWindows.getNext();
let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
windowListener.unloadFromWindow(aDOMWindow, aXULWindow);
}
//Stop listening so future added windows dont get this attached
Services.wm.removeListener(windowListener);
},
//END - DO NOT EDIT HERE
loadIntoWindow: function (aDOMWindow, aXULWindow) {
if (!aDOMWindow) {
return;
}
var contentAreaContextMenu = aDOMWindow.document.getElementById('contentAreaContextMenu');
var myMenuItem;
if (contentAreaContextMenu) {
var menuItems = contentAreaContextMenu.querySelector('menuitem');
[].forEach.call(menuItems, function(item) {
if (item.getAttribute('label') == myLabelText) {
myMenuItem = item;
}
});
contentAreaContextMenu.removeChild(myMenuItem);
if (contentAreaContextMenu.childNodes.length >= positionToInsertMenu) { //position is greater then number of childNodes so append to end
contentAreaContextMenu.appendChild(myMenuItem);
} else {
contentAreaContextMenu.insertBefore(myMenuItem, contentAreaContextMenu.childNodes[thePosition]);
}
}
},
unloadFromWindow: function (aDOMWindow, aXULWindow) {
if (!aDOMWindow) {
return;
}
var myMenuItem = aDOMWindow.document.getElementById('myMenuItem');
if (myMenuItem) {
myMenuItem.parentNode.removeChild(myMenuItem);
}
}
};
windowListener.register();
on unload of your addon add this:
windowListener.unregister();
i copied pasted from a template and modded it real fast. for position to be accurate you probably have to consider which menuitems are hidden and which are not

How can I manipulate the UI for this jQuery div scroller?

I'm currently using the following code to scroll up/down text... I'd like to make the following modifications to the code, but am struggling on how to achieve it:
Check the location of the text and affect the opacity of the
up/down arrows. When the content of #scroll is at the top, the up (#scroll-up) arrow would be faded back. When the content of #scroll is at the bottom, the down (#scroll-down) arrow be faded back. Every where in between, both button's would be faded in.
Hide the scroll buttons if they are not needed
Here's the current code:
var ele = $('#scroll');
var speed = 25, scroll = 5, scrolling;
$('#scroll-up').mouseenter(function() {
scrolling = window.setInterval(function() {
ele.scrollTop( ele.scrollTop() - scroll );
}, speed);
});
$('#scroll-down').mouseenter(function() {
scrolling = window.setInterval(function() {
ele.scrollTop( ele.scrollTop() + scroll );
}, speed);
});
$('#scroll-up, #scroll-down').bind({
click: function(e) {
e.preventDefault();
},
mouseleave: function() {
if (scrolling) {
window.clearInterval(scrolling);
scrolling = false;
}
}
});
Looks like this might do the trick.
$(function() {
var ele = $('#scroll');
var speed = 25, scroll = 5, scrolling;
$("#scroll-up").css('opacity', 0.5);
$('#scroll-up').mouseenter(function() {
// Scroll the element up
scrolling = window.setInterval(function() {
ele.scrollTop( ele.scrollTop() - scroll );
$("#scroll-up").css("opacity", (ele.scrollTop() == 0) ? 0.5 : 1);
$("#scroll-down").css("opacity", (ele[0].scrollHeight - ele.scrollTop() == ele.outerHeight()) ? 0.5 : 1);
}, speed);
});
$('#scroll-down').mouseenter(function() {
// Scroll the element down
scrolling = window.setInterval(function() {
ele.scrollTop( ele.scrollTop() + scroll );
$("#scroll-up").css("opacity", (ele.scrollTop() == 0) ? 0.5 : 1);
$("#scroll-down").css("opacity", (ele[0].scrollHeight - ele.scrollTop() == ele.outerHeight()) ? 0.5 : 1);
}, speed);
});
$('#scroll-up, #scroll-down').bind({
click: function(e) {
// Prevent the default click action
e.preventDefault();
},
mouseleave: function() {
if (scrolling) {
window.clearInterval(scrolling);
scrolling = false;
}
}
});
var winHeight = $(window).height();
$("#scroll").css("height", winHeight - 220);
if (ele[0].scrollHeight == ele.outerHeight()){
$("#contentscrollnav").hide();
}
});
$(window).resize(function() {
var winHeight = $(window).height();
$("#scroll").css("height", winHeight - 220);
var ele = $('#scroll');
if (ele[0].scrollHeight <= ele.outerHeight()){
$("#contentscrollnav").hide();
} else if (ele[0].scrollHeight > ele.outerHeight()) {
$("#contentscrollnav").show();
}
});
You can see the code in action at:
http://jsfiddle.net/MzDst/11/

Pinch and zoom not working on ipad

I am unable to do pinch and zoom on ipad, I guess that the below given code may be effecting the code,
Please give any perfect solution.
Is there any issue with the binding of body child events or need to calculate the touches in different variables, and do manual calculation.
///I-Pad evenet Binding
$(document).ready(function () {
$("body").children().bind('touchstart touchmove touchend touchcancel', function () {
var touches = event.changedTouches, first = touches[0], type = "";
switch (event.type) {
case "touchstart": type = "mousedown";
break;
case "touchmove": type = "mousemove";
break;
case "touchend": type = "mouseup";
break;
default: return;
}
var simulatedEvent = document.createEvent("MouseEvent");
simulatedEvent.initMouseEvent(type, true, true, window, 1,
first.screenX, first.screenY,
first.clientX, first.clientY, false,
false, false, false, 0/*left*/, null);
if (touches.length < 2) {
first.target.dispatchEvent(simulatedEvent);
event.preventDefault();
}
});
(function () {
var last_x = null, last_y = null, w_area = workarea[0],
panning = false, keypan = false, dopanning = false;
$("#svgroot").bind('mousemove mouseup', function (evt) {
if (dopanning === false) return;
var clientxnew = +$("#svgcontent")[0].getAttribute("x"),
clientynew = +$("#svgcontent")[0].getAttribute("y");
clientxnew += (evt.clientX - last_x);
clientynew += (evt.clientY - last_y);
last_x = evt.clientX;
last_y = evt.clientY;
//this.setAttribute("viewBox", vb.join(' '));
// updateCanvas(true);
$("#svgcontent").show();
$("#svgcontent")[0].setAttribute("x", clientxnew);
$("#svgcontent")[0].setAttribute("y", clientynew);
svgedit.select.getSelectorManager().selectorParentGroup.setAttribute("transform", "translate(" + clientxnew + "," + clientynew + ")");
if (evt.type === 'mouseup') { dopanning = false; }
return false;
}).mousedown(function (evt) {
var mouse_target = svgCanvas.getMouseTarget(evt);
if (svgCanvas.getMode() == "text" || svgCanvas.getMode() == "textedit") {
dopanning = false; return;
}
if ((mouse_target.id.indexOf("grouplayerdragged") > -1 || mouse_target.id.indexOf("hotspot") > -1 ||
mouse_target.id.indexOf("clonediv") > -1 || mouse_target.tagName === "text")) { dopanning = false; return; }
if (selectedElement != null) {
dopanning = false; return;
}
if (evt.button === 0) {
dopanning = true;
last_x = evt.clientX;
last_y = evt.clientY;
svgCanvas.clearSelection(true);
return false;
}
});
$(window).mouseup(function () {
panning = false;
dopanning = false;
});
you should use gesturechange. try this way (this is not your exact solution but you can hack it)
var angle = 0;
var newAngle;
var scale = 1;
var newScale;
function saveChanges() {
angle = newAngle;
scale = newScale;
}
function getAngleAndScale(e) {
// Don't zoom or rotate the whole screen
e.preventDefault();
// Rotation and scale are event properties
newAngle = angle + e.rotation;
newScale = scale * e.scale;
// Combine scale and rotation into a single transform
var tString = "scale(" + newScale + ")";
document.getElementById("theDiv").style.webkitTransform = tString;
}
function init() {
// Set scale and rotation during gestures
document.getElementById("theDiv").addEventListener("gesturechange", getAngleAndScale, false);
// Preserve scale and rotation when gesture ends
document.getElementById("theDiv").addEventListener("gestureend", saveChanges, false);
}
<body>
<div style="width:300px;height:300px;overflow:scrool;-webkit-overflow-scrolling: touch;">
<img id="theDiv" style="width:100%;" src="http://animal.discovery.com/guides/wild-birds/gallery/mallard_duck.jpg" />
</div>
Try this on your ipad

Resources