JSFiddle - React, Tailwind, and code Playground

by stovberpv

HTML

<div id="rooms--wrapper">
  <div id="manikin"></div>
  <div id="room--welcome" class="room">
    <span class='room--title'>Студия ...</span>
  </div>
  <div id="room--product" class="room">
    <span class='room--title'>Что мы умеем</span>
    <div id='product--wrapper' class='wrapper'>
      <div class='product cube'>
        <span>Менеджер отеля</span>
      </div>
      <div class='product cube'>
        <span>Система ГИС</span>
      </div>
      <div class='product cube'>
        <span>Магазин</span>
      </div>
      <div class='product cube'>
        <span>Верстка</span>
      </div>
      <div class='product cube'>
        <span>Логотип</span>
      </div>
      <div class='product cube'>
        <span>Дизайн</span>
      </div>
    </div>
  </div>
  <div id="room--request" class="room">
    <span class='room--title'>Приемная</span>
    <div id='request--wrapper' class='wrapper'>
      <div class='request cube'>
        <span>Landing-page</span>
      </div>
      <div class='request cube'>
        <span>Помощь студентам</span>
      </div>
      <div class='request cube'>
        <span>Магазин</span>
      </div>
      <div class='request cube'>
        <span>Верстка</span>
      </div>
      <div class='request cube'>
        <span>Логотипы</span>
      </div>
      <div class='request cube'>
        <span>Дизайн</span>
      </div>
    </div>
  </div>
  <div id="room--styling" class="room">
    <span class='room--title'>Пожелания</span>
  </div>
  <div id="room--confirm" class="room">
    <span class='room--title'>Оформление</span>
  </div>
  <div id="room--contact" class="room">
    <span class='room--title'>Контакты</span>
  </div>
</div>

CSS

html,
body {
  padding: 0;
  margin: 0;
  top: 0;
  left: 0;
  font-family: Calibri;
}

body {
  background: url(https://images.pexels.com/photos/237950/pexels-photo-237950.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260);
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
}

#rooms--wrapper {
  display: inline-flex;
  width: 2400px;
  height: 600px;
  position: relative;
}

.room {
  width: 400px;
  height: 600px;
  text-align: center;
  position: relative;
}

.room--title {
  text-transform: uppercase;
  background-color: rgba(0, 0, 0, .4);
  padding: 20px 30px;
  border-radius: 3px;
  transform: translate(-50%, 50%);
  top: 0%;
  left: 50%;
  position: absolute;
  color: rgba(255, 255, 255, .8);
  text-wrap: nowrap;
  white-space: nowrap;
}

#room--welcome {
  /* background-color: #ADD8E6; */
}
/*
rgba(212,33,64, .5);
rgba(246,216,1, .5);
rgba(72,223,138, .5);
rgba(49,127,210, .5);
rgba(60,77,105, .5);
*/
#room--product {
  background-color: rgba(255,255,255, .5);
}

#room--request {
  background-color: rgba(255,255,255, .5);
}

#room--styling {
  background-color: rgba(255,255,255, .5);
}

#room--confirm {
  background-color: rgba(255,255,255, .5);
}

#room--contact {
  background-color: rgba(255,255,255, .5);
}

#manikin {
  width: 40px;
  height: 60px;
  line-height: 60px;
  background-color: rgba(0, 0, 0, .6);
  position: absolute;
  bottom: 1px;
  left: 0;
  transition: transform 5s linear;
  color: #fff;
  text-align: center;
  z-index: 2;
}

.wrapper {
  position: absolute;
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(2, 100px);
  grid-gap: 10px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.cube {
  width: 100px;
  height: 100px;
  background-color: rgba(255, 255, 255, 1);
  box-shadow: 0 0 5px 0 rgba(0, 0, 0, .2);
  border-radius: 3px;
  transition: all .3s ease-in-out;
  display: flex;
  align-items: center;
  justify-content: center;
  position:...

JavaScript

function getScroll() {
  var position = {};

  position.scroll = {
    x: window.pageXOffset || document.documentElement.scrollLeft,
    y: 0
  };

  position.browser = {
    x: Math.max(
      document.body.scrollWidth, document.documentElement.scrollWidth,
      document.body.offsetWidth, document.documentElement.offsetWidth,
      document.body.clientWidth, document.documentElement.clientWidth
    ),
    y: 0
  };

  return position;
}

var Manikin = (function() {
  var instance;

  function Manikin() {
    var _M = document.getElementById('manikin');
    var _roomWidth = 400;
    var _roomCount = 6;
    var _manikinThickness = 40;

    function calcPosition(position) {
      var scrolled = position.scroll.x;

      var _roomTail = _roomWidth - (scrolled !== 0 ? (scrolled % _roomWidth) : _roomWidth);
      var desiredPosition = scrolled + _roomTail + _roomWidth / 2;
      var adjustedPosition = desiredPosition - _manikinThickness / 2;
      return adjustedPosition;
    }

    this.follow = function(position) {
      _M.style.transform = 'translateX(' + calcPosition(position) + 'px)';
      _M.innerHTML = parseInt(position.scroll.x, 10);
    };
    return this;
  }

  function createInstance() {
    var manikin = new Manikin();
    return manikin;
  }

  return {
    getInstance: function() {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
})();

Manikin.getInstance().follow({
  scroll: {
    x: 0,
    y: 0
  },
  browser: {
    x: 0,
    y: 0
  }
});
window.addEventListener("scroll", function(event) {
  Manikin.getInstance().follow(getScroll());
});