تخفیف ویژه

انیمیشن زیبا برای گریدبندی تصاویر - Grid Loading Animations ( نمونه 1)

زمان مطالعه: 5 دقیقه
۲۱ تیر ۱۳۹۶

در این مطلب و مطالب بعدی تعدادی انیمیشن زیبا و دیدنی برای گریدبندی تصاویر با عنوان Grid Loading Animations رو در خدمتتون قرار میدم که میتونین از اونا در سایتتون استفاده کنید و از اونا ایده بگیرید.

همونطور که دیدیدن تعدادی تصویر بصورت گریدبندی شده قرار گرفتن و زمانی که بر روی دکمه Run Effect کلیک میکنید، انیمیشن لود شدن تصاویر اجرا میشه.

کد HTML :

<div class="content content--center">
	<button class="control__btn" data-fx="Hapi">Run Effect : Hapi</button>
	<div class="grid">
		<div class="grid__sizer"></div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/1.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/2.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/3.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/4.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/10.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/2.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/7.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/8.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/9.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/10.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/11.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/2.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/4.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/8.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/10.jpg" alt="Some image" /></a>
		</div>
		<div class="grid__item">
			<a class="grid__link" href="#"><img class="grid__img" src="img/1.jpg" alt="Some image" /></a>
		</div>
	</div>
</div>

کد CSS :

*,
*::after,
*::before {
	-webkit-box-sizing: border-box;
	box-sizing: border-box;
}

body {
	font-family: 'Roboto Mono', monospace;
	font-size: 14px;
	font-weight: 500;
	color: #82888a;
	background: #2c2d31;
	overflow-x: hidden;
	-webkit-font-smoothing: antialiased;
}

.js .loading::before,
.js .loading::after {
	content: '';
	position: fixed;
	z-index: 1000;
}

.loading::before {
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: #2c2d31;
}

.loading::after {
	top: 50%;
	left: 50%;
	width: 40px;
	height: 40px;
	margin: -20px 0 0 -20px;
	border: 8px solid #383a41;
	border-bottom-color: #565963;
	border-radius: 50%;
	animation: animLoader 0.8s linear infinite forwards;
}

@keyframes animLoader {
	to { transform: rotate(360deg); }
}

a {
	text-decoration: none;
	color: #f2f2f2;
	outline: none;
}

a:hover,
a:focus {
	color: #e6629a;
}

.hidden {
	position: absolute;
	overflow: hidden;
	width: 0;
	height: 0;
	pointer-events: none;
}

.content {
	padding: 2em 0;
}

.control__btn {
    border: none;
    cursor: pointer;
    padding: 25px 80px;
    display: block;
    margin: 20px auto;
    font-weight: 700;
    font-size: 20px;
    outline: none;
    position: relative;
    background: #673ab7;
    color: #fff;
    box-shadow: 0 6px #42454c;
    -webkit-transition: none;
    -moz-transition: none;
    transition: none;
}

.media-item {
	padding: 1em;
}

.media-item__img {
	max-width: 100%;
	opacity: 0.7;
	transition: opacity 0.3s;
}

.media-item:hover .media-item__img,
.media-item:focus .media-item__img {
	opacity: 1;
}

.media-item__title {
	font-size: 1em;
	max-width: 220px;
	padding: 0.5em;
	margin: 0 auto;
}

/* Grid */

.grid {
	position: relative;
	z-index: 2;
	display: block;
	margin: 0 auto;
}

.grid--hidden {
	position: fixed !important;
	z-index: 1;
	top: 0;
	left: 0;
	width: 100%;
	pointer-events: none;
	opacity: 0;
}

.js .grid--loading::before,
.js .grid--loading::after {
	content: '';
	z-index: 1000;
}

.js .grid--loading::before {
	position: fixed;
	top: 0;
	left: 0;
	width: 100vw;
	height: 100vh;
	background: #2c2d31;
}

.js .grid--loading::after {
	position: absolute;
	top: calc(25vh - 20px);
	left: 50%;
	width: 40px;
	height: 40px;
	margin: 0 0 0 -20px;
	border: 8px solid #383a41;
	border-bottom-color: #565963;
	border-radius: 50%;
	animation: animLoader 0.8s linear forwards infinite;
}

.grid__sizer {
	margin-bottom: 0 !important;
}

.grid__link,
.grid__img {
	display: block;
}

.grid__img {
	width: 100%;
}

.grid__deco {
	position: absolute;
	top: 0;
	left: 0;
	pointer-events: none;
}

.grid__deco path {
	fill: none;
	stroke: #fff;
	stroke-width: 2px;
}

.grid__reveal {
	position: absolute;
	z-index: 50;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	pointer-events: none;
	opacity: 0;
	background-color: #2c2d31;
}

.grid .grid__item,
.grid .grid__sizer {
	width: calc(50% - 20px);
	margin: 0 10px 20px;
}

@media screen and (min-width: 60em) {
	.grid .grid__item,
	.grid .grid__sizer {
		width: calc((100% / 3) - 20px);
		margin: 0 10px 20px;
	}
}

@media screen and (min-width: 70em) {
	.grid .grid__item,
	.grid .grid__sizer {
		width: calc(25% - 30px);
		margin: 0 15px 30px;
	}
}

@media screen and (max-width: 50em) {
	.content--center {
		max-width: 100vw;
	}
}

کد JS:

در این مطلب از imageLoaded و masonry و anime استفاده شده است.

