Skip to content

Instantly share code, notes, and snippets.

@kuator
Created July 9, 2019 17:14
Show Gist options
  • Save kuator/18ccd8b663962eb4688e201547d2bed2 to your computer and use it in GitHub Desktop.
Save kuator/18ccd8b663962eb4688e201547d2bed2 to your computer and use it in GitHub Desktop.
GPwxqP
<div class="c-work">
<ul class="c-work__list js-work">
<!-- WORK ITEM -->
<li class="c-work__item">
<div class="c-work-item js-work-item" data-work-preview-id="0">
<span class="c-work-item__number u-b6">
01
</span>
<div class="c-work-item__title">
<h3 class="u-a6">
Hone Products
</h3>
</div>
<span class="c-work-item__category u-b4">
<i>/</i>Website
</span>
</div>
</li>
<!-- //WORK ITEM -->
<!-- WORK ITEM -->
<li class="c-work__item">
<div class="c-work-item js-work-item" data-work-preview-id="1">
<span class="c-work-item__number u-b6">
02
</span>
<div class="c-work-item__title">
<h3 class="u-a6">
Urban Culture
</h3>
</div>
<span class="c-work-item__category u-b4">
<i>/</i>Digital Presentation
</span>
</div>
</li>
<!-- //WORK ITEM -->
<!-- WORK ITEM -->
<li class="c-work__item">
<div class="c-work-item js-work-item" data-work-preview-id="2">
<span class="c-work-item__number u-b6">
03
</span>
<div class="c-work-item__title">
<h3 class="u-a6">
X — 6
</h3>
</div>
<span class="c-work-item__category u-b4">
<i>/</i>Website
</span>
</div>
</li>
<!-- //WORK ITEM -->
<!-- WORK ITEM -->
<li class="c-work__item">
<div class="c-work-item js-work-item" data-work-preview-id="3">
<span class="c-work-item__number u-b6">
04
</span>
<div class="c-work-item__title">
<h3 class="u-a6">
Difference
</h3>
</div>
<span class="c-work-item__category u-b4">
<i>/</i>Branding
</span>
</div>
</li>
<!-- //WORK ITEM -->
<!-- WORK ITEM -->
<li class="c-work__item">
<div class="c-work-item js-work-item" data-work-preview-id="4">
<span class="c-work-item__number u-b6">
05
</span>
<div class="c-work-item__title">
<h3 class="u-a6">
Cali-Hype
</h3>
</div>
<span class="c-work-item__category u-b4">
<i>/</i>E-commerce
</span>
</div>
</li>
<!-- //WORK ITEM -->
<!-- WORK ITEM -->
<li class="c-work__item">
<div class="c-work-item js-work-item" data-work-preview-id="5">
<span class="c-work-item__number u-b6">
06
</span>
<div class="c-work-item__title">
<h3 class="u-a6">
Prada x Diesel
</h3>
</div>
<span class="c-work-item__category u-b4">
<i>/</i>Website
</span>
</div>
</li>
<!-- //WORK ITEM -->
</ul>
<div class="c-work-preview">
<div class="c-work-preview__canvas js-work-preview-list">
<div class="canvas js-work-preview-canvas" data-displacement-map="https://deghq.com/yapp/front-labs/codepen-assets/displacement/7.jpg" style="background-image: url(https://deghq.com/yapp/front-labs/codepen-assets/displacement/7.jpg);"></div>
</div>
<ul class="c-work-preview__list js-work-preview-list">
<!-- WORK ITEM PREVIEW -->
<li class="c-work-preview__item">
<i class="c-work-preview__image js-work-preview" data-work-preview="https://deghq.com/wordpress/bornfight/wp-content/themes/bf/static/images/work-2.jpg" style="background-image: url(https://deghq.com/wordpress/bornfight/wp-content/themes/bf/static/images/work-2.jpg);"></i>
</li>
<!-- //WORK ITEM PREVIEW -->
<!-- WORK ITEM PREVIEW -->
<li class="c-work-preview__item">
<i class="c-work-preview__image js-work-preview" data-work-preview="https://deghq.com/wordpress/bornfight/wp-content/themes/bf/static/images/work-3.jpg" style="background-image: url(https://deghq.com/wordpress/bornfight/wp-content/themes/bf/static/images/work-3.jpg);"></i>
</li>
<!-- //WORK ITEM PREVIEW -->
<!-- WORK ITEM PREVIEW -->
<li class="c-work-preview__item">
<i class="c-work-preview__image js-work-preview" data-work-preview="https://deghq.com/wordpress/bornfight/wp-content/themes/bf/static/images/work-4.jpg" style="background-image: url(https://deghq.com/wordpress/bornfight/wp-content/themes/bf/static/images/work-4.jpg);"></i>
</li>
<!-- //WORK ITEM PREVIEW -->
<!-- WORK ITEM PREVIEW -->
<li class="c-work-preview__item">
<i class="c-work-preview__image js-work-preview" data-work-preview="https://deghq.com/wordpress/bornfight/wp-content/themes/bf/static/images/work-5.jpg" style="background-image: url(https://deghq.com/wordpress/bornfight/wp-content/themes/bf/static/images/work-5.jpg);"></i>
</li>
<!-- //WORK ITEM PREVIEW -->
<!-- WORK ITEM PREVIEW -->
<li class="c-work-preview__item">
<i class="c-work-preview__image js-work-preview" data-work-preview="https://deghq.com/wordpress/bornfight/wp-content/themes/bf/static/images/work-6.jpg" style="background-image: url(https://deghq.com/wordpress/bornfight/wp-content/themes/bf/static/images/work-6.jpg);"></i>
</li>
<!-- //WORK ITEM PREVIEW -->
<!-- WORK ITEM PREVIEW -->
<li class="c-work-preview__item">
<i class="c-work-preview__image js-work-preview" data-work-preview="https://deghq.com/wordpress/bornfight/wp-content/themes/bf/static/images/work-7.jpg" style="background-image: url(https://deghq.com/wordpress/bornfight/wp-content/themes/bf/static/images/work-7.jpg);"></i>
</li>
<!-- //WORK ITEM PREVIEW -->
</ul>
</div>
</div>
class WorkList {
/**
*
* @param {object} options
*/
constructor(options) {
const _defaults = {
workItem: '.js-work-item',
workItemPreviewList: '.js-work-preview-list',
workItemImg: '.js-work-preview',
//
activeItemClass: 'is-active',
//
workCanvas: '.js-work-preview-canvas',
};
this.defaults = Object.assign({}, _defaults, options);
if (this.getWorkItem().length > 0) {
this.init();
this.workItemHover(this.getWorkItem());
this.workHover(this.getWorkItemPreviewList());
this.initWorkCanvas();
}
}
// region Getters
/**
*
* @returns {*|jQuery|HTMLElement}
*/
getWorkItem() {
return $(this.defaults.workItem);
}
getWorkItemImg() {
return $(this.defaults.workItemImg);
}
getWorkItemPreviewList() {
return $(this.defaults.workItemPreviewList);
}
getWorkCanvas() {
return $(this.defaults.workCanvas);
}
getCanvasEl() {
return $(this.defaults.workCanvas).find('canvas');
}
// endregion
init() {
console.log('WorkList init()');
}
/**
*
* @param workItem
*/
workItemHover(workItem) {
workItem.on('mouseenter', (e) => {
e.preventDefault();
const workItemId = $(e.currentTarget).data('work-preview-id');
this.workHoverEnter(workItemId);
});
workItem.on('mouseleave', () => {
this.workHoverLeave();
});
}
/**
*
* @param workContainer
*/
workHover(workContainer) {
$(document).on('mousemove', (ev) => {
const decimalX = (ev.clientX / window.innerWidth) - 0.5;
const decimalY = (ev.clientY / window.innerHeight) - 0.5;
TweenMax.to(workContainer, 0.4, {
x: 180 * decimalX,
y: 90 * decimalY,
ease: Power3.easeOut,
});
});
// SETTINGS
const workItem = $(this.defaults.workItem);
const hoverDuration = 0.4;
const opacityLevel = 0.3;
// CONTEXT SHIFTING
// mouseenter
$(document).on('mouseenter', this.defaults.workItem, (ev) => {
ev.preventDefault();
const notItem = workItem.not(ev.currentTarget);
TweenMax.to(ev.currentTarget, hoverDuration, {
opacity: 1,
ease: Power3.easeOut,
});
TweenMax.to(notItem, hoverDuration, {
opacity: opacityLevel,
x: 0,
ease: Power3.easeOut,
});
});
// mouseleave
$(document).on('mouseleave', this.defaults.workItem, (ev) => {
ev.preventDefault();
const notItem = workItem.not(ev.currentTarget);
TweenMax.to([ev.currentTarget, notItem], hoverDuration, {
opacity: 1,
ease: Power3.easeOut,
});
});
}
initWorkCanvas() {
// CANVAS DIMENSIONS
const canvasWidth = this.getWorkItemImg().innerWidth();
const canvasHeight = this.getWorkItemImg().innerHeight();
// CREATE PIXI APPLICATION
const app = new PIXI.Application(
canvasWidth,
canvasHeight, {
transparent: true,
},
);
// APPEND CANVAS
this.getWorkCanvas().append(app.view);
// CREATE SLIDES CONTAINER
this.slidesContainer = new PIXI.Container();
app.stage.addChild(this.slidesContainer);
// CREATE DISPLACEMENT MAP
//const displacementMap = PIXI.Sprite.fromImage(this.getWorkCanvas().data('displacement-map'));
const displacementMap = PIXI.Sprite.fromImage(this.getWorkCanvas().css('background-image').replace(/.*\s?url\([\'\"]?/, '').replace(/[\'\"]?\).*/, ''));
// CREATE FILTER
const filter = new PIXI.filters.DisplacementFilter(displacementMap);
displacementMap.name = 'displacementMap';
displacementMap.anchor.set(0.5);
displacementMap.scale.set(1);
displacementMap.position.set(canvasWidth / 2, canvasHeight / 2);
app.stage.filterArea = app.screen;
app.stage.filters = [filter];
app.stage.addChild(displacementMap);
// PIXI SPRITE ARRAY
for (const spriteImage of this.getWorkItemImg()) {
//const texture = new PIXI.Texture.fromImage($(spriteImage).data('work-preview'));
const texture = new PIXI.Texture.fromImage($(spriteImage).css('background-image').replace(/.*\s?url\([\'\"]?/, '').replace(/[\'\"]?\).*/, ''));
const image = new PIXI.Sprite(texture);
image.name = `workPreview`;
image.alpha = 0;
image.width = canvasWidth;
image.height = canvasHeight;
this.slidesContainer.addChild(image);
}
// DISPLACE TIMELINE
this.displaceTl = new TimelineMax({
paused: true,
});
this.displaceTl.add('start')
.fromTo(this.getCanvasEl(), 0.4, {
autoAlpha: 0,
}, {
autoAlpha: 1,
ease: Power4.easeOut,
}, "start")
.fromTo(this.getCanvasEl(), 0.8, {
scale: 1.5,
}, {
scale: 1,
ease: Power4.easeOut,
}, "start")
.fromTo(
filter.scale, 1.6, {
x: 150,
y: 150,
},
{
x: 0,
y: 0,
ease: Power4.easeOut,
onComplete: () => {
},
}, "start",
);
return [this.slidesContainer, this.displaceTl];
}
workHoverEnter(layerId) {
// SET ALPHA OF HOVERED CASE PREVIEW
TweenMax.to(this.slidesContainer.children[layerId], 0.4, {
alpha: 1,
ease: Power3.easeOut,
onStart: () => {
this.displaceTl.progress(0);
this.displaceTl.play();
},
});
}
workHoverLeave() {
TweenMax.to(this.slidesContainer.children, 0.4, {
alpha: 0,
ease: Power3.easeOut,
});
}
}
new WorkList();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.7.1/pixi.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
//IMPORTS
@import url("https://fonts.googleapis.com/css?family=Raleway");
//SETTINGS
//colors
$dark-grey: #0d0d0d;
$white: #ffffff;
//grid
$settings-grid-column-width: 60px;
//transitions
$settings-hover: all 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
$settings-hover-delay: all 0.2s 0.1s cubic-bezier(0.25, 0.46, 0.45, 0.94);
//GLOBAL
body {
font-family: "Raleway", sans-serif;
-webkit-font-smoothing: antialiased;
line-height: 1em;
background-color: $dark-grey;
color: $white;
overflow: hidden;
}
.u-b6 {
font-family: "Raleway", sans-serif;
margin: 0;
font-size: 10px;
}
.u-b4 {
font-family: "Raleway", sans-serif;
margin: 0;
font-size: 14px;
}
.u-a6 {
margin: 0;
margin-bottom: 0.6em;
font-size: 54px;
}
.u-a7 {
margin: 0;
font-size: 64px;
padding: $settings-grid-column-width $settings-grid-column-width 0
$settings-grid-column-width;
}
//WORK LIST
.c-work {
width: 100%;
height: 100vh;
display: flex;
align-items: center;
overflow: hidden;
&__list {
position: relative;
z-index: 2;
margin: 0 auto;
text-align: center;
}
&__item {
display: block;
}
}
.c-work-item {
position: relative;
display: block;
cursor: pointer;
padding: 25px 0;
&__number {
position: absolute;
display: inline-block;
right: 100%;
top: 25px;
margin-right: 25px;
pointer-events: none;
transition: $settings-hover-delay;
will-change: transform, opacity;
}
&__title {
transition: $settings-hover;
will-change: transform;
}
&__category {
display: inline-block;
transition: $settings-hover-delay;
will-change: transform;
i {
font-style: normal;
display: inline-block;
margin-right: 8px;
}
}
&:hover {
//overrides
.c-work-item__title {
transform: translateX(10px);
}
.c-work-item__number {
opacity: 0;
transform: translateX(20px);
}
.c-work-item__category {
transform: translateX(10px);
}
}
}
//WORK PREVIEW
.c-work-preview {
position: fixed;
width: 100%;
height: 100vh;
top: 0;
right: 0;
padding-right: $settings-grid-column-width;
pointer-events: none;
z-index: 1;
&:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: $dark-grey;
opacity: 0.5;
}
&__canvas {
display: block;
position: absolute;
top: 0;
left: 0;
width: 140%;
height: 140%;
.canvas {
position: absolute;
top: 50%;
left: 50%;
width: auto;
height: auto;
min-width: 100%;
min-height: 100%;
background-size: 0;
transform: translate(-50%, -50%);
}
canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
&__list {
display: block;
position: absolute;
top: 0;
right: $settings-grid-column-width;
width: percentage(10/24);
height: 100%;
}
&__item {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 100%;
left: 0;
height: 0;
padding-bottom: percentage(9/16);
overflow: hidden;
}
&__image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
//
opacity: 0;
visibility: hidden;
//STATE
&.is-active {
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment