Как сделать медленную прокрутку на странице?
Я столкнулся с проблемой, что не могу сделать тяжелую ( медленную ) прокрутку страницы, чтобы скорость прокрутки можно было регулировать. Я тестил jQuery.scrollSpeed ( 1.0.1 ) и он не дал мне желаемого результат, может я не так что-то прописал.
$(function() {
jQuery.scrollSpeed(100, 800, 'easeOutCubic');
});
Мне нужно получить тяжелую прокрутку, чтобы пользователь не смог быстро прокрутить страницу , заранее спасибо )
Ответы (2 шт):
Автор решения: DiD
→ Ссылка
$("ul li a").click(function(e) {
// Первое - отменить переход по ссылке
e.preventDefault();
// Получаем ссылку на id элемента
const href = $(this).attr("href");
// Останавливаем прошлую анимацию
$("html, body").stop();
// Далее прокручиваем либо <html> либо <body>
// (универсально - оба: и <html> и <body>)
// методом $.animate(),
// первый параметр - вертикальное смещение элемента,
// второй параметр - это время в мс (2 сек).
$("html, body").animate({ scrollTop: $(href).offset().top }, 2000);
});
// Останавливаем анимацию при ручном скролле
$('html, body').on('wheel',function(e){
$('html, body').stop();
document.documentElement.scrollTop-=e.originalEvent.wheelDeltaY/20;
});
let touches = [];
$('body')
.on('touchstart',function(e){
const newTouches = [...e.originalEvent.changedTouches];
for(let touch of newTouches) {
touches.push(copyTouch(touch));
}
return false;
})
.on('touchmove',function(e){
const curTouches=[...e.originalEvent.changedTouches];
let touchOffset=0;
for(let touch of curTouches) {
const prevTouchIdx =
touches.findIndex(prevTouch =>
prevTouch.identifier==touch.identifier);
const prevPageY = touches[prevTouchIdx].pageY;
Object.assign(touches[prevTouchIdx],
copyTouch(touch));
touchOffset += touch.pageY - prevPageY;
}
/*console.log(document.documentElement.scrollTop,
-touchOffset-(curScrollTop-scrollOffset))*/
document.documentElement.scrollTop+=-touchOffset/2;
return false;
})
.on('touchend',function(e){
const endTouches=
[...e.originalEvent.changedTouches];
for(let touch of endTouches){
touches.splice(touches.findIndex(prevTouch=>
prevTouch.identifier==touch.identifier),1);
}
return false;
})
.on('touchcancel',function(e){
const cancelTouches=[...e.originalEvent.changedTouches];
for(let touch of cancelTouches){
touches.splice(touches.findIndex(prevTouch => prevTouch.identifier == touch.identifier),1);
}
return false;
});
function copyTouch({identifier,pageX,pageY}){
return {identifier,pageX,pageY};
}
html,body {
background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MCIgaGVpZ2h0PSI5MCI+CjxnIHRyYW5zZm9ybT0ic2NhbGUoMSAxLjUpIj4KPHJlY3Qgd2lkdGg9Ijk5IiBoZWlnaHQ9Ijk5IiBmaWxsPSIjNmQ2OTVjIj48L3JlY3Q+CjxyZWN0IHdpZHRoPSI0Mi40MiIgaGVpZ2h0PSI0Mi40MiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzAgMCkgcm90YXRlKDQ1KSIgZmlsbD0iIzYyNWY1MyI+PC9yZWN0Pgo8cmVjdCB3aWR0aD0iOTkiIGhlaWdodD0iMSIgdHJhbnNmb3JtPSJyb3RhdGUoNDUpIiBmaWxsPSIjNzE2ZjY0Ij48L3JlY3Q+CjxyZWN0IHdpZHRoPSI5OSIgaGVpZ2h0PSIxIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDYwKSByb3RhdGUoLTQ1KSIgZmlsbD0iIzcxNmY2NCI+PC9yZWN0Pgo8L2c+Cjwvc3ZnPg==");
overflow:hidden;
}
.section{
height: 150vh;
}
ul {
position: fixed;
left: 0;
top: 3rem;
background: #fff;
border: 2px solid #888;
}
h2 {
text-shadow: -1px -1px 3px #000, -1px 1px 3px #000, 1px -1px 3px #000, 1px 1px 3px #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
<ul>
<li><a href="#top">top</a></li>
<li><a href="#section_1">Section 1</a></li>
<li><a href="#section_2">Section 2</a></li>
<li><a href="#section_3">Section 3</a></li>
<li><a href="#section_4">Section 4</a></li>
</ul>
<div class="section">
<h2 id="top">Top</h2>
</div>
<div class="section">
<h2 id="section_1">Section 1</h2>
</div>
<div class="section">
<h2 id="section_2">Section 2</h2>
</div>
<div class="section">
<h2 id="section_3">Section 3</h2>
</div>
<div class="section">
<h2 id="section_4">Section 4</h2>
</div>
По "утяжелению" скролла, первое что пришло в голову - отменять скролл и устанавливать его вручную. Но события как scroll так и wheel невозможно отменить. Тогда пришлось вращать их вручную.
Автор решения: meine
→ Ссылка
class SmoothScroll {
constructor(node) {
this.settings = {
node: node || window,
html: document.documentElement,
target: 0,
scroll: 0
};
this.rAF = false;
this.update = this.update.bind(this);
this.onWheel = this.onWheel.bind(this);
this.onScroll = this.onScroll.bind(this);
this.settings.node.addEventListener('wheel', this.onWheel, false);
this.settings.node.addEventListener('scroll', this.onScroll, false);
}
update() {
this.settings.scroll += (this.settings.target - this.settings.scroll) * .1;
if (Math.abs(this.settings.scroll.toFixed(5) - this.settings.target) <= .47131) {
cancelAnimationFrame(this.rAF);
this.rAF = false;
}
this.settings.node == window
? scrollTo(0, this.settings.scroll)
: this.settings.node.scrollTop = this.settings.scroll;
if (this.rAF)
this.rAF = requestAnimationFrame(this.update);
}
onWheel(e) {
e.preventDefault();
e.stopPropagation();
const scrollEnd = (this.settings.node == window)
? this.settings.html.scrollHeight - this.settings.html.clientHeight
: this.settings.node.scrollHeight - this.settings.node.clientHeight;
this.settings.target += (e.wheelDelta > 0) ? - 70 : 70;
if (this.settings.target < 0)
this.settings.target = 0;
if (this.settings.target > scrollEnd)
this.settings.target = scrollEnd;
if (!this.rAF)
this.rAF = requestAnimationFrame(this.update);
}
onScroll(e) {
if (this.rAF) return;
this.settings.target = (this.settings.node == window)
? pageYOffset || this.settings.html.scrollTop
: this.settings.node.scrollTop;
this.settings.scroll = this.settings.target;
}
}
new SmoothScroll();
* {
margin: 0; padding: 0;
box-sizing: border-box;
}
body {
-webkit-font-smoothing: antialiased;
}
section { height: 100vh; }
section:nth-child(1) { background-color: yellow; }
section:nth-child(2) { background-color: black; }
section:nth-child(3) { background-color: green; }
section:nth-child(4) { background-color: purple; }
<section></section>
<section></section>
<section></section>
<section></section>