如何使用纯 HTML、CSS、JS 创建 Disney+ 克隆版
视频教程
代码
您可能觉得有用的文章
大家好,今天我们将学习如何仅使用 HTML、CSS 和 JS 轻松创建迪士尼 Plus 的 UI 克隆版,无需其他库。我们还将学习如何实现无限滑动的效果。我花了 2-3 个小时来编写代码。
我们的克隆版与迪士尼+原版网站非常相似。它只有一页(首页)。它拥有与迪士尼+相同的导航栏和搜索框,点击效果也很酷炫,此外还有一个滑块或轮播,可以无限滚动或无限循环。这对我来说一开始很难做到。之后,我们还添加了电影卡片,并拥有超棒的卡片悬停效果。此外,我们还提供更多功能。
如果您想观看演示或观看包含讲解的完整编码教程视频,可以观看以下教程。
视频教程
如果您能订阅我的 YouTube 频道来支持我,我将不胜感激。
因此,不要浪费更多时间,让我们看看如何编写代码。
代码
在我们开始编写代码之前。虽然它不是一个 Node 应用,但我们至少应该了解一下它的文件夹结构。
您可以看到我们有一个名为的文件data.js
。此文件包含我们的电影滑块数据。您可以在下面看到。
let movies = [
{
name: 'falcon and the winter soldier',
des: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit porro et veniam excepturi, eaque voluptatem impedit nulla laboriosam facilis ut laboriosam libero!',
image: 'images/slider 2.PNG'
},
{
name: 'loki',
des: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit porro et veniam excepturi, eaque voluptatem impedit nulla laboriosam facilis ut laboriosam libero!',
image: 'images/slider 1.PNG'
},
{
name: 'wanda vision',
des: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Velit porro et veniam excepturi, eaque voluptatem impedit nulla laboriosam facilis ut laboriosam libero!',
image: 'images/slider 3.PNG'
},
/// and so on
]
如果您看到起始数据,您会注意到我们的数据slide-1
位于列表的第二个数字上。这是为什么呢?那是因为。我们的滑块一次会有三张幻灯片,我们希望活动幻灯片位于中心。这意味着当我们第一次从幻灯片数据开始时,我们的活动幻灯片或第一张幻灯片将位于中间。我希望这说得通。如果不通,请观看视频教程以更好地理解。
现在让我们编写网页代码。
网页。
从 开始index.html
。编写基本的 HTML 结构并链接 CSS 和 JS 文件。确保data.js
在 之前添加 file app.js
。这样我们就可以访问 file 中的数据app.js
。
现在首先创建导航栏。
<nav class="navbar">
<img src="images/logo.png" class="brand-logo" alt="">
<ul class="nav-links">
<li class="nav-items"><a href="#">TV</a></li>
<li class="nav-items"><a href="#">movies</a></li>
<li class="nav-items"><a href="#">sports</a></li>
<li class="nav-items"><a href="#">premium</a></li>
</ul>
<div class="right-container">
<input type="text" class="search-box" placeholder="search">
<button class="sub-btn">subscribe</button>
<a href="#" class="login-link">login</a>
</div>
</nav>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
width: 100%;
background: #0c111b;
position: relative;
font-family: roboto, sans-serif;
}
.navbar{
width: 100%;
height: 80px;
position: fixed;
top: 0;
left: 0;
padding: 0 4%;
background: #0c111b;
z-index: 9;
display: flex;
align-items: center;
}
.brand-logo{
height: 70px;
}
.nav-links{
margin-top: 10px;
display: flex;
list-style:none;
}
.nav-items a{
text-decoration: none;
margin-left: 20px;
text-transform: capitalize;
color: #fff;
opacity: 0.9;
}
.right-container{
display: block;
margin-left: auto;
}
.search-box{
border: none;
border-bottom: 1px solid #aaa;
background: transparent;
outline: none;
height: 30px;
color:#fff;
width: 250px;
text-transform: capitalize;
font-size: 16px;
font-weight: 500;
transition: .5s;
}
.search-box:focus{
width: 400px;
border-color: #1f80e0;
}
.sub-btn{
background: #1f80e0;
height: 30px;
padding: 0 20px;
color: #fff;
border-radius: 5px;
border: none;
outline: none;
text-transform: uppercase;
font-weight: 700;
font-size: 12px;
margin: 0 10px;
}
.login-link{
color: #fff;
opacity: 0.9;
text-transform: uppercase;
font-size: 15px;
font-weight: 700;
text-decoration: none;
}
输出
现在我们来制作滑块。我们将使用 JS 创建这些滑块,但出于样式方面的考虑,暂时先用 HTML 创建一个。
div class="carousel-container">
<div class="carousel">
<div class="slider">
<div class="slide-content">
<h1 class="movie-title">loki</h1>
<p class="movie-des">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Suscipit saepe eius ratione nostrum mollitia explicabo quae nam pariatur. Sint, odit?</p>
</div>
<img src="images/slider 1.PNG" alt="">
</div>
</div>
</div>
.carousel-container{
position: relative;
width: 100%;
height: 450px;
padding: 20px 0;
overflow-x: hidden;
margin-top: 80px;
}
.carousel{
display: flex;
width: 92%;
height: 100%;
position: relative;
margin: auto;
}
.slider{
flex: 0 0 auto;
margin-right: 30px;
position: relative;
background: rgba(0, 0, 0,0.5);
border-radius: 5px;
width: 100%;
height: 100%;
left: 0;
transition: 1s;
overflow: hidden;
}
.slider img{
width: 70%;
min-height: 100%;
object-fit: cover;
display: block;
margin-left: auto;
}
.slide-content{
position: absolute;
width: 50%;
height: 100%;
z-index: 2;
background: linear-gradient(to right, #030b17 80%, #0c111b00);
color: #fff;
}
.movie-title{
padding-left: 50px;
text-transform: capitalize;
margin-top: 80px;
}
.movie-des{
width: 80%;
line-height: 30px;
padding-left: 50px;
margin-top: 30px;
opacity: 0.8;
}
输出
现在您可以评论幻灯片了。我们已经完成了样式设置。现在
,让这个滑块可以正常工作。观看此视频,了解滑块的工作原理。
在里面app.js
。选择我们的轮播元素并创建一个空数组来存储所有幻灯片。
const carousel = document.querySelector('.carousel');
let sliders = [];
let slideIndex = 0; // to track current slide index.
现在创建一个createSlide
用于创建幻灯片的函数。
const createSlide = () => {
if(slideIndex >= movies.length){
slideIndex = 0;
}
// creating DOM element
let slide = document.createElement('div');
let imgElement = document.createElement('img');
let content = document.createElement('div');
let h1 = document.createElement('h1');
let p = document.createElement('p');
}
在这个函数中,我们首先使用slideIndex
一些 if/else 条件来增加或设置下一个值。之后,我们创建幻灯片所需的 DOM 元素。所有这些元素都与我们之前创建的完全相同index.html
。
创建所有这些元素后,将这些元素附加/附加到彼此以形成 HTML 结构。
{
// attaching all elements
imgElement.appendChild(document.createTextNode(''));
h1.appendChild(document.createTextNode(movies[slideIndex].name));
p.appendChild(document.createTextNode(movies[slideIndex].des));
content.appendChild(h1);
content.appendChild(p);
slide.appendChild(content);
slide.appendChild(imgElement);
carousel.appendChild(slide);
}
此代码位于
createSlide
函数内部。
将元素附加到一起后,现在设置它们的类名并设置图像的来源。
{
// setting up image
imgElement.src = movies[slideIndex].image;
slideIndex++;
// setting elements classname
slide.className = 'slider';
content.className = 'slide-content';
h1.className = 'movie-title';
p.className = 'movie-des';
sliders.push(slide);
}
最后记得推动slide
内部sliders
数组。
滑块创建完毕。但是滑块无法正常工作,因为我们必须将第一张滑块向左移动。为此,请在函数末尾添加以下代码。
{
if(sliders.length){
sliders[0].style.marginLeft = `calc(-${100 * (sliders.length - 2)}% - ${30 * (sliders.length - 2)}px)`;
}
}
现在,如果您创建幻灯片,您将看到我们的滑块是否正常工作。
for(let i = 0; i < 3; i++){
createSlide();
}
setInterval(() => {
createSlide();
}, 3000);
滑块部分已经制作完毕。现在开始创建视频卡。
<div class="video-card-container">
<div class="video-card">
<img src="images/disney.PNG" class="video-card-image" alt="">
<video src="videos/disney.mp4" mute loop class="card-video"></video>
</div>
<div class="video-card">
<img src="images/pixar.PNG" class="video-card-image" alt="">
<video src="videos/pixar.mp4" mute loop class="card-video"></video>
</div>
<div class="video-card">
<img src="images/marvel.PNG" class="video-card-image" alt="">
<video src="videos/marvel.mp4" mute loop class="card-video"></video>
</div>
<div class="video-card">
<img src="images/star-wars.PNG" class="video-card-image" alt="">
<video src="videos/star-war.mp4" mute loop class="card-video"></video>
</div>
<div class="video-card">
<img src="images/geographic.PNG" class="video-card-image" alt="">
<video src="videos/geographic.mp4" mute loop class="card-video"></video>
</div>
</div>
.video-card-container{
position: relative;
width: 92%;
margin: auto;
height: 10vw;
display: flex;
margin-bottom: 20px;
justify-content: space-between;
}
.video-card{
position: relative;
min-width: calc(100%/5 - 10px);
width: calc(100%/5 - 10px);
height: 100%;
border-radius: 5px;
overflow: hidden;
background: #030b17;
}
.video-card-image,
.card-video{
width: 100%;
height: 100%;
object-fit: cover;
}
.card-video{
position: absolute;
}
.video-card:hover .video-card-image{
display: none;
}
输出
/// video cards
const videoCards = [...document.querySelectorAll('.video-card')];
videoCards.forEach(item => {
item.addEventListener('mouseover', () => {
let video = item.children[1];
video.play();
})
item.addEventListener('mouseleave', () => {
let video = item.children[1];
video.pause();
})
})
此效果仅在用户首先点击您的网站时才会生效。如果用户未先点击您的页面,则由于 Google Chrome 政策,视频将无法播放。
最后,我们来制作卡片。
<h1 class="title">recommended for you</h1>
<div class="movies-list">
<button class="pre-btn"><img src="images/pre.png" alt=""></button>
<button class="nxt-btn"><img src="images/nxt.png" alt=""></button>
<div class="card-container">
<div class="card">
<img src="images/poster 1.png" class="card-img" alt="">
<div class="card-body">
<h2 class="name">movie name</h2>
<h6 class="des">Lorem ipsum dolor sit amet consectetur.</h6>
<button class="watchlist-btn">add to watchlist</button>
</div>
</div>
...20+ more cards
</div>
</div>
.. repeat this whole block 3-4 times with different card content
.title{
color: #fff;
opacity: 0.9;
padding-left: 4%;
text-transform: capitalize;
font-size: 22px;
font-weight: 500;
}
.movies-list{
width: 100%;
height: 220px;
position: relative;
margin: 10px 0 20px;
}
.card-container{
position: relative;
width: 92%;
padding-left: 10px;
height: 220px;
display: flex;
margin: 0 auto;
align-items: center;
overflow-x: auto;
overflow-y: visible;
scroll-behavior: smooth;
}
.card-container::-webkit-scrollbar{
display: none;
}
.card{
position: relative;
min-width: 150px;
width: 150px;
height: 200px;
border-radius: 5px;
overflow: hidden;
margin-right: 10px;
transition: .5s;
}
.card-img{
width: 100%;
height: 100%;
object-fit: cover;
}
.card:hover{
transform: scale(1.1);
}
.card:hover .card-body{
opacity: 1;
}
.card-body{
opacity: 0;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 2;
background: linear-gradient(to bottom, rgba(4, 8, 15, 0), #192133 90%);
padding: 10px;
transition: 0.5s;
}
.name{
color: #fff;
font-size: 15px;
font-weight: 500;
text-transform: capitalize;
margin-top: 60%;
}
.des{
color: #fff;
opacity: 0.8;
margin: 5px 0;
font-weight: 500;
font-size: 12px;
}
.watchlist-btn{
position: relative;
width: 100%;
text-transform: capitalize;
background: none;
border: none;
font-weight: 500;
text-align: right;
color: rgba(255, 255, 255, 0.5);
margin: 5px 0;
cursor: pointer;
padding: 10px 5px;
border-radius: 5px;
}
.watchlist-btn::before{
content: '';
position: absolute;
top: 0;
left: -5px;
height: 35px;
width: 35px;
background-image: url(images/add.png);
background-size: cover;
transform: scale(0.4);
}
.watchlist-btn:hover{
color: #fff;
background: rgba(255, 255, 255, 0.1);
}
.pre-btn,
.nxt-btn{
position: absolute;
top: 0;
width: 5%;
height: 100%;
z-index: 2;
border: none;
cursor: pointer;
outline: none;
}
.pre-btn{
left: 0;
background: linear-gradient(to right, #0c111b 0%, #0c111b00);
}
.nxt-btn{
right: 0;
background: linear-gradient(to left, #0c111b 0%, #0c111b00);
}
.pre-btn img,
.nxt-btn img{
width: 15px;
height: 20px;
opacity: 0;
}
.pre-btn:hover img,
.nxt-btn:hover img{
opacity: 1;
}
输出
我们快完成了。最后一步是让这个卡片滑块正常工作。为此,请app.js
再次打开。
// card sliders
let cardContainers = [...document.querySelectorAll('.card-container')];
let preBtns = [...document.querySelectorAll('.pre-btn')];
let nxtBtns = [...document.querySelectorAll('.nxt-btn')];
cardContainers.forEach((item, i) => {
let containerDimensions = item.getBoundingClientRect();
let containerWidth = containerDimensions.width;
nxtBtns[i].addEventListener('click', () => {
item.scrollLeft += containerWidth - 200;
})
preBtns[i].addEventListener('click', () => {
item.scrollLeft -= containerWidth + 200;
})
})
我们已经完成了。
好了,就是这样。希望你理解了所有内容。如果你有疑问或者我遗漏了什么,请在评论区告诉我。
您可能觉得有用的文章
如果您能订阅我的YouTube频道,我将不胜感激。我创作了非常棒的网络内容。
感谢您的阅读。
文章来源:https://dev.to/themodernweb/how-to-create-disney-plus-clone-for-beginner-in-2021-html-css-js-m3p