フルスクリーンボタン付きギャラリーを作成

フルスクリーンボタン付きギャラリーを作成する方法を紹介します。

サムネイルをクリックすると、モダールウィンドウが表示されます。右上のフルスクリーンボタンをクリックすると、ブラウザーがフルスクリーンで表示されます。

サムネイルをクリックすると、モダールウィンドウが表示

右上のフルスクリーンボタンをクリックすると、ブラウザーがフルスクリーンで表示

コード

<div id="column1">
	<ul class="jazz-gallery">
		<li class="modal-button"><img src="images/jazz002.jpg" alt=""/></li>
		<li class="modal-button"><img src="images/jazz003.jpg" alt=""/></li>
		<li class="modal-button"><img src="images/jazz004.jpg" alt=""/></li>
	</ul>
</div>
img {
    width: 100%;
    object-fit: cover;
}
#column1 {
    display: grid;
	align-content: center;
	align-items: center;
	height: 100vh;
	width: 100vw;
	background-image: url("../images/jazz001.jpeg");
	background-repeat: no-repeat;
	background-position: 70% center;
	background-size: cover;
	position: relative;
	overflow: hidden;
}
.textcontent{
	opacity: 0;
	text-transform: uppercase;
}
.mask1{
	position:absolute;
	width: 100vw;
	height:200vh;
	background: linear-gradient(200deg, rgba(0,0,0,0), rgba(0,0,0,1) 50%, rgba(0,0,0,1) 100%);
	top:-100vh;
	left:0;
	z-index: 0; 
}
.jazz-gallery.thumb li.thumb-active{
	pointer-events: none;
}
#column1 .textcontent1{
	position: absolute;
	margin-bottom: auto ;
	margin-top: auto ;
	top: 50%;
	left: 50%;
    transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    -ms-transform: translate(-50%, -50%);
}
.textcontent{
	opacity: 0;
}
.jazz-gallery{
	display: flex;
	margin: auto;
}
.jazz-gallery li{
	width: 20vw;
	height: 20vw;
	max-width: 200px;
	max-height: 200px;
	overflow: hidden;	
	cursor: pointer;
}
.jazz-gallery li img{
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.jazz-gallery.thumb{
	display: flex;
	margin: 0;
	padding: 0; 
	flex-flow: column;
	position: fixed;
	transform: translateY(-50%);
    -webkit-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
	top: 50%;
	right: 0;
	z-index: 200;
	width: 10vw;
	margin:0;
	cursor: pointer;
}
.jazz-gallery.thumb li{
	width: 10vw;
	height: 10vw;
	max-width: none;
	max-height: none;
	overflow: hidden;	
}
li{
	list-style: none;
}
.modal {
	width: 100%;
	height: 100%;
	position: absolute;
	top: 0;
	left: 0;
	background-color: rgba(0, 0, 0, 0.2);
	display: flex;
	justify-content: center;
	align-items: center;
	z-index: 20;
	cursol: pointer;
	opacity: 0;
}
.inner {
	top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    -webkit-transform: translate(-50%, -50%);
    -ms-transform: translate(-50%, -50%);
	min-width: 350px;
	position: fixed;
	border-radius: 5px;
	text-align: center;
	max-width: 1200px;
	height: auto;
	display: flex;
	justify-content: center;
	align-items: center;
	flex-direction: column;
	animation: fadeInAnimation 800ms ease-out;
	z-index: 30;
}
.modal .inner img{
	width: 100%;
	height: auto;
}
.closemodal{
	width: 50px;
	height: 50px;
	position: fixed;
	top: 0;
	right: 0;
	z-index: 200;
	cursor: pointer;
	background: rgb(0 0 0 / 0.5); 
}
.closemodal::after, .closemodal::before{
	content: '';
	width: 30px;
	height:1px;
	opacity: 0.5;
	top: 50%;
	left: 50%;
	background: #fff;
	position: absolute;
}
.closemodal::after{
	transform: translate(-50%,-50%) rotate(45deg);
}
.closemodal::before{
	transform: translate(-50%,-50%) rotate(-45deg);
}
.fullscreeen{
	width: 50px;
	height: 50px;
	position: fixed;
	top: 0;
	right: 50px;
	z-index: 200;
	cursor: pointer;
	background: rgb(0 0 0 / 0.5); 
}
.fullscreeen::before{
	position: absolute;
	content: '';
	width: 30px;
	height: 30px;
	transform: translate(-50%,-50%) ;
	top: 50%;
	left: 50%;
	background-image: url('../images/icon-fullscreen-wiite.svg');
	opacity: 0.5;
	background-repeat: no-repeat;
	background-position:center;
	background-size: contain;
}
.fullscreeen-cancel{
	width: 50px;
	height: 50px;
	position: fixed;
	top: 0;
	right: 50px;
	z-index: 200;
	cursor: pointer;
	background: rgb(0 0 0 / 0.5); 
}
.fullscreeen-cancel::before{
	position: absolute;
	content: '';
	width: 30px;
	height: 30px;
	transform: translate(-50%,-50%) ;
	top: 50%;
	left: 50%;
	background-image: url('../images/icon-fullscreen-cansel-wiite.svg');
	opacity: 0.5;
	background-repeat: no-repeat;
	background-position:center;
	background-size: contain;
}
.thumb-icon{
	width: 50px;
	height: 50px;
	position: fixed;
	top: 0;
	right: 100px;
	z-index: 200;
	cursor: pointer;
	background: rgb(0 0 0 / 0.5); 
}
.thumb-icon-none{
	display: none;
}
.thumb-icon::before{
	position: absolute;
	content: '';
	width: 30px;
	height: 30px;
	opacity: 0.5;
	transform: translate(-50%,-50%) ;
	top: 50%;
	left: 50%;
	background-image: url('../images/icon-thumb-wiite.svg');
	background-repeat: no-repeat;
	background-position:center;
	background-size: contain;
}
@media (max-width: 740px) {
	.fullscreeen{
		display: none;
	}
	.closemodal{
		width: 40px;
		height: 40px;
	}
	.closemodal::after, .closemodal::before{
		content: '';
		width: 25px;
	}
	.thumb-icon{
		width: 40px;
		height: 40px;
		right: 40px;
	}
	.thumb-icon::before{
		width: 25px;
		height: 25px;
	}
}
@keyframes fadeInAnimation {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
const modalButton = document.querySelectorAll('.modal-button');
const galleryList = document.querySelector('.jazz-gallery');
const galleryListClone = galleryList.cloneNode(true);
galleryListClone.classList.add('thumb');

const mouseenterKeyframes = {
	opacity: [0.5, 1]
}
const mouseleaveKeyframes = {
	opacity: [1, 0.5]
}
const mouseenterKeyframes2 = {
	opacity: [1, 0.7]
}
const mouseleaveKeyframes2 = {
	opacity: [0.7, 1]
}
const mouseOption = {
	duration: 400,
	easing: 'ease',
	fill: 'forwards',
	pseudoElement: "::before",
}
const mouseOption2 = {
	duration: 400,
	easing: 'ease',
	fill: 'forwards',
	pseudoElement: "::after",
}
const mouseOption3 = {
	duration: 400,
	easing: 'ease',
	fill: 'forwards',
}

const galleryListCloneChildren = galleryListClone.children;
for(let i = 0; i < modalButton.length; i++){
	modalButton[i].addEventListener('click', (event) => {
	galleryListClone.classList.add('thumbopen');
	const moalImageSrc =  event.target.src;
	const modalElement = document.createElement('div');
	//modalクラスを付与する
	modalElement.classList.add('modal');
	//モダールウィンドウの内部要素を生成する
	const innerElement = document.createElement('div');
	innerElement.classList.add('inner');
	innerElement.innerHTML = `
		<img src="${moalImageSrc}" alt""/>
	`;
	galleryListClone.style.display=('block'); 
	//クローズボタンを生成する
	const closeElement = document.createElement('div');
	closeElement.classList.add('closemodal');
	//フルスクリーンボタンを生成する
	const fullScreenElement = document.createElement('div');
	fullScreenElement.classList.add('fullscreeen');
	//フルスクリーンキャンセルボタンを生成する
	const fullScreenCancelElement = document.createElement('div');
	fullScreenCancelElement.classList.add('fullscreeen-cancel');
	//サムネイルボタンを生成する
	const thumbnailElement = document.createElement('div');
	thumbnailElement.classList.add('thumb-icon'); 

	//body要素にモダールウィンドウを配置する
	document.body.appendChild(modalElement);
	document.body.appendChild(innerElement);
	document.body.appendChild(closeElement);
	document.body.appendChild(fullScreenElement);
	document.body.appendChild(galleryListClone); 
	document.body.appendChild(thumbnailElement); 
	modalElement.animate(
		{
			opacity: [0, 1]
		},
		{
			duration: 400,
			easing: 'ease',
			fill: 'forwards'
		}
	);
	closeElement.animate(
		{
			opacity: [0, 1]
		},
		{
			duration: 400,
			easing: 'ease',
			fill: 'forwards'
		}
	);
	fullScreenElement.animate(
		{
			opacity: [0, 1]
		},
		{
			duration: 400,
			easing: 'ease',
			fill: 'forwards'
		}
	);
	thumbnailElement.animate(
		{
			opacity: [0, 1]
		},
		{
			duration: 400,
			easing: 'ease',
			fill: 'forwards'
		}
	);
	galleryListClone.animate(
		{
			opacity:[0, 1] 
		},
		{
			duration: 400,
			easing: 'ease',
			fill: 'forwards'
		}
	);
	//thumb
	thumbnailElement.addEventListener('click', (event) => {
		if(galleryListClone.classList.contains('thumbopen')===false){
			galleryListClone.animate(
				{
				 	opacity: [0, 1]
				},
				{
				 	duration: 400,
				 	easing: 'ease',
				 	fill: 'forwards'
			 	}
			);
			galleryListClone.classList.add('thumbopen') ;
			document.body.appendChild(galleryListClone); 
			}else{
				galleryListClone.animate(
					{
						opacity: [1, 0]
					},
					{
				 		duration: 400,
				 		easing: 'ease',
				 		fill: 'forwards'
					}
		 		);
				galleryListClone.classList.remove('thumbopen') ;
				setTimeout( ()=> {
					closeModalWindow(galleryListClone);		
				}, 400);
			}
		});
		//ホバーアクション
		const thumbs = document.querySelectorAll('.jazz-gallery.thumb li');
		for(let k = 0; k < thumbs.length; k++){
			if(i === k){
				thumbs[k].classList.add('thumb-active');
			}
		} 
		thumbs.forEach((thumb) => {
			thumb.addEventListener('mouseenter', () => {
				thumb.animate(
					mouseenterKeyframes2, mouseOption3
				);
			});  
	  		for(let i = 0; i < galleryListCloneChildren.length; i++){
				const thumimage = galleryListCloneChildren[i].firstElementChild;
				const thumimageSrc = thumimage.getAttribute('src');
				galleryListCloneChildren[i].addEventListener('click', () => {
					const innerElementImg = innerElement.firstElementChild;
					innerElementImg.setAttribute('src', `${thumimageSrc}`)
					for(let j = 0; j < thumbs.length; j++){
						thumbs[i]
						if(i === j){
							thumbs[j].classList.add('thumb-active');
						}else{
							thumbs[j].classList.remove('thumb-active');
						}
					}
				});
			}
			thumb.addEventListener('mouseleave', () => {
				thumb.animate(
					mouseleaveKeyframes2, mouseOption3
				);
			});
		});
		closeElement.addEventListener('mouseenter', () => {
			closeElement.animate(
				mouseenterKeyframes, mouseOption
			);
			closeElement.animate(
				mouseenterKeyframes, mouseOption2
			);
		});
		closeElement.addEventListener('mouseleave', () => {
			closeElement.animate(
				mouseleaveKeyframes, mouseOption
			);
			closeElement.animate(
				mouseleaveKeyframes, mouseOption2
			);
		});
		fullScreenElement.addEventListener('mouseenter', () => {
			fullScreenElement.animate(
				mouseenterKeyframes, mouseOption
			);
		});
		fullScreenElement.addEventListener('mouseleave', () => {
			fullScreenElement.animate(
				mouseleaveKeyframes, mouseOption
			);
		});
		fullScreenCancelElement.addEventListener('mouseenter', () => {
			fullScreenCancelElement.animate(
				mouseenterKeyframes, mouseOption
			);
		});
		fullScreenCancelElement.addEventListener('mouseleave', () => {
			fullScreenCancelElement.animate(
				mouseleaveKeyframes, mouseOption
			);
		});
		thumbnailElement.addEventListener('mouseenter', () => {
			thumbnailElement.animate(
				mouseenterKeyframes, mouseOption
			);
		});
		thumbnailElement.addEventListener('mouseleave', () => {
			thumbnailElement.animate(
				mouseleaveKeyframes, mouseOption
			);
		});
		//モダールクローズ関数
		function closeModalAction(){
			modalElement.animate(
				{
					opacity: [1, 0]
				},
				{
					duration: 400,
					easing: 'ease',
					fill: 'forwards'
				}
			);
			innerElement.animate(
				{
					opacity: [1, 0]
				},
				{
					duration: 400,
					easing: 'ease',
					fill: 'forwards'
				}
			);
			closeElement.animate(
				{
					opacity: [1, 0]
				},
				{
					duration: 400,
					easing: 'ease',
					fill: 'forwards'
				}
			);
			closeElement.animate(
				{
					transform: ['translate(-50%,-50%) rotate(45deg)','translate(-50%,-50%) rotate(0deg)']
				},
				{
					duration: 400,
					pseudoElement: "::after",
					easing: 'ease',
				}
			);
			closeElement.animate(
				{
					transform: ['translate(-50%,-50%) rotate(-45deg)','translate(-50%,-50%) rotate(-90deg)']
				},
				{
					duration: 400,
					pseudoElement: "::before",
					easing: 'ease',
				}
			);
			fullScreenElement.animate(
				{
					opacity: [0]
				},
				{
					duration: 400,
					easing: 'ease',
					fill: 'forwards'
				}
			);
			fullScreenElement.animate(
				{
					transform: ['translate(-50%,-50%) rotate(0deg)','translate(-50%,-50%) rotate(-45deg)']
				},
				{
					duration: 400,
					easing: 'ease',
					pseudoElement: "::before",
				}
			);
			fullScreenCancelElement.animate(
				{
					opacity: [0]
				},
				{
					duration: 400,
					easing: 'ease',
					fill: 'forwards'
				}
			);
			fullScreenCancelElement.animate(
				{
					transform: ['translate(-50%,-50%) rotate(0deg)','translate(-50%,-50%) rotate(-45deg)']
				},
				{
					duration: 400,
					easing: 'ease',
					pseudoElement: "::before",
				}
			);
			galleryListClone.animate(
				{
					opacity: [0]
				},
				{
					duration: 400,
					easing: 'ease',
				fill: 'forwards'
				}
			);
			thumbnailElement.animate(
				{
					opacity: [1, 0]
				},
				{
					duration: 400,
					easing: 'ease',
					fill: 'forwards'
				}
			);
			thumbnailElement.animate(
				{
					transform: ['translate(-50%,-50%) rotate(0deg)','translate(-50%,-50%) rotate(-45deg)']
				},
				{
					duration: 400,
					easing: 'ease',
					pseudoElement: "::before",
				}
			);
			thumbnailElement.style.pointerEvents=('none');
			fullScreenElement.style.pointerEvents=('none');
			fullScreenCancelElement.style.pointerEvents=('none');
			setTimeout(() => {	
				closeModalWindow(modalElement);
				closeModalWindow(innerElement);
				closeModalWindow(closeElement);
				closeModalWindow(fullScreenElement);
				closeModalWindow(fullScreenCancelElement);
				closeModalWindow(galleryListClone);
				closeModalWindow(thumbnailElement);
				thumbnailElement.style.display=('none');
				fullScreenElement.style.display=('none');
				fullScreenCancelElement.style.displays=('none');
			}, 400);
		 	myCancelFullScreen();
		}
		//内部要素をクリックしたらモダールウィンドウを削除する処理
		modalElement.addEventListener('click', () => {
			closeModalAction();
		}); 
		//内部要素をクリックしたらモダールウィンドウを削除する処理
		closeElement.addEventListener('click', () => {
			closeModalAction();
		});
	 	fullScreenElement.addEventListener('click', () => {
			myReqeustFullScreen(document.body);
			document.body.removeChild(fullScreenElement);
			document.body.appendChild(fullScreenCancelElement);
		}); 
	 	function myReqeustFullScreen(element) {
			if (element.requestFullscreen) {
				// 標準仕様
    			element.requestFullscreen();
  			} else if (element.webkitRequestFullscreen) {
    			// Safari, Chrome
    			element.webkitRequestFullscreen();
  			} else if (element.mozRequestFullScreen) {
				// Firefox
    			element.mozRequestFullScreen();
  			} else if (element.msRequestFullscreen) {
    			// IE11+
    			element.msRequestFullscreen();
  			}
		}
		fullScreenCancelElement.addEventListener('click', (event) => {
  			// フルスクリーンを解除する
  			myCancelFullScreen();
  			document.body.removeChild(fullScreenCancelElement);
			document.body.appendChild(fullScreenElement);
		});
		function myCancelFullScreen() {
  			if (document.exitFullscreen) {
    			// 標準仕様
				document.exitFullscreen();
  			} else if (document.webkitCancelFullScreen) {
    			// Safari, Chrome
    			document.webkitCancelFullScreen();
  			} else if (document.mozCancelFullScreen) {
    			// Firefox
    			document.mozCancelFullScreen();
  			} else if (document.msExitFullscreen) {
   				// IE 11+
    			document.msExitFullscreen();
  			}
		}
	});
}
function closeModalWindow(modalElement) {
	document.body.removeChild(modalElement)
}
modalButton.forEach((modalButtonss) => {
	modalButtonss.addEventListener('mouseenter', () => {
		modalButtonss.animate(
			mouseenterKeyframes2, mouseOption3
		);
	});
	modalButtonss.addEventListener('mouseleave', () => {
		modalButtonss.animate(
			mouseleaveKeyframes2, mouseOption3
		);
	});
});

RECOMMEND

CONTACT

Webサイト作成は、是非
CXG DESIGNへご検討ください。