Record the process of making a carousel map plug-in…

rendering

Ordinary rotation chart

Card-type rote chart

Stacked wheel cast diagram

Ordinary rotation chart

Function:

* Can control whether automatic rotation * left and right arrow switch on one, next, throttling processing * Mouse on the arrow, pictures stop automatic rotation, mouse away and then continue to play * Click the small dot to jump to the corresponding sequence of pictures * Mobile terminal can slide left, slide right switchCopy the code

General rotation chart – demo

Ordinary round – cast chart – source code

Ideas:

As shown in the figure above, suppose there are three images in rotation, the green area is the display area, and the rest is hidden

  • When rendering the page, two more images will be selected. The numbers 1, 2 and 3 in the figure respectively represent the number of pictures, and A,B,C and D respectively represent the state of picture list div at different times
  • A Rectangle for the page startup effect, showing the first image
  • B is the effect drawing of the next one, showing the second picture
  • Continue to the next image until the first one is displayed, as shown in C, which is the last one in the current list of images. Therefore, to change the state of C to the state of D, the first image is displayed again. This is equivalent to quietly changing the left value of the image list div, and the image displayed remains the first image
  • The last slide was the same idea

The page layout

  • Class =”swiper-list” class=”swiper-list” class=”swiper-list” class=”swiper-list” class=”swiper-list
  • Class =”swiper-main” this div is a list of images div, changing the left value to switch between the previous image and the next image
  • When switching to the next image, the left value of the image list div is subtracted by one image
  • When toggling the previous image, the left value of the image list div adds one image width to the original one

The source code

Previous, next core method

NowIndex is used to indicate the number of images being displayed, starting with 0