;(function(window) {

	/**
	 * GridLoaderFx obj.
	 */
	function GridLoaderFx(el, options) {
		this.el = el;
		this.items = this.el.querySelectorAll('.grid__item > .grid__link');
	}

	GridLoaderFx.prototype._render = function(effect) {
		// Reset styles.
		this._resetStyles();

		var self = this,
			effects = {
				'Hapi': {
					animeOpts: {
						duration: function(t,i) {
							return 600 + i*75;
						},
						easing: 'easeOutExpo',
						delay: function(t,i) {
							return i*50;
						},
						opacity: {
							value: [0,1],
							easing: 'linear'
						},
						scale: [0,1]	
					}
				}
			},
			effectSettings = effects[effect],
			animeOpts = effectSettings.animeOpts

		if( effectSettings.perspective != undefined ) {
			[].slice.call(this.items).forEach(function(item) { 
				item.parentNode.style.WebkitPerspective = item.parentNode.style.perspective = effectSettings.perspective + 'px';
			});
		}
		
		if( effectSettings.origin != undefined ) {
			[].slice.call(this.items).forEach(function(item) { 
				item.style.WebkitTransformOrigin = item.style.transformOrigin = effectSettings.origin;
			});
		}

		if( effectSettings.lineDrawing != undefined ) {
			[].slice.call(this.items).forEach(function(item) { 
				// Create SVG.
				var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'),
					path = document.createElementNS('http://www.w3.org/2000/svg', 'path'),
					itemW = item.offsetWidth,
					itemH = item.offsetHeight;

				svg.setAttribute('width', itemW + 'px');
				svg.setAttribute('height', itemH + 'px');
				svg.setAttribute('viewBox', '0 0 ' + itemW + ' ' + itemH);
				svg.setAttribute('class', 'grid__deco');
				path.setAttribute('d', 'M0,0 l' + itemW + ',0 0,' + itemH + ' -' + itemW + ',0 0,-' + itemH);
				path.setAttribute('stroke-dashoffset', anime.setDashoffset(path));
				svg.appendChild(path);
				item.parentNode.appendChild(svg);
			});

			var animeLineDrawingOpts = effectSettings.animeLineDrawingOpts;
			animeLineDrawingOpts.targets = this.el.querySelectorAll('.grid__deco > path');
			anime.remove(animeLineDrawingOpts.targets);
			anime(animeLineDrawingOpts);
		}

		if( effectSettings.revealer != undefined ) {
			[].slice.call(this.items).forEach(function(item) { 
				var revealer = document.createElement('div');
				revealer.className = 'grid__reveal';
				if( effectSettings.revealerOrigin != undefined ) {
					revealer.style.transformOrigin = effectSettings.revealerOrigin;
				}
				if( effectSettings.revealerColor != undefined ) {
					revealer.style.backgroundColor = effectSettings.revealerColor;
				}
				item.parentNode.appendChild(revealer);
			});

			var animeRevealerOpts = effectSettings.animeRevealerOpts;
			animeRevealerOpts.targets = this.el.querySelectorAll('.grid__reveal');
			animeRevealerOpts.begin = function(obj) {
				for(var i = 0, len = obj.animatables.length; i < len; ++i) {
					obj.animatables[i].target.style.opacity = 1;
				}
			};
			anime.remove(animeRevealerOpts.targets);
			anime(animeRevealerOpts);
		}

		if( effectSettings.itemOverflowHidden ) {
			[].slice.call(this.items).forEach(function(item) {
				item.parentNode.style.overflow = 'hidden';
			});
		}

		animeOpts.targets = effectSettings.sortTargetsFn && typeof effectSettings.sortTargetsFn === 'function' ? [].slice.call(this.items).sort(effectSettings.sortTargetsFn) : this.items;
		anime.remove(animeOpts.targets);
		anime(animeOpts);
	};

	GridLoaderFx.prototype._resetStyles = function() {
		this.el.style.WebkitPerspective = this.el.style.perspective = 'none';
		[].slice.call(this.items).forEach(function(item) {
			var gItem = item.parentNode;
			item.style.opacity = 0;
			item.style.WebkitTransformOrigin = item.style.transformOrigin = '50% 50%';
			item.style.transform = 'none';

			var svg = item.parentNode.querySelector('svg.grid__deco');
			if( svg ) {
				gItem.removeChild(svg);
			}

			var revealer = item.parentNode.querySelector('.grid__reveal');
			if( revealer ) {
				gItem.removeChild(revealer);
			}

			gItem.style.overflow = '';
		});
	};

	window.GridLoaderFx = GridLoaderFx;

	var body = document.body,
		masonry = [],
		currentGrid = document.querySelector('.grid'),
		// Choose effect buttons.
		fxCtrl = document.querySelector('.control__btn'),
		// The GridLoaderFx instances.
		loadingTimeout;

	function init() {
		// Preload images
		imagesLoaded(body, function() {
			// Initialize Masonry on each grid.
			var m = new Masonry(currentGrid, {
				itemSelector: '.grid__item',
				columnWidth: '.grid__sizer',
				percentPosition: true,
				transitionDuration: 0
			});
			masonry.push(m);
			// Hide the grid.
			currentGrid.classList.add('grid--hidden');
			// Init GridLoaderFx.
			loader = new GridLoaderFx(currentGrid);

			// Show current grid.
			currentGrid.classList.remove('grid--hidden');
			// Init/Bind events.
			initEvents();
			// Remove loading class from body
			body.classList.remove('loading');
		});
	}

	function initEvents() {
		// Effect selection.
		fxCtrl.addEventListener('click', applyFx);
	}

	function applyFx(ev) {
		// Simulate loading grid to show the effect.
		clearTimeout(loadingTimeout);
		currentGrid.classList.add('grid--loading');

		loadingTimeout = setTimeout(function() {
			currentGrid.classList.remove('grid--loading');

			// Apply effect.
			loader._render(ev.target.getAttribute('data-fx'));
		}, 500);
	}

	init();

})(window);

امیدوارم خوشتون بیاد.

موفق باشید. یا علی

Source

چه امتیازی به این مقاله می دید؟
نویسنده محمد اسفندیاری
بسیار به طراحی وب علاقمندم و به سرعت در حال یادگیری تمام مباحث پیشرفته هستم و دوست دارم که به دیگران هم یاد بدهم.

نظرات کاربران

اولین دیدگاه این پست رو تو بنویس !

ارسال دیدگاه
خوشحال میشیم دیدگاه و یا تجربیات خودتون رو با ما در میون بذارید :