Codrops 원본
3D Perspective Glitch Hover Effect
섹션 · MIT
갤러리 안에서는 화면을 벗어나거나 움직임을 멈추면 예제도 닫힙니다. 다시 재생할 때는 처음부터 시작해요.
SOURCE FILES
원본 코드 읽기
수집한 원본 소스와 실행 안내를 함께 제공합니다.
css/base.css
*,
*::after,
*::before {
box-sizing: border-box;
}
:root {
font-size: 16px;
--color-text: #000;
--color-bg: #3124c7;
--color-link: #fff;
--color-link-hover: #000;
--color-label: #fff;
--content-hover: #f3727e;
/* Glitch variables */
--gap-horizontal: 20px;
--gap-vertical: 5px;
--time-anim: 1s;
--blend-mode-1: none;
--blend-mode-2: color-dodge;
--blend-mode-3: luminosity;
--blend-mode-4: none;
--blend-mode-5: none;
--blend-color-1: #f3727e;
--blend-color-2: #f3727e;
--blend-color-3: #3124c7;
--blend-color-4: #3124c7;
--blend-color-5: #f3727e;
/* Rotation variables */
--rotate-time: 0.5s;
--rotate-easing: cubic-bezier(0.2,1,0.3,1);
/* Cover variables */
--fade-out-time: 0.25s;
--fade-in-time: 0.25s;
--fade-out-easing: ease-out;
--fade-in-easing: ease-out;
}
.demo-2 {
--color-bg: #6d5c5b;
--content-hover: #000;
}
body {
margin: 0;
color: var(--color-text);
background-color: var(--color-bg);
font-family: widescreen-ex, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow-x: hidden;
}
/* Page Loader */
.js .loading::before,
.js .loading::after {
content: '';
position: fixed;
z-index: 1000;
}
.js .loading::before {
top: 0;
left: 0;
width: 100%;
height: 100%;
background: var(--color-bg);
}
.js .loading::after {
top: 50%;
left: 50%;
width: 60px;
height: 60px;
margin: -30px 0 0 -30px;
border-radius: 50%;
opacity: 0.4;
background: var(--color-link);
animation: loaderAnim 0.7s linear infinite alternate forwards;
}
@keyframes loaderAnim {
to {
opacity: 1;
transform: scale3d(0.5,0.5,1);
}
}
a {
text-decoration: none;
color: var(--color-link);
outline: none;
cursor: pointer;
}
a:hover {
color: var(--color-link-hover);
outline: none;
}
/* Better focus styles from https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible */
a:focus {
/* Provide a fallback style for browsers
that don't support :focus-visible */
outline: none;
background: lightgrey;
}
a:focus:not(:focus-visible) {
/* Remove the focus indicator on mouse-focus for browsers
that do support :focus-visible */
background: transparent;
}
a:focus-visible {
/* Draw a very noticeable focus style for
keyboard-focus on browsers that do support
:focus-visible */
outline: 2px solid red;
background: transparent;
}
.unbutton {
background: none;
border: 0;
padding: 0;
margin: 0;
font: inherit;
cursor: pointer;
}
.unbutton:focus {
outline: none;
}
.frame {
padding: 1rem 2rem;
text-transform: uppercase;
}
.frame__title-main {
font-size: 1rem;
margin: 0;
font-weight: normal;
}
.frame__title-back {
position: relative;
display: flex;
align-items: flex-end;
margin-bottom: 0.15rem;
}
.frame__title-back span {
display: none;
}
.frame__title-back svg {
fill: var(--color-text);
}
.frame__title-prev {
margin: 0 2rem 0 0;
}
.frame__demo {
margin: 0 1rem 0 0;
}
.frame__demo--current {
color: var(--color-link-hover);
}
.intro {
padding: 10vh 2rem 10vh;
margin-bottom: 2rem;
}
.intro__title {
grid-area: title;
font-family: widescreen-ex, sans-serif;
font-weight: 800;
font-size: clamp(2rem,12vw,10rem);
line-height: 1;
margin: 0;
}
.intro__title span {
text-transform: uppercase;
-webkit-text-stroke: 1px #000;
text-stroke: 1px #000;
-webkit-text-fill-color: transparent;
text-fill-color: transparent;
color: transparent;
text-shadow: -10px 10px 0 #000;
}
.intro__title em {
font-family: park-lane, serif;
font-weight: 300;
font-style: normal;
display: block;
margin: -2.5vw 0 0 0;
text-transform: uppercase;
font-size: clamp(2rem,10vw,10rem);
-webkit-text-stroke: 1px #000;
text-stroke: 1px #000;
-webkit-text-fill-color: var(--color-bg);
text-fill-color: var(--color-bg);
color: var(--color-bg);
}
.intro__description {
margin: 1.75vw 0 0 0;
grid-area: desc;
font-weight: 500;
font-size: clamp(1rem, 2vw, 1.25rem);
max-width: 350px;
}
.intro__button {
grid-area: button;
border: 1px solid var(--color-text);
background: var(--color-bg);
box-shadow: 1px 2px 0 #000;
font-size: 1.25rem;
padding: 1rem 2rem;
border-radius: 1.25rem;
justify-self: end;
font-weight: bold;
text-transform: uppercase;
margin-top: 1rem;
}
.intro__button:hover,
.intro__button:focus {
transform: translate3d(1px,2px,0);
box-shadow: 0px 0px 0 #000;
}
.content {
display: grid;
grid-gap: 1.5rem;
margin: 0 auto;
padding-bottom: 30vh;
grid-template-columns: repeat(auto-fill, minmax(350px,1fr));
}
.item {
aspect-ratio: 0.8;
cursor: pointer;
display: grid;
grid-template-columns: 100%;
grid-template-rows: 100%;
perspective: 1000px;
overflow: hidden;
position: relative;
margin: 0;
}
.demo-2 .item {
overflow: visible;
}
.demo-2 .item--oh {
overflow: hidden;
}
.item__img {
grid-area: 1 / 1 / -1 / -1;
position: relative;
opacity: 0;
width: 100%;
height: 100%;
}
.item:hover .item__img {
opacity: 1;
transition: transform var(--rotate-time) var(--rotate-easing);
transform: translateZ(-200px) rotateX(60deg) rotateY(0) rotateZ(-35deg);
}
.glitch {
display: grid;
place-items: center;
}
.glitch__img {
grid-area: 1 / 1 / -1 / -1;
background-image: var(--img);
background-position: 50% 50%;
background-size: cover;
image-rendering: pixelated;
width: 100%;
height: 100%;
background-color: var(--blend-color-1);
transform: translate3d(0,0,0);
background-blend-mode: var(--blend-mode-1);
}
.glitch__img:nth-child(2) {
background-color: var(--blend-color-2);
background-blend-mode: var(--blend-mode-2);
}
.glitch__img:nth-child(3) {
background-color: var(--blend-color-3);
background-blend-mode: var(--blend-mode-3);
}
.glitch__img:nth-child(4) {
background-color: var(--blend-color-4);
background-blend-mode: var(--blend-mode-4);
}
.glitch__img:nth-child(5) {
background-color: var(--blend-color-5);
background-blend-mode: var(--blend-mode-5);
}
/* Hide all images except the first one */
.glitch__img:nth-child(n+2) {
opacity: 0;
}
/* Hovers */
/* On hover we show the 2nd, 3rd, 4th and 5th image*/
.item:hover .glitch__img:nth-child(n+2) {
opacity: 1;
}
/* Hover animations for horizontal case */
.item:hover .glitch__img:nth-child(2) {
transform: translate3d(var(--gap-horizontal),0,0);
animation: glitch-anim-1-horizontal var(--time-anim) infinite linear alternate;
}
.item:hover .glitch__img:nth-child(3) {
transform: translate3d(calc(-1 * var(--gap-horizontal)),0,0);
animation: glitch-anim-2-horizontal var(--time-anim) infinite linear alternate;
}
.item:hover .glitch__img:nth-child(4) {
transform: translate3d(0, calc(-1 * var(--gap-vertical)), 0) scale3d(-1,-1,1);
animation: glitch-anim-3-horizontal var(--time-anim) infinite linear alternate;
}
/* Hover flash animation on last image */
.item:hover .glitch__img:nth-child(5) {
animation: glitch-anim-flash 0.5s steps(1,end) infinite;
}
/* Animations */
/* Horizontal */
@keyframes glitch-anim-1-horizontal {
0% {
-webkit-clip-path: polygon(0 2%, 100% 2%, 100% 5%, 0 5%);
clip-path: polygon(0 2%, 100% 2%, 100% 5%, 0 5%);
}
10% {
-webkit-clip-path: polygon(0 15%, 100% 15%, 100% 15%, 0 15%);
clip-path: polygon(0 15%, 100% 15%, 100% 15%, 0 15%);
}
20% {
-webkit-clip-path: polygon(0 10%, 100% 10%, 100% 20%, 0 20%);
clip-path: polygon(0 10%, 100% 10%, 100% 20%, 0 20%);
}
30% {
-webkit-clip-path: polygon(0 1%, 100% 1%, 100% 2%, 0 2%);
clip-path: polygon(0 1%, 100% 1%, 100% 2%, 0 2%);
}
40% {
-webkit-clip-path: polygon(0 33%, 100% 33%, 100% 33%, 0 33%);
clip-path: polygon(0 33%, 100% 33%, 100% 33%, 0 33%);
}
50% {
-webkit-clip-path: polygon(0 44%, 100% 44%, 100% 44%, 0 44%);
clip-path: polygon(0 44%, 100% 44%, 100% 44%, 0 44%);
}
60% {
-webkit-clip-path: polygon(0 50%, 100% 50%, 100% 20%, 0 20%);
clip-path: polygon(0 50%, 100% 50%, 100% 20%, 0 20%);
}
70% {
-webkit-clip-path: polygon(0 70%, 100% 70%, 100% 70%, 0 70%);
clip-path: polygon(0 70%, 100% 70%, 100% 70%, 0 70%);
}
80% {
-webkit-clip-path: polygon(0 80%, 100% 80%, 100% 80%, 0 80%);
clip-path: polygon(0 80%, 100% 80%, 100% 80%, 0 80%);
}
90% {
-webkit-clip-path: polygon(0 50%, 100% 50%, 100% 55%, 0 55%);
clip-path: polygon(0 50%, 100% 50%, 100% 55%, 0 55%);
}
100% {
-webkit-clip-path: polygon(0 70%, 100% 70%, 100% 80%, 0 80%);
clip-path: polygon(0 70%, 100% 70%, 100% 80%, 0 80%);
}
}
@keyframes glitch-anim-2-horizontal {
0% {
-webkit-clip-path: polygon(0 25%, 100% 25%, 100% 30%, 0 30%);
clip-path: polygon(0 25%, 100% 25%, 100% 30%, 0 30%);
}
15% {
-webkit-clip-path: polygon(0 3%, 100% 3%, 100% 3%, 0 3%);
clip-path: polygon(0 3%, 100% 3%, 100% 3%, 0 3%);
}
22% {
-webkit-clip-path: polygon(0 5%, 100% 5%, 100% 20%, 0 20%);
clip-path: polygon(0 5%, 100% 5%, 100% 20%, 0 20%);
}
31% {
-webkit-clip-path: polygon(0 20%, 100% 20%, 100% 20%, 0 20%);
clip-path: polygon(0 20%, 100% 20%, 100% 20%, 0 20%);
}
45% {
-webkit-clip-path: polygon(0 40%, 100% 40%, 100% 40%, 0 40%);
clip-path: polygon(0 40%, 100% 40%, 100% 40%, 0 40%);
}
51% {
-webkit-clip-path: polygon(0 52%, 100% 52%, 100% 59%, 0 59%);
clip-path: polygon(0 52%, 100% 52%, 100% 59%, 0 59%);
}
63% {
-webkit-clip-path: polygon(0 60%, 100% 60%, 100% 60%, 0 60%);
clip-path: polygon(0 60%, 100% 60%, 100% 60%, 0 60%);
}
76% {
-webkit-clip-path: polygon(0 75%, 100% 75%, 100% 75%, 0 75%);
clip-path: polygon(0 75%, 100% 75%, 100% 75%, 0 75%);
}
81% {
-webkit-clip-path: polygon(0 65%, 100% 65%, 100% 40%, 0 40%);
clip-path: polygon(0 65%, 100% 65%, 100% 40%, 0 40%);
}
94% {
-webkit-clip-path: polygon(0 45%, 100% 45%, 100% 50%, 0 50%);
clip-path: polygon(0 45%, 100% 45%, 100% 50%, 0 50%);
}
100% {
-webkit-clip-path: polygon(0 14%, 100% 14%, 100% 33%, 0 33%);
clip-path: polygon(0 14%, 100% 14%, 100% 33%, 0 33%);
}
}
@keyframes glitch-anim-3-horizontal {
0% {
-webkit-clip-path: polygon(0 1%, 100% 1%, 100% 3%, 0 3%);
clip-path: polygon(0 1%, 100% 1%, 100% 3%, 0 3%);
}
5% {
-webkit-clip-path: polygon(0 10%, 100% 10%, 100% 9%, 0 9%);
clip-path: polygon(0 10%, 100% 10%, 100% 9%, 0 9%);
}
10% {
-webkit-clip-path: polygon(0 5%, 100% 5%, 100% 6%, 0 6%);
clip-path: polygon(0 5%, 100% 5%, 100% 6%, 0 6%);
}
25% {
-webkit-clip-path: polygon(0 20%, 100% 20%, 100% 20%, 0 20%);
clip-path: polygon(0 20%, 100% 20%, 100% 20%, 0 20%);
}
27% {
-webkit-clip-path: polygon(0 10%, 100% 10%, 100% 10%, 0 10%);
clip-path: polygon(0 10%, 100% 10%, 100% 10%, 0 10%);
}
30% {
-webkit-clip-path: polygon(0 30%, 100% 30%, 100% 25%, 0 25%);
clip-path: polygon(0 30%, 100% 30%, 100% 25%, 0 25%);
}
33% {
-webkit-clip-path: polygon(0 15%, 100% 15%, 100% 16%, 0 16%);
clip-path: polygon(0 15%, 100% 15%, 100% 16%, 0 16%);
}
37% {
-webkit-clip-path: polygon(0 40%, 100% 40%, 100% 39%, 0 39%);
clip-path: polygon(0 40%, 100% 40%, 100% 39%, 0 39%);
}
40% {
-webkit-clip-path: polygon(0 20%, 100% 20%, 100% 21%, 0 21%);
clip-path: polygon(0 20%, 100% 20%, 100% 21%, 0 21%);
}
45% {
-webkit-clip-path: polygon(0 60%, 100% 60%, 100% 55%, 0 55%);
clip-path: polygon(0 60%, 100% 60%, 100% 55%, 0 55%);
}
50% {
-webkit-clip-path: polygon(0 30%, 100% 30%, 100% 31%, 0 31%);
clip-path: polygon(0 30%, 100% 30%, 100% 31%, 0 31%);
}
53% {
-webkit-clip-path: polygon(0 70%, 100% 70%, 100% 69%, 0 69%);
clip-path: polygon(0 70%, 100% 70%, 100% 69%, 0 69%);
}
57% {
-webkit-clip-path: polygon(0 40%, 100% 40%, 100% 41%, 0 41%);
clip-path: polygon(0 40%, 100% 40%, 100% 41%, 0 41%);
}
60% {
-webkit-clip-path: polygon(0 80%, 100% 80%, 100% 75%, 0 75%);
clip-path: polygon(0 80%, 100% 80%, 100% 75%, 0 75%);
}
65% {
-webkit-clip-path: polygon(0 50%, 100% 50%, 100% 51%, 0 51%);
clip-path: polygon(0 50%, 100% 50%, 100% 51%, 0 51%);
}
70% {
-webkit-clip-path: polygon(0 90%, 100% 90%, 100% 90%, 0 90%);
clip-path: polygon(0 90%, 100% 90%, 100% 90%, 0 90%);
}
73% {
-webkit-clip-path: polygon(0 60%, 100% 60%, 100% 60%, 0 60%);
clip-path: polygon(0 60%, 100% 60%, 100% 60%, 0 60%);
}
80% {
-webkit-clip-path: polygon(0 100%, 100% 100%, 100% 99%, 0 99%);
clip-path: polygon(0 100%, 100% 100%, 100% 99%, 0 99%);
}
100% {
-webkit-clip-path: polygon(0 70%, 100% 70%, 100% 71%, 0 71%);
clip-path: polygon(0 70%, 100% 70%, 100% 71%, 0 71%);
}
}
/* Vertical */
@keyframes glitch-anim-1-vertical {
0% {
-webkit-clip-path: polygon(2% 0, 5% 0, 5% 100%, 2% 100%);
clip-path: polygon(2% 0, 5% 0, 5% 100%, 2% 100%);
}
10% {
-webkit-clip-path: polygon(15% 0, 15% 0, 15% 100%, 15% 100%);
clip-path: polygon(15% 0, 15% 0, 15% 100%, 15% 100%);
}
20% {
-webkit-clip-path: polygon(10% 0, 20% 0, 20% 100%, 10% 100%);
clip-path: polygon(10% 0, 20% 0, 20% 100%, 10% 100%);
}
30% {
-webkit-clip-path: polygon(1% 0, 2% 0, 2% 100%, 1% 100%);
clip-path: polygon(1% 0, 2% 0, 2% 100%, 1% 100%);
}
40% {
-webkit-clip-path: polygon(33% 0, 33% 0, 33% 100%, 33% 100%);
clip-path: polygon(33% 0, 33% 0, 33% 100%, 33% 100%);
}
50% {
-webkit-clip-path: polygon(44% 0, 44% 0, 44% 100%, 44% 100%);
clip-path: polygon(44% 0, 44% 0, 44% 100%, 44% 100%);
}
60% {
-webkit-clip-path: polygon(50% 0, 20% 0, 20% 100%, 50% 100%);
clip-path: polygon(50% 0, 20% 0, 20% 100%, 50% 100%);
}
70% {
-webkit-clip-path: polygon(70% 0, 70% 0, 70% 100% 70%, 70% 100%);
clip-path: polygon(70% 0, 70% 0, 70% 100% 70%, 70% 100%);
}
80% {
-webkit-clip-path: polygon(80% 0, 80% 0, 80% 100% 80%, 80% 100%);
clip-path: polygon(80% 0, 80% 0, 80% 100% 80%, 80% 100%);
}
90% {
-webkit-clip-path: polygon(50% 0, 55% 0, 55% 100%, 50% 100%);
clip-path: polygon(50% 0, 55% 0, 55% 100%, 50% 100%);
}
100% {
-webkit-clip-path: polygon(70% 0, 80% 0, 80% 100%, 70% 100%);
clip-path: polygon(70% 0, 80% 0, 80% 100%, 70% 100%);
}
}
@keyframes glitch-anim-2-vertical {
0% {
-webkit-clip-path: polygon(25% 0, 30% 0, 30% 100%, 25% 100%);
clip-path: polygon(25% 0, 30% 0, 30% 100%, 25% 100%);
}
15% {
-webkit-clip-path: polygon(3% 0, 3% 0, 3% 100%, 3% 100%);
clip-path: polygon(3% 0, 3% 0, 3% 100%, 3% 100%);
}
22% {
-webkit-clip-path: polygon(5% 0, 20% 0, 20% 100%, 5% 100%);
clip-path: polygon(5% 0, 20% 0, 20% 100%, 5% 100%);
}
31% {
-webkit-clip-path: polygon(20% 0, 20% 0, 20% 100%, 20% 100%);
clip-path: polygon(20% 0, 20% 0, 20% 100%, 20% 100%);
}
45% {
-webkit-clip-path: polygon(40% 0, 40% 0, 40% 100%, 40% 100%);
clip-path: polygon(40% 0, 40% 0, 40% 100%, 40% 100%);
}
51% {
-webkit-clip-path: polygon(52% 0, 59% 0, 59% 100%, 52% 100%);
clip-path: polygon(52% 0, 59% 0, 59% 100%, 52% 100%);
}
63% {
-webkit-clip-path: polygon(60% 0, 60% 0, 60% 100%, 60% 100%);
clip-path: polygon(60% 0, 60% 0, 60% 100%, 60% 100%);
}
76% {
-webkit-clip-path: polygon(75% 0, 75% 0, 75% 100%, 75% 100%);
clip-path: polygon(75% 0, 75% 0, 75% 100%, 75% 100%);
}
81% {
-webkit-clip-path: polygon(65% 0, 40% 0, 40% 100%, 65% 100%);
clip-path: polygon(65% 0, 40% 0, 40% 100%, 65% 100%);
}
94% {
-webkit-clip-path: polygon(45% 0, 50% 0, 50% 100%, 45% 100%);
clip-path: polygon(45% 0, 50% 0, 50% 100%, 45% 100%);
}
100% {
-webkit-clip-path: polygon(14% 0, 33% 0, 33% 100%, 14% 100%);
clip-path: polygon(14% 0, 33% 0, 33% 100%, 14% 100%);
}
}
@keyframes glitch-anim-3-vertical {
0% {
-webkit-clip-path: polygon(1% 0, 3% 0, 3% 100%, 1% 100%);
clip-path: polygon(1% 0, 3% 0, 3% 100%, 1% 100%);
}
5% {
-webkit-clip-path: polygon(10% 0, 9% 0, 9% 100%, 10% 100%);
clip-path: polygon(10% 0, 9% 0, 9% 100%, 10% 100%);
}
10% {
-webkit-clip-path: polygon(5% 0, 6% 0 6% 100%, 5% 100%);
clip-path: polygon(5% 0, 6% 0 6% 100%, 5% 100%);
}
25% {
-webkit-clip-path: polygon(20% 0, 20% 0, 20% 100%, 20% 100%);
clip-path: polygon(20% 0, 20% 0, 20% 100%, 20% 100%);
}
27% {
-webkit-clip-path: polygon(10% 0, 10% 0, 10% 100%, 10% 100%);
clip-path: polygon(10% 0, 10% 0, 10% 100%, 10% 100%);
}
30% {
-webkit-clip-path: polygon(30% 0, 25% 0, 25% 100%, 30% 100%);
clip-path: polygon(30% 0, 25% 0, 25% 100%, 30% 100%);
}
33% {
-webkit-clip-path: polygon(15% 0, 16% 0, 16% 100%, 15% 100%);;
clip-path: polygon(15% 0, 16% 0, 16% 100%, 15% 100%);
}
37% {
-webkit-clip-path: polygon(40% 0, 39% 0, 39% 100%, 40% 100%);;
clip-path: polygon(40% 0, 39% 0, 39% 100%, 40% 100%);
}
40% {
-webkit-clip-path: polygon(20% 0, 21% 0, 21% 100%, 20% 100%);
clip-path: polygon(20% 0, 21% 0, 21% 100%, 20% 100%);
}
45% {
-webkit-clip-path: polygon(60% 0, 55% 0, 55% 100%, 60% 100%);
clip-path: polygon(60% 0, 55% 0, 55% 100%, 60% 100%);
}
50% {
-webkit-clip-path: polygon(30% 0, 31% 0, 31% 100%, 30% 100%);
clip-path: polygon(30% 0, 31% 0, 31% 100%, 30% 100%);
}
53% {
-webkit-clip-path: polygon(70% 0, 69% 0, 69% 100%, 70% 100%);
clip-path: polygon(70% 0, 69% 0, 69% 100%, 70% 100%);
}
57% {
-webkit-clip-path: polygon(40% 0, 41% 0, 41% 100%, 40% 100%);
clip-path: polygon(40% 0, 41% 0, 41% 100%, 40% 100%);
}
60% {
-webkit-clip-path: polygon(80% 0, 75% 0, 75% 100%, 80% 100%);
clip-path: polygon(80% 0, 75% 0, 75% 100%, 80% 100%);
}
65% {
-webkit-clip-path: polygon(50% 0, 51% 0, 51% 100%, 50% 100%);
clip-path: polygon(50% 0, 51% 0, 51% 100%, 50% 100%);
}
70% {
-webkit-clip-path: polygon(90% 0, 90% 0, 90% 100%, 90% 100%);
clip-path: polygon(90% 0, 90% 0, 90% 100%, 90% 100%);
}
73% {
-webkit-clip-path: polygon(60% 0, 60% 0, 60% 100%, 60% 100%);
clip-path: polygon(60% 0, 60% 0, 60% 100%, 60% 100%);
}
80% {
-webkit-clip-path: polygon(100% 0, 99% 0, 99% 100%, 100% 100%);
clip-path: polygon(100% 0, 99% 0, 99% 100%, 100% 100%);
}
100% {
-webkit-clip-path: polygon(70% 0, 71% 0, 71% 100%, 70% 100%);
clip-path: polygon(70% 0, 71% 0, 71% 100%, 70% 100%);
}
}
/* Flash */
@keyframes glitch-anim-flash {
0% {
opacity: 0.2;
transform: translate3d(var(--gap-horizontal), var(--gap-vertical), 0);
}
33%, 100% {
opacity: 0;
transform: translate3d(0,0,0);
}
}
.item__cover {
grid-area: 1 / 1 / -1 / -1;
background-size: cover;
background-position: 50% 50%;
position: relative;
transition: opacity var(--fade-in-time) var(--fade-in-easing);
pointer-events: none;
}
.item__cover::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(0deg,rgb(54 58 199 / 38%), rgba(0,0,0,0.2));
}
.item:hover .item__cover {
opacity: 0;
transition: opacity var(--fade-out-time) var(--fade-out-easing);
}
.item__content {
display: flex;
flex-direction: column;
pointer-events: none;
padding: 1.5rem;
position: relative;
grid-area: 1 / 1 / -1 / -1;
color: var(--color-label);
}
.item__content-title {
font-family: park-lane, serif;
font-weight: 300;
font-style: normal;
font-size: clamp(3rem,4vw,5rem);
line-height: 1;
margin: 0;
}
.item:hover .item__content-title,
.item:hover .item__content-label {
color: var(--content-hover);
}
.item__content-label {
margin: auto 0 0;
}
blockquote {
font-weight: 500;
font-size: clamp(1rem, 2vw, 1.25rem);
}
@media screen and (min-width: 53em) {
.frame {
text-align: center;
display: grid;
grid-template-columns: auto auto;
grid-template-rows: auto auto;
grid-template-areas: 'title sponsor' 'demos demos';
grid-row-gap: 1rem;
align-content: space-between;
}
.frame__title {
grid-area: title;
display: grid;
grid-auto-flow: column;
grid-template-columns: auto auto 1fr;
align-items: start;
justify-items: flex-start;
}
.frame__demos {
grid-area: demos;
justify-self: end;
}
.frame__demo {
margin: 0 0 0 1rem;
}
.intro {
display: grid;
grid-column-gap: 1rem;
grid-template-areas: 'title desc'
'title button';
justify-content: space-between;
align-items: start;
text-align: right;
}
}
index.html
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>3D Perspective Glitch Hover Effect | Demo 1 | Codrops</title>
<meta name="description" content="A fun hover effect that shows a pixelated image with a glitch animation as seen on buōy's website." />
<meta name="keywords" content="hover effect, pixel art, glitch effect, css" />
<meta name="author" content="Codrops" />
<link rel="shortcut icon" href="favicon.ico">
<link rel="stylesheet" href="https://use.typekit.net/ili2osz.css">
<link rel="stylesheet" type="text/css" href="css/base.css" />
<script>document.documentElement.className="js";var supportsCssVars=function(){var e,t=document.createElement("style");return t.innerHTML="root: { --tmp-var: bold; }",document.head.appendChild(t),e=!!(window.CSS&&window.CSS.supports&&window.CSS.supports("font-weight","var(--tmp-var)")),t.parentNode.removeChild(t),e};supportsCssVars()||alert("Please view this demo in a modern browser that supports CSS Variables.");</script>
<script src="//tympanus.net/codrops/adpacks/analytics.js"></script>
</head>
<body class="demo-1">
<main>
<div class="frame">
<div class="frame__title">
<a class="frame__title-prev" href="https://tympanus.net/Development/EmitterCursor/">Previous demo</a>
<h1 class="frame__title-main">3D Perspective Glitch Hover Effect </h1>
<a aria-label="Back to the article" class="frame__title-back" href="https://tympanus.net/codrops/?p=64948">
<span class="oh__inner">Back to the article</span>
<svg width="18px" height="18px" viewBox="0 0 24 24"><path vector-effect="non-scaling-stroke" d="M18.25 15.5a.75.75 0 00.75-.75v-9a.75.75 0 00-.75-.75h-9a.75.75 0 000 1.5h7.19L6.22 16.72a.75.75 0 101.06 1.06L17.5 7.56v7.19c0 .414.336.75.75.75z"></path>
</svg>
</a>
</div>
<nav class="frame__demos">
<a href="index.html" class="frame__demo frame__demo--current">demo 1</a>
<a href="index2.html" class="frame__demo">demo 2</a>
</nav>
</div>
<div class="intro">
<h2 class="intro__title">
<span>Techno</span>
<em>workshop</em>
</h2>
<p class="intro__description">
Techno Workshop is a collective of the weirdest creative minds. We share art and inspiration and create design contests to showcase futile but cute additions to the consumer world.
</p>
<button class="intro__button unbutton">Create with us</button>
</div>
<div class="content">
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/1.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/1.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Wallace <br> MacKenzie</h3>
<h4 class="item__content-label">Uplift, 2001</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/2.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/2.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Gunnar <br> Redsocks</h3>
<h4 class="item__content-label">The Fashion Drop, 2003</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/3.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/3.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Frankie <br> Tankie</h3>
<h4 class="item__content-label">Constant Ink, 2010</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/4.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/4.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Helder <br> Brunckhorst</h3>
<h4 class="item__content-label">Happy Space, 2011</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/5.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/5.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Bolder <br> Da Mouth</h3>
<h4 class="item__content-label">Freedom Press, 2012</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/6.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/6.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Marie <br> Sockamoodle</h3>
<h4 class="item__content-label">Fashion House, 2013</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/7.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/7.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Walter <br> Meckage</h3>
<h4 class="item__content-label">The Hotel Room, 2019</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/8.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/8.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Kelly <br> Braylor</h3>
<h4 class="item__content-label">Chique, 2020</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/9.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/9.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Fundo <br> Constanza</h3>
<h4 class="item__content-label">Love Affair, 2015</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/10.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/10.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Bernie <br> Kunst</h3>
<h4 class="item__content-label">Decadence, 2017</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/11.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/11.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Sandra <br> M. Lester</h3>
<h4 class="item__content-label">Drifters, 2018</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/12.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/12.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Mister <br> DonGold</h3>
<h4 class="item__content-label">The Shift, 2021</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/13.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/13.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Laura <br> Murdoch</h3>
<h4 class="item__content-label">Trendphile, 2017</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/14.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/14.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">John <br> Van Hoff</h3>
<h4 class="item__content-label">The Lace, 2018</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/15.png);">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/15.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Armin <br> Harbinger</h3>
<h4 class="item__content-label">Fringe Punch, 2022</h4>
</figcaption>
</figure>
</div>
<blockquote>
<p>The disruption of everyday reality, effects on instinct<br>
rational, irrational, expression, depression, to be persuaded.<br>
Assessments, values, from glancing in a mirror and the wider<br>
significance of commentaries, refrains, classifieds, link to chaos!<br>
The exploitation and denial of confirmation<br>
Pre-conceptions, non-threatening; bright lights.
</p>
<p class="author">Enamour encore by <a href="https://www.smashwords.com/profile/view/sunnyjetsun">Sunny Jetsun</a></p>
</blockquote>
</main>
<script src="https://tympanus.net/codrops/adpacks/cda_sponsor.js"></script>
</body>
</html>
함께 쓰는 파일 4개 보기
index2.html
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>3D Perspective Glitch Hover Effect | Demo 2 | Codrops</title>
<meta name="description" content="A fun hover effect that shows a pixelated image with a glitch animation as seen on buōy's website." />
<meta name="keywords" content="hover effect, pixel art, glitch effect, css, javascript, tilt" />
<meta name="author" content="Codrops" />
<link rel="shortcut icon" href="favicon.ico">
<link rel="stylesheet" href="https://use.typekit.net/ili2osz.css">
<link rel="stylesheet" type="text/css" href="css/base.css" />
<script>document.documentElement.className="js";var supportsCssVars=function(){var e,t=document.createElement("style");return t.innerHTML="root: { --tmp-var: bold; }",document.head.appendChild(t),e=!!(window.CSS&&window.CSS.supports&&window.CSS.supports("font-weight","var(--tmp-var)")),t.parentNode.removeChild(t),e};supportsCssVars()||alert("Please view this demo in a modern browser that supports CSS Variables.");</script>
<script src="//tympanus.net/codrops/adpacks/analytics.js"></script>
</head>
<body class="demo-2">
<main>
<div class="frame">
<div class="frame__title">
<a class="frame__title-prev" href="https://tympanus.net/Development/EmitterCursor/">Previous demo</a>
<h1 class="frame__title-main">3D Perspective Glitch Hover Effect </h1>
<a aria-label="Back to the article" class="frame__title-back" href="https://tympanus.net/codrops/?p=64948">
<span class="oh__inner">Back to the article</span>
<svg width="18px" height="18px" viewBox="0 0 24 24"><path vector-effect="non-scaling-stroke" d="M18.25 15.5a.75.75 0 00.75-.75v-9a.75.75 0 00-.75-.75h-9a.75.75 0 000 1.5h7.19L6.22 16.72a.75.75 0 101.06 1.06L17.5 7.56v7.19c0 .414.336.75.75.75z"></path>
</svg>
</a>
</div>
<nav class="frame__demos">
<a href="index.html" class="frame__demo">demo 1</a>
<a href="index2.html" class="frame__demo frame__demo--current">demo 2</a>
</nav>
</div>
<div class="intro">
<h2 class="intro__title">
<span>Techno</span>
<em>workshop</em>
</h2>
<p class="intro__description">
Techno Workshop is a collective of the weirdest creative minds. We share art and inspiration and create design contests to showcase futile but cute additions to the consumer world.
</p>
<button class="intro__button unbutton">Create with us</button>
</div>
<div class="content">
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/1.png);" data-tilt data-tilt-max="15" data-tilt-speed="3000" data-tilt-perspective="1500" data-tilt-scale="0.95" data-tilt-mouse-event-element=".content .item:nth-child(1)">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/1.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Wallace <br> MacKenzie</h3>
<h4 class="item__content-label">Uplift, 2001</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/2.png);" data-tilt data-tilt-max="15" data-tilt-speed="3000" data-tilt-perspective="1500" data-tilt-scale="0.95" data-tilt-mouse-event-element=".content .item:nth-child(2)">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/2.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Gunnar <br> Redsocks</h3>
<h4 class="item__content-label">The Fashion Drop, 2003</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/3.png);" data-tilt data-tilt-max="15" data-tilt-speed="3000" data-tilt-perspective="1500" data-tilt-scale="0.95" data-tilt-mouse-event-element=".content .item:nth-child(3)">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/3.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Frankie <br> Tankie</h3>
<h4 class="item__content-label">Constant Ink, 2010</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/4.png);" data-tilt data-tilt-max="35" data-tilt-speed="3000" data-tilt-perspective="1500" data-tilt-scale="0.95" data-tilt-mouse-event-element=".content .item:nth-child(4)" data-tilt-reverse="true">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/4.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Helder <br> Brunckhorst</h3>
<h4 class="item__content-label">Happy Space, 2011</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/5.png);" data-tilt data-tilt-max="35" data-tilt-speed="3000" data-tilt-perspective="1500" data-tilt-scale="0.95" data-tilt-mouse-event-element=".content .item:nth-child(5)" data-tilt-reverse="true">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/5.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Bolder <br> Da Mouth</h3>
<h4 class="item__content-label">Freedom Press, 2012</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/6.png);" data-tilt data-tilt-max="35" data-tilt-speed="3000" data-tilt-perspective="1500" data-tilt-scale="0.95" data-tilt-mouse-event-element=".content .item:nth-child(6)" data-tilt-reverse="true">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/6.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Marie <br> Sockamoodle</h3>
<h4 class="item__content-label">Fashion House, 2013</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/7.png);" data-tilt data-tilt-max="15" data-tilt-speed="1000" data-tilt-perspective="1500" data-tilt-scale="0.6" data-tilt-mouse-event-element=".content .item:nth-child(7)">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/7.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Walter <br> Meckage</h3>
<h4 class="item__content-label">The Hotel Room, 2019</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/8.png);" data-tilt data-tilt-max="15" data-tilt-speed="1000" data-tilt-perspective="1500" data-tilt-scale="0.6" data-tilt-mouse-event-element=".content .item:nth-child(8)">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/8.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Kelly <br> Braylor</h3>
<h4 class="item__content-label">Chique, 2020</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/9.png);" data-tilt data-tilt-max="15" data-tilt-speed="1000" data-tilt-perspective="1500" data-tilt-scale="0.6" data-tilt-mouse-event-element=".content .item:nth-child(9)">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/9.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Fundo <br> Constanza</h3>
<h4 class="item__content-label">Love Affair, 2015</h4>
</figcaption>
</figure>
<figure class="item item--oh">
<div class="item__img glitch" style="--img:url(../img/10.png);" data-tilt data-tilt-max="15" data-tilt-speed="1000" data-tilt-perspective="1500" data-tilt-scale="1.5" data-tilt-mouse-event-element=".content .item:nth-child(10)" data-tilt-reverse="true">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/10.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Bernie <br> Kunst</h3>
<h4 class="item__content-label">Decadence, 2017</h4>
</figcaption>
</figure>
<figure class="item item--oh">
<div class="item__img glitch" style="--img:url(../img/11.png);" data-tilt data-tilt-max="15" data-tilt-speed="1000" data-tilt-perspective="1500" data-tilt-scale="1.5" data-tilt-mouse-event-element=".content .item:nth-child(11)" data-tilt-reverse="true">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/11.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Sandra <br> M. Lester</h3>
<h4 class="item__content-label">Drifters, 2018</h4>
</figcaption>
</figure>
<figure class="item item--oh">
<div class="item__img glitch" style="--img:url(../img/12.png);" data-tilt data-tilt-max="15" data-tilt-speed="1000" data-tilt-perspective="1500" data-tilt-scale="1.5" data-tilt-mouse-event-element=".content .item:nth-child(12)" data-tilt-reverse="true">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/12.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Mister <br> DonGold</h3>
<h4 class="item__content-label">The Shift, 2021</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/13.png);" data-tilt data-tilt-max="25" data-tilt-speed="2000" data-tilt-perspective="500" data-tilt-axis="y" data-tilt-scale="0.8" data-tilt-mouse-event-element=".content .item:nth-child(13)">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/13.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Laura <br> Murdoch</h3>
<h4 class="item__content-label">Trendphile, 2017</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/14.png);" data-tilt data-tilt-max="25" data-tilt-speed="2000" data-tilt-perspective="500" data-tilt-axis="y" data-tilt-scale="0.8" data-tilt-mouse-event-element=".content .item:nth-child(14)">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/14.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">John <br> Van Hoff</h3>
<h4 class="item__content-label">The Lace, 2018</h4>
</figcaption>
</figure>
<figure class="item">
<div class="item__img glitch" style="--img:url(../img/15.png);" data-tilt data-tilt-max="25" data-tilt-speed="2000" data-tilt-perspective="500"data-tilt-axis="y" data-tilt-scale="0.8" data-tilt-mouse-event-element=".content .item:nth-child(15)">
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
<div class="glitch__img"></div>
</div>
<div class="item__cover" style="background-image:url(img/15.avif)"></div>
<figcaption class="item__content">
<h3 class="item__content-title">Armin <br> Harbinger</h3>
<h4 class="item__content-label">Fringe Punch, 2022</h4>
</figcaption>
</figure>
</div>
<blockquote>
<p>The disruption of everyday reality, effects on instinct<br>
rational, irrational, expression, depression, to be persuaded.<br>
Assessments, values, from glancing in a mirror and the wider<br>
significance of commentaries, refrains, classifieds, link to chaos!<br>
The exploitation and denial of confirmation<br>
Pre-conceptions, non-threatening; bright lights.
</p>
<p class="author">Enamour encore by <a href="https://www.smashwords.com/profile/view/sunnyjetsun">Sunny Jetsun</a></p>
</blockquote>
</main>
<script type="text/javascript" src="js/vanilla-tilt.js"></script>
<script src="https://tympanus.net/codrops/adpacks/cda_sponsor.js"></script>
</body>
</html>
js/vanilla-tilt.js
var VanillaTilt = (function () {
'use strict';
/**
* Created by Sergiu Șandor (micku7zu) on 1/27/2017.
* Original idea: https://github.com/gijsroge/tilt.js
* MIT License.
* Version 1.7.2
*/
class VanillaTilt {
constructor(element, settings = {}) {
if (!(element instanceof Node)) {
throw ("Can't initialize VanillaTilt because " + element + " is not a Node.");
}
this.width = null;
this.height = null;
this.clientWidth = null;
this.clientHeight = null;
this.left = null;
this.top = null;
// for Gyroscope sampling
this.gammazero = null;
this.betazero = null;
this.lastgammazero = null;
this.lastbetazero = null;
this.transitionTimeout = null;
this.updateCall = null;
this.event = null;
this.updateBind = this.update.bind(this);
this.resetBind = this.reset.bind(this);
this.element = element;
this.settings = this.extendSettings(settings);
this.reverse = this.settings.reverse ? -1 : 1;
this.glare = VanillaTilt.isSettingTrue(this.settings.glare);
this.glarePrerender = VanillaTilt.isSettingTrue(this.settings["glare-prerender"]);
this.fullPageListening = VanillaTilt.isSettingTrue(this.settings["full-page-listening"]);
this.gyroscope = VanillaTilt.isSettingTrue(this.settings.gyroscope);
this.gyroscopeSamples = this.settings.gyroscopeSamples;
this.elementListener = this.getElementListener();
if (this.glare) {
this.prepareGlare();
}
if (this.fullPageListening) {
this.updateClientSize();
}
this.addEventListeners();
this.reset();
this.updateInitialPosition();
}
static isSettingTrue(setting) {
return setting === "" || setting === true || setting === 1;
}
/**
* Method returns element what will be listen mouse events
* @return {Node}
*/
getElementListener() {
if (this.fullPageListening) {
return window.document;
}
if (typeof this.settings["mouse-event-element"] === "string") {
const mouseEventElement = document.querySelector(this.settings["mouse-event-element"]);
if (mouseEventElement) {
return mouseEventElement;
}
}
if (this.settings["mouse-event-element"] instanceof Node) {
return this.settings["mouse-event-element"];
}
return this.element;
}
/**
* Method set listen methods for this.elementListener
* @return {Node}
*/
addEventListeners() {
this.onMouseEnterBind = this.onMouseEnter.bind(this);
this.onMouseMoveBind = this.onMouseMove.bind(this);
this.onMouseLeaveBind = this.onMouseLeave.bind(this);
this.onWindowResizeBind = this.onWindowResize.bind(this);
this.onDeviceOrientationBind = this.onDeviceOrientation.bind(this);
this.elementListener.addEventListener("mouseenter", this.onMouseEnterBind);
this.elementListener.addEventListener("mouseleave", this.onMouseLeaveBind);
this.elementListener.addEventListener("mousemove", this.onMouseMoveBind);
if (this.glare || this.fullPageListening) {
window.addEventListener("resize", this.onWindowResizeBind);
}
if (this.gyroscope) {
window.addEventListener("deviceorientation", this.onDeviceOrientationBind);
}
}
/**
* Method remove event listeners from current this.elementListener
*/
removeEventListeners() {
this.elementListener.removeEventListener("mouseenter", this.onMouseEnterBind);
this.elementListener.removeEventListener("mouseleave", this.onMouseLeaveBind);
this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind);
if (this.gyroscope) {
window.removeEventListener("deviceorientation", this.onDeviceOrientationBind);
}
if (this.glare || this.fullPageListening) {
window.removeEventListener("resize", this.onWindowResizeBind);
}
}
destroy() {
clearTimeout(this.transitionTimeout);
if (this.updateCall !== null) {
cancelAnimationFrame(this.updateCall);
}
this.reset();
this.removeEventListeners();
this.element.vanillaTilt = null;
delete this.element.vanillaTilt;
this.element = null;
}
onDeviceOrientation(event) {
if (event.gamma === null || event.beta === null) {
return;
}
this.updateElementPosition();
if (this.gyroscopeSamples > 0) {
this.lastgammazero = this.gammazero;
this.lastbetazero = this.betazero;
if (this.gammazero === null) {
this.gammazero = event.gamma;
this.betazero = event.beta;
} else {
this.gammazero = (event.gamma + this.lastgammazero) / 2;
this.betazero = (event.beta + this.lastbetazero) / 2;
}
this.gyroscopeSamples -= 1;
}
const totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX;
const totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY;
const degreesPerPixelX = totalAngleX / this.width;
const degreesPerPixelY = totalAngleY / this.height;
const angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero);
const angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero);
const posX = angleX / degreesPerPixelX;
const posY = angleY / degreesPerPixelY;
if (this.updateCall !== null) {
cancelAnimationFrame(this.updateCall);
}
this.event = {
clientX: posX + this.left,
clientY: posY + this.top,
};
this.updateCall = requestAnimationFrame(this.updateBind);
}
onMouseEnter() {
this.updateElementPosition();
this.element.style.willChange = "transform";
this.setTransition();
}
onMouseMove(event) {
if (this.updateCall !== null) {
cancelAnimationFrame(this.updateCall);
}
this.event = event;
this.updateCall = requestAnimationFrame(this.updateBind);
}
onMouseLeave() {
this.setTransition();
if (this.settings.reset) {
requestAnimationFrame(this.resetBind);
}
}
reset() {
this.event = {
clientX: this.left + this.width / 2,
clientY: this.top + this.height / 2
};
if (this.element && this.element.style) {
this.element.style.transform = `perspective(${this.settings.perspective}px) ` +
`rotateX(0deg) ` +
`rotateY(0deg) ` +
`scale3d(1, 1, 1)`;
}
this.resetGlare();
}
resetGlare() {
if (this.glare) {
this.glareElement.style.transform = "rotate(180deg) translate(-50%, -50%)";
this.glareElement.style.opacity = "0";
}
}
updateInitialPosition() {
if (this.settings.startX === 0 && this.settings.startY === 0) {
return;
}
this.onMouseEnter();
if (this.fullPageListening) {
this.event = {
clientX: (this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.clientWidth,
clientY: (this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.clientHeight
};
} else {
this.event = {
clientX: this.left + ((this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.width),
clientY: this.top + ((this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.height)
};
}
let backupScale = this.settings.scale;
this.settings.scale = 1;
this.update();
this.settings.scale = backupScale;
this.resetGlare();
}
getValues() {
let x, y;
if (this.fullPageListening) {
x = this.event.clientX / this.clientWidth;
y = this.event.clientY / this.clientHeight;
} else {
x = (this.event.clientX - this.left) / this.width;
y = (this.event.clientY - this.top) / this.height;
}
x = Math.min(Math.max(x, 0), 1);
y = Math.min(Math.max(y, 0), 1);
let tiltX = (this.reverse * (this.settings.max - x * this.settings.max * 2)).toFixed(2);
let tiltY = (this.reverse * (y * this.settings.max * 2 - this.settings.max)).toFixed(2);
let angle = Math.atan2(this.event.clientX - (this.left + this.width / 2), -(this.event.clientY - (this.top + this.height / 2))) * (180 / Math.PI);
return {
tiltX: tiltX,
tiltY: tiltY,
percentageX: x * 100,
percentageY: y * 100,
angle: angle
};
}
updateElementPosition() {
let rect = this.element.getBoundingClientRect();
this.width = this.element.offsetWidth;
this.height = this.element.offsetHeight;
this.left = rect.left;
this.top = rect.top;
}
update() {
let values = this.getValues();
this.element.style.transform = "perspective(" + this.settings.perspective + "px) " +
"rotateX(" + (this.settings.axis === "x" ? 0 : values.tiltY) + "deg) " +
"rotateY(" + (this.settings.axis === "y" ? 0 : values.tiltX) + "deg) " +
"scale3d(" + this.settings.scale + ", " + this.settings.scale + ", " + this.settings.scale + ")";
if (this.glare) {
this.glareElement.style.transform = `rotate(${values.angle}deg) translate(-50%, -50%)`;
this.glareElement.style.opacity = `${values.percentageY * this.settings["max-glare"] / 100}`;
}
this.element.dispatchEvent(new CustomEvent("tiltChange", {
"detail": values
}));
this.updateCall = null;
}
/**
* Appends the glare element (if glarePrerender equals false)
* and sets the default style
*/
prepareGlare() {
// If option pre-render is enabled we assume all html/css is present for an optimal glare effect.
if (!this.glarePrerender) {
// Create glare element
const jsTiltGlare = document.createElement("div");
jsTiltGlare.classList.add("js-tilt-glare");
const jsTiltGlareInner = document.createElement("div");
jsTiltGlareInner.classList.add("js-tilt-glare-inner");
jsTiltGlare.appendChild(jsTiltGlareInner);
this.element.appendChild(jsTiltGlare);
}
this.glareElementWrapper = this.element.querySelector(".js-tilt-glare");
this.glareElement = this.element.querySelector(".js-tilt-glare-inner");
if (this.glarePrerender) {
return;
}
Object.assign(this.glareElementWrapper.style, {
"position": "absolute",
"top": "0",
"left": "0",
"width": "100%",
"height": "100%",
"overflow": "hidden",
"pointer-events": "none"
});
Object.assign(this.glareElement.style, {
"position": "absolute",
"top": "50%",
"left": "50%",
"pointer-events": "none",
"background-image": `linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)`,
"transform": "rotate(180deg) translate(-50%, -50%)",
"transform-origin": "0% 0%",
"opacity": "0",
});
this.updateGlareSize();
}
updateGlareSize() {
if (this.glare) {
const glareSize = (this.element.offsetWidth > this.element.offsetHeight ? this.element.offsetWidth : this.element.offsetHeight) * 2;
Object.assign(this.glareElement.style, {
"width": `${glareSize}px`,
"height": `${glareSize}px`,
});
}
}
updateClientSize() {
this.clientWidth = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
this.clientHeight = window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
}
onWindowResize() {
this.updateGlareSize();
this.updateClientSize();
}
setTransition() {
clearTimeout(this.transitionTimeout);
this.element.style.transition = this.settings.speed + "ms " + this.settings.easing;
if (this.glare) this.glareElement.style.transition = `opacity ${this.settings.speed}ms ${this.settings.easing}`;
this.transitionTimeout = setTimeout(() => {
this.element.style.transition = "";
if (this.glare) {
this.glareElement.style.transition = "";
}
}, this.settings.speed);
}
/**
* Method return patched settings of instance
* @param {boolean} settings.reverse - reverse the tilt direction
* @param {number} settings.max - max tilt rotation (degrees)
* @param {startX} settings.startX - the starting tilt on the X axis, in degrees. Default: 0
* @param {startY} settings.startY - the starting tilt on the Y axis, in degrees. Default: 0
* @param {number} settings.perspective - Transform perspective, the lower the more extreme the tilt gets
* @param {string} settings.easing - Easing on enter/exit
* @param {number} settings.scale - 2 = 200%, 1.5 = 150%, etc..
* @param {number} settings.speed - Speed of the enter/exit transition
* @param {boolean} settings.transition - Set a transition on enter/exit
* @param {string|null} settings.axis - What axis should be disabled. Can be X or Y
* @param {boolean} settings.glare - What axis should be disabled. Can be X or Y
* @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%)
* @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise
* @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element
* @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events
* @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit
* @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events
* @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc..
* @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position.
*/
extendSettings(settings) {
let defaultSettings = {
reverse: false,
max: 15,
startX: 0,
startY: 0,
perspective: 1000,
easing: "cubic-bezier(.03,.98,.52,.99)",
scale: 1,
speed: 300,
transition: true,
axis: null,
glare: false,
"max-glare": 1,
"glare-prerender": false,
"full-page-listening": false,
"mouse-event-element": null,
reset: true,
gyroscope: true,
gyroscopeMinAngleX: -45,
gyroscopeMaxAngleX: 45,
gyroscopeMinAngleY: -45,
gyroscopeMaxAngleY: 45,
gyroscopeSamples: 10
};
let newSettings = {};
for (var property in defaultSettings) {
if (property in settings) {
newSettings[property] = settings[property];
} else if (this.element.hasAttribute("data-tilt-" + property)) {
let attribute = this.element.getAttribute("data-tilt-" + property);
try {
newSettings[property] = JSON.parse(attribute);
} catch (e) {
newSettings[property] = attribute;
}
} else {
newSettings[property] = defaultSettings[property];
}
}
return newSettings;
}
static init(elements, settings) {
if (elements instanceof Node) {
elements = [elements];
}
if (elements instanceof NodeList) {
elements = [].slice.call(elements);
}
if (!(elements instanceof Array)) {
return;
}
elements.forEach((element) => {
if (!("vanillaTilt" in element)) {
element.vanillaTilt = new VanillaTilt(element, settings);
}
});
}
}
if (typeof document !== "undefined") {
/* expose the class to window */
window.VanillaTilt = VanillaTilt;
/**
* Auto load
*/
VanillaTilt.init(document.querySelectorAll("[data-tilt]"));
}
return VanillaTilt;
}());Media credits and license evidence실행 안내·자료
README.md
## Credits
- Images from [Unsplash](https://unsplash.com/)
## License
[MIT](LICENSE)
Made with :blue_heart: by [Codrops](http://www.codrops.com)
LICENSE실행 안내·자료
MIT License
Copyright (c) 2009 - 2021 [Codrops](https://tympanus.net/codrops)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
BEHIND THE EXAMPLE
이 장면을 만드는 원리
기울기·조각 이동·깜박임의 분리
효과를 멈추거나 제거해도 같은 정보와 행동에 도달할 수 있어야 합니다.
- 이 예제에서는
- hover는 다섯 이미지 레이어 중 추가 레이어를 켜며 마지막 레이어에는 0.5초 steps 깜박임을 반복합니다. 기울기만 줄여도 깜박임은 별도로 남습니다.
