So I have write a script for my portfolio website to scroll to section by index. It works on every tested browser and smartphone but on a mac device it does not work probably instead to scroll to the next sections it is going automatically to the second next section.
Hopefully someone can help me.
var anchorPoints = [];
var anchorLocation = [];
var anchorIndex = 0;
var waiting = false;
var canScroll = true;
var offset = 0
window.onload = function () {
anchorPoints = document.getElementsByClassName("js-anchor");
for (i = 0; i < anchorPoints.length; i++) {
getLocation = anchorPoints[i].getBoundingClientRect();
getLocation = getLocation.top - offset;
anchorLocation.push(parseInt(getLocation));
}
}
$(document).on('mousewheel DOMMouseScroll', function (e) {
if (detectMobile() == true) {
return;
}
if ((waiting || canScroll == false)) {
return;
}
e.preventDefault();//prevent the default mousewheel scrolling
var active = $('section.active');
var delta = e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0 ? 1 : -1;
waiting = true;
if (delta < 0) {
anchorIndex += 1;
if (anchorIndex > (anchorPoints.length - 1)) {
anchorIndex = 0;
}
scrollTo({
top: anchorLocation[anchorIndex],
left: 0,
behavior: 'smooth'
});
console.log(anchorIndex);
console.log('scrolling down');
} else {
anchorIndex -= 1;
if (anchorIndex < 0) {
anchorIndex = anchorPoints.length - 1;
}
scrollTo({
top: anchorLocation[anchorIndex],
left: 0,
behavior: 'smooth'
});
console.log(anchorIndex);
console.log('scrolling up');
}
setTimeout(function () {
waiting = false;
}, 1000);
});
Related
I am trying to create a on scroll fade animation in my website i am using reactjs for this although i didnt knew how to bring this effect so i found this jquery code to achive this effect but i want to bring this effect without jquery using plane react is it possible? here is the jquery code:
var html = $('html');
// Detections
if (!("ontouchstart" in window)) {
html.addClass("noTouch");
}
if ("ontouchstart" in window) {
html.addClass("isTouch");
}
if ("ontouchstart" in window) {
html.addClass("isTouch");
}
if (document.documentMode || /Edge/.test(navigator.userAgent)) {
if (navigator.appVersion.indexOf("Trident") === -1) {
html.addClass("isEDGE");
} else {
html.addClass("isIE isIE11");
}
}
if (navigator.appVersion.indexOf("MSIE") !== -1) {
html.addClass("isIE");
}
if (
navigator.userAgent.indexOf("Safari") != -1 &&
navigator.userAgent.indexOf("Chrome") == -1
) {
html.addClass("isSafari");
}
// On Screen
$.fn.isOnScreen = function() {
var elementTop = $(this).offset().top,
elementBottom = elementTop + $(this).outerHeight(),
viewportTop = $(window).scrollTop(),
viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
function detection() {
for (var i = 0; i < items.length; i++) {
var el = $(items[i]);
if (el.isOnScreen()) {
el.addClass("in-view");
} else {
el.removeClass("in-view");
}
}
}
var items = document.querySelectorAll(
"*[data-animate-in], *[data-detect-viewport]"
),
waiting = false,
w = $(window);
w.on("resize scroll", function() {
if (waiting) {
return;
}
waiting = true;
detection();
setTimeout(function() {
waiting = false;
}, 100);
});
$(document).ready(function() {
setTimeout(function() {
detection();
}, 500);
for (var i = 0; i < items.length; i++) {
var d = 0,
el = $(items[i]);
if (items[i].getAttribute("data-animate-in-delay")) {
d = items[i].getAttribute("data-animate-in-delay") / 1000 + "s";
} else {
d = 0;
}
el.css("transition-delay", d);
}
});
});
is there any way that i can bring this effect from react only or do i have to use :
import $ from jquery
thanks in advance
i have an issue concerning a JS scrolling function.
const scroll = document.querySelectorAll(".scroll");
const maxIndex = 3; //NB DE PAGES
let index = 0;
let animationEnd = true;
let boolUp = 0;
const start = {
x: 0,
y: 0
};
function touchStart(event) {
event.preventDefault();
start.x = event.touches[0].pageX;
start.y = event.touches[0].pageY;
}
function touchMove(event) {
event.preventDefault();
const offset = {};
offset.x = start.x - event.touches[0].pageX;
offset.y = start.y - event.touches[0].pageY;
scrollHandler({
deltaY: offset.y
});
}
function scrollHandler(e) {
if(e.preventDefault) e.preventDefault();
if (animationEnd) {
if (e.deltaY > 0) index++;
else index--;
if (index < 0) index = 0;
if (index > scroll.length - 1) index = scroll.length - 1;
scroll[0].style.marginTop = "-" + index * 100 + "vh";
animationEnd = false;
setTimeout(() => animationEnd = true, 450)
}
}
function keyScroll(e) {
if (e.key == "ArrowUp") {
index--;
if (index < 0) {
index = 0;
}
scroll[0].style.marginTop = "-" + index * 100 + "vh";
animationEnd = false;
setTimeout(() => animationEnd = true, 450);
} else if (e.key == "ArrowDown") {
if (index < maxIndex) {
index++;
scroll[0].style.marginTop = "-" + index * 100 + "vh";
animationEnd = false;
setTimeout(() => animationEnd = true, 450);
}
}
}
I'm calling those by body event listeners :
document.addEventListener("scroll", (e) => e.preventDefault())
document.body.addEventListener("keydown", keyScroll);
document.body.addEventListener("wheel", scrollHandler,);
document.body.addEventListener("touchstart", touchStart, false);
document.body.addEventListener("touchmove", touchMove, false);
It's working perfectly => example at https://darleanow.github.io .
But when i'm on smartphone (Iphone), scroll might bug and the height of divs would appear different, you can try it on your own smartphone to see what i'm talking about, try scrolling a bit fast etc...
If anybody has an idea :)
This isn't a solution necessarily, but you might try printing scroll[0].stlye.marginTop to the console every time it changes.
If that value is never erroneous, I'd guess the issue is with the animation (maybe scrolling while it's animating, or something like that).
I have a small problem with my looping scroll. It works pretty well on larger displays, but on handheld devices it glitches quite a lot. I'm not sure where I'm doing something wrong or where I should adjust the code to work on mobile as well.
Link to site: https://studio-6-9ede0f.webflow.io/
Here's what I got so far:
var origDivHeight = document.querySelector(".infinite").offsetHeight;
var clone=$(".infinite").contents().clone();
clone.appendTo(".infinite");
clone.prependTo(".infinite");
$(document).scroll(function(){
var scrollWindowPos = $(document).scrollTop();
if(scrollWindowPos >= origDivHeight ) {
$(document).scrollTop(0);
}
if(scrollWindowPos <= 0 ) {
$(document).scrollTop(origDivHeight);
}
});
window.scrollBy(0, 1);
window.scrollBy(0, -1);
Got it to work based on this codepen: https://codepen.io/vincentorback/pen/zxRyzj
Sharing it here as well if somebody finds it useful:
<style>
html,
body {
height: 100%;
overflow: hidden;
}
.infinite {
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.clone {
height: 50vw;
}
</style>
<script>
var doc = window.document,
context = doc.querySelector('.infinite'),
clones = context.querySelectorAll('.clone'),
disableScroll = false,
scrollHeight = 0,
scrollPos = 0,
clonesHeight = 0,
i = 0;
function getScrollPos () {
return (context.pageYOffset || context.scrollTop) - (context.clientTop || 0);
}
function setScrollPos (pos) {
context.scrollTop = pos;
}
function getClonesHeight () {
clonesHeight = 0;
for (i = 0; i < clones.length; i += 1) {
clonesHeight = clonesHeight + clones[i].offsetHeight;
}
return clonesHeight;
}
function reCalc () {
scrollPos = getScrollPos();
scrollHeight = context.scrollHeight;
clonesHeight = getClonesHeight();
if (scrollPos <= 0) {
setScrollPos(1); // Scroll 1 pixel to allow upwards scrolling
}
}
function scrollUpdate () {
if (!disableScroll) {
scrollPos = getScrollPos();
if (clonesHeight + scrollPos >= scrollHeight) {
// Scroll to the top when you’ve reached the bottom
setScrollPos(1); // Scroll down 1 pixel to allow upwards scrolling
disableScroll = true;
} else if (scrollPos <= 0) {
// Scroll to the bottom when you reach the top
setScrollPos(scrollHeight - clonesHeight);
disableScroll = true;
}
}
if (disableScroll) {
// Disable scroll-jumping for a short time to avoid flickering
window.setTimeout(function () {
disableScroll = false;
}, 40);
}
}
function init () {
reCalc();
context.addEventListener('scroll', function () {
window.requestAnimationFrame(scrollUpdate);
}, false);
window.addEventListener('resize', function () {
window.requestAnimationFrame(reCalc);
}, false);
}
if (document.readyState !== 'loading') {
init()
} else {
doc.addEventListener('DOMContentLoaded', init, false)
}
</script>
I use only a little part of Jquery code and I want to translate it
$("html,body").animate(
{
scrollTop: sections[counter].offsetTop,
behavior: "smooth",
},
800
);
Window.scrollTo() doesn't work
Full code
let delay = false;
let counter = 0;
// let scrollHeight = 0;
const sections = document.querySelectorAll(".scrolling-block");
function scrollToSection(e, directionY, directionX) {
if (delay) return;
// console.log(e);
delay = true;
if (directionY !== 0) {
// if scroll by y
setTimeout(function () {
delay = false;
}, 1500);
} else {
// if scroll by x
delay = false;
}
if (directionY !== 0 || directionY !== -0) {
e.preventDefault();
}
if (directionY > 0) {
//scroll down
if (counter + 1 !== sections.length) {
// scrollHeight += sections[counter].clientHeight;
counter++;
} else {
scrollHeight = scrollHeight;
counter = counter;
}
$("html,body").animate(
{
scrollTop: sections[counter].offsetTop,
behavior: "smooth",
},
800
);
// console.log(scrollHeight + "\n", counter);
return counter;
} else if (directionY < 0) {
//scroll up
if (counter - 1 !== -1) {
// scrollHeight -= sections[counter - 1].clientHeight;
counter--;
} else {
scrollHeight = scrollHeight;
counter = counter;
}
$("html,body").animate(
{
scrollTop: sections[counter].offsetTop,
behavior: "smooth",
},
800
);
// console.log(scrollHeight);
return counter;
}
}
window.addEventListener(
"wheel",
function (e) {
let directionY = e.deltaY;
let directionX = e.deltaX;
let maxY = sections[sections.length - 1].offsetTop;
if (pageYOffset < maxY - 10) {
// console.log(scrollHeight, " < ", maxY);
if (directionY !== 0) {
e.preventDefault();
}
scrollToSection(e, directionY, directionX);
} else {
if (pageYOffset < maxY && directionY < 0) {
if (directionY !== 0) {
e.preventDefault();
}
scrollToSection(e, directionY, directionX);
}
// console.log(scrollHeight, " > ", maxY);
}
// e.stopPropagation();
},
{ passive: false }
);
Technically both scroll and scrollTo should do the same thing
window.scrollTo({
top: 100,
left: 100,
behavior: 'smooth'
});
OR
window.scroll({
top: 100,
left: 100,
behavior: 'smooth'
});
Please check the documentation here:
[1]: https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo
[2]: https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll
im currently making a game, and this is the jump mechanic.
the idea behind it is that it goes up for 500ms, waits for 200ms, and goes back to the ground (the ground is at top 471).
everything works now but it doesn't stop when its at top 471 i tried doing this:
if (characterTop > 471) {
stopMoveDown()
}
that didn't work so then i tried doing this: (in the movingDown function)
if (characterTop > -1 || character < 471) {
character.style.top = top + "px";
}
both of these didn't work.
and there is another problem, how can i make sure the player can't jump again while jumping?
this is the code i have now:
document.body.onkeydown = function(e){
if(e.keyCode == 32){
jump = setInterval(function(){
let top =
parseInt (window.getComputedStyle(character).getPropertyValue("top"));
top -= 1;
var characterTop = parseInt(
window.getComputedStyle(character).getPropertyValue("top")
)
if (characterTop > -1 || character < 471) {
character.style.top = top + "px";
}
}, 1);
setTimeout(function() {
stopMoveUp()
}, 500);
setTimeout(function() {
movingDown()
}, 700);
//if (characterTop > 471) {
// stopMoveDown()
//}
}
}
function movingDown() {
falling = setInterval(function(){
let top =
parseInt (window.getComputedStyle(character).getPropertyValue("top"));
top += 1;
var characterTop = parseInt(
window.getComputedStyle(character).getPropertyValue("top")
)
if (characterTop > -1 || character < 471) {
character.style.top = top + "px";
}
}, 1);
}
function stopMoveUp() {
clearInterval(jump);
}
function stopMoveDown() {
clearInterval(movingDown);
}
var movingRight = false;
var movingLeft = false;
can anybody please help me with these 2 problems?