<div class="o-page">
  <div class="o-main">
    <div class="o-container">
      <h1 class="c-author js-liquify-trigger">
        <div class="c-author__korean">신윤복</div>
        <div class="c-author__english">Shin Yun-bok</div>
      </h1>

      <div class="js-ink-trigger c-transition c-transition--large c-transition--center">
        <img class="c-transition__img" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/204808/Hyewon-Wolha-jeongin.jpg" alt="Lovers under the moon " />
      </div>

      <p class="u-korean" data-delay="1.5">혜원 신윤복 (1758-1813)은 조선시대의 화가이다.</p>
      <p data-delay="1.7" class="u-spacing-top-small">Shin Yun-bok, better known by his pen name Hyewon (1758–1813), was a Korean painter of the Joseon Dynasty.</p>

      <p class="u-korean" data-delay="2">당대의 단원 김홍도와 긍재 김득신과 같이, 그때 당시의 일상생활의 사실적 묘사로 잘 알려져 있다.</p>
      <p data-delay="2.2" class="u-spacing-top-small">Like his contemporaries Danwon and Geungjae, he is known for his realistic depictions of daily life in his time.</p>
      
      <div class="js-ink-trigger c-transition c-transition--center">
        <img class="c-transition__img" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/204808/Hyewon-Jusa.geobae.jpg" alt="Drinking bout" />
      </div>
      
      <p class="u-korean" data-delay="2.5">혜원의 그림은 단원의 작품보다 성적묘사가 훨씬 강했고, 이것은 당시 왕립 미술 학교에서 파면을 당하는데 이유가 되었다.</p>
      <p data-delay="2.7" class="u-spacing-top-small">His genre paintings are distinctly more erotic than Danwon's, a fact which contributed to his expulsion from the royal painting institute, Dohwaseo.</p>
      
      <div class="js-ink-trigger c-transition c-transition--center">
        <img class="c-transition__img" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/204808/Hyewon-Dano.pungjeong.jpg" alt="Dano day" />
      </div>

      <p class="u-korean">단원, 오원과 더불어, 혜원은 현재 조선시대 "3원 화가"로 불리우고 있다.</p>
      <p class="u-spacing-top-small">Together with Danwon and the later painter Owon, Hyewon is remembered today as one of the "Three Wons" of Joseon-period painting.</p>
      
      <div class="js-ink-trigger c-transition c-transition--portrait c-transition--img-top c-transition--center">
        <img class="c-transition__img" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/204808/Hyewon-Miindo.jpg" alt="Miindo" />
      </div>
      
      <p><img class="c-stamp" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/204808/heywon-stamp.png" alt="Hyewon stamp" /></p>
    </div>
  </div>
</div>

<svg style="height: 0; opacity: 0; visibility: hidden;">
  <filter id="liquify">
      <feTurbulence baseFrequency="0.015" numOctaves="3" result="warp" type="fractalNoise"></feTurbulence>
      <feDisplacementMap id="liquid" in="SourceGraphic" in2="warp" scale="300" xChannelSelector="R" yChannelSelector="B"></feDisplacementMap>
    </filter>
</svg>

<div class="c-intro">
  <p class="c-fe30">Learn 30 real-world front-end skills like this pen @ <a href="https://frontend30.com/?utm_source=codepen&utm_medium=link&utm_campaign=shinyunbok" target="_blank">FrontEnd30.com</a>.
  </p>
  <a class="c-ryanyu" href="https://frontend30.com/?utm_source=codepen&utm_medium=logo&utm_campaign=shinyunbok" target="_blank">
    <div class="c-ryanyu__front">
      <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/204808/ryan-yu-brand.png" alt="Ryan Yu" />
    </div>
    <div class="c-ryanyu__back"></div>
  </a>
</div>
/**
 * Variabbles
 */
 
// Fonts
$roboto: 'Roboto', sans-serif;
$nanum-gothic: 'Nanum Gothic', sans-serif;
$nanum-pen: 'Nanum Pen Script', cursive;
$kalam: 'Kalam', cursive;

