531 lines
18 KiB
JavaScript
531 lines
18 KiB
JavaScript
(function (win) {
|
|
// 初始化样式和方法
|
|
|
|
console.log("courseHomeStyle init", win, win.location.href,);
|
|
|
|
if (win.location.href.indexOf("courseHome.html") !== -1) {
|
|
// 1、导航条切换
|
|
initNav();
|
|
|
|
// 2、左 侧边栏
|
|
initSidebar();
|
|
|
|
// 3、按钮样式
|
|
// 初始化增强的按钮效果
|
|
initEnhancedButtonEffects();
|
|
|
|
// 简化问题文本动画
|
|
simplifyQuestionAnimation();
|
|
} else if (win.location.href.indexOf("courseHomeBarrierFree.html") !== -1) {
|
|
// 1、导航条切换
|
|
initNav();
|
|
|
|
// 2、左 侧边栏
|
|
initSidebarBarrier();
|
|
}
|
|
|
|
})(window);
|
|
|
|
// 1、导航条切换
|
|
function initNav() {
|
|
$(".container-header-nav > div").each(function (index) {
|
|
$(this).on("click", function () {
|
|
$(".container-header-nav > div").removeClass("active");
|
|
$(this).addClass("active");
|
|
window.open(`./${$(this).data("url")}.html`);
|
|
|
|
// console.log("this", this, $(this));
|
|
// $(".container-header-nav > div").eq(index).addClass("active");
|
|
});
|
|
});
|
|
}
|
|
|
|
// 2、侧边栏
|
|
function initSidebar() {
|
|
if (
|
|
window &&
|
|
window.GLOBAL_CONFIG &&
|
|
window.GLOBAL_CONFIG.courseList
|
|
) {
|
|
// 从路由获取当前课程信息 courseHome.html?id=l01
|
|
const id = window.location.search.replace("?id=", "") || "m2x04";
|
|
const type = {
|
|
l: "live",
|
|
c: "language",
|
|
m: "math",
|
|
}[id[0]];
|
|
const courseList = window.GLOBAL_CONFIG.courseList[type];
|
|
|
|
const iconList = {
|
|
"course": "📺",
|
|
"video": "🤼♂️",
|
|
"play": "🎮",
|
|
};
|
|
|
|
// console.log("initSidebar", id, type, courseList);
|
|
|
|
$(".container-main-sidebar .directory-list").empty();
|
|
let dom = `<ul class="directory-list">`;
|
|
|
|
courseList.map((grade, gradeI) => {
|
|
grade.map((progress, progressI) => {
|
|
dom = `${dom}
|
|
<li class="grade-item">
|
|
<div class="grade-title">
|
|
<span>${gradeI + 1}年级 <span>${"上下"[progressI]}册</span></span>
|
|
<span class="arrow">▶</span>
|
|
</div>
|
|
`;
|
|
|
|
if (progress) {
|
|
dom = `${dom} <ul class="chapter-list">`;
|
|
|
|
progress.map((chapter, chapterI) => {
|
|
|
|
dom = `${dom}
|
|
<li class="chapter-item">
|
|
<div class="chapter-title" data-id="${chapter.id}" >
|
|
<span>第${chapterI + 1}章 ${chapter.name}</span>
|
|
<span class="arrow">▶</span>
|
|
</div>
|
|
`;
|
|
|
|
if (chapter.list) {
|
|
dom = `${dom} <ul class="section-list">`;
|
|
|
|
chapter.list.map((section, sectionI) => {
|
|
|
|
if (sectionI == 0) {
|
|
dom = `${dom}
|
|
<div>- 课堂教学 -</div>
|
|
`;
|
|
}
|
|
else if (
|
|
sectionI > 0 &&
|
|
chapter.list[sectionI - 1].type == "course" &&
|
|
section.type == "video"
|
|
) {
|
|
dom = `${dom}
|
|
<div>- 课堂互动 -</div>
|
|
`;
|
|
}
|
|
else if (
|
|
sectionI > 0 &&
|
|
(chapter.list[sectionI - 1].type == "video" || sectionI == 1) &&
|
|
section.type == "play"
|
|
) {
|
|
dom = `${dom}
|
|
<div>- 趣味游戏 -</div>
|
|
`;
|
|
}
|
|
|
|
dom = `${dom}
|
|
<li class="section-item">
|
|
<div
|
|
class="section-title"
|
|
onclick="sectionClick(event)"
|
|
data-info='${JSON.stringify(section)}'
|
|
>
|
|
<span>${iconList[section.type]}</span>
|
|
${section.title}
|
|
</div>
|
|
</li>
|
|
`;
|
|
});
|
|
|
|
dom = `${dom} </ul>`;
|
|
};
|
|
|
|
dom = `${dom} </li>`;
|
|
});
|
|
|
|
dom = `${dom} </ul>`;
|
|
}
|
|
|
|
dom = `${dom} </li>`;
|
|
})
|
|
});
|
|
|
|
dom = `${dom} </ul>`;
|
|
$(".container-main-sidebar .directory-list").append(dom);
|
|
|
|
initSidebarEvent();
|
|
}
|
|
}
|
|
|
|
// 2、侧边栏 无障碍版本
|
|
function initSidebarBarrier() {
|
|
if (
|
|
window &&
|
|
window.GLOBAL_CONFIG &&
|
|
window.GLOBAL_CONFIG.playList
|
|
) {
|
|
let playList = window.GLOBAL_CONFIG.playList;
|
|
|
|
const typeName = {
|
|
"live": "生活",
|
|
"language": "语文",
|
|
"math": "数学",
|
|
};
|
|
|
|
$(".container-main-sidebar .directory-list").empty();
|
|
let dom = `<ul class="directory-list">`;
|
|
|
|
Object.entries(playList).map((value, valueI) => {
|
|
// console.log("initSidebarBarrier", value);
|
|
|
|
dom = `${dom}
|
|
<div
|
|
class="type-item"
|
|
aria-label="${typeName[value[0]]}课程"
|
|
onmouseenter="debouncedSpeechDomTextBarrier(event)"
|
|
onmouseout="debouncedSpeechDomTextBarrier(event)"
|
|
>
|
|
- ${typeName[value[0]]} -
|
|
</div>`;
|
|
|
|
value[1].map((play, playI) => {
|
|
dom = `${dom}
|
|
<li class="grade-item">
|
|
<div
|
|
class="grade-title"
|
|
aria-label="${typeName[value[0]]}课程中的${play.title}游戏"
|
|
onmouseenter="debouncedSpeechDomTextBarrierGame(event)"
|
|
onmouseout="debouncedSpeechDomTextBarrierGame(event)"
|
|
data-info='${JSON.stringify(play)}'
|
|
>
|
|
${play.title}
|
|
</div>
|
|
</li>
|
|
`;
|
|
});
|
|
});
|
|
|
|
dom = `${dom} </ul>`;
|
|
$(".container-main-sidebar .directory-list").append(dom);
|
|
|
|
// 年级点击事件
|
|
$(".container-main-sidebar .grade-title").click(function (event) {
|
|
|
|
// console.log(".container-main-sidebar .grade-title click", this, event);
|
|
|
|
if (
|
|
event &&
|
|
event.target &&
|
|
event.target.dataset &&
|
|
event.target.dataset.info
|
|
) {
|
|
const info = JSON.parse(event.target.dataset.info);
|
|
let mainPlay = document.getElementById("mainPlay");
|
|
mainPlay.src = info.url;
|
|
}
|
|
|
|
// 移除所有active类
|
|
$(".container-main-sidebar .grade-title").removeClass("active");
|
|
|
|
// 为当前点击的添加active类
|
|
$(this).addClass("active");
|
|
|
|
});
|
|
}
|
|
}
|
|
|
|
// 2、侧边栏 事件
|
|
function initSidebarEvent() {
|
|
// 年级点击事件
|
|
$(".container-main-sidebar .grade-title").click(function () {
|
|
$(this).parent().toggleClass("active");
|
|
});
|
|
|
|
// 章节点击事件
|
|
$(".container-main-sidebar .chapter-title").click(function (e) {
|
|
e.stopPropagation(); // 阻止事件冒泡到年级标题
|
|
$(this).parent().toggleClass("active");
|
|
});
|
|
|
|
// 小节点击事件
|
|
$(".container-main-sidebar .section-title").click(function (e) {
|
|
e.stopPropagation();
|
|
|
|
// 移除所有active类
|
|
$(".container-main-sidebar .section-title").removeClass("active");
|
|
|
|
// 为当前点击的添加active类
|
|
$(this).addClass("active");
|
|
});
|
|
|
|
$(".container-main .sidebar-circle").click(function (e) {
|
|
// 是否隐藏了
|
|
const isShow = !$(".container-main-sidebar").hasClass("hidden");
|
|
// console.log(".sidebar-circle", e, this, isShow);
|
|
$(".container-main-sidebar").toggleClass("hidden");
|
|
|
|
if (isShow) {
|
|
$(".container-main-sidebar").css("width", "0px");
|
|
$(this).css("left", "0px");
|
|
$(this).text("▶");
|
|
$(".container-main-course").css("width", "100%");
|
|
} else {
|
|
$(".container-main-sidebar").css("width", "var(--sidebar-width)");
|
|
$(this).css("left", "var(--sidebar-width)");
|
|
$(this).text("◀");
|
|
$(".container-main-course").css("width", "calc(100vw - var(--sidebar-width) - 30px)");
|
|
}
|
|
});
|
|
}
|
|
|
|
// 控制功能按钮的展示隐藏 course-operation
|
|
function showOperationDom() {
|
|
$(".course-operation").toggleClass("show");
|
|
}
|
|
|
|
// 初始化所有增强的按钮效果
|
|
function initEnhancedButtonEffects() {
|
|
// 首先解除所有现有的事件绑定,避免重复
|
|
$('.box-btn-left, .box-btn-right').off();
|
|
|
|
// 按钮悬停基本效果
|
|
$('.box-btn-left, .box-btn-right').hover(
|
|
function () {
|
|
const button = $(this);
|
|
|
|
// 添加文字缩放动画
|
|
button.find('.btn-text').css({
|
|
'animation': 'text-pop 0.8s ease infinite alternate'
|
|
});
|
|
|
|
// 添加粒子效果
|
|
addButtonParticles(button);
|
|
|
|
// 添加3D变换效果
|
|
button.addClass('btn-hover-active');
|
|
},
|
|
function () {
|
|
const button = $(this);
|
|
|
|
// 移除文字动画
|
|
button.find('.btn-text').css({
|
|
'animation': 'none'
|
|
});
|
|
|
|
// 移除粒子
|
|
removeButtonParticles();
|
|
|
|
// 移除3D效果
|
|
button.removeClass('btn-hover-active');
|
|
}
|
|
);
|
|
|
|
// 添加3D移动效果
|
|
$('.box-btn-left, .box-btn-right').on('mousemove', function (e) {
|
|
const button = $(this);
|
|
|
|
// 只有在悬停状态才应用3D效果
|
|
if (button.hasClass('btn-hover-active')) {
|
|
const buttonRect = button[0].getBoundingClientRect();
|
|
|
|
// 计算鼠标在按钮上的相对位置 (-1 到 1 的范围)
|
|
const x = ((e.clientX - buttonRect.left) / buttonRect.width) * 2 - 1;
|
|
const y = ((e.clientY - buttonRect.top) / buttonRect.height) * 2 - 1;
|
|
|
|
// 根据鼠标位置应用3D旋转
|
|
button.css({
|
|
'transform': `translateY(-50%) scale(1.15) rotateX(${-y * 15}deg) rotateY(${x * 15}deg)`,
|
|
'transition': 'transform 0.1s ease'
|
|
});
|
|
}
|
|
});
|
|
|
|
// 鼠标离开时恢复原始状态
|
|
$('.box-btn-left, .box-btn-right').on('mouseleave', function () {
|
|
$(this).css({
|
|
'transform': 'translateY(-50%)',
|
|
'transition': 'transform 0.5s ease'
|
|
});
|
|
});
|
|
|
|
// 添加按钮动画样式
|
|
addButtonAnimationStyles();
|
|
}
|
|
|
|
// 简化问题文本动画
|
|
function simplifyQuestionAnimation() {
|
|
// DOMSubtreeModified MutationObserver
|
|
$('.box-btn-question').on('MutationObserver', function () {
|
|
const question = $(this);
|
|
const text = question.text().trim();
|
|
|
|
if (text.length > 0 && !question.hasClass('animated-question')) {
|
|
question.addClass('animated-question');
|
|
question.css('opacity', '0');
|
|
|
|
setTimeout(function () {
|
|
// 添加有趣的表情符号
|
|
if (!text.includes('🤔')) {
|
|
question.html('🤔 ' + text);
|
|
}
|
|
|
|
question.css({
|
|
'opacity': '1',
|
|
'transform': 'translate(-50%, -65%) scale(1.1)',
|
|
'transition': 'all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275)'
|
|
});
|
|
|
|
setTimeout(function () {
|
|
question.css({
|
|
'transform': 'translate(-50%, -50%) scale(1)',
|
|
'transition': 'all 0.4s ease'
|
|
});
|
|
}, 500);
|
|
}, 100);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 添加按钮动画样式
|
|
function addButtonAnimationStyles() {
|
|
// 移除现有的样式元素,避免重复
|
|
$('#button-animation-styles').remove();
|
|
|
|
// 创建新的样式元素
|
|
const styleElement = document.createElement('style');
|
|
styleElement.id = 'button-animation-styles';
|
|
styleElement.innerHTML = `
|
|
@keyframes text-pop {
|
|
0% { transform: scale(1); }
|
|
100% { transform: scale(1.1); color: #ff6b6b; }
|
|
}
|
|
|
|
@keyframes shadow-dance {
|
|
0% { box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3); }
|
|
50% { box-shadow: 0 20px 45px rgba(74, 223, 218, 0.4); }
|
|
100% { box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3); }
|
|
}
|
|
|
|
@keyframes particle-float {
|
|
0% { transform: translate(-50%, -50%) translateY(0) rotate(0deg); opacity: 0.7; }
|
|
100% { transform: translate(-50%, -50%) translateY(-50px) rotate(360deg); opacity: 0; }
|
|
}
|
|
|
|
@keyframes sparkle-float {
|
|
0% { transform: scale(0); opacity: 0; }
|
|
50% { transform: scale(1); opacity: 0.8; }
|
|
100% { transform: scale(0); opacity: 0; }
|
|
}
|
|
|
|
/* 按钮颜色变化动画 */
|
|
@keyframes color-shift-left {
|
|
0% { background: linear-gradient(145deg, #4adfda, #1bb5ad); }
|
|
50% { background: linear-gradient(145deg, #ffa3b7, #ff6b93); }
|
|
100% { background: linear-gradient(145deg, #a694ff, #7e64ff); }
|
|
}
|
|
|
|
@keyframes color-shift-right {
|
|
0% { background: linear-gradient(145deg, #9bea72, #5cc332); }
|
|
50% { background: linear-gradient(145deg, #ffb347, #ffcc33); }
|
|
100% { background: linear-gradient(145deg, #66a6ff, #3d7edb); }
|
|
}
|
|
|
|
/* 应用颜色变化动画 */
|
|
.box-btn-left.btn-hover-active {
|
|
animation: border-dance 3s ease infinite, color-shift-left 6s infinite alternate !important;
|
|
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.35) !important;
|
|
}
|
|
|
|
.box-btn-right.btn-hover-active {
|
|
animation: border-dance 3s ease infinite, color-shift-right 6s infinite alternate !important;
|
|
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.35) !important;
|
|
}
|
|
|
|
/* 3D文本效果 */
|
|
.btn-text {
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.btn-hover-active .btn-text {
|
|
text-shadow: 2px 2px 0 #ff6b93, 4px 4px 0 rgba(0, 0, 0, 0.2);
|
|
letter-spacing: 1px;
|
|
}
|
|
|
|
/* 修复冲突 */
|
|
.box-btn-left:hover, .box-btn-right:hover {
|
|
animation: none !important;
|
|
}
|
|
`;
|
|
document.head.appendChild(styleElement);
|
|
}
|
|
|
|
// 添加按钮粒子效果
|
|
function addButtonParticles(button) {
|
|
// 移除已有粒子
|
|
removeButtonParticles();
|
|
|
|
// 获取按钮位置
|
|
const buttonPos = button.offset();
|
|
const buttonWidth = button.outerWidth();
|
|
const buttonHeight = button.outerHeight();
|
|
|
|
// 创建粒子容器
|
|
const particleContainer = $('<div class="button-particles"></div>');
|
|
particleContainer.css({
|
|
'position': 'absolute',
|
|
'left': buttonPos.left + 'px',
|
|
'top': buttonPos.top + 'px',
|
|
'width': buttonWidth + 'px',
|
|
'height': buttonHeight + 'px',
|
|
'pointer-events': 'none',
|
|
'z-index': 1000
|
|
});
|
|
|
|
// 添加粒子
|
|
const colors = ['#ffde59', '#ff914d', '#ff66c4', '#5ce1e6'];
|
|
for (let i = 0; i < 12; i++) {
|
|
const particle = $('<div class="particle"></div>');
|
|
const size = Math.random() * 8 + 4;
|
|
const color = colors[Math.floor(Math.random() * colors.length)];
|
|
|
|
particle.css({
|
|
'position': 'absolute',
|
|
'width': size + 'px',
|
|
'height': size + 'px',
|
|
'background-color': color,
|
|
'border-radius': '50%',
|
|
'left': (Math.random() * 100) + '%',
|
|
'top': (Math.random() * 100) + '%',
|
|
'opacity': 0.7,
|
|
'animation': `particle-float ${Math.random() * 2 + 1}s ease-out infinite`,
|
|
'transform': 'translate(-50%, -50%)'
|
|
});
|
|
|
|
particleContainer.append(particle);
|
|
}
|
|
|
|
// 添加闪烁效果
|
|
for (let i = 0; i < 5; i++) {
|
|
const sparkle = $('<div class="sparkle"></div>');
|
|
const size = Math.random() * 6 + 2;
|
|
|
|
sparkle.css({
|
|
'position': 'absolute',
|
|
'width': size + 'px',
|
|
'height': size + 'px',
|
|
'background-color': '#fff',
|
|
'border-radius': '50%',
|
|
'left': (Math.random() * 100) + '%',
|
|
'top': (Math.random() * 100) + '%',
|
|
'box-shadow': '0 0 10px 2px rgba(255, 255, 255, 0.8)',
|
|
'opacity': 0.8,
|
|
'animation': `sparkle-float ${Math.random() * 1.5 + 0.5}s ease-out infinite`
|
|
});
|
|
|
|
particleContainer.append(sparkle);
|
|
}
|
|
|
|
// 添加粒子容器到body
|
|
$('body').append(particleContainer);
|
|
}
|
|
|
|
// 移除按钮粒子效果
|
|
function removeButtonParticles() {
|
|
$('.button-particles').remove();
|
|
} |