3D translation with blurred backdrop

testing an idea to translate layered containers to achieve a pseudo-3D effect

by Andrew Holloway

HTML

Requires Safari for blur effect
<div class="perspective-container">
  <div id="test" class="main-transform">
    <div class="subitem unshifted-subitem">Lorem Ipsum</div>
    <div class="subitem shifted-subitem"></div>
  </div>
</div>

CSS

.perspective-container {
  perspective: 1000px;
}

.main-transform {
  position: relative;
  transform-style: preserve-3d;
}

.unshifted-subitem {}

.subitem {
  position: absolute;
}

.shifted-subitem {
  transform: translateZ(100px) scale(0.9);
}


/* now colors and such (non-essential styles) */
.unshifted-subitem {
  color: white;
  text-align: center;
  width: 100%;
  margin-top: 1.5em;
}
.main-transform {
  margin: 50px 0 0 50px;
  width: 300px;
  height: 300px;
  background-color: #333;
}

.shifted-subitem {
  width: 250px;
  height: 250px;
  left: 0.656em;
  
  border: 3px solid cornflowerblue;
  background-color: rgba(255, 255, 255, 0.1);
  -webkit-backdrop-filter: blur(5px);
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;margin-left: 2em;
  
  transition: border-color 350ms ease-in-out;
}

.shifted-subitem:hover {
  border-color: yellow;
}

JavaScript

// On mouse over, maybe you'd want to have a 3d effect?
// First iteration has stacked elements where, when you hover
// it moves the content around in pseudo 3d effect. (best viewed in Safari)

var container = document.getElementById('test');
var inContainer = false;
var transformElem = document.getElementsByClassName('main-transform')[0];

container.addEventListener('mouseover', function(ev) {
  inContainer = true;
  transformElem.style.transition = '';
}, true);

container.addEventListener('mouseout', function(ev) {
  inContainer = false;
  transformElem.style.transition = 'transform 500ms cubic-bezier(1.000, -0.600, 0.580, 1.650)';
  transformElem.style.transform = '';
});

container.addEventListener('mousemove', function(ev) {
  if (inContainer) {
    var x1, x2, y1, y2, z1, multi_factor;

    multi_factor = .276;

		// values should range from ~ -0.138 to 0.138 based on the mouse corners
    x1 = (multi_factor / 2) - (multi_factor * (Math.min(ev.clientX / 300, 1)));
    x2 = -x1;
 
    y1 = (multi_factor / 2) - (multi_factor * (Math.min(ev.clientY / 300, 1)));
    y2 = -y1;
    
    // TODO: this has a problem with vertical slopes. need a different calculation. Changing to zero for now
    z2 = (150 - (ev.clientY - 200)/(ev.clientX - 200) - 150);

		// Todo: This should change based on the mouse ratios :
    // (y=mx +b := 1 => 0.02)
    // (y=mx +b := -1 => -0.02)
    // setting to -0.02 right now because laziness
    z1 = 0
    z2 = 0;

		// ENTER THE MATRIX
    // 1,  z1,  x1, 0,
    // z2, 1,   y1, 0,
    // x2, y2,  1,  0,
    // 0,  0,   0,  1

    var str = 'matrix3d(1, '+ z1 +', ' + x1 + ', 0, ' + z2 + ', 1, ' + y1 + ', 0, ' + x2 + ', ' + y2 + ', 1, 0, 0, 0, 0, 1)';
		
    transformElem.style.transform = str;
  }
}, true);