5+ JavaScript 3D Image Effect Examples

This post contains a total of 5+ JavaScript 3D Image Effect Examples with Source Code. All these 3D Image Effects are made using JavaScript & Styled using CSS.

You can use the source code of these examples with credits to the original owner.

Related Posts

JavaScript 3D Image Effect Examples

1. 3D Image Transition (mouse wheel)

Made by Kevin Levron. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <title></title>  
  <link rel='stylesheet' href='https://codepen.io/soju22/pen/PoZLGJj/4aeaa568d7a4f3459bcde0e70b10f35a.css'>
<link rel='stylesheet' href='https://fonts.googleapis.com/css2?family=Montserrat:[email protected]&amp;display=swap'>
<style>
body {
  margin: 0;
  width: 100%;
  height: 100%;  
}

canvas {
  display: block;
  cursor: pointer;
}
</style>
</head>
<body>
  <canvas id="canvas"></canvas>

<p class="collection">
<a href="https://codepen.io/collection/AGZywR" target="_blank">WebGL Collection</a>
</p>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/3.4.2/gsap.min.js'></script>
      <script id="rendered-js" type="module">
import {
BufferGeometry,
Color,
DoubleSide,
Face3,
Geometry,
InstancedBufferAttribute,
InstancedMesh,
MathUtils,
MeshBasicMaterial,
Object3D,
PerspectiveCamera,
Scene,
TextureLoader,
Vector2,
Vector3,
WebGLRenderer } from
'https://unpkg.com/[email protected]/build/three.module.js';

function App() {
  const conf = {
    size: 10,
    images: [
    { src: 'https://assets.codepen.io/33787/img1.jpg' },
    { src: 'https://assets.codepen.io/33787/img2.jpg' },
    { src: 'https://assets.codepen.io/33787/img3.jpg' },
    { src: 'https://assets.codepen.io/33787/img4.jpg' }] };



  let renderer, scene, camera, cameraCtrl;
  const screen = {
    width: 0, height: 0,
    wWidth: 0, wHeight: 0,
    ratio: 0 };


  const loader = new TextureLoader();
  const textures = [];
  let planes, plane1, plane2;
  let progress = 0,targetProgress = 0;

  const mouse = new Vector2();

  init();

  function init() {
    renderer = new WebGLRenderer({ canvas: document.getElementById('canvas'), antialias: true });

    camera = new PerspectiveCamera(50);
    camera.position.z = 150;

    updateSize();
    window.addEventListener('resize', onResize);

    Promise.all(conf.images.map(loadTexture)).then(responses => {
      initScene();
      initListeners();

      gsap.fromTo(plane1.uProgress,
      {
        value: -2 },

      {
        value: 0,
        duration: 2.5,
        ease: Power4.easeOut });



      requestAnimationFrame(animate);
    });
  }

  function initScene() {
    scene = new Scene();
    scene.background = new Color(0);

    plane1 = new AnimatedPlane({
      renderer, screen,
      size: conf.size,
      anim: 1,
      texture: textures[0] });


    plane2 = new AnimatedPlane({
      renderer, screen,
      size: conf.size,
      anim: 2,
      texture: textures[1] });


    setPlanesProgress(0);

    planes = new Object3D();
    planes.add(plane1.o3d);
    planes.add(plane2.o3d);
    scene.add(planes);
  }

  function initListeners() {
    document.addEventListener('mousemove', e => {
      mouse.x = e.clientX / screen.width * 2 - 1;
      mouse.y = -(e.clientY / screen.height) * 2 + 1;
    });

    window.addEventListener('wheel', e => {
      e.preventDefault();
      if (e.deltaY > 0) {
        targetProgress = limit(targetProgress + 1 / 20, 0, conf.images.length - 1);
      } else {
        targetProgress = limit(targetProgress - 1 / 20, 0, conf.images.length - 1);
      }
    });

    document.addEventListener('click', e => {
      if (e.clientY < screen.height / 2) {
        navPrevious();
      } else {
        navNext();
      }
    });

    document.addEventListener('keyup', e => {
      if (e.keyCode === 37 || e.keyCode === 38) {
        navPrevious();
      } else if (e.keyCode === 39 || e.keyCode === 40) {
        navNext();
      }
    });
  }

  function navNext() {
    if (Number.isInteger(targetProgress)) targetProgress += 1;else
    targetProgress = Math.ceil(targetProgress);
    targetProgress = limit(targetProgress, 0, conf.images.length - 1);
  }

  function navPrevious() {
    if (Number.isInteger(targetProgress)) targetProgress -= 1;else
    targetProgress = Math.floor(targetProgress);
    targetProgress = limit(targetProgress, 0, conf.images.length - 1);
  }

  function updateProgress() {
    const progress1 = lerp(progress, targetProgress, 0.1);
    const pdiff = progress1 - progress;
    if (pdiff === 0) return;

    const p0 = progress % 1;
    const p1 = progress1 % 1;
    if (pdiff > 0 && p1 < p0 || pdiff < 0 && p0 < p1) {
      const i = Math.floor(progress1);
      plane1.setTexture(textures[i]);
      plane2.setTexture(textures[i + 1]);
    }

    progress = progress1;
    setPlanesProgress(progress % 1);
  }

  function setPlanesProgress(progress) {
    plane1.uProgress.value = progress;
    plane2.uProgress.value = -1 + progress;
    plane1.material.opacity = 1 - progress;
    plane2.material.opacity = progress;
    plane1.o3d.position.z = progress;
    plane2.o3d.position.z = progress - 1;
  }

  function animate() {
    requestAnimationFrame(animate);

    updateProgress();

    const tiltX = lerp(planes.rotation.x, -mouse.y * 0.2, 0.1);
    const tiltY = lerp(planes.rotation.y, mouse.x * 0.2, 0.1);
    planes.rotation.set(tiltX, tiltY, 0);

    renderer.render(scene, camera);
  }

  let resizeTimeout;
  function onResize() {
    clearTimeout(resizeTimeout);
    resizeTimeout = setTimeout(updateSize, 200);
  }

  function updateSize() {
    screen.width = window.innerWidth;
    screen.height = window.innerHeight;
    screen.ratio = screen.width / screen.height;
    if (renderer && camera) {
      renderer.setSize(screen.width, screen.height);
      camera.aspect = screen.ratio;
      camera.updateProjectionMatrix();
      const wsize = getRendererSize();
      screen.wWidth = wsize[0];screen.wHeight = wsize[1];
    }
    if (plane1) plane1.resize();
    if (plane2) plane2.resize();
  }

  function getRendererSize() {
    const vFOV = camera.fov * Math.PI / 180;
    const h = 2 * Math.tan(vFOV / 2) * Math.abs(camera.position.z);
    const w = h * camera.aspect;
    return [w, h];
  }

  function loadTexture(img, index) {
    return new Promise(resolve => {
      loader.load(
      img.src,
      texture => {
        textures[index] = texture;
        resolve(texture);
      });

    });
  }
}

class AnimatedPlane {
  constructor(params) {
    for (const [key, value] of Object.entries(params)) {
      this[key] = value;
    }
    this.o3d = new Object3D();
    this.uProgress = { value: 0 };
    this.uvScale = new Vector2();

    this.initMaterial();
    this.initPlane();
  }