PrevSlider (aniTIme) {let that = this;
	if (this.imgArr.length===1) return;
	this.mainDom.style.transition = `left ${aniTIme / 1000}s`
	this.mainDom.style.left = `${parseInt(this.mainDom.style.left) + this.moveWidth}px`; // The left value of the image list div changesif (this.nowIndex === 0) {
		that.nowIndex = (that.imgArr.length-1);
		that.setActiveSpot();
		setTimeout(function() {					
			that.mainDom.style.transitionProperty = 'none'; // This property should be set when the left value is changed quietly, otherwise the animation that.maindom.style. left = 'will be played${-that.imgArr.length * that.moveWidth}px`; }, aniTIme) // Select * from aniTIme; // Select * from aniTIme;else{ this.nowIndex--; this.setActiveSpot(); }}, // Next slide nextSlider(aniTIme) {let that = this;
	if (this.imgArr.length===1) return;
	this.nowIndex++;
	this.mainDom.style.transition = `left ${aniTIme / 1000}s`
	this.mainDom.style.left = `${parseInt(this.mainDom.style.left) - this.moveWidth}px`;
	if (this.nowIndex === (this.imgArr.length)) {
		that.nowIndex = 0;
		that.setActiveSpot();
		setTimeout(function() {
			that.mainDom.style.transitionProperty = 'none';
			that.mainDom.style.left = `${-that.moveWidth}px`; }, aniTIme) // The left value of the list div is changed so that the last image is displayed.else{ this.setActiveSpot(); }}, // Set the origin stylesetActiveSpot: function() {
	for (let i = 0; i < this.swiperSpotDom.childElementCount; i++) {				
		if (i === Math.abs(this.nowIndex)) {
			document.getElementsByClassName('spot-item')[i].style.backgroundColor = '#ff5c1f'
		} else {
			document.getElementsByClassName('spot-item')[i].style.backgroundColor = '#ccc'}}},Copy the code

Next button event binding, throttling processing

eventBind() {... / / the next button event binding enclosing rightBtn. AddEventListener ('mouseover'.function() {
    	clearInterval(that.timer);
    })
    this.rightBtn.addEventListener('mouseout'.function() {
    	that.timer = setInterval(that.nextSlider.bind(that, that.aniTIme), that.intervalTime);
    })
    this.rightBtn.addEventListener('click'.function() { that.throttle(that.nextSlider, 300, 300); })... } // Throttle: throttle(handle, delay, val) {var now = date.now ();if(now - this.prev >= delay) { handle.call(this, val); this.prev = Date.now(); }},Copy the code

Throttling: Causes events to fire evenly spaced

The throttles here are a little different from the other throttles, you can use your own

The dot clicks on the event binding

eventBind() {... This event / / dots binding. SwiperSpotDom. AddEventListener ('mouseover'.function() {
		clearInterval(that.timer);
	})
	this.swiperSpotDom.addEventListener('mouseout'.function() {
		that.timer = setInterval(that.nextSlider.bind(that, that.aniTIme), that.intervalTime);
	})
	this.swiperSpotDom.addEventListener('click'.function(e) { e = e || window.event; // This line and the next line are compatible with IE8 and below & EMsp; &emsp; var target = e.target || e.srcElement; &emsp; &emsp;if (target.tagName.toLowerCase() === "li") { &emsp; &emsp; &emsp; &emsp; var ret = this.querySelectorAll("li"); &emsp; &emsp; &emsp; &emsp;let index = Array.prototype.indexOf.call(ret, target);
			that.nowIndex = index;
			that.setActiveSpot();
			that.mainDom.style.transition = `left .8s`
			that.mainDom.style.left = `${-(that.nowIndex+1) * that.moveWidth}px`;
	&emsp;&emsp;}
	})
    
    ...
}
Copy the code

Determine which li is clicked and assign the subscript value to nowIndex. The left value of image list div (mainDom) changes and updates the style of the origin

Move side slide left and right event

eventBind() {... this.mainDom.addEventListener('touchstart'.function(e) {
		clearInterval(that.timer);
		that.startX = e.changedTouches[0].clientX;
		that.startY = e.changedTouches[0].clientY;
	})
	this.mainDom.addEventListener('touchmove'.function(e) {
		clearInterval(that.timer);
		that.endX = e.changedTouches[0].clientX;
		that.endY = e.changedTouches[0].clientY;
	})
	this.mainDom.addEventListener('touchend'.function(e) {
		if(! that.mainDom.style.transition) { that.mainDom.style.transition = `left${that.aniTIme / 1000}s`
		}
		let angle = that.angle({ X: that.startX, Y: that.startY }, { X: that.endX, Y: that.endY });
		if (Math.abs(angle) > 30) return;
	    if(tha.endx > tha.startx){// Right slider tha.prevslider (); }else{// Slide that.nextslider (); } that.timer =setInterval(that.nextSlider.bind(that, that.aniTIme), that.intervalTime); })... @param {Object} start @param {Object} end @param {Object} endfunction(start, end) {var _X = end.x - start.X, _Y = end.y - start.Y // return Angle/math.atan () returns the arctangent of the numberreturn 360 * Math.atan(_Y / _X) / (2 * Math.PI);
}
Copy the code

Left to call nextSlider(), right to call prevSlider()

Use:

The introduction of the slider. Js

	<div class="swiper-list"></div>
Copy the code
let imgArr = [
	{
		url: The '#',
		imgPath: '.. /i.jpg'
	},
	{
		url: The '#',
		imgPath: '.. /o.jpg'
	},
	{
		url: The '#',
		imgPath: '.. /q.jpeg'
	},
	{
		url: The '#',
		imgPath: '.. /w.jpg'
	},
	{
		url: The '#',
		imgPath: '.. /z.png'}]; //let imgArr = ['i.jpg'.'o.jpg'.'q.jpeg'];
// let imgArr = ['i.jpg'.'o.jpg'];
// let imgArr = ['i.jpg']; New Swiper({imgArr: imgArr, // Image array aniTIme: 1000, // Animation execution time intervalTime: 1000, // image retention time autoplay:true}).init();Copy the code

css

<style> ul{padding: 0; list-style: none; } .swiper-list{ width: 640px; height: 360px; margin: 0 auto; position: relative; overflow: hidden; } .swiper-main { height: 100%; position: relative; overflow: hidden; } .swiper-item{ height: 100%; display: inline; position: absolute; } img { width: 100%; height: 100%; display: block; } .swiper-spot{ width: 100%; height: 15px; display: flex; justify-content: center; align-items: center; position: absolute; bottom: 10px; } .swiper-spot .spot-item{ width: 15px; height: 15px; border-radius: 50%; background-color:#ccc;
		margin-left: 10px;
	}
	.swiper-spot .spot-item:nth-of-type(1) {
		margin-left: 0;
	}

	.leftBtn{
		position: absolute;
		left: 15px;
		top: 50%;
		transform: translateY(-50%);
		width: 30px;
		height: 30px;
	}
	.rightBtn{
		position: absolute;
		right: 15px;
		top: 50%;
		transform: translateY(-50%);
		width: 30px;
		height: 30px;
	}
</style>
Copy the code

Card-type round casting

Function:

* Can control whether automatic rotation * left and right arrow switch on one, next, throttling processing * Mouse on the arrow, the picture stops automatic rotation, mouse away and then continue to play * Mobile terminal can slide left, slide right switchCopy the code

Card-type rotation – demo

Card – round – source

Ideas:

The idea is the same as the ordinary rotation diagram, but two pictures are added to the header and the end respectively for transition. When the picture moves to the critical value, the left value of the picture list div changes, showing the same picture, but the left value of the picture list div is different

code

Here the nowIndex defaults to 3, and since two images are appended to the header, the element with subscript 3 is the middle image and is not scaled, while the rest of the image is shrunk

/** * obj: * imgArr Image array * imgWidth Image width * aniTime Animation switch time * intervalTime stay time * Scale Image zoom * AutoPlay whether toplay automatically * GAP between images */functionSwiper(obj) { this.imgArr = obj.imgArr || []; This. Scale = obj. Scale | | 0.8; This. gap = obj. Gap; // The space between images in unscaled state // mobile terminalif((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fenne c|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) { this.containerWidth = document.body.clientWidth; // Box width}else{
		// PC端
	   this.containerWidth = 600; // 轮播图盒子宽度
	}
	this.imgWidth = obj.imgWidth; // 图片宽度
	this.aniTime = obj.aniTime || 500;
	this.intervalTime = this.aniTime + obj.intervalTime || 2000;
	this.nowIndex = 3;
	this.imgDoms = document.getElementsByClassName('swiper-slide');
	this.mainDom = document.getElementsByClassName('swiper-main') [0]; this.listDoms = document.getElementsByClassName('swiper-list') [0]; this.activeDom = this.imgDoms[0]; this.autoplay = obj.autoplay; this.listDoms.style.width = `${this.containerWidth}px`; this.timer; This.prev = date.now (); this.diffLen = (this.containerWidth - this.imgWidth - (this.gap * 2)) / 2; this.clsSuffix = obj.clsSuffix; // Class name suffix}Copy the code

DiffLen value:

prevSlider: function(aniTime) {
	if(this.imgArr.length ===2) { this.nowIndex = this.nowIndex ? 0:1; this.setScale() }else if (this.imgArr.length ===1) {
		return;
	} else {
		this.nowIndex--;
		this.mainDom.style.transition = `left ${aniTime/1000}s`
		this.mainDom.style.left = `${parseInt(this.mainDom.style.left)+(this.gap + this.imgWidth)}px`;
		if (this.nowIndex === 1) {
			this.setScale()
			setTimeout(function() {
				this.nowIndex = (this.imgArr.length+1);
				this.setScale()
				this.mainDom.style.transitionProperty = 'none';
				this.mainDom.style.left = `${-(parseInt(this.imgDoms[this.nowIndex].style.left) - this.diffLen - this.gap)}px`;
			}.bind(this), aniTime)
		} else {
			this.setScale()
		}
	}
},
nextSlider: function(aniTime) {
	if(this.imgArr.length ===2) { this.nowIndex = this.nowIndex ? 0:1; this.setScale() }else if (this.imgArr.length ===1) {
		return;
	} else {
		if (this.nowIndex >=2) {	
			this.mainDom.style.transition = `left ${aniTime/1000}s`
			this.mainDom.style.left = `${parseInt(this.mainDom.style.left)-(this.gap + this.imgWidth)}px`;
			// this.mainDom.style.left = `${this.gap + this.imgWidth}px`;
		}
		if (this.nowIndex === (this.imgArr.length+1)) {
			this.nowIndex = (this.imgArr.length+2);
			this.setScale()
			setTimeout(function() {
				this.nowIndex = 2;
				this.setScale()
				this.mainDom.style.transitionProperty = 'none';
				this.mainDom.style.left = `${-(this.imgWidth - this.diffLen)}px`;
			}.bind(this), aniTime)
		} else {
			this.nowIndex++;
			this.setScale()
		}
	}
},
setScale: function() {// stackif (this.gap < 0) {

		for (let i = 0; i < this.imgDoms.length; i++) {
			if (this.imgArr.length ===2) {
				this.imgDoms[0].style.left = `${(this.containerWidth/4) - (this.imgWidth/2)}px`;
				this.imgDoms[1].style.left = `${(this.containerWidth/4)*3 - (this.imgWidth/2)}px`;
			} else if (this.imgArr.length ===1) {
				this.imgDoms[i].style.left = `${(this.containerWidth/2) - (this.imgWidth/2)}px`;
			} else {
				this.imgDoms[i].style.left = `${(i - 1) * (this.imgWidth + this.gap)}px`;
			}


			if (i === this.nowIndex) {
				this.imgDoms[i].style.transform = 'scale(1)';
				this.imgDoms[i].style.zIndex = '1001';
			} else if (i < this.nowIndex) {
				this.imgDoms[i].style.transform = `scale(${1 - ((this.nowIndex -i) * 0.2)} ${1 - ((this.nowIndex -i) * 0.2)}) `; this.imgDoms[i].style.zIndex = 1000 - ((this.nowIndex - i)); }else if (i > this.nowIndex) {
				this.imgDoms[i].style.transform = `scale(${1 - ((I - this.nowindex) * 0.2)} ${1 - ((I - this.nowindex) * 0.2)}) `; this.imgDoms[i].style.zIndex = 1000 - (i - this.nowIndex); }}}else{// card typefor (let i = 0; i < this.imgDoms.length; i++) {
			if (this.imgArr.length ===2) {
				this.imgDoms[0].style.left = `${(this.containerWidth/4) - (this.imgWidth/2)}px`;
				this.imgDoms[1].style.left = `${(this.containerWidth/4)*3 - (this.imgWidth/2)}px`;
			} else if (this.imgArr.length ===1) {
				this.imgDoms[i].style.left = `${(this.containerWidth/2) - (this.imgWidth/2)}px`;
			} else {
				this.imgDoms[i].style.left = `${(i - 1) * (this.imgWidth + this.gap)}px`;
			}
			if (i === this.nowIndex) {
				this.imgDoms[i].style.transform = 'scale(1)';
			} else {
				this.imgDoms[i].style.transform = `scale(${this.scale}) `; }}}},Copy the code

usage

<div class="swiper-list-card swiper-list">	
	<div class="swiper-main-card swiper-main"></div>
	<img id="prev-card" class="btn leftBtn" src=".. /left.png" alt="">
	<img id="next-card" class="btn rightBtn" src=".. /right.png" alt="">
</div>
Copy the code
// introduce slider_card.js <script SRC ="./slider_card.js"></script>
Copy the code
let imgArr = [{
		url: The '#',
		imgPath: '.. /i.jpg'
	},
	{
		url: The '#',
		imgPath: '.. /o.jpg'
	},
	{
		url: The '#',
		imgPath: '.. /q.jpeg'
	},
	{
		url: The '#',
		imgPath: '.. /w.jpg'
	},
	{
		url: The '#',
		imgPath: '.. /z.png'}]; //let imgArr = ['i.jpg'.'o.jpg'.'q.jpeg'];
// let imgArr = ['i.jpg'.'o.jpg'];
// let imgArr = ['i.jpg']; New Swiper({imgArr: imgArr, // image array imgWidth: 200, // image width aniTime: 1000, // Animation switch time intervalTime: 1500, // Dwell time scale: 0.8, // Image zoom autoplay:true, // Whether to automatically play gap: 0, // the interval between pictures clsSuffix:'-card'// Element class name suffix}).init();Copy the code

css

<style>
    .swiper-list{
		height: 200px;
		position: relative;
		overflow: hidden;
		border: 1px solid #eee;
		padding: 30px 0;
	}
	.swiper-main{
		height: 100%;
		position: relative;
	}
	.swiper-main img{
		height: 100%;
		display: block;
		position: absolute;
		top: 0px;
		border-radius: 4px;
		display: inline-block;
		box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
	}
	.btn{
		position: absolute;
		top: 50%;
		transform: translateY(-50%);
		width: 30px;
		height: 30px;
		z-index: 1002;
	}
	.leftBtn{
		left: 0px;
	}
	.rightBtn{
		right: 0px;
	}
</style>
Copy the code

Stack rotation

Stack shuffling and card shuffling principle is the same, just spacing gap set negative picture is good, usage with card shuffling

The demo source code

<div class="swiper-list-stack swiper-list">	
	<div class="swiper-main-stack swiper-main"></div>
	<img id="prev-stack" class="btn leftBtn" src=".. /left.png" alt="">
	<img id="next-stack" class="btn rightBtn" src=".. /right.png" alt="">
</div>
Copy the code
// introduce slider_card.js <script SRC ="./slider_card.js"></script>
Copy the code
New Swiper({imgArr: imgArr, imgWidth: 320, aniTime: 1000, intervalTime: 1500, Scale: 0.8, Autoplay:false,
	gap: -200,
  	clsSuffix: '-stack'
}).init();
Copy the code

The reason for adding clsSuffix is that page fetch elements are fetched by class names, and a suffix is added to distinguish card and stack formats