前言
主打:快速获取完善开发思想。
您是否在众多文章中看到过「50projects50days」项目的详细描述?垂涎三尺了?没有时间?如果您时间有限,或者只想快速领略其中的亮点,那么您来对地方了。
50projects50days项目地址:?????
GitHub – bradtraversy/50projects50days: 50+ mini web projects using HTML, CSS & JS
简介:
想要快速领略「50projects50days」的精华,却又没有足够的时间?本文为您呈现这个项目系列的精华概览,每个项目都展示了不同的技术和创意,我们将深入剖析每个项目的关键代码和实现步骤,了解其背后的设计思想和技术原理。无论您是初学者还是有一定经验的开发者,本文都将为您提供灵感和知识,帮助您更好地理解和应用 HTML、CSS 和 JavaScript。无需大量时间投入,让我们一起探索这些项目,汲取前端技术的精华。前方的创意和知识等待着您的发现!
目录
由于篇幅问题:
上期解析 1day-5day,项目展示。
- ✅ Expanding Cards(展开卡片)
- ✅ Progress Steps(进度步骤)
- ✅ Rotating Navigation Animation(旋转导航动画)
- ✅ Hidden Search Widget(隐藏的搜索小工具)
- ✅ Blurry Loading(模糊加载)
本期解析 6day-10day,项目展示。
- ✅ Scroll Animation(滚动动画)
- ✅ Split Landing Page(拆分登录页)
- ✅ Form Input Wave(表单输入时波浪效果)
- ✅ Sound Board(声音播放按钮)
- ✅ Dad Jokes(Dad的笑话)
传送门?
- ✅ 前端创意探索:速览「50projects50days」项目精华 – 第一部分(1-5 天)
- ✅ 前端创意探索:速览「50projects50days」项目精华 – 第二部分(6-10 天)
- 前端创意探索:速览「50projects50days」项目精华 – 第三部分(11-15 天)
- 前端创意探索:速览「50projects50days」项目精华 – 第四部分(16-20 天)
- 前端创意探索:速览「50projects50days」项目精华 – 第五部分(21-25 天)
- 前端创意探索:速览「50projects50days」项目精华 – 第六部分(26-30 天)
- 前端创意探索:速览「50projects50days」项目精华 – 第七部分(31-35 天)
- 前端创意探索:速览「50projects50days」项目精华 – 第八部分(36-40 天)
- 前端创意探索:速览「50projects50days」项目精华 – 第九部分(41-45 天)
- 前端创意探索:速览「50projects50days」项目精华 – 第十部分(46-50 天)
6、Scroll Animation(滚动动画)
主要关注点:了解函数getBoundingClientRect()
实现效果:
通过滚动页面,实现方块的动画滑入效果。
实现关键代码
HTML 结构:定义方块容器和方块元素
<div class="box-container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<!-- 添加更多方块元素... -->
</div>
JavaScript 逻辑:实现面板切换的功能
const boxes = document.querySelectorAll('.box')
window.addEventListener('scroll', checkBoxes)
// 页面加载时执行一次 checkBoxes,以初始化初始状态
checkBoxes()
function checkBoxes() {
// 计算触发点的位置,通常在窗口底部的四分之一位置
const triggerBottom = window.innerHeight / 5 * 4
boxes.forEach(box => {
//该盒子离html顶部的距离
const boxTop = box.getBoundingClientRect().top
if(boxTop < triggerBottom) {
box.classList.add('show')
} else {
box.classList.remove('show')
}
})
}
实现步骤:
- 监听窗口滚动事件,当滚动发生时触发
checkBoxes
函数。 - 在
checkBoxes
函数中,计算触发点的位置,通常在窗口底部的四分之一位置。 - 利用一个函数
getBoundingClientRect()
去获取高度该方块到上部的距离
- 对每个方块,获取其相对于视口的位置,如果其顶部位置小于触发点位置,就为方块添加
show
类,使其滑入显示。 - 如果方块的顶部位置大于触发点位置,就移除
show
类,隐藏方块。
CSS样式
?容器样式:使用 Flex 布局、圆角和阴影
/* 容器样式:使用 Flex 布局、圆角和阴影 */
.box-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
margin-top: 100px;
}
?方块样式:定义方块的基本样式、动画效果和展示效果
.box {
background-color: steelblue;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
width: 400px;
height: 200px;
margin: 10px;
border-radius: 10px;
box-shadow: 2px 4px 5px rgba(0, 0, 0, 0.3);
transform: translateX(400%);
transition: transform 0.4s ease;
}
.box:nth-of-type(even) {
transform: translateX(-400%);
}
/* 添加 show 类时的样式,实现方块滑入效果 */
.box.show {
transform: translateX(0);
}
总结:
该实例通过监听滚动事件,而利用一个函数getBoundingClientRect()
去获取高度该方块到上部的距离,根据方块位置的相对视口位置来决定是否添加展示效果的类,方块的滑入效果是通过添加或移除类来实现的,从而实现了简单的滚动动画效果。
7、Split Landing Page(拆分登录页)
主要关注点:CSS 分割布局、交互动画。
实现效果:
左右分割的页面,鼠标悬停在左右两边时,会展开对应一侧的背景,同时按钮的颜色也会变化。
实现关键代码
HTML 结构:分割容器,左右两侧内容
<div class="container">
<div class="split left">
<h1>Playstation 5</h1>
<a href="#" class="btn">Buy Now</a>
</div>
<div class="split right">
<h1>XBox Series X</h1>
<a href="#" class="btn">Buy Now</a>
</div>
</div>
JavaScript 逻辑:监听鼠标进入和离开事件,添加或移除类来实现背景展开效果
const left = document.querySelector('.left')
const right = document.querySelector('.right')
const container = document.querySelector('.container')
left.addEventListener('mouseenter', () => container.classList.add('hover-left'))
left.addEventListener('mouseleave', () => container.classList.remove('hover-left'))
right.addEventListener('mouseenter', () => container.classList.add('hover-right'))
right.addEventListener('mouseleave', () => container.classList.remove('hover-right'))
实现步骤:
- 获取
left
与right
的标签 - 对标签进行监听鼠标的移入还是移出事件
CSS样式
? 根变量:定义颜色、宽度和动画速度
为什么专门提起这个,因为算是一个知识点,根元素变量的引用(再内容样式中)
:root {
--left-bg-color: rgba(87, 84, 236, 0.7);
--right-bg-color: rgba(43, 43, 43, 0.8);
--left-btn-hover-color: rgba(87, 84, 236, 1);
--right-btn-hover-color: rgba(28, 122, 28, 1);
--hover-width: 75%;
--other-width: 25%;
--speed: 1000ms;
}
?容器样式:设置盒模型、字体、背景、滚动隐藏
* {
box-sizing: border-box;
}
.container {
position: relative;
width: 100%;
height: 100%;
background: #333;
}
?内容样式:定义标题和按钮样式
.split {
/* 分割区域样式 */
position: absolute;
width: 50%;
height: 100%;
overflow: hidden;
}
/**其他的定义...... **/
.split.left {
left: 0;
background: url('ps.jpg');
background-repeat: no-repeat;
background-size: cover;
}
/**其他的定义...... **/
.split.right,
.split.left,
.split.right::before,
.split.left::before {
transition: all var(--speed) ease-in-out;
}
/**其他的定义...... **/
.hover-left .left {
width: var(--hover-width);
}
.hover-left .right {
width: var(--other-width);
}
.hover-right .right {
width: var(--hover-width);
}
.hover-right .left {
width: var(--other-width);
}
根变量:--hover-width
为 75%
,--other-width
为 25%
.
鼠标移动到left
上的区域,被添加了hover-left
类,left
宽度占比就是75%
,right
宽度占比就是25%
,同理right
的被添加了hover-right
类,right
宽度占比就是75%
,left
宽度占比就是25%
,利用动画,实现了上述功能。
总结:
这个项目通过 CSS 和少量的 JavaScript 代码,实现了一个引人注目的分割式落地页。采用监听鼠标的移入移出添加移除hover-left
或者hover-right
利用过渡动画和背景图片,实现挤占的效果,创造了吸引人的页面效果。通过根变量的使用,使得样式调整变得更加便捷。同时,响应式设计也使页面在不同屏幕尺寸下保持了良好的可视性
8、Form Input Wave(表单输入时波浪效果)
主要关注点:JS操作类的删除与添加与transition
的延迟效果。
实现效果:
通过使用 CSS 和 JavaScript ,在表单的输入框和标签上添加波浪效果,使得标签在输入框获得焦点或输入框内有内容时上移和变色,以提升表单的交互体验。
实现关键代码
HTML 结构:定义表单输入和标签元素
这个是实现的表单
<div class="container">
<h1>Please Login</h1>
<form>
<div class="form-control">
<input type="text" required>
<label>Email</label>
</div>
<div class="form-control">
<input type="password" required>
<label>Password</label>
</div>
<button class="btn">Login</button>
<p class="text">Don't have an account? <a href="#">Register</a> </p>
</form>
</div>
JavaScript 逻辑:为输入框标签创建波浪效果
// `'.form-control label'`可以直接选中label像极了css选择器
const labels = document.querySelectorAll('.form-control label')
labels.forEach(label => {
label.innerHTML = label.innerText
.split('') //对字节切成数组-》对数组进行字符段拼接-》对拼接好的进行join连接
.map((letter, idx) => `<span style="transition-delay:${idx * 50}ms">${letter}</span>`)
.join('')
})
使用 js
创造的表单 label
的内容:主要就是延迟
<label>
<span style="transition-delay: 0ms">E</span>
<span style="transition-delay: 50ms">m</span>
<span style="transition-delay: 100ms">a</span>
<span style="transition-delay: 150ms">i</span>
<span style="transition-delay: 200ms">l</span>
</label>
实现步骤:
- 在HTML中,创建一个登录表单,包括邮箱输入框、密码输入框和登录按钮。
- 在CSS中,使用
:focus
和:valid
选择器定义输入框和标签的样式,以及动画过渡效果。 - 在JavaScript中,遍历每个输入框的标签,为每个字母创建带有延迟的
span
元素,以实现标签的波浪效果。 - 通过添加和删除CSS类,实现按钮点击时的缩放效果。
- 使用响应式设计,确保在不同屏幕尺寸下页面显示效果良好。
CSS样式
?容器样式:使用定位布局
.form-control {
position: relative;
margin: 20px 0 40px;
width: 300px;
}
?面板样式:定义输入框和标签的基本样式和弹性属性
.form-control label {
position: absolute;
top: 15px;
left: 0;
pointer-events: none;
}
.form-control label span {
display: inline-block;
font-size: 18px;
min-width: 5px;
transition: 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
.form-control input:focus + label span,
.form-control input:valid + label span {
color: lightblue;
transform: translateY(-30px);
}
总结:
这个项目通过 CSS 和 JavaScript 创造了一个独特的表单输入波浪效果,使得用户在填写表单时有更好的交互体验,实现方法主要使用 transition
的 transition-delay
的延迟效果,在容器使用相对定位 relative
,字体绝对定位 absolute
到 input 中,点击聚焦 input 的时候,开始运行 transform: translateY(-30px)
的移动。
标签的波浪动画和输入框的样式变化为表单添加了生动感,而按钮的缩放效果则增强了用户操作的可感知性。响应式设计也确保了页面在不同设备上的合适显示
扩展:
-
transform
中的cubic-bezier
CSS cubic-bezier() 函数 算是自定义时
间实现效果关于我如何使用cubic-bezier的。
文中给span使用
transition: 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
-
input:valid
是一种校验的判断.form-control input:valid + label span{ color: rgb(255, 0, 106); transform: translateY(-30px); }
效果展示
9、Sound Board(声音播放按钮)
主要关注点:JavaScript 播放音频的逻辑。
实现效果:
通过一组按钮实现不同声音的播放,类似于声音面板。点击按钮将播放相应的音频,同时确保只有一个音频在播放时。
实现关键代码
HTML 结构:定义音频元素和按钮容器
<audio id="applause" src="sounds/applause.mp3"></audio>
<audio id="boo" src="sounds/boo.mp3"></audio>
<audio id="gasp" src="sounds/gasp.mp3"></audio>
<audio id="tada" src="sounds/tada.mp3"></audio>
<audio id="victory" src="sounds/victory.mp3"></audio>
<audio id="wrong" src="sounds/wrong.mp3"></audio>
<!--JS的操作就添加到button的节点中-->
<div id="buttons"></div>
JavaScript 逻辑:为按钮添加点击事件,控制音频播放和停止
const sounds = ['applause', 'boo', 'gasp', 'tada', 'victory', 'wrong']
sounds.forEach(sound => {
const btn = document.createElement('button')
btn.classList.add('btn') //这个是创建的class,在css中给与名字与样式
btn.innerText = sound //添加了button的内容
// 为按钮添加点击事件
btn.addEventListener('click', () => {
// 停止所有正在播放的声音
stopSongs()
// 播放当前按钮对应的声音
document.getElementById(sound).play()
})
//添加到buttons中
document.getElementById('buttons').appendChild(btn)
})
// 停止所有正在播放的声音
function stopSongs() {
sounds.forEach(sound => {
const song = document.getElementById(sound)
song.pause()
song.currentTime = 0;
})
}
实现步骤:
- 在HTML中,创建一组音频元素,每个元素对应一个按钮。为每个音频元素设置唯一的ID,并引用对应的音频文件。
- 在JavaScript中,使用循环遍历声音数组,并为每个声音创建一个按钮。为按钮添加点击事件,使其在点击时播放相应的音频。
- 创建一个函数
stopSongs()
,用于停止所有正在播放的音频,并将播放进度归零。 - 在CSS中,定义按钮的样式,包括颜色、边框、字体等。为按钮的hover效果添加透明度。
- 使用响应式设计,确保在不同屏幕尺寸下页面显示效果良好。
CSS样式
?按钮样式:设置按钮的基本样式
.btn {
background-color: rebeccapurple;
border-radius: 5px;
border: none;
color: #fff;
margin: 1rem;
padding: 1.5rem 3rem;
font-size: 1.2rem;
font-family: inherit;
cursor: pointer;
}
?按钮悬停样式:定义按钮悬停时的透明度
.btn:hover {
opacity: 0.9;
}
.btn:focus {
outline: none;
}
总结:
本项目通过创建一组按钮,每个按钮对应一个声音,实现了声音播放的效果。注意 audio
标签,是没有宽高大小的,利用 JS 逻辑,使用 id
属性,进行控制,播放与暂停。点击按钮会播放相应的音频,通过控制播放状态和播放进度,确保同一时间只有一个声音在播放。按钮样式的设计增加了页面的交互性,悬停效果提供了用户点击按钮的视觉反馈。响应式设计使得页面在不同设备上显示效果良好。
10、Dad Jokes(Dad的笑话)
主要关注点:使用 Fetch API 获取数据并更新页面内容
实现效果:
通过点击按钮,从外部API获取爸爸笑话,并将其显示在页面上。笑话内容会在点击按钮时更新。
实现关键代码
HTML 结构:定义笑话显示区域和按钮
<div class="container">
<h3>Don't Laugh Challenge</h3>
<div id="joke" class="joke">// Joke goes here</div>
<button id="jokeBtn" class="btn">Get Another Joke</button>
</div>
JavaScript 逻辑:使用 Fetch API 获取笑话数据并更新页面内容
// 获取笑话元素和按钮元素
const jokeEl = document.getElementById('joke')
const jokeBtn = document.getElementById('jokeBtn')
// 为按钮添加点击事件,触发获取笑话函数
jokeBtn.addEventListener('click', generateJoke)
// 初始化页面,显示初始笑话
generateJoke()
// 使用 async/await 获取笑话数据并更新页面
async function generateJoke() {
const config = {
headers: {
Accept: 'application/json',
},
}
const res = await fetch('https://icanhazdadjoke.com', config)
const data = await res.json()
jokeEl.innerHTML = data.joke
}
实现步骤:
- 在HTML中,创建笑话显示区域和获取笑话的按钮。
- 在JavaScript中,获取笑话元素和按钮元素,为按钮添加点击事件。点击按钮时,调用
generateJoke()
函数获取笑话数据并更新页面内容。 - 使用 Fetch API 发送请求到外部API,使用
await
关键字等待数据返回,然后将获取的笑话内容更新到笑话元素中。 - 在CSS中,定义页面容器和按钮的样式,包括背景色、边框、字体等。
- 增加悬停效果和点击效果,提供按钮交互性。
CSS样式
?页面容器样式:设置容器的基本样式
/* 页面容器的基本样式 */
.container {
background-color: #fff;
border-radius: 10px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1), 0 6px 6px rgba(0, 0, 0, 0.1);
padding: 50px 20px;
text-align: center;
max-width: 100%; /*通过max-width的优先级,压过了width*/
width: 800px; /*一开始定死*/
}
?按钮样式:定义按钮的基本样式和悬停效果
/* 按钮的基本样式 */
.btn {
background-color: #9f68e0;
color: #fff;
border: 0;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1), 0 6px 6px rgba(0, 0, 0, 0.1);
padding: 14px 40px;
font-size: 16px;
cursor: pointer;
}
/* 按钮悬停时的样式 */
.btn:hover {
opacity: 0.9;
}
总结:
本项目通过使用 Fetch API
获取外部API
中的笑话数据,并将其更新到页面上的笑话元素中,实现了动态获取和显示笑话的效果。使用 async/await
简化了异步请求的处理,提高了代码的可读性和可维护性。页面容器和按钮的样式设计增强了页面的可视化效果,增加了页面的交互性。
有注意到CSS的效果了?
- 开始时,容器的宽度是固定的,后面会随着屏幕缩放而自由调整。
- 在
body
上使用padding
来分割最后的隔离防线,创造了页面的边界。 - 当容器很宽时,使用
width: 800px
限制宽度,不能再更宽。而当缩小屏幕时,使用max-width
设置为100%,确保容器随屏幕缩放而自适应,这是因为max-width
的优先级大于width
,所以在缩小的情况下,实际宽度会受到max-width
的限制. - 合并一下,就是
max-width: 800px
。
?预知后事如何,待下回分解