Почему "заедает" скролл?

77
20 марта 2022, 18:00

Если полоса прокрутки дошла до конца или находится в начале (в любом направлении), она иногда там "застревает"... нужно активно пошевелить мышкой или ещё что-то, я если честно не разобрал... почему это происходит?

Код очень простой: курсор правее центра - происходит скрол вправо, выше центра - вверх и т.д

var X, Y; 
var [xCounter, yCounter, xDirection, yDirection, dx, dy] = [0, 0, 0, 0, 0, 0]; 
var centerX, centerY, innerWidthHalf, innerHeightHalf; 
 
init(); 
 
window.addEventListener('mousemove', mouseMoveHandler); 
 
function mouseMoveHandler(e) { 
  X = e.x; 
  Y = e.y; 
 
  dx = e.x - innerWidthHalf; 
  dy = e.y - innerHeightHalf; 
 
  if (X > innerWidthHalf) xDirection = -1; 
  else if (X < innerWidthHalf) xDirection = 1; 
  else xDirection = 0; 
 
  if (Y > innerHeightHalf) yDirection = -1; 
  else if (Y < innerHeightHalf) yDirection = 1; 
  else yDirection = 0; 
} 
 
requestAnimationFrame(move); 
 
function move() { 
  var speedX = Math.abs(dx / 30); 
  var speedY = Math.abs(dy / 15); 
 
  xCounter = xCounter + xDirection * speedX; 
  yCounter = yCounter + yDirection * speedY; 
 
  window.scroll(X - xCounter, Y - yCounter); 
 
  requestAnimationFrame(move); 
} 
 
function init() { 
  centerX = innerWidth * 2; 
  centerY = innerHeight * 2; 
 
  innerWidthHalf = innerWidth / 2; 
  innerHeightHalf = innerHeight / 2; 
} 
 
window.addEventListener('resize', () => init());
body { 
  margin: 0; 
  height: 400vh; 
  width: 400vw; 
  background-image: url(https://st2.depositphotos.com/1430176/7473/v/950/depositphotos_74731081-stock-illustration-medicine-doodle-seamless-background.jpg); 
}

Я так понял, оно застревает, потому что функция move успевает навызываться кучу раз пока скролл находится вначале или в конце...

Вот значения того, находится ли скролл в конце или в начале:

function move() {
  .....
  var dE = document.documentElement;
  var dBBox = document.body.getBoundingClientRect();
  isXEnd = pageXOffset == dBBox.width - dE.clientWidth;
  isYEnd = pageYOffset == dBBox.height - dE.clientHeight;
  isXStart = pageXOffset == 0;
  isYStart = pageYOffset == 0;
  .....
  .....
}

Как с помощью них остановить функцию я могу сделать, но как потом заново всё возобновить я не понимаю )

Answer 1

У вас проблема в том, что "нужная" позиция прокрутки сохраяется в переменной и много раз в секунду задается из переменной. И если проскролить страницу мышкой, оно тут же возвращает значение из переменной. Я это исправил, заменив scroll(toX, toY) на scrollBy(dx, dy)

var cursorX = 0, 
  cursorY = 0; 
 
var xDirection = 0, 
  yDirection = 0; 
 
var centerX, centerY; 
 
function mouseMoveHandler(event) { 
  cursorX = event.x; 
  cursorY = event.y; 
 
  if (cursorX > centerX) { 
    xDirection = 1; 
  } else if (cursorX < centerX) { 
    xDirection = -1; 
  } else { 
    xDirection = 0; 
  } 
 
  if (cursorY > centerY) { 
    yDirection = 1; 
  } else if (cursorY < centerY) { 
    yDirection = -1; 
  } else { 
    yDirection = 0; 
  } 
} 
window.addEventListener('mousemove', mouseMoveHandler); 
 
function move() { 
  var speedX = Math.abs(centerX - cursorX) / 30; 
  var speedY = Math.abs(centerY - cursorY) / 15; 
 
  var scrollX = xDirection * speedX; 
  var scrollY = yDirection * speedY; 
 
  window.scrollBy(scrollX, scrollY); 
 
  requestAnimationFrame(move); 
} 
requestAnimationFrame(move); 
 
function init() { 
  centerX = window.innerWidth / 2; 
  centerY = window.innerHeight / 2; 
} 
 
window.addEventListener('resize', init); 
init();
body { 
  margin: 0; 
  height: 400vh; 
  width: 400vw; 
  background-image: url(https://st2.depositphotos.com/1430176/7473/v/950/depositphotos_74731081-stock-illustration-medicine-doodle-seamless-background.jpg); 
}

READ ALSO
Google charts с видоискателем

Google charts с видоискателем

Подскажите, как построить с помощью Google charts график из видоискателем по времени типа http://nvd3org/examples/lineWithFocus

66
Proxy для вложенных объектов

Proxy для вложенных объектов

Всем привет! Я относительно недавно пришёл в JS и время от времени люблю создавать свои велосипеды чтобы понять лучше сам язык и реализацию...

222