У меня есть div
в моем html, и я добавил overflow: scroll
. Я хочу, чтобы он прокручивался в соответствии с движением мыши. Если мышь находится в левой части экрана, прокрутка должна быть в начале. Если мышь находится в центре экрана, прокрутка должна быть в центре, и то же самое касается права.
Загляните на этот сайт . Вы должны увидеть верхнюю панель навигации с миниатюрами, которая прокручивается в соответствии с движениями мыши. Я хочу точно такой же эффект. Я построил его, но он не работает, как ожидалось. Если моя мышь находится в центре экрана, полоса прокрутки находится не в центре, а справа. посмотри. Ниже мой код:
const gallery = document.getElementById('gallery');
const activeImage = document.getElementById('active-image');
const thumbnail = document.querySelector('.thumbnail');
const thumbnailWrapper = document.getElementById('thumbnail-wrapper');
thumbnailWrapper.addEventListener('mouseenter', handleMouseMove);
thumbnailWrapper.addEventListener('mousemove', handleMouseMove);
function handleMouseMove(e) {
const noOfPics = Array.from(thumbnailWrapper.childNodes).length
const clientX = e.clientX;
const clientY = e.clientY;
const width = window.innerWidth;
const height = window.innerHeight;
const wrapperWidth = thumbnail.clientWidth * noOfPics;
const wrapperHeight = thumbnailWrapper.clientHeight;
const percentX = clientX / width * 100;
const percentY = clientY / height * 100;
const scrollX = (wrapperWidth - width) * percentX / 100 - width / 2;
thumbnailWrapper.scroll(scrollX, 0)
}
* {
box-sizing: border-box;
padding: 0%;
margin: 0%;
}
#gallery {
width: 100vw;
height: 100vh;
background-color: #303030;
display: flex;
flex-direction: column;
}
#thumbnail-wrapper {
display: flex;
/* justify-content: center; */
overflow-x: scroll;
padding: 0.5rem 1rem;
}
#thumbnail-wrapper::-webkit-scrollbar {
/* display: none; */
background-color: #000;
}
::-webkit-scrollbar-thumb {
background: red;
}
.thumbnail {
flex: none;
width: 150px;
height: 100px;
border: 3px solid #303030;
background-color: #202020;
border-radius: 10px;
}
#active-image {
flex: 1;
position: relative;
margin: 1rem;
}
.overflow-hidden {
overflow: hidden;
}
.overflow-scroll {
overflow: scroll;
}
.fit {
height: 100%;
margin: 0 auto;
}
.original {
height: auto;
position: absolute;
top: 0%;
}
<div id = "gallery">
<div id = "thumbnail-wrapper">
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
</div>
<div id = "active-image" class = "overflow-scroll">
<img src = "https://www.lifewire.com/thmb/_cH2YBd-iyPP1cqqj2WWXiCWudg=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/hdwallpapersnet-free-wallpaper-5919d3ca3df78cf5fa49bda3.jpg" alt = "something went wrong" class = "original">
</div>
</div>
Я думаю, что я неправильно вычисляю scrollX, я пробовал много комбинаций, но не могу получить ожидаемое поведение.
Так что в основном это линейная вещь, начиная с (0, 0) до (clientWidth, maxScroll). Итак, я рассчитываю линейную формулу, тогда легко добавить clientX и получить offsetX.
Возможно, потребуется некоторая настройка по краям. Вероятно, вычислите уравнение от 0+imageWidth до maxWidth-imageWidth. Поиграйте с этим.
Обновление: я играл с ним. Теперь должно быть идеально.
function getLinearFunction(x1, y1, x2, y2) {
var slope = (y2 - y1) / (x2 - x1);
return function(x) {
return slope * (x - x1) + y1;
}
}
const gallery = document.getElementById('gallery');
const thumbnail = document.querySelector('.thumbnail');
const thumbnailWrapper = document.getElementById('thumbnail-wrapper');
thumbnailWrapper.addEventListener('mousemove', handleMouseMove);
// document.addEventListener('key')
function handleMouseMove(e) {
const noOfPics = Array.from(thumbnailWrapper.childNodes).length
const clientX = e.clientX;
const clientY = e.clientY;
const width = thumbnailWrapper.clientWidth;
const height = thumbnailWrapper.clientHeight;
const wrapperWidth = thumbnail.clientWidth * noOfPics;
const wrapperHeight = thumbnailWrapper.clientHeight;
const percentX = clientX / width * 100;
const percentY = clientY / height * 100;
const scrollLeft = thumbnailWrapper.scrollLeft
var maxScrollLeft = thumbnailWrapper.scrollWidth - thumbnailWrapper.clientWidth;
// when clientX = 0 you want scrollx = 0
// when clientx = width you want scrollX = maxScrollLeft
var foo = getLinearFunction(0, 0, width, maxScrollLeft);
// EDIT: improvement:
var foo = getLinearFunction(0 + 150, 0, width - 150, maxScrollLeft);
output.innerHTML = JSON.stringify({
clientX,
clientY,
width,
height,
wrapperWidth,
wrapperHeight,
scrollLeft,
maxScrollLeft
}, null, 4)
thumbnailWrapper.scroll(foo(clientX), 0)
}
* {
box-sizing: border-box;
padding: 0%;
margin: 0%;
}
#gallery {
width: 100vw;
background-color: #303030;
display: flex;
flex-direction: column;
}
#thumbnail-wrapper {
display: flex;
/* justify-content: center; */
overflow-x: scroll;
padding: 0.5rem 1rem;
background: yellow;
}
#thumbnail-wrapper::-webkit-scrollbar {
/* display: none; */
background-color: #000;
}
::-webkit-scrollbar-thumb {
background: red;
}
.thumbnail {
flex: none;
width: 150px;
height: 100px;
border: 3px solid #303030;
background-color: #202020;
border-radius: 10px;
}
#active-image {
flex: 1;
position: relative;
margin: 1rem;
}
.overflow-hidden {
overflow: hidden;
}
.overflow-scroll {
overflow: scroll;
}
.fit {
height: 100%;
margin: 0 auto;
}
.original {
height: auto;
position: absolute;
top: 0%;
}
<div id = "gallery">
<div id = "thumbnail-wrapper">
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
<div class = "thumbnail"></div>
</div>
</div>
<pre id = "output"></pre>
Если вы не возражаете, не могли бы вы занять секунду, чтобы объяснить мне, как это работает. Извините, я младший разработчик, это мой первый месяц на моей первой работе в качестве разработчика.
см., нет никаких оснований полагать, что движение полосы прокрутки нелинейно. я имею в виду, что он прокручивается прямо с той же скоростью, а не быстрее в тот или иной момент. линейный. поэтому, если в одной точке (мышь x) вы знаете значение, которое она должна прокручивать (y), и вы знаете его в другой точке, то вы можете указать все точки, потому что между двумя точками есть ровно одна прямая линия. ну у нас 2 очка. 0, 0 — левая сторона. правая сторона (maxX, maxY), где maxX — максимальная мышь, а maxY — максимальная прокрутка. так что в целом вы должны знать, что можете рассчитать все точки между использованием формулы ax+b=y
Ааааа, это гениально, я рассчитывал, сколько он прокручивает, когда мышь находится в точке x. Я не думал о скорости. Спасибо
Да, это прекрасно. Хотя я все еще не могу понять это, но пойму это после того, как завершу проект. Уже поздно доставлять это :)