"Untitled"
Bootstrap 4.1.1 Snippet by divyalahad

<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <!------ Include the above in your HEAD tag ----------> <!--pictures from Adobe Stock--> <p id="loading">loading...</p> <div id="images"> <div class="lighten"> <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/593507/lighten1.jpg" alt="" /> <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/593507/lighten2.jpg" alt="" /> <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/593507/lighten3.jpg" alt="" /> <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/593507/lighten4.jpg" alt="" /> </div> <div class="normal"> <img src="https://img.traveltriangle.com/blog/wp-content/tr:w-700,h-400/uploads/2016/07/shutterstock_115227475.jpg" alt="" /> <img src="https://img.traveltriangle.com/blog/wp-content/tr:w-700,h-400/uploads/2017/07/Varanasi.jpg" alt="" /> <img src="https://img.traveltriangle.com/blog/wp-content/tr:w-700,h-400/uploads/2017/07/Agra1.jpg" alt="" /> <img src="https://img.traveltriangle.com/blog/wp-content/tr:w-700,h-400/uploads/2016/07/spiti-valley-ki-monastery.jpg" alt="" /> </div> <nav> <ul> <li class="pre"></li> <li class="next"></li> </ul> </nav> </div>
*{ margin: 0; padding: 0; } body{ background: #222; } #loading{ color: #fff; position: absolute; letter-spacing: 3px; width: 10em; line-height: 2em; top: calc(50% - 1em) ; left: calc(50% - 5em); z-index: 2; text-align: center; } .loading-done{ display: none; } #images{ position: absolute; width: 600px; left: calc(50% - 300px); } .canvas{ position: relative; display:block; overflow: hidden; } #images img{ display: none; vertical-align: bottom; } canvas{ vertical-align: bottom; position: absolute; } nav ul{ height: 0; margin: 0; } nav li { position: absolute; width: 25px; height: 25px; opacity: .3; list-style: none; top: calc(50% - 12px); z-index: 100; transition: opacity .3s; } nav li:hover{ opacity: .7; } .pre.after-loading{ left: -40px; -webkit-transform: rotate(-45deg); transform: rotate(-45deg); border-top: 2px solid #fff; border-left: 2px solid #fff; } .next.after-loading{ -webkit-transform: rotate(45deg); transform: rotate(45deg); border-top: 2px solid #fff; border-right: 2px solid #fff; right: -40px; }
/* Double exposure is photographic technique that combines 2 different images into a single image. Then I use this technique with canvas blend modes. */ window.onload = function(){ var loading = document.getElementById("loading"); loading.classList.add("loading-done"); var property = { element: "#images", parallax: .6, interval: 2200, animDuration: 1300, easing: easingInOutQuad } var slider = new DXslider(property); slider.init(); } class DXslider{ constructor(property){ this.images = document.querySelector(property.element); this.preButton = document.querySelector(property.element + " nav .pre"); this.nextButton = document.querySelector(property.element + " nav .next"); this.lightenImages = document.querySelectorAll(".lighten img"); this.normalImages = document.querySelectorAll(".normal img"); this.canvasBox = document.createElement("div"); this.paraEffect = property.parallax; //have to clamp 0 ~ 1 this.canvasArray = []; this.progress = 0; this.animating = false; this.interval = property.interval; this.left = true; this.duration = property.animDuration; this.easing = property.easing; this.images.appendChild(this.canvasBox); this.canvasBox.classList.add("canvas"); } init(){ this.settingStyle(); this.settingCanvas(); this.preButton.addEventListener("click", function(e){ if(!this.animating){ this.left = false; clearTimeout(this.timer); this.slide(); } }.bind(this), false); this.preButton.addEventListener("touchend", function(e){ if(!this.animating){ this.left = false; clearTimeout(this.timer); this.slide(); } }.bind(this), false); this.nextButton.addEventListener("click", function(e){ if(!this.animating){ this.left = true; clearTimeout(this.timer); this.slide(); } }.bind(this), false); this.nextButton.addEventListener("touchend", function(e){ if(!this.animating){ this.left = true; clearTimeout(this.timer); this.slide(); } }.bind(this), false); } settingStyle(){ this.imagesWidth = this.images.offsetWidth; this.width = this.lightenImages[0].width; this.height = this.lightenImages[0].height; this.dpi = this.width / this.imagesWidth; this.images.style.height = this.canvasBox.style.height = this.imagesWidth * this.height / this.width + "px"; this.preButton.classList.add("after-loading"); this.nextButton.classList.add("after-loading"); } settingCanvas(){ var canvas, context, normal, lighten, n; for(var i = 0, len = this.normalImages.length * 2; i < len; i++){ canvas = document.createElement("canvas"); this.canvasBox.appendChild(canvas); context = canvas.getContext("2d"); canvas.width = this.width; canvas.height = this.height; canvas.style.width = this.imagesWidth + "px"; canvas.style.height = this.imagesWidth * this.height / this.width + "px"; //add images(lighten and normal) into canvasArray n = i % (len / 2); normal = this.normalImages[n]; lighten = this.lightenImages[n]; this.canvasArray.push({ canvas: canvas, context: context, normal: normal, lighten: lighten }); } this.render(this.progress, -this.imagesWidth); this.timer = setTimeout(this.slide.bind(this), this.interval); } slide(){ this.left ? this.tween(-this.imagesWidth, this.duration, this.easing) : this.tween(this.imagesWidth, this.duration, this.easing); } tween(change, duration, easingFunc){ var startTime = new Date(); this.progress = 0; this.animating = true; this.update(startTime, change, duration, easingFunc); } update(startTime, change, duration, easingFunc){ var time = new Date() - startTime; if(time < duration){ this.progress = easingFunc(time / duration); this.render(this.progress, change); requestAnimationFrame(this.update.bind(this, startTime, change, duration, easingFunc)); } else { if(this.left){ var firstEle = this.canvasArray[0]; this.canvasArray.shift(); this.canvasArray.push(firstEle); } else { var lastEle = this.canvasArray[this.canvasArray.length - 1]; this.canvasArray.pop(); this.canvasArray.unshift(lastEle); } this.progress = 1; this.animating = false; time = duration; this.left = true; this.render(0, -this.imagesWidth); this.timer = setTimeout(this.slide.bind(this), this.interval); } } render(progress, position){ for(var i = 0, len = this.canvasArray.length; i < len; i++){ var canvas = this.canvasArray[i].canvas; canvas.style.setProperty("-webkit-transform", "translate(" + (progress * position - (len / 2 - i) * this.imagesWidth) + "px, 0)"); canvas.style.transform = "translate(" + (progress * position - (len / 2 - i) * this.imagesWidth) + "px, 0)"; var context = this.canvasArray[i].context; context.clearRect(0, 0, this.width, this.height); context.globalCompositeOperation = "source-over"; context.drawImage(this.canvasArray[i].normal, 0, 0, this.width, this.height); context.globalCompositeOperation = "lighten"; context.drawImage(this.canvasArray[i].lighten, ((len / 2 - i) * this.imagesWidth - progress * position) * this.dpi * this.paraEffect, 0, this.width, this.height); } } } //easing //prepare only easingInOutQuad function easingInOutQuad(t){ return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; }

Related: See More


Questions / Comments: