2016-12-07 2 views
1

В настоящее время я работаю над проектом, где желаемый пользовательский интерфейс включает в себя очень индивидуальное взаимодействие со свитками.Пользовательский прокрутка UX

проблема: страница имеет секции X, каждый из них с высоты, равной видового экрана Hight height: 100vh;. Когда пользователь прокручивается в окне просмотра, текущий видимый раздел остается там, где он есть, и индикатор прокрутки анимируется на основе порога прокрутки по расстоянию (например, 30 пикселей). После того, как пользователь прокрутил порог, следующий раздел появляется внизу экрана и закрывает текущий раздел (который по-прежнему не перемещается).

Initial Approach: Установите каждую секцию на абсолютную позицию и регулировать их с помощью изменения классов CSS на основе scrollwheel события. Body overflow:hidden и transform свойство управлять разделами. Однако я столкнулся с проблемами.

  1. Событие scrollwheel, как представляется, документировано как очень неустойчивое решение для реализации.
  2. . Катушка WelelDelta события срабатывает асинхронно и с трудом фиксируется. (На хром он просто выплескивает кратное 3 раза, а не расстояние жест в px). Это затрудняет установление порога и оживление элементов, которые реагируют на этот порог.

В основном я хочу, чтобы иметь возможность отслеживать количество пикселей, покрывающих прокрутки, и применять это число к позиции определенного элемента подсказки прокрутки до тех пор, пока не будет достигнуто пороговое значение прокрутки. Как только он будет выполнен, функция запускает изменения классов и обновляет некоторую информацию на странице. Если пороговое значение не выполнено, элемент подсказки прокрутки возвращается к позиции по умолчанию.

Мой приложенный подход не очень способствует выполнению этого, поэтому я ищу либо 1) другой и более стабильный подход, либо 2) изменения/критические замечания по поводу того, что я делаю неправильно с этим подходом, чтобы сделать он стабилен.

(function scrollerTest($){ 
 
\t $('body').on ('mousewheel', function (e) { 
 
     
 
\t  var delta = e.originalEvent.wheelDelta, 
 
      currentScreenID = $('section.active').data('self').section_id, 
 
       currentScreen = $('section.part-' + currentScreenID), 
 
       nextScreenID = currentScreenID + 1, 
 
       nextScreen = $('section.part-' + nextScreenID);; 
 
\t 
 
\t  if (delta < 0) { // User is Scrolling Down 
 
      currentScreen.removeClass('active').addClass('top'); 
 
      nextScreen.removeClass('bottom').addClass('active') 
 
\t  } else if (delta > 0) { // User is Scrolling Up 
 
\t   
 
      
 
\t  } 
 
\t }); 
 

 
}(jQuery));
body { 
 
    overflow: hidden; 
 
    padding: 0; 
 
    margin: 0; 
 
    } 
 
section { 
 
    position: absolute; 
 
    top: 0; 
 
    left: 0; 
 
    width: 100%; 
 
    height: 100vh; 
 
    z-index: 999; 
 
    background-color: #CA5D44; 
 
    transition: 0.8s all ease-in-out; 
 
    } 
 
section.part-1 { 
 
    position: relative; 
 
    z-index: 9; 
 
    } 
 
section.part-2 { 
 
    background-color: #222629; 
 
    } 
 
section.active { 
 
    transform: translateY(0); 
 
    } 
 
section.top { 
 
    transform: translateY(-10%); 
 
    } 
 