  initMaterial() {
    this.material = new MeshBasicMaterial({
      side: DoubleSide,
      transparent: true,
      map: this.texture,
      onBeforeCompile: shader => {
        shader.uniforms.progress = this.uProgress;
        shader.uniforms.uvScale = { value: this.uvScale };
        shader.vertexShader = `
          uniform float progress;
          uniform vec2 uvScale;

          attribute vec3 offset;
          attribute vec3 rotation;
          attribute vec2 uvOffset;

          mat3 rotationMatrixXYZ(vec3 r)
          {
            float cx = cos(r.x);
            float sx = sin(r.x);
            float cy = cos(r.y);
            float sy = sin(r.y);
            float cz = cos(r.z);
            float sz = sin(r.z);

            return mat3(
               cy * cz, cx * sz + sx * sy * cz, sx * sz - cx * sy * cz,
              -cy * sz, cx * cz - sx * sy * sz, sx * cz + cx * sy * sz,
                    sy,               -sx * cy,                cx * cy
            );
          }
        ` + shader.vertexShader;

        shader.vertexShader = shader.vertexShader.replace('#include <uv_vertex>', `
          #include <uv_vertex>
          vUv = vUv * uvScale + uvOffset;
        `);

        shader.vertexShader = shader.vertexShader.replace('#include <project_vertex>', `
          mat3 rotMat = rotationMatrixXYZ(progress * rotation);
          transformed = rotMat * transformed;

          vec4 mvPosition = vec4(transformed, 1.0);
          #ifdef USE_INSTANCING
            mvPosition = instanceMatrix * mvPosition;
          #endif

          mvPosition.xyz += progress * offset;

          mvPosition = modelViewMatrix * mvPosition;
          gl_Position = projectionMatrix * mvPosition;
        `);
      } });

  }

  initPlane() {
    const { width, wWidth, wHeight } = this.screen;
    this.wSize = this.size * wWidth / width;
    this.nx = Math.ceil(wWidth / this.wSize) + 1;
    this.ny = Math.ceil(wHeight / this.wSize) + 1;
    this.icount = this.nx * this.ny;

    this.initGeometry();
    this.initUV();
    this.initAnimAttributes();

    if (this.imesh) {
      this.o3d.remove(this.imesh);
    }
    this.imesh = new InstancedMesh(this.bGeometry, this.material, this.icount);
    this.o3d.add(this.imesh);

    const dummy = new Object3D();
    let index = 0;
    let x = -(wWidth - (wWidth - this.nx * this.wSize)) / 2 + this.dx;
    for (let i = 0; i < this.nx; i++) {
      let y = -(wHeight - (wHeight - this.ny * this.wSize)) / 2 + this.dy;
      for (let j = 0; j < this.ny; j++) {
        dummy.position.set(x, y, 0);
        dummy.updateMatrix();
        this.imesh.setMatrixAt(index++, dummy.matrix);
        y += this.wSize;
      }
      x += this.wSize;
    }
  }

  initGeometry() {
    // square
    const geometry = new Geometry();
    geometry.vertices.push(new Vector3(0, 0, 0));
    geometry.vertices.push(new Vector3(this.wSize, 0, 0));
    geometry.vertices.push(new Vector3(0, this.wSize, 0));
    geometry.vertices.push(new Vector3(this.wSize, this.wSize, 0));
    geometry.faces.push(new Face3(0, 2, 1));
    geometry.faces.push(new Face3(2, 3, 1));

    geometry.faceVertexUvs[0].push([
    new Vector2(0, 0),
    new Vector2(0, 1),
    new Vector2(1, 0)]);

    geometry.faceVertexUvs[0].push([
    new Vector2(0, 1),
    new Vector2(1, 1),
    new Vector2(1, 0)]);


    // geometry.computeFaceNormals();
    // geometry.computeVertexNormals();

    // center
    this.dx = this.wSize / 2;
    this.dy = this.wSize / 2;
    geometry.translate(-this.dx, -this.dy, 0);

    this.bGeometry = new BufferGeometry().fromGeometry(geometry);
  }

  initAnimAttributes() {
    const { randFloat: rnd, randFloatSpread: rndFS } = MathUtils;
    const v3 = new Vector3();

    const offsets = new Float32Array(this.icount * 3);
    for (let i = 0; i < offsets.length; i += 3) {
      if (this.anim === 1) v3.set(rndFS(10), rnd(50, 100), rnd(20, 50)).toArray(offsets, i);else
      v3.set(rndFS(20), rndFS(20), rnd(20, 200)).toArray(offsets, i);
    }
    this.bGeometry.setAttribute('offset', new InstancedBufferAttribute(offsets, 3));

    const rotations = new Float32Array(this.icount * 3);
    const angle = Math.PI * 4;
    for (let i = 0; i < rotations.length; i += 3) {
      rotations[i] = rndFS(angle);
      rotations[i + 1] = rndFS(angle);
      rotations[i + 2] = rndFS(angle);
    }
    this.bGeometry.setAttribute('rotation', new InstancedBufferAttribute(rotations, 3));
  }

  initUV() {
    const ratio = this.nx / this.ny;
    const tRatio = this.texture.image.width / this.texture.image.height;
    if (ratio > tRatio) this.uvScale.set(1 / this.nx, tRatio / ratio / this.ny);else
    this.uvScale.set(ratio / tRatio / this.nx, 1 / this.ny);
    const nW = this.uvScale.x * this.nx;
    const nH = this.uvScale.y * this.ny;

    const v2 = new Vector2();
    const uvOffsets = new Float32Array(this.icount * 2);
    for (let i = 0; i < this.nx; i++) {
      for (let j = 0; j < this.ny; j++) {
        v2.set(
        this.uvScale.x * i + (1 - nW) / 2,
        this.uvScale.y * j + (1 - nH) / 2).
        toArray(uvOffsets, (i * this.ny + j) * 2);
      }
    }
    this.bGeometry.setAttribute('uvOffset', new InstancedBufferAttribute(uvOffsets, 2));
  }

  setTexture(texture) {
    this.texture = texture;
    this.material.map = texture;
    this.initUV();
  }

  resize() {
    this.initPlane();
  }}


function limit(val, min, max) {
  return val < min ? min : val > max ? max : val;
}

function lerp(a, b, x) {
  return a + x * (b - a);
}

App();
//# sourceURL=pen.js
    </script>
</body>
</html>

2. 3d image rotation & text color change

Made by shubham chaudhari. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <title></title>  
  <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css'>
  
<style>
@import url('https://fonts.googleapis.com/css?family=ZCOOL+XiaoWei');
.anim-text-flow,
.anim-text-flow-hover:hover {
  /*
   * Animation variables
   */
  /*
   * Elements settings
   */
  /*
   * Keyframe loop
   */
  /*
   * Element animation delay loop
   */
}
.anim-text-flow span,
.anim-text-flow-hover:hover span {
  -webkit-animation-name: anim-text-flow-keys;
          animation-name: anim-text-flow-keys;
  -webkit-animation-duration: 3s;
          animation-duration: 3s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
  -webkit-animation-direction: alternate;
          animation-direction: alternate;
  -webkit-animation-fill-mode: forwards;
          animation-fill-mode: forwards;
}
@-webkit-keyframes anim-text-flow-keys {
  0% {
    color: #ed1c24;
    text-shadow: 0 1px 2px rgba(0,0,0,.6);
  }
  50% {
    color: #ffc20e;
    text-shadow: 0 1px 2px rgba(0,0,0,.6);
  }
  100% {
    color: transparent;
  }
  
}
@keyframes anim-text-flow-keys {
  0% {
    color: #ed1c24;
    text-shadow: 0 1px 2px rgba(0,0,0,.6);
  }
  50% {
    color: #ffc20e;
    text-shadow: 0 1px 2px rgba(0,0,0,.6);
  }
  100% {
    color: transparent;
  }s
}
.anim-text-flow span:nth-of-type(1),
.anim-text-flow-hover:hover span:nth-of-type(1) {
  -webkit-animation-delay: -19.8s;
          animation-delay: -19.8s;
}
.anim-text-flow span:nth-of-type(2),
.anim-text-flow-hover:hover span:nth-of-type(2) {
  -webkit-animation-delay: -19.6s;
          animation-delay: -19.6s;
}
.anim-text-flow span:nth-of-type(3),
.anim-text-flow-hover:hover span:nth-of-type(3) {
  -webkit-animation-delay: -19.4s;
          animation-delay: -19.4s;
}
.anim-text-flow span:nth-of-type(4),
.anim-text-flow-hover:hover span:nth-of-type(4) {
  -webkit-animation-delay: -19.2s;
          animation-delay: -19.2s;
}
.anim-text-flow span:nth-of-type(5),
.anim-text-flow-hover:hover span:nth-of-type(5) {
  -webkit-animation-delay: -19s;
          animation-delay: -19s;
}
.anim-text-flow span:nth-of-type(6),
.anim-text-flow-hover:hover span:nth-of-type(6) {
  -webkit-animation-delay: -18.8s;
          animation-delay: -18.8s;
}
.anim-text-flow span:nth-of-type(7),
.anim-text-flow-hover:hover span:nth-of-type(7) {
  -webkit-animation-delay: -18.6s;
          animation-delay: -18.6s;
}
.anim-text-flow span:nth-of-type(8),
.anim-text-flow-hover:hover span:nth-of-type(8) {
  -webkit-animation-delay: -18.4s;
          animation-delay: -18.4s;
}
.anim-text-flow span:nth-of-type(9),
.anim-text-flow-hover:hover span:nth-of-type(9) {
  -webkit-animation-delay: -18.2s;
          animation-delay: -18.2s;
}
body 
{
	padding: 8% 0 0;
	margin: 0px;
  color: #000;
  position: relative;
  font-family: 'ZCOOL XiaoWei', serif;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  font-size: 6em;
  line-height: 2;
  font-weight: 100;
  text-rendering: optimizeLegibility;
  text-align: center;
}