// Colors
$pure-white: hsla(0, 0%, 100%, 1); // #fff
$pure-black: hsla(0, 0%, 0%, 1); // #000
$grey-dark: hsla(0, 0%, 25%, 1); // #404040
$white-dark: hsla(0, 0%, 95%, 1); /// #f1f1f1
$fuel-yellow: hsla(36, 100%, 49%, 1); // #f89500
$yellow: hsla(42, 78%, 70%, 1.00);
$white: hsla(0, 0%, 100%, 1);
$charade: hsla(220, 13%, 18%, 1);
$light-grey: hsla(0, 0%, 83%, 1);
$fuel-yellow: hsla(39, 84%, 53%, 1);
$red: hsla(0, 100%, 50%, 1);
$jade: hsla(158, 100%, 34%, 1);
$gable-green: hsla(180, 49%, 14%, 1);

// Layout
$title-width: 80;

// transition
$transition: .5s cubic-bezier(.77, 0, .175, 1);
$transition-fast: .2s cubic-bezier(.77, 0, .175, 1);

// Ink transition
$frameWidth: 1440;
$frameHeight: 900;

/**
 * Functions
 */

@function rem($pixel) {
  @return $pixel / 16 + rem;
}

/**
 * Mixins
 */

@mixin frame-size($imageWidth, $framePortrait: false) {
  @if $framePortrait == false {
    height: ($frameHeight * $imageWidth / $frameWidth);
    width: $imageWidth;
  } @else {
    height: $imageWidth;
    width: ($frameHeight * $imageWidth / $frameWidth);
  }
}

/**
 * Styles
 */

body {
  background-color: hsla(52, 40%, 96%, 1.00);
  font-family: $roboto;
  font-size: rem(14);
}

p {
  margin: rem(20) 0;
  opacity: 0;
  transform: translateY(20px);
}

.o-page {
  overflow: hidden;
  width: 100vw;
}

.o-main {
  margin: 0 auto;
  max-width: rem(600);
  padding: rem(20);
}

.o-container {
  margin: rem(20) 0;
}

// Author
.c-author {
  font-size: rem(60);
  filter: url('#liquify');
  opacity: 0;
  text-align: center;
  transform: translateY(50px);
}

.c-author__korean {
  font-family: $nanum-pen;
  font-size: rem(100);
  font-weight: 400;
}

.c-author__english {
  font-size: rem(22.5);
}
 
.c-transition {
  @include frame-size(400px);
  margin: rem(80) 0;
  overflow: hidden;
  position: relative;
  
  &::before {
    background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/204808/ink-photo-frame.png');
    background-size: 100% 100%;
    background-position: 50% 50%;
    content: '';
    height: 100%;
    position: absolute;
    width: 100%;
  }
  
  &::after {
    //animation: ink-transition 1.5s steps(39) 0.5s forwards;
    background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/204808/ink-transition-sprite.png');
    background-size: 100% 100%;
    content: '';
    height: 100%;
    left: 50%;
    position: absolute;
    top: 0;
    transform: translateX(-1.25%);
    width: 4000%;
  }
  
  &.is-active::after {
    animation: ink-transition 2s steps(39) 0.5s forwards;
  }
}

.c-transition--portrait {
  @include frame-size(400px, true);
  &::before {
    background-image: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/204808/ink-photo-frame-portrait.png');
  }
}

.c-transition--large {
  @include frame-size(600px);
}

.c-transition--center {
  margin-left: auto;
  margin-right: auto;
}

.c-transition__img {
  height: 100%;
  object-fit: cover;
  opacity: 0;
  width: 100%;
  
  .is-active & {
    opacity: 1;
  }
  
  .c-transition--img-top & {
    object-position: 50% 0;
  }
}
 
.c-stamp {
  display: block;
  margin: 0 auto;
  width: rem(32);
}