section.bottom { 
 
    transform: translateY(100%); 
 
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script> 
 

 
<body> 
 
    <section class="part-1 home active" data-self='{ "section_id" : 1, "section_title" : "Home", "menu_main_clr" : "#fff" , "menu_second_clr" : "#CA5D44", "logo_clr" : "white" }'> 
 
    </section> 
 
    <section class="part-2 about bottom" data-self='{ "section_id" : 1, "section_title" : "About", "menu_main_clr" : "#CA5D44" , "menu_second_clr" : "#fff", "logo_clr" : "white" }'> 
 
    </section> 
 
    <section class="part-3 contact bottom" data-self='{ "section_id" : 1, "section_title" : "Contact", "menu_main_clr" : "#fff" , "menu_second_clr" : "#CA5D44", "logo_clr" : "white" }'> 
 
    </section> 
 
</body>

Edit Примечание: Сниппет, кажется, есть некоторые проблемы с обжигом события и изменения классов после первого экземпляра - не знаю, почему. На моем местном примере он запускает их всех сразу.

** Edite Note 2: ** Перечисленный код - это всего лишь копия самого близкого поведения, которого я мог бы достичь. К сожалению, вся эта функция порога кажется довольно недосягаемой, поскольку событие колеса не ведет себя как событие прокрутки.

+0

Вы с учетом проверки [fullPage.js] (http://alvarotrigo.com/fullPage/)? Самая популярная библиотека для такого рода вещей. – Alvaro

ответ

0

вся тема прокрутки довольно сложная, особенно когда вы думаете о событиях с прокруткой сенсорных экранов. Есть некоторые библиотеки там - посмотреть этот список, например: http://ninodezign.com/30-jquery-plugins-for-scrolling-effects-with-css-animation/

Я использовал https://projects.lukehaas.me/scrollify/ раньше, и это может позволить вам делать то, что вы собираетесь (с помощью обратного вызова, прежде чем в конце концов), но я не могу сказать, не пытаясь себя. Также обратите внимание, что scrollify является относительно большим (8kb minified) по сравнению с другими библиотеками.

+0

Это отличный список плагинов, спасибо! Я надеюсь, что мне придется загружать зависимости для кода, если можно. В идеале я хотел бы просто создать прототип «следующего экрана» и вызвать его на определенных пороговых значениях. Мобильный не слишком жесткий, но получение этого эффекта на компьютере дает мне большую головную боль. Собираюсь дать прокрутку выстрела и посмотреть, сможет ли он получить меня там эффективно –

0

Вы можете подходить к этому использованию, гарантируя, что за каждой заполненной содержимым секцией следует пустой прозрачный зазор (в приведенном ниже примере также 100vh), а затем с помощью javascript применить position:fixed к каждому заполненному содержимым разделу, когда он попадает в верхней части окна просмотра.

Пример:

var screens = document.getElementsByClassName('screen'); 
 

 
function checkPosition() { 
 

 
\t for (var i = 0; i < (screens.length - 1); i++) { 
 
\t  var topPosition = screens[i].getBoundingClientRect().top; 
 
    
 
     if (topPosition < 1) { 
 
      screens[i].style.top = '0'; 
 
      screens[i].style.position = 'fixed'; 
 
     } 
 
    } 
 
} 
 

 
window.addEventListener('scroll',checkPosition,false);
.screen { 
 
position: absolute; 
 
display: block; 
 
left: 0; 
 
width: 100%; 
 
height: 100vh; 
 
} 
 

 
.red { 
 
position: fixed; 
 
top: 0; 
 
background-color: rgb(255,0,0); 
 
} 
 

 
.orange { 
 
top: 200vh; 
 
background-color: rgb(255,140,0); 
 
} 
 

 
.yellow { 
 
top: 400vh; 
 
background-color: rgb(255,255,0); 
 
} 
 

 
.green { 
 
top: 600vh; 
 
background-color: rgb(0,191,0); 
 
} 
 

 
.blue { 
 
top: 800vh; 
 
background-color: rgb(0,0,127); 
 
} 
 

 
p { 
 
font-size: 20vh; 
 
line-height: 20vh; 
 
text-align: center; 
 
color: rgba(255,255,255,0.4); 
 
}
<div class="red screen"> 
 
<p>Screen One</p> 
 
</div> 
 

 
<div class="orange screen"> 
 
<p>Screen Two</p> 
 
</div> 
 

 
<div class="yellow screen"> 
 
<p>Screen Three</p> 
 
</div> 
 

 
<div class="green screen"> 
 
<p>Screen Four</p> 
 
</div> 
 

 
<div class="blue screen"> 
 
<p>Screen Five</p> 
 
</div>