.txt {
  display: block;
  margin-top: 30px;
}

.cube {
  margin: auto;
  position: relative;
  height: 200px;
  width: 200px;
  font-size: 12px;
  transform-style: preserve-3d;
}

.cube > div {
  position: absolute;
  box-sizing: border-box;
  height: 100%;
  width: 100%;
  opacity: 0.9;
  background-color: #fff;
  color: #ffffff;
}
.front {
  transform: translateZ(100px);
}

.back {
  transform: translateZ(-100px) rotateY(180deg);
}

.right {
  transform: rotateY(-270deg) translateX(100px);
  transform-origin: top right;
}

.left {
  transform: rotateY(270deg) translateX(-100px);
  transform-origin: center left;
}

.top {
  transform: rotateX(-270deg) translateY(-100px);
  transform-origin: top center;
}

.bottom {
  transform: rotateX(270deg) translateY(100px);
  transform-origin: bottom center;
}
@keyframes rotate {
  from {
    transform: rotateX(0deg) rotateY(90deg);
  }
  
  to {
    transform: rotateX(360deg) rotateY(360deg);
  }
}

.cube {
  animation: rotate 5s infinite linear;
}
.cube div img
{
	width: 100%;
  height:200px;
  object-fit:cover;
}
</style>
</head>
<body>
  <div class="container">
<div class="wrap">
  <div class="cube">
    <div class="front">
      <img src="https://images.pexels.com/photos/1481096/pexels-photo-1481096.jpeg?auto=compress&cs=tinysrgb&h=350">
    </div>
    <div class="back">
      <img src="https://images.pexels.com/photos/1149066/pexels-photo-1149066.jpeg?auto=compress&cs=tinysrgb&h=350">
    </div>
    <div class="top">
      <img src="https://images.pexels.com/photos/1478685/pexels-photo-1478685.jpeg?auto=compress&cs=tinysrgb&h=350">
    </div>
    <div class="bottom">
      <img src="https://images.pexels.com/photos/1480799/pexels-photo-1480799.jpeg?auto=compress&cs=tinysrgb&h=350">
    </div>
    <div class="left">
      <img src="https://images.pexels.com/photos/1320684/pexels-photo-1320684.jpeg?auto=compress&cs=tinysrgb&h=350">
    </div>
    <div class="right">
     <img src="https://images.pexels.com/photos/614494/pexels-photo-614494.jpeg?auto=compress&cs=tinysrgb&h=350">
    </div>
  </div>
</div>
  <span class="txt anim-text-flow">3D BOX</span>
</div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script>
      <script id="rendered-js" >
$('.txt').html(function (i, html) {
  var chars = $.trim(html).split("");

  return '<span>' + chars.join('</span><span>') + '</span>';
});
//# sourceURL=pen.js
    </script>
</body>
</html>

3. LUME shiny 3D image grid (webgl, three.js)

Made by Joe Pea. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <title></title>
<style>
html,
body {
	background: #222;
	width: 100%;
	height: 100%;
	margin: 0;
}

lume-scene {
	/* Prevent touch scrolling from interfering with out pointermove handler. */
	touch-action: none;
}

lume-node {
}

img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
	background: black;
}
</style>
</head>
<body>
  <!--
Made with LUME.
http://github.com/lume/lume
-->
<script src="https://assets.codepen.io/191583/LUME-5f4f19fa4d6908f1b6d74532ddb2554582e7e86e.js"></script>

<!-- Polyfill for Pointer Events (boo Safari) -->
<script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>

<!-- By default a <lume-scene> fills the space of it's parent, in this case the <body>. -->
<lume-scene experimental-webgl touch-action="none">

	<!-- Add some light to the scene! -->
	<lume-point-light size="0 0" position="0 0 1000" color="white" intensity="1.5"></lume-point-light>

	<!-- Make the grid fill 75% width and 75% height of the scene, and center it. -->
	<grid-layout size-mode="proportional proportional" size="0.75 0.75" align="0.5 0.5" mount-point="0.5 0.5">

		<!-- Each direct child of the <grid-layout> element will be positioned (its position and size
		properties will be set by the parent grid-layout). -->
		<lume-node>

			<!--
			A way to create padding is make a smaller node inside its parent.

			The <lume-dom-plane> element is a node that intends to contains traditional HTML
			content (f.e. a <img> tag), but it also renders a WebGL plane for GPU-powered shading.

			We give the WebGL plane a black coloring. We apply a material opacity in the JavaScript below.
			-->
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/car-light-streaks.jpg" />
			</lume-dom-plane>

		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/oakland-lake-merrit-sunset.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/goof-troops.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/hack-sesh.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/oreo-cookie.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/wooooo-graduation-sac-state-2014.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/ada-lovelace.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/albany-lizard.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/half-dome-yosemite.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/hawaiian-spider.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/hawaiian-starnight.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/joe-ana-anniversary-2020.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/jeremiahs-techie-selfie.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/mom-and-son.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/shelby-gt350.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/silhouettes.jpg" />
			</lume-dom-plane>
		</lume-node>

		<lume-node>
			<lume-dom-plane color="black" size-mode="proportional proportional" size="0.95 0.95">
				<img src="https://assets.codepen.io/191583/thor-beach-sunset.jpg" />
			</lume-dom-plane>
		</lume-node>

	</grid-layout>