/**
 * Utilities
 */

.u-korean {
  font-family: $nanum-gothic;
}

.u-spacing-top-small {
  margin-top: rem(-15);
}

/**
 * Keyframes
 */

@keyframes ink-transition {
  0% {
    transform: translateX(-1.25%);
  }

  99% {
    transform: translateX(-98.75%);
    opacity: 1;
  }

  100% {
    transform: translateX(-98.75%);
    opacity: 0;
  }
}

.c-fe30 {
  margin-top: rem(40);
  text-align: center;
  
  a {
    color: $fuel-yellow;
    
    &:hover {
      text-decoration: none;
    }
  }
}

.c-ryanyu {
  background-color: transparent;
  display: block;
  font-family: $kalam;
  height: rem(77);
  margin: rem(20) auto;
  position: relative;
  text-align: center;
  width: rem(77);

  img {
    background-color: $pure-white;
    border: rem(3) solid $fuel-yellow;
    border-radius: 50%;
    height: rem(70);
    object-fit: contain;
    width: rem(70);
  }
}

.c-ryanyu__front {
  backface-visibility: hidden;
  height: inherit;
  position: absolute;
  top: 0;
  transform: rotateX(0) rotateY(0);
  transform-style: preserve-3d;
  transition: all $transition;
  z-index: 2000;

  .c-ryanyu:hover & {
    transform: rotateY(180deg);
  }
}

.c-ryanyu__back {
  background-color: $pure-white;
  backface-visibility: hidden;
  border-radius: 50%;
  color: $fuel-yellow;
  height: inherit;
  position: absolute;
  text-align: center;
  top: 0;
  transform: rotateY(180deg);
  transform-style: preserve-3d;
  transition: all $transition;
  width: inherit;
  z-index: 1000;

  &::before {
    content: 'Ryan Yu';
    display: block;
    transform: rotate(-45deg) translate(-6px, 27px);
    width: rem(50);
  }

  .c-ryanyu:hover & {
    transform: rotateY(0);
  }
}
View Compiled
const liquifyTrigger = document.querySelector('.js-liquify-trigger');
const textTriggers = [...document.querySelectorAll('p')];
const inkTriggers = [...document.querySelectorAll('.js-ink-trigger')];

const controller = new ScrollMagic.Controller();
 
const sceneAuthorLiquid = new ScrollMagic.Scene({
    triggerElement: liquifyTrigger,
    triggerHook: 'onEnter',
  })
  .setTween('#liquid', 2, {
    attr: {
      scale: '0'
    },
    ease: Power4.easeOut,
    delay: 1,
  })
  .reverse(false)
  .addTo(controller);

const sceneAuthorTransition = new ScrollMagic.Scene({
    triggerElement: liquifyTrigger,
    triggerHook: 'onEnter',
  })
  .setTween(liquifyTrigger, 3, {
    opacity: 1,
    y: 1,
    ease: Power4.easeOut,
    delay: 1,
  })
  .reverse(false)
  .addTo(controller);
 
textTriggers.map(text => {
  const isBelowScreen = (text.getBoundingClientRect().top > window.innerHeight) ? true : false;
  const dataDealy = (text.getAttribute('data-delay') === null || isBelowScreen) ? 0.5 : text.getAttribute('data-delay');
  const sceneText = new ScrollMagic.Scene({
    triggerElement: text,
    triggerHook: 'onEnter',
  })
  .setTween(text, 1.5, {
    y: 0,
    opacity: 1,
    ease: Power4.easeOut,
    delay: dataDealy,
  })
  .reverse(false)
  .addTo(controller);
});

inkTriggers.map(ink => {
  const sceneInk = new ScrollMagic.Scene({
    triggerElement: ink,
    triggerHook: 'onEnter',
  })
  .setClassToggle(ink, 'is-active')
  .reverse(false)
  .addTo(controller);
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/ScrollMagic.min.js
  3. //cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/plugins/animation.gsap.js