如何实现自定义导航以按ID触发每张幻灯片?

时间:2019-07-09 15:13:29

标签: javascript navigation

我是JavaScript的新手,正在尝试向SVG动画幻灯片(https://cordova.apache.org/docs/en/latest/cordova/events/events.html)添加一个缩略图导航。我想通过单击缩略图导航的锚点来导航/触发每张幻灯片。预先感谢您,如果有人可以帮助我...!

/**
 * demo2.js
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * Copyright 2017, Codrops
 * http://www.codrops.com
 */
{
    // From https://davidwalsh.name/javascript-debounce-function.
	function debounce(func, wait, immediate) {
		var timeout;
		return function() {
			var context = this, args = arguments;
			var later = function() {
				timeout = null;
				if (!immediate) func.apply(context, args);
			};
			var callNow = immediate && !timeout;
			clearTimeout(timeout);
			timeout = setTimeout(later, wait);
			if (callNow) func.apply(context, args);
		};
    };
    
    class Slideshow {
        constructor(el) {
            this.DOM = {};
            this.DOM.el = el;
            this.settings = {
                animation: {
                    slides: {
                        duration: 600,
                        easing: 'easeOutQuint'
                    },
                    shape: {
                        duration: 300,
                        easing: {in: 'easeOutQuad', out: 'easeOutQuad'}
                    }
                },
                frameFill: '#111'
            }
            this.init();
        }
        init() {
            this.DOM.slides = Array.from(this.DOM.el.querySelectorAll('.slides > .slide'));
            this.slidesTotal = this.DOM.slides.length;
            this.DOM.nav = this.DOM.el.querySelector('.slidenav');
            this.DOM.nextCtrl = this.DOM.nav.querySelector('.slidenav__item--next');
            this.DOM.prevCtrl = this.DOM.nav.querySelector('.slidenav__item--prev');
            this.current = 0;
            this.createFrame(); 
            this.initEvents();
        }
        createFrame() {
            this.rect = this.DOM.el.getBoundingClientRect();
            this.frameSize = this.rect.width/12;
            this.paths = {
                initial: this.calculatePath('initial'),
                final: this.calculatePath('final')
            };
            this.DOM.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
            this.DOM.svg.setAttribute('class', 'shape');
            this.DOM.svg.setAttribute('width','100%');
            this.DOM.svg.setAttribute('height','100%');
            this.DOM.svg.setAttribute('viewbox',`0 0 ${this.rect.width} ${this.rect.height}`);
            this.DOM.svg.innerHTML = `<path fill="${this.settings.frameFill}" d="${this.paths.initial}"/>`;
            this.DOM.el.insertBefore(this.DOM.svg, this.DOM.nav);
            this.DOM.shape = this.DOM.svg.lastElementChild;
        }
        updateFrame() {
            this.paths.initial = this.calculatePath('initial');
            this.paths.final = this.calculatePath('final');
            this.DOM.svg.setAttribute('viewbox',`0 0 ${this.rect.width} ${this.rect.height}`);
            this.DOM.shape.setAttribute('d', this.isAnimating ? this.paths.final : this.paths.initial);
        }
        calculatePath(path = 'initial') {
            if ( path === 'initial' ) {
                return `M 0,0 0,${this.rect.height} ${this.rect.width},${this.rect.height} ${this.rect.width},0 0,0 Z M 0,0 ${this.rect.width},0 ${this.rect.width},${this.rect.height} 0,${this.rect.height} Z`;
            }
            else {
                return {
                    next: `M 0,0 0,${this.rect.height} ${this.rect.width},${this.rect.height} ${this.rect.width},0 0,0 Z M ${this.frameSize},${this.frameSize} ${this.rect.width-this.frameSize},${this.frameSize/2} ${this.rect.width-this.frameSize},${this.rect.height-this.frameSize/2} ${this.frameSize},${this.rect.height-this.frameSize} Z`,
                    prev: `M 0,0 0,${this.rect.height} ${this.rect.width},${this.rect.height} ${this.rect.width},0 0,0 Z M ${this.frameSize},${this.frameSize/2} ${this.rect.width-this.frameSize},${this.frameSize} ${this.rect.width-this.frameSize},${this.rect.height-this.frameSize} ${this.frameSize},${this.rect.height-this.frameSize/2} Z`
                }
            }
        }
        initEvents() {
            this.DOM.nextCtrl.addEventListener('click', () => this.navigate('next'));
            this.DOM.prevCtrl.addEventListener('click', () => this.navigate('prev'));
            
            window.addEventListener('resize', debounce(() => {
                this.rect = this.DOM.el.getBoundingClientRect();
                this.updateFrame();
            }, 20));
            
            document.addEventListener('keydown', (ev) => {
                const keyCode = ev.keyCode || ev.which;
                if ( keyCode === 37 ) {
                    this.navigate('prev');
                }
                else if ( keyCode === 39 ) {
                    this.navigate('next');
                }
            });
        }
        navigate(dir = 'next') {
            if ( this.isAnimating ) return false;
            this.isAnimating = true;

            const animateShapeIn = anime({
                targets: this.DOM.shape,
                duration: this.settings.animation.shape.duration,
                easing: this.settings.animation.shape.easing.in,
                d: dir === 'next' ? this.paths.final.next : this.paths.final.prev
            });

            const animateSlides = () => {
                return new Promise((resolve, reject) => {
                    const currentSlide = this.DOM.slides[this.current];
                    anime({
                        targets: currentSlide,
                        duration: this.settings.animation.slides.duration,
                        easing: this.settings.animation.slides.easing,
                        translateX: dir === 'next' ? -1*this.rect.width : this.rect.width,
                        complete: () => {
                            currentSlide.classList.remove('slide--current');
                            resolve();
                        }
                    });
        
                    this.current = dir === 'next' ? 
                        this.current < this.slidesTotal-1 ? this.current + 1 : 0 :
                        this.current > 0 ? this.current - 1 : this.slidesTotal-1; 
                    
                    const newSlide = this.DOM.slides[this.current];
                    newSlide.classList.add('slide--current');
                    anime({
                        targets: newSlide,
                        duration: this.settings.animation.slides.duration,
                        easing: this.settings.animation.slides.easing,
                        translateX: [dir === 'next' ? this.rect.width : -1*this.rect.width,0]
                    });
        
                    const newSlideImg = newSlide.querySelector('.slide__img');
                    newSlideImg.style.transformOrigin = dir === 'next' ? '-10% 50%' : '110% 50%';
                    anime.remove(newSlideImg);
                    anime({
                        targets: newSlideImg,
                        duration: this.settings.animation.slides.duration*4,
                        easing: 'easeOutElastic',
                        elasticity: 350,
                        scale: [1.2,1],
                        rotate: [dir === 'next' ? 4 : -4,0]
                    });
        
                    anime({
                        targets: [newSlide.querySelector('.slide__title'), newSlide.querySelector('.slide__desc'), newSlide.querySelector('.slide__link')],
                        duration: this.settings.animation.slides.duration,
                        easing: this.settings.animation.slides.easing,
                        delay: (t,i,total) => dir === 'next' ? i*100+750 : (total-i-1)*100+750,
                        translateY: [dir === 'next' ? 300 : -300,0],
                        rotate: [15,0],
                        opacity: [0,1]
                    });
                });
            };

            const animateShapeOut = () => {
                anime({
                    targets: this.DOM.shape,
                    duration: this.settings.animation.shape.duration,
                    delay: 150,
                    easing: this.settings.animation.shape.easing.out,
                    d: this.paths.initial,
                    complete: () => this.isAnimating = false
                });
            }

            animateShapeIn.finished.then(animateSlides).then(animateShapeOut);
        }
    };

    new Slideshow(document.querySelector('.slideshow'));
    imagesLoaded('.slide__img', { background: true }, () => document.body.classList.remove('loading'));
};
<!DOCTYPE html>
<html lang="en" class="no-js">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>Jubiläum by Wortwerkstatt</title>
		<meta name="description" content="Festakt, Pressearbeit, Ausstellung, Museum, Familientag für Ihr Firmenjubiläum. Entdecken, was möglich ist. " />
		<meta name="keywords" content="Fimrmenjubiläum, PR, Wortwerkstatt, Eventplanung und Druchführung" />
		<link rel="shortcut icon" href="favicon.ico">
		<link rel="stylesheet" type="text/css" href="css/base.css" />
		<link rel="stylesheet" type="text/css" href="pater/pater.css" />
		<script src="jquery.js"></script>
		<script>document.documentElement.className="js";var supportsCssVars=function(){var e,t=document.createElement("style");return t.innerHTML="root: { --tmp-var: bold; }",document.head.appendChild(t),e=!!(window.CSS&&window.CSS.supports&&window.CSS.supports("font-weight","var(--tmp-var)")),t.parentNode.removeChild(t),e};supportsCssVars()||alert("Please view this demo in a modern browser that supports CSS Variables.");</script>
	</head>
	<body class="demo-2 loading">
		<main>
			<div class="content content--fixed">
				<header class="codrops-header">
					<h1 class="codrops-header__title"><span>Firmenjubiläum </span><img src="img/logo.png" alt="" /> <span>by Wortwerkstatt.</span></h1>
				</header>				
			</div>
			<div class="slideshow">
				<div class="slides">
					<div class="slide slide--current" id="one">
						<div class="slide__img" style="background-image: url(img/start.jpg);"></div>
						<h2 class="slide__title">Jubiläum</h2>
						<p class="slide__desc">Created by Wortwerkstatt</p>
						<a class="slide__link menubutton1" href="#">Einführung</a>
					</div>
					<div class="slide" id="two">
						<div class="slide__img" style="background-image: url(img/chronik.jpg);"></div>
						<h2 class="slide__title">Chronik</h2>
						<p class="slide__desc">Digital und Print - die Geschichte schafft Ein- und Ausblicke, <br />verbindet historische Leistungen mit der Zukunft</p>
						<a class="slide__link menubutton3" href="#">Discover calmness</a>
					</div>
					<div class="slide" id="three">
						<div class="slide__img" style="background-image: url(img/presse-1.jpg);"></div>
						<h2 class="slide__title">Presse</h2>
						<p class="slide__desc">Kommunikation intern - und extern</p>
						<a class="slide__link" href="#">mehr dazu</a>
					</div>
					<div class="slide" id="four">
						<div class="slide__img" style="background-image: url(img/festakt.jpg);"></div>
						<h2 class="slide__title">Festakt</h2>
						<p class="slide__desc">The Hightlight. Unique. Full of moments to share and to remember.</p>
						<a class="slide__link" href="#">Adventure yourself</a>
					</div>
					<div class="slide" id="five">
						<div class="slide__img" style="background-image: url(img/familie.jpg);"></div>
						<h2 class="slide__title">Familientag</h2>
						<p class="slide__desc">Leave society behind and indulge yourself in tranquility ;-).</p>
						<a class="slide__link" href="#">Discover calmness</a>
					</div>
					<div class="slide" id="six">
						<div class="slide__img" style="background-image: url(img/museum-2.jpg); background-position:center 25%;"></div>
						<h2 class="slide__title">Exhibition</h2>
						<p class="slide__desc">Discover great activities with breathtaking views.</p>
						<a class="slide__link" href="#">Find out more</a>
					</div>
				</div>
				
				<!-- Thumb Navigation, doesn't work -->
				<nav class="thumbnav">
					<a href="#one"><img src="img/thumb1.jpg" alt="" /></a>
					<a href="#two"><img src="img/thumb2.jpg" alt="" /></a>
					<a href="#three"><img src="img/thumb3.jpg" alt="" /></a>
					<a href="#four"><img src="img/thumb4.jpg" alt="" /></a>
					<a href="#five"><img src="img/thumb5.jpg" alt="" /></a>
					<a href="#six"><img src="img/thumb6.jpg" alt="" /></a>
				</nav>
				
				<!-- This works: -->
				<nav class="slidenav">
					<button class="slidenav__item slidenav__item--prev">Previous</button>
					<span>/</span>
					<button class="slidenav__item slidenav__item--next">Next</button>
				</nav>
			</div>

		</main>
		<script src="js/demo.js"></script>
		<script src="js/imagesloaded.pkgd.min.js"></script>
		<script src="js/anime.min.js"></script>
		<script src="js/demo2.js"></script>
		<script src="menu.js"></script>

	</body>
</html>

0 个答案:

没有答案