</lume-scene>
      <script>
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
{
    // Define LUME's HTML elements with their default names.
    LUME.useDefaultNames();
    /**
     * @mixin
     * @class ChildWatcher -
     * A mixin class that gives your custom element a childrenChangedCallback()
     * that runs any time your element's children have changed while your element
     * is connected into a live DOM tree.
     *
     * For example:
     *
     * ```js
     * @element('my-element')
     * class MyElement extends ChildWatcher(HTMLElement) {
     *   childrenChangedCallback() {
     *     console.log('The new children are:', this.children)
     *   }
     * }
     * ```
     * ```html
     * <my-element>
     *   <div>...</div>
     *   <img />
     * </my-element>
     * ```
     *
     * This will log the two children of `<my-element>` when `<my-element>` is placed into the page's HTML tree.
     */
    function ChildWatcher(Base) {
        return class ChildWatcher extends Base {
            connectedCallback() {
                var _a;
                (_a = super.connectedCallback) === null || _a === void 0 ? void 0 : _a.call(this);
                // When children have changed, recompute the layout.
                this.observer = new MutationObserver(() => { var _a; return (_a = this.childrenChangedCallback) === null || _a === void 0 ? void 0 : _a.call(this); });
                this.observer.observe(this, { childList: true });
            }
            disconnectedCallback() {
                var _a;
                (_a = super.disconnectedCallback) === null || _a === void 0 ? void 0 : _a.call(this);
                this.observer.disconnect();
            }
        };
    }
    const { reactive, element, numberAttribute } = LUME;
    let GridLayout = class GridLayout extends ChildWatcher(LUME.Node) {
        connectedCallback() {
            super.connectedCallback();
            // Run an initial layout on connect, and also recompute layout whenever this.rows or this.columns change.
            this.stop = LUME.autorun(() => {
                this.layout(this.rows, this.columns);
            });
        }
        disconnectedCallback() {
            // Don't forget cleanup!
            this.stop();
        }
        childrenChangedCallback() {
            // Recompute layout any time this element's children have changed
            // (it is batched, so happens once per macrotask, for better performance)
            this.layout(this.rows, this.columns);
        }
        layout(rows, columns) {
            // Calculate the grid rows and columns to be a square if rows/columns isn't provided.
            if (!rows || !columns) {
                const size = Math.ceil(Math.sqrt(this.children.length));
                rows = size;
                columns = size;
            }
            const cells = rows * columns;
            const gridSize = this.calculatedSize; // [x, y, z] in px units
            const cellWidth = gridSize.x / columns;
            const cellHeight = gridSize.y / rows;
            for (let i = 0; i < cells; i += 1) {
                const node = this.children[i];
                // If we have less nodes than total cells, quit early.
                if (!node)
                    break;
                node.size = [cellWidth, cellHeight];
                node.position = {
                    x: (i % columns) * cellWidth,
                    y: Math.floor(i / columns) * cellHeight
                };
            }
        }
    };
    __decorate([
        reactive,
        numberAttribute(0),
        __metadata("design:type", Object)
    ], GridLayout.prototype, "rows", void 0);
    __decorate([
        reactive,
        numberAttribute(0),
        __metadata("design:type", Object)
    ], GridLayout.prototype, "columns", void 0);
    GridLayout = __decorate([
        element("grid-layout")
    ], GridLayout);
    // The following is temporary way to set material opacity because it
    // isn't exposed through the HTML interface yet, but this shows how
    // we can manipulate the underlying Three.js objects if we so wish.
    Array.from(document.querySelectorAll("lume-dom-plane")).forEach((node) => {
        // Once the node's GL API is ready, then we can access underlying Three.js stuff.
        node.on(LUME.Events.GL_LOAD, async () => {
            // node.three in this case is a Three.js Mesh instance.
            // Three.js Mesh docs: https://threejs.org/docs/index.html#api/en/objects/Mesh
            node.three.material.opacity = 0.3;
            // If we modify properties on the underlying Three.js objects, we need to
            // manually signal to LUME that a re-render should happen:
            node.needsUpdate();
        });
    });
    Array.from(document.querySelectorAll("lume-point-light")).forEach((node) => {
        // Once the node's GL API is ready, then we can access underlying Three.js stuff.
        node.on(LUME.Events.GL_LOAD, async () => {
            // node.three in this case is a Three.js PointLight instance.
            // Three.js PointLight docs: https://threejs.org/docs/index.html#api/en/lights/PointLight
            // A little bias adjustment helps make things look smooth when the light source is further away.
            node.three.shadow.bias = -0.001;
            // If we modify properties on the underlying Three.js objects, we need to
            // manually signal to LUME that a re-render should happen:
            node.needsUpdate();
        });
    });
    const scene = document.querySelector("lume-scene");
    const light = document.querySelector("lume-point-light");
    const grid = document.querySelector("grid-layout");
    const rotationAmount = 15;
    // Add some interaction so we can see the shine from the light!
    scene.addEventListener("pointermove", (event) => {
        // Move the light on mouse move or finger drag.
        light.position.x = event.clientX;
        light.position.y = event.clientY;
        // Rotate the grid a little bit too.
        grid.rotation.y = -((event.clientX / scene.calculatedSize.x) * (rotationAmount * 2) -
            rotationAmount);
        grid.rotation.x =
            (event.clientY / scene.calculatedSize.y) * (rotationAmount * 3) -
                rotationAmount;
    });
}
    </script>
</body>
</html>

4. 3D Image Container

Made by Mihai. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <title></title>
<style>
body {
  /* Full screen width and height */
  width: 100%;
  min-height: 100vh;

  /* Centers the container in the middle of the screen */
  display: flex;
  justify-content: center;
  align-items: center;

  margin: 0;
  background-color: rgb(220, 220, 220);
}

#container {
  perspective: 25px;
}

#inner {
  width: 20em;
  height: 18em;
  background-color: white;
  box-shadow: 2px 2px 50px rgba(0, 0, 0, 0.2);
  transition: transform 0.5s;
  -webkit-transition: transform 0.5s;
  -moz-transition: transform 0.5s;
  -o-transition: transform 0.5s;
}
</style>
</head>
<body>
  <div id="container">
  <div id="inner"></div>
</div>
      <script>
(function () {
  // Init
  var container = document.getElementById("container"),
  inner = document.getElementById("inner");

  // Mouse
  var mouse = {
    _x: 0,
    _y: 0,
    x: 0,
    y: 0,
    updatePosition: function (event) {
      var e = event || window.event;
      this.x = e.clientX - this._x;
      this.y = (e.clientY - this._y) * -1;
    },
    setOrigin: function (e) {
      this._x = e.offsetLeft + Math.floor(e.offsetWidth / 2);
      this._y = e.offsetTop + Math.floor(e.offsetHeight / 2);
    },
    show: function () {
      return "(" + this.x + ", " + this.y + ")";
    } };


  // Track the mouse position relative to the center of the container.
  mouse.setOrigin(container);

  //-----------------------------------------

  var counter = 0;
  var updateRate = 10;
  var isTimeToUpdate = function () {
    return counter++ % updateRate === 0;
  };

  //-----------------------------------------

  var onMouseEnterHandler = function (event) {
    update(event);
  };

  var onMouseLeaveHandler = function () {
    inner.style = "";
  };

  var onMouseMoveHandler = function (event) {
    if (isTimeToUpdate()) {
      update(event);
    }
  };

  //-----------------------------------------

  var update = function (event) {
    mouse.updatePosition(event);
    updateTransformStyle(
    (mouse.y / inner.offsetHeight / 2).toFixed(2),
    (mouse.x / inner.offsetWidth / 2).toFixed(2));

  };

  var updateTransformStyle = function (x, y) {
    var style = "rotateX(" + x + "deg) rotateY(" + y + "deg)";
    inner.style.transform = style;
    inner.style.webkitTransform = style;
    inner.style.mozTransform = style;
    inner.style.msTransform = style;
    inner.style.oTransform = style;
  };

  //-----------------------------------------

  container.onmouseenter = onMouseEnterHandler;
  container.onmouseleave = onMouseLeaveHandler;
  container.onmousemove = onMouseMoveHandler;
})();
//# sourceURL=pen.js
    </script>
</body>
</html>

5. 3D Image Gallery with scss

Made by Sascha Sigl. Source

<!DOCTYPE html>
<html lang="en" >
<head>
  <title></title>
  <link href='https://fonts.googleapis.com/css?family=Roboto:400,700' rel='stylesheet' type='text/css'>
<meta name="viewport" content="width=device-width">
<style>
/* Tabletts */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

body {
  background: radial-gradient(ellipse at center, #b5bdc8 0%, #828c95 36%, #28343b 100%);
  font-family: "Roboto", sans-serif;
}

/*
	--------------------------- Article
*/
input[type=button] {
  bottom: 3em;
}

section {
  width: 100%;
  height: 100%;
  overflow: hidden;
}
section .inner {
  width: 80%;
  left: 10%;
  top: 0;
  bottom: 0;
  max-width: 1024px;
  position: absolute;
  perspective: 15em;
  transform-style: preserve-3d;
  height: 100%;
}
@media (min-width: 1280px) {
  section .inner {
    width: 60%;
  }
}
@media (min-width: 1024px) {
  section .inner {
    width: 75%;
  }
}
@media (min-width: 600px) {
  section .inner {
    width: 80%;
  }
}
@media (max-width: 600px) {
  section .inner {
    width: 65%;
    left: 10%;
    right: 0;
  }
}

article.post {
  width: 100%;
  background: #eee;
  display: table-cell;
  vertical-align: middle;
  position: absolute;
  cursor: pointer;
  transition-duration: 0.5s;
  transform: rotateY(-20deg) translateX(-30%);
}

article.post:before {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  box-shadow: 0.4em 0em 0 0 rgba(0, 0, 0, 0.6);
}
article.post header {
  width: 100%;
  position: relative;
  background-size: cover;
  background-position: center center;
  background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/61062/bild-1.jpg);
}
article.post header h1 {
  bottom: 1em;
  padding: 0.2em 2em;
  text-align: left;
  background: rgba(255, 255, 255, 0.5);
  line-height: 1.4em;
  width: 100%;
  position: absolute;
}
@media (max-width: 600px) {
  article.post header h1 {
    bottom: 0;
  }
}
article.post header h1:before {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  width: 0.35em;
  height: 100%;
  z-index: 2;
  background: rgba(255, 255, 255, 0.2);
  right: -0.35em;
}
article.post header:after {
  content: "";
  display: block;
  padding-bottom: 60%;
}
article.post .content {
  padding: 1em;
  position: relative;
  width: 60%;
  right: 0;
  color: #666;
  font-style: italic;
  position: absolute;
  background: #eee;
}
article.post .content:before {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  width: 0.38em;
  height: 100%;
  z-index: 2;
  background: rgba(255, 255, 255, 0.2);
  right: -0.38em;
}
article.post .content:after {
  content: "";
  display: block;
  position: absolute;
  bottom: -0.38em;
  width: 100%;
  height: 0.38em;
  z-index: 2;
  background: rgba(0, 0, 0, 0.1);
  right: -0.38em;
}
@media (max-width: 600px) {
  article.post .content {
    width: 100%;
  }
}

