Skip to content

Instantly share code, notes, and snippets.

@beseidel
Last active December 14, 2020 18:24
Show Gist options
  • Save beseidel/e80602d4ce6beff0d6a58131f41ed820 to your computer and use it in GitHub Desktop.
Save beseidel/e80602d4ce6beff0d6a58131f41ed820 to your computer and use it in GitHub Desktop.
Gray & White - Skewed Slider with Scrolling

Gray & White - Skewed Slider with Scrolling

This Skewed Slider with Scrolling based on Pure JS and CSS (without libraries).

A Pen by Victor Belozyorov on CodePen.

License.

<section class="slider-pages">
<article class="js-scrolling__page js-scrolling__page-1 js-scrolling--active">
<div class="slider-page slider-page--left">
<div class="slider-page--skew">
<div class="slider-page__content">
</div>
<!-- /.slider-page__content -->
</div>
<!-- /.slider-page--skew -->
</div>
<!-- /.slider-page slider-page--left -->
<div class="slider-page slider-page--right">
<div class="slider-page--skew">
<div class="slider-page__content">
<h1 class="slider-page__title slider-page__title--big">
Gray & White - Skewed Slider with Scrolling
</h1>
<!-- /.slider-page__title slider-page__title--big -->
<h2 class="slider-page__title">
Start of your story
</h2>
<!-- /.slider-page__title -->
<p class="slider-page__description">
Please scroll down or press the down arrow on your keyboard
</p>
<!-- /.slider-page__description -->
</div>
<!-- /.slider-page__content -->
</div>
<!-- /.slider-page--skew -->
</div>
<!-- /.slider-page slider-page--right -->
</article>
<!-- /.js-scrolling__page js-scrolling__page-1 js-scrolling--active -->
<article class="js-scrolling__page js-scrolling__page-2">
<div class="slider-page slider-page--left">
<div class="slider-page--skew">
<div class="slider-page__content">
<h1 class="slider-page__title">
Now you are here
</h1>
<!-- /.slider-page__title -->
<p class="slider-page__description">
Please continue scrolling
</p>
<!-- /.slider-page__description -->
</div>
<!-- /.slider-page__content -->
</div>
<!-- /.slider-page--skew -->
</div>
<!-- /.slider-page slider-page--left -->
<div class="slider-page slider-page--right">
<div class="slider-page--skew">
<div class="slider-page__content">
</div>
<!-- /.slider-page__content -->
</div>
<!-- /.slider-page--skew -->
</div>
<!-- /.slider-page slider-page--right -->
</article>
<!-- /.js-scrolling__page js-scrolling__page-2 -->
<article class="js-scrolling__page js-scrolling__page-3">
<div class="slider-page slider-page--left">
<div class="slider-page--skew">
<div class="slider-page__content">
</div>
<!-- /.slider-page__content -->
</div>
<!-- /.slider-page--skew -->
</div>
<!-- /.slider-page slider-page--left -->
<div class="slider-page slider-page--right">
<div class="slider-page--skew">
<div class="slider-page__content">
<h1 class="slider-page__title">
Final is just the beginning
</h1>
<!-- /.slider-page__title -->
<p class="slider-page__description">
Feel free to follow me on <a class="slider-page__link" href="https://twitter.com/WispProxy"
target="_blank">Twitter</a>
and check of <a class="slider-page__link" href="https://codepen.io/WispProxy/pens/public"
target="_blank">my other works</a>
</p>
<!-- /.slider-page__description -->
</div>
<!-- /.slider-page__content -->
</div>
<!-- /.slider-page--skew -->
</div>
<!-- /.slider-page slider-page--right -->
</article>
<!-- /.js-scrolling__page js-scrolling__page-3 -->
</section>
<!-- /.slider-pages -->
/*********************
* Helpers Code
********************/
/**
* @function DOMReady
*
* @param callback
* @param element
* @param listener
* @returns {*}
* @constructor
*/
const DOMReady = ((
callback = () => {},
element = document,
listener = 'addEventListener'
) => {
return (element[listener]) ? element[listener]('DOMContentLoaded', callback) : window.attachEvent('onload', callback);
});
/**
* @function ProjectAPI
*
* @type {{hasClass, addClass, removeClass}}
*/
const ProjectAPI = (() => {
let hasClass,
addClass,
removeClass;
hasClass = ((el, className) => {
if (el === null) {
return;
}
if (el.classList) {
return el.classList.contains(className);
}
else {
return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
}
});
addClass = ((el, className) => {
if (el === null) {
return;
}
if (el.classList) {
el.classList.add(className);
}
else if (!hasClass(el, className)) {
el.className += ' ' + className
}
});
removeClass = ((el, className) => {
if (el === null) {
return;
}
if (el.classList) {
el.classList.remove(className);
}
else if (hasClass(el, className)) {
let reg = new RegExp('(\\s|^)' + className + '(\\s|$)');
el.className = el.className.replace(reg, ' ');
}
});
return {
hasClass: hasClass,
addClass: addClass,
removeClass: removeClass
};
})();
/*********************
* Application Code
********************/
/**
* @function readyFunction
*
* @type {Function}
*/
const readyFunction = (() => {
const KEY_UP = 38;
const KEY_DOWN = 40;
let scrollingClass = 'js-scrolling',
scrollingActiveClass = scrollingClass + '--active',
scrollingInactiveClass = scrollingClass + '--inactive',
scrollingTime = 1350,
scrollingIsActive = false,
currentPage = 1,
countOfPages = document.querySelectorAll('.' + scrollingClass + '__page').length,
prefixPage = '.' + scrollingClass + '__page-',
_switchPages,
_scrollingUp,
_scrollingDown,
_mouseWheelEvent,
_keyDownEvent,
init;
/**
* @function _switchPages
*
* @private
*/
_switchPages = () => {
let _getPageDomEl;
/**
* @function _getPageDomEl
*
* @param page
* @returns {Element}
* @private
*/
_getPageDomEl = (page = currentPage) => {
return document.querySelector(prefixPage + page);
};
scrollingIsActive = true;
ProjectAPI.removeClass(
_getPageDomEl(),
scrollingInactiveClass
);
ProjectAPI.addClass(
_getPageDomEl(),
scrollingActiveClass
);
ProjectAPI.addClass(
_getPageDomEl(currentPage - 1),
scrollingInactiveClass
);
ProjectAPI.removeClass(
_getPageDomEl(currentPage + 1),
scrollingActiveClass
);
setTimeout(
() => {
return scrollingIsActive = false;
},
scrollingTime
);
};
/**
* @function _scrollingUp
*
* @private
*/
_scrollingUp = () => {
if (currentPage === 1) {
return;
}
currentPage--;
_switchPages();
};
/**
* @function _scrollingDown
*
* @private
*/
_scrollingDown = () => {
if (currentPage === countOfPages) {
return;
}
currentPage++;
_switchPages();
};
/**
* @function _mouseWheelEvent
*
* @param e
* @private
*/
_mouseWheelEvent = (e) => {
if (scrollingIsActive) {
return;
}
if (e.wheelDelta > 0 || e.detail < 0) {
_scrollingUp();
}
else if (e.wheelDelta < 0 || e.detail > 0) {
_scrollingDown();
}
};
/**
* @function _keyDownEvent
*
* @param e
* @private
*/
_keyDownEvent = (e) => {
if (scrollingIsActive) {
return;
}
let keyCode = e.keyCode || e.which;
if (keyCode === KEY_UP) {
_scrollingUp();
}
else if (keyCode === KEY_DOWN) {
_scrollingDown();
}
};
/**
* @function init
*
* @note auto-launch
*/
init = (() => {
document.addEventListener(
'mousewheel',
_mouseWheelEvent,
false
);
document.addEventListener(
'DOMMouseScroll',
_mouseWheelEvent,
false
);
document.addEventListener(
'keydown',
_keyDownEvent,
false
);
})();
});
/**
* Launcher
*/
DOMReady(readyFunction);
/***********************
* Variables
**********************/
$font-family: 'Open Sans', sans-serif;
$font-size: 1em;
$color-body: #282828;
$color-text: #e2e2e2;
$color-link: #80a1c1;
$color-link-active: #6386a9;
$variable-skewX: 18deg;
$variable-vHForSkewX: 32.5vh;
$variable-scrollingTime: 1350ms;
/***********************
* Project Main Styles
**********************/
*,
*:before,
*:after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: $font-family;
background-color: $color-body;
}
.slider-pages {
overflow: hidden;
position: relative;
height: 100vh;
}
.slider-page {
position: absolute;
top: 0;
width: 50%;
height: 100vh;
transition: transform $variable-scrollingTime;
}
.slider-page--skew {
overflow: hidden;
position: absolute;
top: 0;
width: 140%;
height: 100%;
background: $color-body;
transform: skewX($variable-skewX * -1);
}
.slider-page--left {
left: 0;
transform: translateX($variable-vHForSkewX * -1)
translateY(100%)
translateZ(0);
.slider-page--skew {
left: -40%;
}
.slider-page__content {
padding: auto 30% auto 30%;
transform-origin: 100% 0;
}
}
.slider-page--right {
left: 50%;
transform: translateX($variable-vHForSkewX)
translateY(-100%)
translateZ(0);
.slider-page--skew {
right: -40%;
}
.slider-page__content {
padding: auto 30% auto 30%;
transform-origin: 0 100%;
}
}
.slider-page__content {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
flex-flow: column wrap;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 0 30% 0 30%;
color: $color-text;
background-size: cover;
transform: skewX($variable-skewX);
transition: transform $variable-scrollingTime;
}
.slider-page__title {
margin-bottom: 1em;
font-size: $font-size;
text-align: center;
text-transform: uppercase;
}
.slider-page__title--big {
font-size: $font-size * 1.2;
}
.slider-page__description {
font-size: $font-size;
text-align: center;
}
.slider-page__link {
color: $color-link;
&:hover,
&:focus {
color: $color-link-active;
text-decoration: none;
}
}
/***********************
* Project JS Styles
**********************/
.js-scrolling__page {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.js-scrolling--active {
.slider-page {
transform: translateX(0)
translateY(0)
translateZ(0);
}
}
.js-scrolling--inactive {
.slider-page__content {
transform: skewX($variable-skewX)
scale(.9);
}
}
.js-scrolling__page-1 {
.slider-page--left .slider-page__content {
background-image: url("https://s-media-cache-ak0.pinimg.com/originals/a6/6a/a3/a66aa3134eb9f439838e676297a75bd6.jpg");
}
.slider-page--right .slider-page__content {
background-color: $color-body;
}
}
.js-scrolling__page-2 {
.slider-page--left .slider-page__content {
background-color: $color-text;
}
.slider-page--left .slider-page__title,
.slider-page--left .slider-page__description {
color: $color-body;
}
.slider-page--right .slider-page__content {
background-image: url("https://s-media-cache-ak0.pinimg.com/originals/7a/8d/51/7a8d51f4968960334274ac7959d31a7d.jpg");
}
}
.js-scrolling__page-3 {
.slider-page--left .slider-page__content {
background-image: url("https://s-media-cache-ak0.pinimg.com/originals/4c/d8/7b/4cd87bc93cca92f76285c061cef16585.jpg");
}
.slider-page--right .slider-page__content {
background-color: $color-body;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment