-
Notifications
You must be signed in to change notification settings - Fork 183
Drag'n'Drop with mouse events #322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
833a6cd
b4158fc
c843f3d
8c95048
98e602d
b966c14
acaea59
e0403bd
016297c
ea5b2b1
016b25d
f747b5f
b90a49a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| As we can see from HTML/CSS, the slider is a `<div>` with a colored background, that contains a runner -- another `<div>` with `position:relative`. | ||
| Як можна бачити з `HTML/CSS`, слайдер - це `<div>`, з кольровим фоном, всередині якого знаходиться інший `<div>`, оформлений як бігунок, з `position: relative`. | ||
|
|
||
| To position the runner we use `position:relative`, to provide the coordinates relative to its parent, here it's more convenient here than `position:absolute`. | ||
| Використовуємо для його позиціювання `position: relative`, тобто координати встановлюються не абсолютні, а відносно зовнішнього родича, так як це зручніше. | ||
AntonBurchak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Then we implement horizontal-only Drag'n'Drop with limitation by width. | ||
| І далі реалізуємо Drag'n'Drop тільки по горизонталі, з обмеженням по ширині. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,7 +13,7 @@ | |
| </div> | ||
|
|
||
| <script> | ||
| // ...your code... | ||
| // ...ваш код... | ||
| </script> | ||
|
|
||
| </body> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| To drag the element we can use `position:fixed`, it makes coordinates easier to manage. At the end we should switch it back to `position:absolute` to lay the element into the document. | ||
| Щоб перетягнути елемент, ми можемо використовувати `position: fixed`, це робить управління координатами простіше. В кінці слід переключитися назад на `position: absolute`, щоб покласти елемент в документ. | ||
AntonBurchak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| When coordinates are at window top/bottom, we use `window.scrollTo` to scroll it. | ||
| Коли координати знаходяться у верхній/нижній частині вікна, ми використовуємо `window.scrollTo` для прокрутки. | ||
|
|
||
| More details in the code, in comments. | ||
| Деталі рішення розписані в коментарях в вихідному коді. | ||
AntonBurchak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -24,9 +24,9 @@ document.addEventListener('mousedown', function(event) { | |||||
| moveAt(event.clientX, event.clientY); | ||||||
| } | ||||||
|
|
||||||
| // on drag start: | ||||||
| // remember the initial shift | ||||||
| // move the element position:fixed and a direct child of body | ||||||
| // на початку переміщення елемента: | ||||||
| // запам'ятовуємо місце кліку по елементу (shiftX, shiftY) , | ||||||
AntonBurchak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| // перемикаємо позиціонування елемента (position: fixed) і рухаємо елемент | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| function startDrag(element, clientX, clientY) { | ||||||
| if(isDragging) { | ||||||
| return; | ||||||
|
|
@@ -45,7 +45,8 @@ document.addEventListener('mousedown', function(event) { | |||||
| moveAt(clientX, clientY); | ||||||
| }; | ||||||
|
|
||||||
| // switch to absolute coordinates at the end, to fix the element in the document | ||||||
| // перемикаємося назад на абсолютні координати | ||||||
| // щоб закріпити елемент відносно документа | ||||||
|
||||||
| function finishDrag() { | ||||||
| if(!isDragging) { | ||||||
| return; | ||||||
|
|
@@ -61,49 +62,50 @@ document.addEventListener('mousedown', function(event) { | |||||
| } | ||||||
|
|
||||||
| function moveAt(clientX, clientY) { | ||||||
| // new window-relative coordinates | ||||||
| // обчислюємо нові координати (відносно вікна) | ||||||
| let newX = clientX - shiftX; | ||||||
| let newY = clientY - shiftY; | ||||||
|
|
||||||
| // check if the new coordinates are below the bottom window edge | ||||||
| let newBottom = newY + dragElement.offsetHeight; // new bottom | ||||||
| // перевіряємо, чи не переходять нові координати за нижній край вікна: | ||||||
AntonBurchak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| // спочатку обчислюємо гіпотетичний новий нижній край вікна | ||||||
|
||||||
| let newBottom = newY + dragElement.offsetHeight; | ||||||
|
|
||||||
| // below the window? let's scroll the page | ||||||
| // новий край вікна виходить за межі документа? прокручуємо сторінку | ||||||
AntonBurchak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| if (newBottom > document.documentElement.clientHeight) { | ||||||
| // window-relative coordinate of document end | ||||||
| // координата нижнього краю документа щодо вікна | ||||||
| let docBottom = document.documentElement.getBoundingClientRect().bottom; | ||||||
|
|
||||||
| // scroll the document down by 10px has a problem | ||||||
| // it can scroll beyond the end of the document | ||||||
| // Math.min(how much left to the end, 10) | ||||||
| // скролл документа на 10px вниз має проблему - | ||||||
AntonBurchak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| // він може прокручувати документ за його межі, | ||||||
AntonBurchak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| // тому використовуємо Math.min (відстань до кінця, 10) | ||||||
| let scrollY = Math.min(docBottom - newBottom, 10); | ||||||
|
|
||||||
| // calculations are imprecise, there may be rounding errors that lead to scrolling up | ||||||
| // that should be impossible, fix that here | ||||||
| // обчислення можуть бути не зовсім точні - трапляються помилки при округленні, | ||||||
AntonBurchak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| // які призводять до негативного значенням прокрутки. відфільтруємо їх: | ||||||
AntonBurchak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| if (scrollY < 0) scrollY = 0; | ||||||
|
|
||||||
| window.scrollBy(0, scrollY); | ||||||
|
|
||||||
| // a swift mouse move make put the cursor beyond the document end | ||||||
| // if that happens - | ||||||
| // limit the new Y by the maximally possible (right at the bottom of the document) | ||||||
| // швидке переміщення миші може помістити курсор за межі документа вниз | ||||||
| // якщо це сталося - | ||||||
| // обмежуємо нове значення Y максимально можливим виходячи з розміру документа: | ||||||
AntonBurchak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| newY = Math.min(newY, document.documentElement.clientHeight - dragElement.offsetHeight); | ||||||
| } | ||||||
|
|
||||||
| // check if the new coordinates are above the top window edge (similar logic) | ||||||
| // перевіряємо, чи не переходять нові координати за верхній край вікна (по схожому алгоритму) | ||||||
AntonBurchak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| if (newY < 0) { | ||||||
| // scroll up | ||||||
| let scrollY = Math.min(-newY, 10); | ||||||
| if (scrollY < 0) scrollY = 0; // check precision errors | ||||||
| if (scrollY < 0) scrollY = 0; // перевіряємо помилки точності | ||||||
|
|
||||||
| window.scrollBy(0, -scrollY); | ||||||
| // a swift mouse move can put the cursor beyond the document start | ||||||
| newY = Math.max(newY, 0); // newY may not be below 0 | ||||||
| // швидке переміщення миші може помістити курсор за межі документа вгору | ||||||
AntonBurchak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| newY = Math.max(newY, 0); // newY не може бути менше нуля | ||||||
| } | ||||||
|
|
||||||
|
|
||||||
| // limit the new X within the window boundaries | ||||||
| // there's no scroll here so it's simple | ||||||
| // обмежимо newX розмірами вікна | ||||||
| // згідно з умовою, горизонтальна прокрутка відсутня, тому це не складно: | ||||||
| if (newX < 0) newX = 0; | ||||||
| if (newX > document.documentElement.clientWidth - dragElement.offsetWidth) { | ||||||
| newX = document.documentElement.clientWidth - dragElement.offsetWidth; | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,18 +8,18 @@ | |
|
|
||
| <body> | ||
|
|
||
| <h2>Place superheroes around the soccer field.</h2> | ||
|
|
||
| <p>Superheroes and the ball are elements with the class "draggable". Make them really draggable.</p> | ||
|
|
||
| <p>Important: limit dragging by the window. If a draggable reaches window top or bottom, then the page should scroll to let us drag it further.</p> | ||
|
|
||
| <p>If your screen is big enough to fit the whole document -- make the window smaller to get vertical scrolling, so that you could test it.</p> | ||
|
|
||
| <p>In this task it's enough to handle vertical scrolling. There's no horizontal scrolling usually, and it's handled the similar way if needed.</p> | ||
|
|
||
| <p>And one more thing: heroes may never leave the page. If they reach the edge of the document, no dragging outside of it.</p> | ||
|
|
||
| <h2>Розставте супергероїв по полю.</h2> | ||
|
||
|
|
||
| <p>Супергерої і м’яч - це елементи з класом "draggable". Зробіть так, щоб їх можна було переносити.</p> | ||
| <p>Важливо: обмежити перетягування межами вікна. Якщо супергероя підносять до верхньої або нижньої межі сторінки, вона повинна автоматично прокручуватися.</p> | ||
| <p>Якщо сторінка поміщається на вашому екрані цілком і не має вертикальної прокрутки - зробіть вікно браузера менше, щоб протестувати цю можливість.</p> | ||
| <p>У цьому завданні достатньо впоратися з вертикальною прокруткою. Зазвичай немає горизонтальної прокрутки, і вона обробляється аналогічним чином, якщо це необхідно.</p> | ||
| <p>Так, і ще: супергерої ні за яких умов не повинні потрапити за край екрану.</p> | ||
| <div id="field"> | ||
|
|
||
| </div> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| // Your code | ||
| // Ваш код |
Uh oh!
There was an error while loading. Please reload this page.