article.post[data-postid=post-1] {
  transform: translateX(-20%) translateZ(-2em);
  box-shadow: 1em 1em 1.9em 0 rgba(0, 0, 0, 0.75);
  filter: blur(-1px);
  opacity: 1;
}

article.post[data-postid=post-2] {
  transform: translateX(-10%) translateZ(-4em);
  box-shadow: 1em 1em 1.8em 0 rgba(0, 0, 0, 0.7);
  filter: blur(0px);
  opacity: 0.9;
}

article.post[data-postid=post-3] {
  transform: translateX(0%) translateZ(-6em);
  box-shadow: 1em 1em 1.7em 0 rgba(0, 0, 0, 0.65);
  filter: blur(1px);
  opacity: 0.8;
}

article.post[data-postid=post-4] {
  transform: translateX(10%) translateZ(-8em);
  box-shadow: 1em 1em 1.6em 0 rgba(0, 0, 0, 0.6);
  filter: blur(2px);
  opacity: 0.7;
}

article.post[data-postid=post-5] {
  transform: translateX(20%) translateZ(-10em);
  box-shadow: 1em 1em 1.5em 0 rgba(0, 0, 0, 0.55);
  filter: blur(3px);
  opacity: 0.6;
}

article.post[data-postid=post-6] {
  transform: translateX(30%) translateZ(-12em);
  box-shadow: 1em 1em 1.4em 0 rgba(0, 0, 0, 0.5);
  filter: blur(4px);
  opacity: 0.5;
}

article.post[data-postid=post-7] {
  transform: translateX(40%) translateZ(-14em);
  box-shadow: 1em 1em 1.3em 0 rgba(0, 0, 0, 0.45);
  filter: blur(5px);
  opacity: 0.4;
}

article.post[data-postid=post-8] {
  transform: translateX(50%) translateZ(-16em);
  box-shadow: 1em 1em 1.2em 0 rgba(0, 0, 0, 0.4);
  filter: blur(6px);
  opacity: 0.3;
}

article.post[data-postid=post-9] {
  transform: translateX(60%) translateZ(-18em);
  box-shadow: 1em 1em 1.1em 0 rgba(0, 0, 0, 0.35);
  filter: blur(7px);
  opacity: 0.2;
}

article.post[data-postid=post-10] {
  transform: translateX(70%) translateZ(-20em);
  box-shadow: 1em 1em 1em 0 rgba(0, 0, 0, 0.3);
  filter: blur(8px);
  opacity: 0.1;
}

article.post[data-postid=post-11] {
  transform: translateX(80%) translateZ(-22em);
  box-shadow: 1em 1em 0.9em 0 rgba(0, 0, 0, 0.25);
  filter: blur(9px);
  opacity: 0;
}

article.post[data-postid=post-12] {
  transform: translateX(90%) translateZ(-24em);
  box-shadow: 1em 1em 0.8em 0 rgba(0, 0, 0, 0.2);
  filter: blur(10px);
  opacity: -0.1;
}

article.post[data-postid=post-13] {
  transform: translateX(100%) translateZ(-26em);
  box-shadow: 1em 1em 0.7em 0 rgba(0, 0, 0, 0.15);
  filter: blur(11px);
  opacity: -0.2;
}

article.post[data-postid=post-14] {
  transform: translateX(110%) translateZ(-28em);
  box-shadow: 1em 1em 0.6em 0 rgba(0, 0, 0, 0.1);
  filter: blur(12px);
  opacity: -0.3;
}

article.post[data-postid=post-15] {
  transform: translateX(120%) translateZ(-30em);
  box-shadow: 1em 1em 0.5em 0 rgba(0, 0, 0, 0.05);
  filter: blur(13px);
  opacity: -0.4;
}

article.post[data-postid=post-16] {
  transform: translateX(130%) translateZ(-32em);
  box-shadow: 1em 1em 0.4em 0 rgba(0, 0, 0, 0);
  filter: blur(14px);
  opacity: -0.5;
}
</style>
</head>
<body>
  <section>
  <div class='inner'>
    <article class='post' data-postid='post-1'>
      <header style='background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/61062/bild-1.jpg)'>
        <h1>Headline 1</h1>
      </header>
    </article>
    <article class='post' data-postid='post-2'>
      <header style='background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/61062/bild-2.jpg)'>
        <h1>Headline 2</h1>
      </header>
    </article>
    <article class='post' data-postid='post-3'>
      <header style='background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/61062/bild-3.jpg)'>
        <h1>Headline 3</h1>
      </header>
    </article>
    <article class='post' data-postid='post-4'>
      <header style='background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/61062/bild-4.jpg)'>
        <h1>Headline 4</h1>
      </header>
      <div class='content'>
        <p>Provident voluptates pariatur asperiores odio!</p>
      </div>
    </article>
    <article class='post' data-postid='post-5'>
      <header style='background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/61062/bild-5.png)'>
        <h1>Headline 5</h1>
      </header>
    </article>
    <article class='post' data-postid='post-6'>
      <header style='background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/61062/bild-1.jpg)'>
        <h1>Headline 6</h1>
      </header>
    </article>
    <article class='post' data-postid='post-7'>
      <header style='background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/61062/bild-2.jpg)'>
        <h1>Headline 7</h1>
      </header>
    </article>
    <article class='post' data-postid='post-8'>
      <header style='background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/61062/bild-3.jpg)'>
        <h1>Headline 8</h1>
      </header>
      <div class='content'>
        <p>Provident voluptates pariatur asperiores odio!</p>
      </div>
    </article>
    <article class='post' data-postid='post-9'>
      <header style='background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/61062/bild-4.jpg)'>
        <h1>Headline 9</h1>
      </header>
    </article>
    <article class='post' data-postid='post-10'>
      <header style='background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/61062/bild-5.png)'>
        <h1>Headline 10</h1>
      </header>
    </article>
  </div>
</section>
<input type='button' value='click'>
  <script src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
      <script id="rendered-js" >
var $length = $('article').length;
var $slide = $('article');
$('input[type="button"],article').click(function () {
  performe($slide, '$direction');
}); //end of click


function performe($obj, $direction) {
  $obj.each(function () {
    var $id = $(this).attr('data-postid').split('post-')[1];

    var $newID = parseFloat($id) - 1;
    if ($newID == 0) {
      $newID = $length;
    }
    console.log($id);
    $(this).attr('data-postid', 'post-' + $newID);
  });
}
    </script>
</body>
</html>

6. 3D Image Shatter & Explode Slider/Carousel by three.js + tweenMax

Made by UIUX Lab. Source

<!DOCTYPE html>
<html lang="en" >
<head>
 <title></title>
<style>
body {
  margin: 0;
  padding: 0;
}

#pagination {
  position: fixed;
  top: 50%;
  transform: translateY(-50%);
  right: 30px;
  z-index: 6;
}
#pagination > a {
  display: block;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  border: 0;
  width: 16px;
  height: 16px;
  background-color: #FFFFFF;
  border-radius: 100%;
  padding: 0;
  margin: 30px 0;
  cursor: pointer;
  position: relative;
  opacity: 0.2;
  transition: opacity 0.2s ease-in-out;
  outline: none;
}
#pagination > a:hover {
  opacity: 0.5;
}
#pagination > a.active {
  opacity: 1;
}

canvas {
  height: 100%;
}
</style>
</head>
<body>
  <div id="3D-gallery-three-canvas__loader" style="height: 5px; background: #A45CFB; position: absolute; z-index: 1; bottom: 0; left: 0; width: 0%;"></div>
	
	<div id="pagination">
		<a href="javascript:" class="active"></a>
		<a href="javascript:"></a>
		<a href="javascript:"></a>
	</div>

<!-- Fork me on GitHub ribbon -->
<a href="https://github.com/xizon/uix-kit" target="_blank"><img style="position: absolute; top: 0; right: 0; border: 0; z-index: 9999" src="https://camo.githubusercontent.com/38ef81f8aca64bb9a64448d0d70f1308ef5341ab/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"></a>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/103/three.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.2/TweenMax.min.js'></script>
      <script id="rendered-js" >
/**
 * @author qiao / //github.com/qiao
 * @author mrdoob / //mrdoob.com
 * @author alteredq / //alteredqualia.com/
 * @author WestLangley / //github.com/WestLangley
 * @author erich666 / //erichaines.com
 */
THREE.OrbitControls = function (a, b) {function x() {return 2 * Math.PI / 60 / 60 * c.autoRotateSpeed;}function y() {return Math.pow(.95, c.zoomSpeed);}function z(a) {k.theta -= a;}function A(a) {k.phi -= a;}function E(a) {c.object.isPerspectiveCamera ? l /= a : c.object.isOrthographicCamera ? (c.object.zoom = Math.max(c.minZoom, Math.min(c.maxZoom, c.object.zoom * a)), c.object.updateProjectionMatrix(), n = !0) : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), c.enableZoom = !1);}function F(a) {c.object.isPerspectiveCamera ? l *= a : c.object.isOrthographicCamera ? (c.object.zoom = Math.max(c.minZoom, Math.min(c.maxZoom, c.object.zoom / a)), c.object.updateProjectionMatrix(), n = !0) : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled."), c.enableZoom = !1);}function G(a) {o.set(a.clientX, a.clientY);}function H(a) {u.set(a.clientX, a.clientY);}function I(a) {r.set(a.clientX, a.clientY);}function J(a) {p.set(a.clientX, a.clientY), q.subVectors(p, o).multiplyScalar(c.rotateSpeed);var b = c.domElement === document ? c.domElement.body : c.domElement;z(2 * Math.PI * q.x / b.clientHeight), A(2 * Math.PI * q.y / b.clientHeight), o.copy(p), c.update();}function K(a) {v.set(a.clientX, a.clientY), w.subVectors(v, u), w.y > 0 ? E(y()) : w.y < 0 && F(y()), u.copy(v), c.update();}function L(a) {s.set(a.clientX, a.clientY), t.subVectors(s, r).multiplyScalar(c.panSpeed), D(t.x, t.y), r.copy(s), c.update();}function M(a) {}function N(a) {a.deltaY < 0 ? F(y()) : a.deltaY > 0 && E(y()), c.update();}function O(a) {var b = !1;switch (a.keyCode) {case c.keys.UP:D(0, c.keyPanSpeed), b = !0;break;case c.keys.BOTTOM:D(0, -c.keyPanSpeed), b = !0;break;case c.keys.LEFT:D(c.keyPanSpeed, 0), b = !0;break;case c.keys.RIGHT:D(-c.keyPanSpeed, 0), b = !0;}b && (a.preventDefault(), c.update());}function P(a) {o.set(a.touches[0].pageX, a.touches[0].pageY);}function Q(a) {if (c.enableZoom) {var b = a.touches[0].pageX - a.touches[1].pageX,d = a.touches[0].pageY - a.touches[1].pageY,e = Math.sqrt(b * b + d * d);u.set(0, e);}if (c.enablePan) {var f = .5 * (a.touches[0].pageX + a.touches[1].pageX),g = .5 * (a.touches[0].pageY + a.touches[1].pageY);r.set(f, g);}}function R(a) {p.set(a.touches[0].pageX, a.touches[0].pageY), q.subVectors(p, o).multiplyScalar(c.rotateSpeed);var b = c.domElement === document ? c.domElement.body : c.domElement;z(2 * Math.PI * q.x / b.clientHeight), A(2 * Math.PI * q.y / b.clientHeight), o.copy(p), c.update();}function S(a) {if (c.enableZoom) {var b = a.touches[0].pageX - a.touches[1].pageX,d = a.touches[0].pageY - a.touches[1].pageY,e = Math.sqrt(b * b + d * d);v.set(0, e), w.set(0, Math.pow(v.y / u.y, c.zoomSpeed)), E(w.y), u.copy(v);}if (c.enablePan) {var f = .5 * (a.touches[0].pageX + a.touches[1].pageX),g = .5 * (a.touches[0].pageY + a.touches[1].pageY);s.set(f, g), t.subVectors(s, r).multiplyScalar(c.panSpeed), D(t.x, t.y), r.copy(s);}c.update();}function T(a) {}function U(a) {if (!1 !== c.enabled) {switch (a.preventDefault(), c.domElement.focus ? c.domElement.focus() : window.focus(), a.button) {case c.mouseButtons.LEFT:if (a.ctrlKey || a.metaKey || a.shiftKey) {if (!1 === c.enablePan) return;I(a), h = g.PAN;} else {if (!1 === c.enableRotate) return;G(a), h = g.ROTATE;}break;case c.mouseButtons.MIDDLE:if (!1 === c.enableZoom) return;H(a), h = g.DOLLY;break;case c.mouseButtons.RIGHT:if (!1 === c.enablePan) return;I(a), h = g.PAN;}h !== g.NONE && (document.addEventListener("mousemove", V, !1), document.addEventListener("mouseup", W, !1), c.dispatchEvent(e));}}function V(a) {if (!1 !== c.enabled) switch (a.preventDefault(), h) {case g.ROTATE:if (!1 === c.enableRotate) return;J(a);break;case g.DOLLY:if (!1 === c.enableZoom) return;K(a);break;case g.PAN:if (!1 === c.enablePan) return;L(a);}}function W(a) {!1 !== c.enabled && (M(a), document.removeEventListener("mousemove", V, !1), document.removeEventListener("mouseup", W, !1), c.dispatchEvent(f), h = g.NONE);}function X(a) {!1 === c.enabled || !1 === c.enableZoom || h !== g.NONE && h !== g.ROTATE || (a.preventDefault(), a.stopPropagation(), c.dispatchEvent(e), N(a), c.dispatchEvent(f));}function Y(a) {!1 !== c.enabled && !1 !== c.enableKeys && !1 !== c.enablePan && O(a);}function Z(a) {if (!1 !== c.enabled) {switch (a.preventDefault(), a.touches.length) {case 1:if (!1 === c.enableRotate) return;P(a), h = g.TOUCH_ROTATE;break;case 2:if (!1 === c.enableZoom && !1 === c.enablePan) return;Q(a), h = g.TOUCH_DOLLY_PAN;break;default:h = g.NONE;}h !== g.NONE && c.dispatchEvent(e);}}function $(a) {if (!1 !== c.enabled) switch (a.preventDefault(), a.stopPropagation(), a.touches.length) {case 1:if (!1 === c.enableRotate) return;if (h !== g.TOUCH_ROTATE) return;R(a);break;case 2:if (!1 === c.enableZoom && !1 === c.enablePan) return;if (h !== g.TOUCH_DOLLY_PAN) return;S(a);break;default:h = g.NONE;}}function _(a) {!1 !== c.enabled && (T(a), c.dispatchEvent(f), h = g.NONE);}function aa(a) {!1 !== c.enabled && a.preventDefault();}this.object = a, this.domElement = void 0 !== b ? b : document, this.enabled = !0, this.target = new THREE.Vector3(), this.minDistance = 0, this.maxDistance = 1 / 0, this.minZoom = 0, this.maxZoom = 1 / 0, this.minPolarAngle = 0, this.maxPolarAngle = Math.PI, this.minAzimuthAngle = -1 / 0, this.maxAzimuthAngle = 1 / 0, this.enableDamping = !1, this.dampingFactor = .25, this.enableZoom = !0, this.zoomSpeed = 1, this.enableRotate = !0, this.rotateSpeed = 1, this.enablePan = !0, this.panSpeed = 1, this.screenSpacePanning = !1, this.keyPanSpeed = 7, this.autoRotate = !1, this.autoRotateSpeed = 2, this.enableKeys = !0, this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 }, this.mouseButtons = { LEFT: THREE.MOUSE.LEFT, MIDDLE: THREE.MOUSE.MIDDLE, RIGHT: THREE.MOUSE.RIGHT }, this.target0 = this.target.clone(), this.position0 = this.object.position.clone(), this.zoom0 = this.object.zoom, this.getPolarAngle = function () {return j.phi;}, this.getAzimuthalAngle = function () {return j.theta;}, this.saveState = function () {c.target0.copy(c.target), c.position0.copy(c.object.position), c.zoom0 = c.object.zoom;}, this.reset = function () {c.target.copy(c.target0), c.object.position.copy(c.position0), c.object.zoom = c.zoom0, c.object.updateProjectionMatrix(), c.dispatchEvent(d), c.update(), h = g.NONE;}, this.update = function () {var b = new THREE.Vector3(),e = new THREE.Quaternion().setFromUnitVectors(a.up, new THREE.Vector3(0, 1, 0)),f = e.clone().inverse(),o = new THREE.Vector3(),p = new THREE.Quaternion();return function () {var q = c.object.position;return b.copy(q).sub(c.target), b.applyQuaternion(e), j.setFromVector3(b), c.autoRotate && h === g.NONE && z(x()), j.theta += k.theta, j.phi += k.phi, j.theta = Math.max(c.minAzimuthAngle, Math.min(c.maxAzimuthAngle, j.theta)), j.phi = Math.max(c.minPolarAngle, Math.min(c.maxPolarAngle, j.phi)), j.makeSafe(), j.radius *= l, j.radius = Math.max(c.minDistance, Math.min(c.maxDistance, j.radius)), c.target.add(m), b.setFromSpherical(j), b.applyQuaternion(f), q.copy(c.target).add(b), c.object.lookAt(c.target), !0 === c.enableDamping ? (k.theta *= 1 - c.dampingFactor, k.phi *= 1 - c.dampingFactor, m.multiplyScalar(1 - c.dampingFactor)) : (k.set(0, 0, 0), m.set(0, 0, 0)), l = 1, !!(n || o.distanceToSquared(c.object.position) > i || 8 * (1 - p.dot(c.object.quaternion)) > i) && (c.dispatchEvent(d), o.copy(c.object.position), p.copy(c.object.quaternion), n = !1, !0);};}(), this.dispose = function () {c.domElement.removeEventListener("contextmenu", aa, !1), c.domElement.removeEventListener("mousedown", U, !1), c.domElement.removeEventListener("wheel", X, !1), c.domElement.removeEventListener("touchstart", Z, !1), c.domElement.removeEventListener("touchend", _, !1), c.domElement.removeEventListener("touchmove", $, !1), document.removeEventListener("mousemove", V, !1), document.removeEventListener("mouseup", W, !1), window.removeEventListener("keydown", Y, !1);};var c = this,d = { type: "change" },e = { type: "start" },f = { type: "end" },g = { NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY_PAN: 4 },h = g.NONE,i = 1e-6,j = new THREE.Spherical(),k = new THREE.Spherical(),l = 1,m = new THREE.Vector3(),n = !1,o = new THREE.Vector2(),p = new THREE.Vector2(),q = new THREE.Vector2(),r = new THREE.Vector2(),s = new THREE.Vector2(),t = new THREE.Vector2(),u = new THREE.Vector2(),v = new THREE.Vector2(),w = new THREE.Vector2(),B = function () {var a = new THREE.Vector3();return function (c, d) {a.setFromMatrixColumn(d, 0), a.multiplyScalar(-c), m.add(a);};}(),C = function () {var a = new THREE.Vector3();return function (d, e) {!0 === c.screenSpacePanning ? a.setFromMatrixColumn(e, 1) : (a.setFromMatrixColumn(e, 0), a.crossVectors(c.object.up, a)), a.multiplyScalar(d), m.add(a);};}(),D = function () {var a = new THREE.Vector3();return function (d, e) {var f = c.domElement === document ? c.domElement.body : c.domElement;if (c.object.isPerspectiveCamera) {var g = c.object.position;a.copy(g).sub(c.target);var h = a.length();h *= Math.tan(c.object.fov / 2 * Math.PI / 180), B(2 * d * h / f.clientHeight, c.object.matrix), C(2 * e * h / f.clientHeight, c.object.matrix);} else c.object.isOrthographicCamera ? (B(d * (c.object.right - c.object.left) / c.object.zoom / f.clientWidth, c.object.matrix), C(e * (c.object.top - c.object.bottom) / c.object.zoom / f.clientHeight, c.object.matrix)) : (console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."), c.enablePan = !1);};}();c.domElement.addEventListener("contextmenu", aa, !1), c.domElement.addEventListener("mousedown", U, !1), c.domElement.addEventListener("wheel", X, !1), c.domElement.addEventListener("touchstart", Z, !1), c.domElement.addEventListener("touchend", _, !1), c.domElement.addEventListener("touchmove", $, !1), window.addEventListener("keydown", Y, !1), this.update();}, THREE.OrbitControls.prototype = Object.create(THREE.EventDispatcher.prototype), THREE.OrbitControls.prototype.constructor = THREE.OrbitControls, Object.defineProperties(THREE.OrbitControls.prototype, { center: { get: function () {return console.warn("THREE.OrbitControls: .center has been renamed to .target"), this.target;} }, noZoom: { get: function () {return console.warn("THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead."), !this.enableZoom;}, set: function (a) {console.warn("THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead."), this.enableZoom = !a;} }, noRotate: { get: function () {return console.warn("THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead."), !this.enableRotate;}, set: function (a) {console.warn("THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead."), this.enableRotate = !a;} }, noPan: { get: function () {return console.warn("THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead."), !this.enablePan;}, set: function (a) {console.warn("THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead."), this.enablePan = !a;} }, noKeys: { get: function () {return console.warn("THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead."), !this.enableKeys;}, set: function (a) {console.warn("THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead."), this.enableKeys = !a;} }, staticMoving: { get: function () {return console.warn("THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead."), !this.enableDamping;}, set: function (a) {console.warn("THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead."), this.enableDamping = !a;} }, dynamicDampingFactor: { get: function () {return console.warn("THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead."), this.dampingFactor;}, set: function (a) {console.warn("THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead."), this.dampingFactor = a;} } });

//==============================================
//==============================================
//==============================================
//==============================================

/**
 * Make all faces use unique vertices
 * so that each face can be separated from others
 *
 * @author alteredq / http://alteredqualia.com/
 */
!function (a, b) {"function" == typeof define && define.amd ? define("three.ExplodeModifier", ["three"], b) : "undefined" != typeof exports && "undefined" != typeof module ? module.exports = b(require("three")) : b(a.THREE);}(this, function (a) {a.ExplodeModifier = function () {}, a.ExplodeModifier.prototype.modify = function (a) {for (var b = [], c = 0, d = a.faces.length; c < d; c++) {var e = b.length,f = a.faces[c],g = f.a,h = f.b,i = f.c,j = a.vertices[g],k = a.vertices[h],l = a.vertices[i];b.push(j.clone()), b.push(k.clone()), b.push(l.clone()), f.a = e, f.b = e + 1, f.c = e + 2;}a.vertices = b;};});




