- 逼真的翻页动画:使用 CSS 3D 变换和 JavaScript 实现类似真实书页的翻动效果。
- 鼠标交互:点击页角进行翻页。
- 键盘导航:使用左右方向键翻页。
- 导航控制:首页、上一页、下一页、末页按钮。
- 进度条:直观地显示当前阅读进度。
- 响应式设计:在不同屏幕尺寸上都能良好显示。
最终效果预览
第一步:HTML 结构 (index.html)
这是页面的骨架,定义了书的容器、页面、导航控件等。

(图片来源网络,侵删)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">电子书翻页效果</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="book-container">
<!-- 书的封面 -->
<div class="book-cover">
<h1>我的电子书</h1>
<p>作者:前端小能手</p>
</div>
<!-- 书的页面容器 -->
<div class="book">
<!-- 左页 -->
<div class="page" id="page1">
<div class="page-content">
<h2>第一章:开始</h2>
<p>欢迎来到这本神奇的电子书,您将体验到前所未有的阅读乐趣。</p>
<p>请点击右下角或使用键盘方向键开始您的旅程。</p>
</div>
</div>
<!-- 右页 -->
<div class="page" id="page2">
<div class="page-content">
<h2>第一章:开始 (续)</h2>
<p>每一页都充满了智慧与想象,翻页的不仅是纸张,更是知识的边界。</p>
<p>愿您在这本书中找到属于自己的故事。</p>
</div>
</div>
<!-- 后续页面 -->
<div class="page" id="page3">
<div class="page-content">
<h2>第二章:探索</h2>
<p>第二章的内容即将展开,准备好迎接新的挑战和发现了吗?</p>
</div>
</div>
<div class="page" id="page4">
<div class="page-content">
<h2>第二章:探索 (续)</h2>
<p>探索的道路永无止境,知识的大门正为您缓缓打开。</p>
</div>
</div>
<div class="page" id="page5">
<div class="page-content">
<h2>第三章:收获</h2>
<p>恭喜您!您已经读完了这本精心制作的电子书模板。</p>
<p>希望这个效果能给您带来启发。</p>
</div>
</div>
</div>
<!-- 导航控件 -->
<div class="book-controls">
<button id="firstPage" title="首页">首页</button>
<button id="prevPage" title="上一页">上一页</button>
<div class="page-info">
<span id="currentPage">1</span> / <span id="totalPages">3</span>
</div>
<button id="nextPage" title="下一页">下一页</button>
<button id="lastPage" title="末页">末页</button>
</div>
<!-- 进度条 -->
<div class="progress-bar">
<div class="progress-fill"></div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
第二步:CSS 样式 (style.css)
这是模板的核心,负责所有的视觉呈现和3D动画效果。
/* 基础样式和重置 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Georgia', serif;
background-color: #f4f4f4;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
color: #333;
}
/* 书的容器 */
.book-container {
position: relative;
width: 90%;
max-width: 800px;
height: 600px;
perspective: 2000px; /* 3D效果的透视距离 */
}
/* 书的封面和整体 */
.book-cover, .book {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
transform-style: preserve-3d; /* 保持子元素的3D变换 */
transition: transform 1s ease-in-out;
}
/* 书本封面样式 */
.book-cover {
background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
color: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
z-index: 1;
backface-visibility: hidden;
}
.book-cover h1 {
font-size: 3em;
margin-bottom: 10px;
}
.book-cover p {
font-size: 1.2em;
}
/* 书本主体样式 */
.book {
background-color: #fff;
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
transform-origin: left center; /* 翻转时的轴心点 */
z-index: 0;
}
/* 单页样式 */
.page {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
padding: 40px;
background-color: #fdfdfd;
border-radius: 10px;
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1);
backface-visibility: hidden; /* 隐藏背面,防止闪烁 */
transform-style: preserve-3d;
transform-origin: left center;
transition: transform 1.2s cubic-bezier(0.645, 0.045, 0.355, 1); /* 自定义贝塞尔曲线,模拟翻页 */
}
*/
.page-content {
height: 100%;
padding: 20px;
overflow-y: auto; /* 内容过长时滚动 */
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="100" height="100" fill="none" stroke="%23e0e0e0" stroke-width="0.5"/></svg>');
background-size: 20px 20px;
}
.page-content h2 {
margin-bottom: 20px;
color: #2c3e50;
}
.page-content p {
line-height: 1.8;
margin-bottom: 15px;
text-align: justify;
}
/* 翻页动画类 */
/* 向右翻页(当前页) */
.flipping-right {
transform: rotateY(-180deg);
}
/* 向左翻页(下一页) */
.flipping-left {
transform: rotateY(180deg);
}
/* 导航控件 */
.book-controls {
position: absolute;
bottom: -60px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 10px;
align-items: center;
background-color: rgba(255, 255, 255, 0.9);
padding: 10px 20px;
border-radius: 30px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
}
.book-controls button {
background-color: #3498db;
color: white;
border: none;
padding: 8px 15px;
border-radius: 20px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.3s;
}
.book-controls button:hover {
background-color: #2980b9;
}
.book-controls button:disabled {
background-color: #bdc3c7;
cursor: not-allowed;
}
.page-info {
font-size: 16px;
font-weight: bold;
color: #2c3e50;
min-width: 60px;
text-align: center;
}
/* 进度条 */
.progress-bar {
position: absolute;
bottom: -90px;
left: 50%;
transform: translateX(-50%);
width: 80%;
height: 8px;
background-color: #ecf0f1;
border-radius: 4px;
overflow: hidden;
}
.progress-fill {
height: 100%;
width: 0%;
background: linear-gradient(90deg, #3498db, #2ecc71);
border-radius: 4px;
transition: width 0.5s ease-in-out;
}
/* 响应式设计 */
@media (max-width: 768px) {
.book-container {
height: 500px;
}
.page-content {
padding: 20px;
}
.book-controls {
bottom: -70px;
padding: 8px 15px;
gap: 8px;
}
.book-controls button {
padding: 6px 12px;
font-size: 12px;
}
.page-info {
font-size: 14px;
}
}
第三步:JavaScript 逻辑 (script.js)
这是模板的大脑,处理用户交互、页面状态管理和动画触发。
document.addEventListener('DOMContentLoaded', () => {
const book = document.querySelector('.book');
const pages = document.querySelectorAll('.page');
const totalPages = pages.length;
const currentPageSpan = document.getElementById('currentPage');
const totalPagesSpan = document.getElementById('totalPages');
const progressFill = document.querySelector('.progress-fill');
// 控制按钮
const firstPageBtn = document.getElementById('firstPage');
const prevPageBtn = document.getElementById('prevPage');
const nextPageBtn = document.getElementById('nextPage');
const lastPageBtn = document.getElementById('lastPage');
let currentPage = 1; // 当前显示的页码(从1开始)
// 初始化
totalPagesSpan.textContent = totalPages;
updatePage();
// 更新页面状态(UI、按钮状态、进度条)
function updatePage() {
currentPageSpan.textContent = currentPage;
progressFill.style.width = `${(currentPage / totalPages) * 100}%`;
// 更新按钮状态
prevPageBtn.disabled = currentPage === 1;
firstPageBtn.disabled = currentPage === 1;
nextPageBtn.disabled = currentPage === totalPages;
lastPageBtn.disabled = currentPage === totalPages;
// 重置所有页面的动画类
pages.forEach(page => {
page.classList.remove('flipping-right', 'flipping-left');
});
}
// 翻到指定页码
function goToPage(pageNumber) {
if (pageNumber < 1 || pageNumber > totalPages || pageNumber === currentPage) {
return;
}
const direction = pageNumber > currentPage ? 'right' : 'left';
const pagesToFlip = Math.abs(pageNumber - currentPage);
for (let i = 0; i < pagesToFlip; i++) {
const pageTurn = currentPage + (direction === 'right' ? i : -i);
if (pageTurn >= 1 && pageTurn <= totalPages) {
const page = document.getElementById(`page${pageTurn}`);
if (direction === 'right') {
page.classList.add('flipping-right');
} else {
page.classList.add('flipping-left');
}
}
}
currentPage = pageNumber;
updatePage();
}
// 事件监听器
firstPageBtn.addEventListener('click', () => goToPage(1));
prevPageBtn.addEventListener('click', () => goToPage(currentPage - 1));
nextPageBtn.addEventListener('click', () => goToPage(currentPage + 1));
lastPageBtn.addEventListener('click', () => goToPage(totalPages));
// 键盘导航
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowLeft') {
goToPage(currentPage - 1);
} else if (e.key === 'ArrowRight') {
goToPage(currentPage + 1);
}
});
// 点击页面翻页(点击右半部分向右翻,左半部分向左翻)
book.addEventListener('click', (e) => {
const rect = book.getBoundingClientRect();
const clickX = e.clientX - rect.left;
const clickWidth = rect.width;
// 点击右半部分
if (clickX > clickWidth / 2 && currentPage < totalPages) {
goToPage(currentPage + 1);
}
// 点击左半部分
else if (clickX <= clickWidth / 2 && currentPage > 1) {
goToPage(currentPage - 1);
}
});
});
如何使用这个模板
- 创建文件:在你的项目文件夹中创建三个文件:
index.html、style.css和script.js。 - 复制代码:将上面提供的代码分别复制到对应的文件中。
- 打开浏览器:用浏览器打开
index.html文件,你就能看到电子书的翻页效果了。
如何自定义和扩展
- :直接编辑
index.html文件中.page-content内的 HTML 和文字即可。 - 添加更多页面:在
.book容器内复制.pagediv,并递增其id(如page6,page7),在script.js中,totalPages的值会自动更新,无需手动修改。 - 改变样式:修改
style.css文件中的颜色、字体、阴影等属性,以匹配你的设计风格。 - 调整动画:在
style.css中修改transition属性的duration(持续时间)和timing-function(缓动函数),可以改变翻页的速度和感觉。 - 封面图片:你可以为
.book-cover添加一个背景图片,只需在 CSS 中设置background-image: url('your-image.jpg');即可。
这个模板提供了一个坚实的基础,你可以基于它进行二次开发,添加更多高级功能,如目录跳转、书签、夜间模式等。

(图片来源网络,侵删)
