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

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

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

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

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

    コード

    <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
    		);
    	});
    });