//==============================================
//==============================================
//==============================================
//==============================================
//==============================================
//==============================================
//==============================================
//==============================================



(function ($) {
  "use strict";

  $(function () {


    var windowWidth = window.innerWidth,
    windowHeight = window.innerHeight;


    // Generate one plane geometries mesh to scene
    //-------------------------------------	
    var camera,
    controls,
    scene,
    light,
    renderer,
    material,
    explodeMaterial,
    displacementSprite,
    theta = 0;


    var offsetWidth = 640,
    offsetHeight = 360,
    allImages = [],
    imgTotal,
    sliderImages = [],
    imagesLoaded = false;

    var activeSlider = 0;


    init();
    render();



    function init() {
      //camera
      camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 10, 2500); // FlyCamera // FlyControls
      camera.movementSpeed = 100.0;
      camera.rollSpeed = 0.5;
      camera.position.y = 60;
      camera.position.z = 500;



      //Scene
      scene = new THREE.Scene();


      //HemisphereLight
      scene.add(new THREE.AmbientLight(0x555555));

      light = new THREE.SpotLight(0xffffff, 1.5);
      light.position.set(0, 0, 2000);
      scene.add(light);



      //WebGL Renderer	
      // create a render and set the size
      renderer = new THREE.WebGLRenderer({ antialias: true });
      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.setClearColor(0x000000, 1);

      //controls
      controls = new THREE.OrbitControls(camera, renderer.domElement);
      controls.autoRotate = false;
      controls.autoRotateSpeed = 0.5;
      controls.rotateSpeed = 0.5;
      controls.zoomSpeed = 1.2;
      controls.panSpeed = 0.8;
      controls.enableZoom = false;
      controls.target.set(0, 0, 0);
      controls.update();


      // add the output of the renderer to the html element
      document.body.appendChild(renderer.domElement);




      // Immediately use the texture for material creation
      // Create a texture loader so we can load our image file
      var imgs = [
      'https://placekitten.com/800/363',
      'https://placekitten.com/800/361',
      'https://placekitten.com/800/362'];





      //A loader for loading all images from array.
      var loader = new THREE.TextureLoader();
      loader.crossOrigin = 'anonymous';


      imgs.forEach(function (img) {
        var image = loader.load(img);
        image.magFilter = image.minFilter = THREE.LinearFilter;
        image.anisotropy = renderer.capabilities.getMaxAnisotropy();
        sliderImages.push(image);
      });

      console.log(sliderImages);

      //Preload
      imgTotal = imgs.length;


      imgs.forEach(function (element, index) {
        loadImage(loader, element, index, offsetWidth, offsetHeight, imgTotal, sliderImages, $('#3D-gallery-three-canvas__loader'));
      });




      // Fires when the window changes
      window.addEventListener('resize', onWindowResize, false);


    }


    //Fire the slider transtion with buttons
    var isAnimating = false;
    var $btn = $('#pagination > a');



    $btn.on('click', function (e) {
      e.preventDefault();

      if (!isAnimating) {
        isAnimating = true;

        var slideCurId = $('#pagination > a.active').index();

        $btn.removeClass('active');
        $(this).addClass('active');

        var slideNextId = $(this).index();


        console.log('Current: ' + slideCurId + ' | Next: ' + slideNextId);


        //next object
        activeSlider = slideNextId;

        if (typeof allImages[slideNextId] != typeof undefined) {

          var fragment = allImages[slideNextId].geometry.vertices;

          for (var i = 0; i < fragment.length; i++) {

            TweenMax.to(fragment[i], 2, {
              x: fragment[i].origPos.x,
              y: fragment[i].origPos.y,
              z: fragment[i].origPos.z,
              ease: "Expo.easeInOut" });

          }


        }


        //current object
        if (typeof allImages[slideCurId] != typeof undefined) {

          var fragment = allImages[slideCurId].geometry.vertices;

          for (var i = 0; i < fragment.length; i++) {

            var pos = new THREE.Vector3();
            var final = Math.random();

            pos.x = Math.random();
            pos.y = Math.random() * (50 * i);
            pos.z = Math.random() * -300;

            TweenMax.to(fragment[i], 2, {
              x: pos.x,
              y: pos.y,
              z: pos.z,
              ease: "Expo.easeInOut",
              onComplete: function onComplete() {

                //reset button status
                isAnimating = false;

              } });

          }


        }



      }

    });


    function render() {
      requestAnimationFrame(render);

      theta += 0.1;


      //To set a background color.
      //renderer.setClearColor( 0x000000 );	



      //Animating Three.js vertices
      allImages.forEach(function (element, index) {
        element.geometry.verticesNeedUpdate = true;
      });



      //check all images loaded
      if (typeof allImages != typeof undefined) {
        if (!imagesLoaded && allImages.length === imgTotal) {
          allImages.forEach(function (element, index) {
            scene.add(element);


            //initialize all objects
            if (index > 0) {
              var fragment = element.geometry.vertices;

              for (var i = 0; i < fragment.length; i++) {

                var pos = new THREE.Vector3();
                var final = Math.random();

                pos.x = Math.random();
                pos.y = Math.random() * (50 * i);
                pos.z = Math.random() * -300;

                fragment[i].x = pos.x;
                fragment[i].y = pos.y;
                fragment[i].z = pos.z;

              }
            }

            console.log(element);
          });
          imagesLoaded = true;


        }

      }



      //update camera and controls
      controls.update();

      renderer.render(scene, camera);


    }


    function onWindowResize() {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    }


    /*
     * Load Image
     *
     * @param  {Object} imgLoader       - A loader for loading all images from array.
     * @param  {String} src             - URL of image.
     * @param  {Number} index           - Index of image.
     * @param  {Number} w               - The width of an image, in pixels. 
     * @param  {Number} h               - The height of an image, in pixels. 
     * @param  {Number} total           - Total number of preload images.
     * @param  {Array} sliderImages     - Images for implementing loaders.
     * @param  {Object} loading         - Progress bar display control.
     * @return {Void}
     */
    function loadImage(imgLoader, src, index, w, h, total, sliderImages, loading) {

      var imgW = w,
      imgH = h;



      // load a resource
      imgLoader.load(
      // resource URL
      src,

      // onLoad callback
      function (texture) {
        // in this example we create the material when the texture is loaded
        material = new THREE.MeshBasicMaterial({
          map: texture });



        var geometryExplode = new THREE.BoxGeometry(imgW, imgH, 13),


        displacementSprite = new THREE.Mesh(geometryExplode, material);

        displacementSprite.minFilter = THREE.LinearFilter;
        displacementSprite.overdraw = true;
        displacementSprite.position.set(0, 0, 0);


        geometryExplode.center();

        // Shattering Images
        var explodeModifier = new THREE.ExplodeModifier();
        explodeModifier.modify(geometryExplode);

        // add some additional vars to the
        // fragments to ensure we can do physics
        // and so on
        for (var i = 0; i < geometryExplode.vertices.length; i++) {
          var fragment = geometryExplode.vertices[i];
          fragment.origPos = {
            x: fragment.x,
            y: fragment.y,
            z: fragment.z };


        }


        allImages.push(displacementSprite);


        //loading
        TweenMax.to(loading, 0.5, {
          width: Math.round(100 * allImages.length / total) + '%',
          onComplete: function () {

            if ($(this.target).width() >= windowWidth - 50) {

              TweenMax.to(this.target, 0.5, {
                alpha: 0 });

            }

          } });


      },

      // onProgress callback currently not supported
      undefined,

      // onError callback
      function (err) {
        console.error('An error happened.');
      });


    }


    /*
     * Get Image Data when Draw Image To Canvas
     *
     * @param  {Object} image         - Overridden with a record type holding data, width and height.
     * @return {JSON}                 - The image data.
     */
    function getImageData(image) {

      var canvas = document.createElement('canvas');
      canvas.width = image.width;
      canvas.height = image.height;

      var ctx = canvas.getContext('2d');
      ctx.drawImage(image, 0, 0);

      return ctx.getImageData(0, 0, image.width, image.height);
    }




  });


})(jQuery);
//# sourceURL=pen.js
    </script>
</body>
</html>