穿越火线怀旧服预约网页vue3版本
- 源码下载地址: https://github.com/superBiuBiuMan/crossfire-old-vue3
- 版权来自穿越火线,项目仅供参考学习!!!
效果
- 源码下载地址: https://github.com/superBiuBiuMan/crossfire-old-vue3
- 预览地址: https://crossfire.123916.xyz/
- 官网效果: https://www.cfhuodong.com/2025-1-https://cf.qq.com/cp/a20241227reserve/index.html
- 移动端有的问题,哈哈,不调整了
用到的库
重要的库
名称 | 描述 | 链接 |
---|---|---|
JQuery | 不用说了 | |
mmd.videoPlayer.min.js | milo 旗下的-是适用于移动端H5的轻量视频播放组件 | https://tgideas.qq.com/doc/frontend/component/m/mmd.html |
milo.js | milo 是一款前端JS库,包含了双端登录、弹出层、TAB切换等常用组件 | https://tgideas.qq.com/doc/frontend/component/common/milo.html |
milo.gbk.min.js | 同上 | |
swiper-3.4.2.min.js | 轮播图 | |
preloadjs.min.js | createj旗下的内容 | https://createjs.com/ |
Howler.js | 适合现代网络的音频库。 | https://howlerjs.com/ |
不重要的库
名称 | 描述 | 链接 |
---|---|---|
sequence.js | 他们自己写的js库(当前二级目录有具体代码) | |
loadImgList.js | 代码图片素材的js代码 | |
index.js | 预约主逻辑 | |
apptLogic.js | 预约逻辑 | |
yuyue.js | 预约逻辑 | |
html2canvas.js | 转图片 | |
record.js | 预约话术逻辑 | |
atReport.js | 上报的,腾讯内部用的应该是 |
穿越火线说明
- 素材图片一张的大小为82宽度,这里有8个格子,所以最小的宽度是82*8 = 656px,实际情况可以大一些,
- 当然,这个还是要手动去调整,最好打开控制台,使用小键盘调整
音乐播放器
- 顺带一体,他们开发人员将play和pause搞错了好像
进度条关键代码
设置进度条控制块的样式
- 关键属性是
**-webkit-slider-thumb**
**,**然后我们拿到了素材图片,设置下就好了,下面是源代码,当然,你也可以将图片下载到本地, - 注意,设置滑块需要先消除基于操作系统主题的原生外观,否者你设置了thumb也不会生效
- appearance说明: https://developer.mozilla.org/zh-CN/docs/Web/CSS/appearance
.input-range {appearance: none;background: none;border: none;outline: none;
}
.input-range::-webkit-slider-thumb {width: 44px;height: 22px;background-image: url(//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/process-btn.png?=t1735836008125);
}
- 更多的内容可以看这里
- https://juejin.cn/post/7074774487815684110
::-webkit-slider-container {/*可以修改容器的若干样式*/
}
::-webkit-slider-runnable-track {/*可以修改轨道的若干样式*/
}
::-webkit-slider-thumb {/*可以修改滑块的若干样式*/
}
音符律动(音波音浪)效果怎么做
- 可以看到,当播放的时候律动效果展示,暂停后再继续播放会以之前的位置开始跳跃展示,并且波动效果不和音调有关系,也就是一个写死的动画
- 翻看下代码
function initVisualizer() {const visualizer = document.getElementById("visualizer");const barWidth = 2; // Width of each barconst barGap = 3; // Gap between barsconst containerWidth = visualizer.clientWidth;const barCount = Math.floor(containerWidth / (barWidth + barGap)); // Calculate number of barsvisualizer.innerHTML = ""; // Clear existing barsfor (let i = 0; i < barCount; i++) {const bar = document.createElement("div");bar.className = "bar";const isDown = Math.random() < 0.5; // Randomly determine animation direction// Set random initial height between 15% and 50%const minHeight = 15 + Math.random() * 35;const maxHeight = minHeight + 30 + Math.random() * 20;bar.style.setProperty("--min-height",`${isDown ? minHeight : maxHeight}%`);bar.style.setProperty("--max-height",`${isDown ? maxHeight : minHeight}%`);bar.style.animationDuration = `${0.8 + Math.random() * 0.6}s`;// bar.style.marginRight = `${barGap}px`;visualizer.appendChild(bar);}
}
- 仿照着着写一下,基础逻辑就是为每一个竖条设置独一无二的最小高度,最大高度,和动画持续时间
- index.vue
<template><div class="wave" ref="waveRef" :class="{ running: isRunning }"><divclass="wave-bar"v-for="(_, index) in divCount":key="index":style="divs[index]"></div></div>
</template><script setup lang="ts">
import { ref, computed, onMounted, nextTick } from "vue";
const isRunning = ref(false); //是否播放动画效果
// 添加一个ref来存储wave容器的宽度
const waveRef = ref<HTMLElement | null>(null);
const divCount = ref(0);const divs = computed(() => {return Array.from({ length: divCount.value }, (_, index) => {//随机生成minHeight和maxHeight和持续时间//同时也随机minHeight和maxHeight谁更大,// const minHeight = 15 + Math.random() * 35;const minHeight = 15 + Math.random() * 16; //调整下,不然会超出高度了const maxHeight = minHeight + 30 + Math.random() * 20;const duration = 1 + Math.random() * 0.6;const isDown = Math.random() < 0.5; // Randomly determine animation direction(随机方向)return {//设置成css变量,后续可以根据优先级被读取到"--min-height": `${isDown ? minHeight : maxHeight}px`,"--max-height": `${isDown ? maxHeight : minHeight}px`,"animation-duration": `${duration}s`,};});
});
onMounted(() => {nextTick(() => {// 获取容器元素const container = waveRef.value;if (container) {// 获取容器宽度//clientWidth 返回元素的宽度(包括元素宽度、内边距,不包括边框和外边距)//offsetWidth 返回元素的宽度(包括元素宽度、内边距和边框,不包括外边距)const containerWidth = container.clientWidth;const barWidth = 2; // 波浪线的宽度,和css保持一致const barGap = 2; // Gap between bars// 计算可以容纳的波浪条数量divCount.value = Math.floor(containerWidth / (barWidth + barGap));}});
});
defineExpose({start: () => {isRunning.value = true;},stop: () => {isRunning.value = false;},
});
</script>
<style>
@keyframes volume {0% {height: var(--min-height);}100% {height: var(--max-height);}
}
</style>
<style scoped lang="scss">
.wave {height: 100%;box-sizing: border-box;padding: 0 20px;display: flex;align-items: flex-end;justify-content: center;gap: 2px; // 添加波浪条之间的间距&.running &-bar {animation-play-state: running;}&-bar {width: 2px;//读取顺序 行内样式 -> 外部样式表 -> style标签 -> 默认值height: var(--min-height);background-color: #5c6589;//alternate 往返效果animation: volume 1s ease-in-out infinite alternate;animation-play-state: paused;}
}
</style>
- 效果
css变量读取的顺序?先从行内样式读取?
在 CSS 中,CSS 变量(即自定义属性)是按照特定的优先级顺序被解析的,优先级的顺序如下:
- 行内样式:行内样式的优先级最高,浏览器会优先读取和应用内联样式中的 CSS 变量。如果你在 HTML 元素的
style
属性中定义了 CSS 变量,这些变量会优先于其他来源的定义。 - 外部样式表:如果没有在行内样式中定义,浏览器会查看外部或嵌入式的样式表(包括
@import
导入的样式表)中的 CSS 变量定义。 **<style>**
** 标签**:内嵌样式(通过<style>
标签定义的 CSS)会被应用,并且在应用过程中会考虑其优先级。- 默认值:如果在某些地方没有定义 CSS 变量,那么它们可能会使用默认值,或者在
@keyframes
等规则中,使用无效的值会导致样式不生效。
在你的示例中,@keyframes
规则中的 var(--min-height)
和 var(--max-height)
会按照以下顺序解析:
解析顺序:
- 首先,它会尝试从 行内样式 中读取
--min-height
和--max-height
(如果定义了的话)。 - 如果在行内样式中找不到,它会去查看 外部或内嵌样式表 中是否定义了这些 CSS 变量。
- 如果样式表中也没有定义这些变量,
@keyframes
动画规则会使用默认值(即var(--min-height)
和var(--max-height)
会被视为无效变量,导致动画效果不生效)。
示例代码:
<div style="--min-height: 100px; --max-height: 200px;"><!-- 内容 -->
</div><style>
@keyframes volume {0% {height: var(--min-height);}100% {height: var(--max-height);}
}.animated-div {width: 100px;background-color: lightblue;margin: 10px;animation: volume 2s ease-in-out forwards;
}
</style>
关键点:
- 在上面的代码中,
<div>
元素的style
属性定义了--min-height
和--max-height
,这些变量会被@keyframes
中的height
动画读取到。 - 如果没有在
div
中定义这些 CSS 变量,那么动画会因找不到这些变量而无法正常工作。
总结:
- 优先级:行内样式 > 外部样式表和
<style>
标签 > 默认值。 **@keyframes**
会在动画的运行时计算变量的值,因此必须确保相关的 CSS 变量在动画运行之前已经定义和赋值,否则动画将无法生效。
图片列表
- 关键是Swiper的实例如何获取
- 可以参考文档https://swiperjs.com/vue#swiper-events
- 安装
yarn add swiper
<swiper @swiper="onSwiper"></swiper>// 获取实例
import type { Swiper as SwiperType } from "swiper";
const swiperInstance = ref<SwiperType>();const handleSwiper = (type: "prev" | "next") => {if (!swiperInstance.value) return;if (type === "prev") {//上一张swiperInstance.value.slidePrev();} else {//下一张swiperInstance.value.slideNext();}
};
怎么解决缩放的问题,
- 官网的效果ctrl加滚轮是无法缩放的,并且中间的形状一直保持在中间
- 我们找下,发现在div#app下面有一个属性,会随着页面变化而变化
transform:translate3d(0%, 0%, 1px) scale(0.8, 0.8)
transform-origin:center center;
- 发现是下面这一段代码变更调整的,JQuery版本的
function coverBoxToViewport(boxSelector) {const box = $(boxSelector);if (box.length === 0) {console.error("Box not found with the given selector.");return;}// 设计稿的宽高比const designWidth = 1920;const designHeight = 1080;const designAspectRatio = designWidth / designHeight;function resizeBox() {// 获取视窗的宽高const ww = $(window).width();const hh = $(window).height();// 视窗宽高比const viewportAspectRatio = ww / hh;let scaleX, scaleY;if (viewportAspectRatio > designAspectRatio) {// 视窗更宽,以视窗宽度为基准scaleX = ww / designWidth;scaleY = scaleX; // 保持比例} else {// 视窗更高,以视窗高度为基准scaleY = hh / designHeight;scaleX = scaleY; // 保持比例}// 设置transform以缩放盒子box.css({transform: translate3d(0%, 0%, 1px) scale(${scaleX}, ${scaleY}),transformOrigin: "center",});// 设置 overflow: hidden 来隐藏超出的部分,避免滚动条$("html, body").css({overflow: "hidden",margin: "0",});}// 初始化和监听窗口大小变化resizeBox();$(window).on("resize", resizeBox);}
- 纯js版本
function coverBoxToViewport(boxSelector) {const box = document.querySelector(boxSelector);if (!box) {console.error("Box not found with the given selector.");return;}// 设计稿的宽高比const designWidth = 1920;const designHeight = 1080;const designAspectRatio = designWidth / designHeight;function resizeBox() {// 获取视窗的宽高const ww = window.innerWidth;const hh = window.innerHeight;// 视窗宽高比const viewportAspectRatio = ww / hh;let scaleX, scaleY;if (viewportAspectRatio > designAspectRatio) {// 视窗更宽,以视窗宽度为基准scaleX = ww / designWidth;scaleY = scaleX; // 保持比例} else {// 视窗更高,以视窗高度为基准scaleY = hh / designHeight;scaleX = scaleY; // 保持比例}// 设置 transform 以缩放盒子box.style.transform = `translate3d(0%, 0%, 1px) scale(${scaleX}, ${scaleY})`;box.style.transformOrigin = "center";// 设置 overflow: hidden 来隐藏超出的部分,避免滚动条document.documentElement.style.overflow = "hidden";document.documentElement.style.margin = "0";document.body.style.overflow = "hidden";document.body.style.margin = "0";}// 初始化和监听窗口大小变化resizeBox();window.addEventListener("resize", resizeBox);
}
- 这样子就会影响之前设置的
.desktop-main
的定位了,所以我们调整下,设置和官网的一样
.desktop-main{top: 90px;left: 390px;width: 1112px;height: 808px;
}
- 再设置为他们设计稿的尺寸,人家注释就说明了嘛,设计稿尺寸是1920 * 1080,
html,
body {width: 100%;height: 100%;overflow: hidden;background: #000;
}
/* 确保应用在任何屏幕尺寸下都保持1920x1080的显示比例 */
/* 始终保持应用在视窗中居中显示 */
/* 适合全屏展示的应用,如游戏界面或展示页面 */
#app {position: absolute;top: 50%;left: 50%;width: 1920px;height: 1080px;margin: -540px 0 0 -960px;will-change: transform;
}# 为什么这么设置请看下方1# html和body的样式:
width: 100% 和 height: 100%:确保页面占满整个视窗
overflow: hidden:隐藏超出视窗范围的内容,防止出现滚动条
background: #000:设置背景色为黑色
2# app容器的样式:
position: absolute 和 top: 50%, left: 50%:将应用容器定位在页面的正中心
width: 1920px 和 height: 1080px:设置固定的宽高(1920x1080分辨率)
margin: -540px 0 0 -960px:通过负边距进行居中偏移调整
-540px 是高度的一半(1080/2)
-960px 是宽度的一半(1920/2)
will-change: transform:提示浏览器该元素可能会有变换,优化渲染性能
- 我们使用scss就用scss
html,
body {width: 100%;height: 100%;overflow: hidden;background: #000;
}
/* 确保应用在任何屏幕尺寸下都保持1920x1080的显示比例 */
/* 始终保持应用在视窗中居中显示 */
/* 适合全屏展示的应用,如游戏界面或展示页面 */
$design-width: 1920px;
$design-height: 1080px;#app {position: absolute;top: 50%;left: 50%;width: $design-width;height: $design-height;margin: calc(#{$design-height} / -2) 0 0 calc(#{$design-width} / -2);will-change: transform;
}
- 我们试试看效果,可以看到
添加了遮罩背景,无法点击图标了
- 添加下
pointer-events:none
即可
无法自动播放音频
- 调用play方法出现控制台错误
- Uncaught (in promise) NotAllowedError: play() failed because the user didn’t interact with the document first. https://goo.gl/xX8pDD
- 解决
- 添加mute属性即可,就是让他静音,示例如下
<videoref="enterVideoRef"class="enter_video":controls="false"mutedsrc="@/assets/video/enter.mp4"@canplay="handleVideoCanPlay"></video>
他们的代码内容
sequence.js
window.requestAnimFrame = (function() {return window.requestAnimationFrame ||window.webkitRequestAnimationFrame ||window.mozRequestAnimationFrame ||function(callback) {window.setTimeout(callback, 1000 / 60);};
})();function sequence(opt) {var drawWrap = document.querySelector(opt.el);var useMode = 2;var ctx = null;var imgsdom = null;var list = opt.list;var count = list.length; // 修正为总长度var loadNumber = 0;var sprite = {};var frameNumber = -1;var lastUpdate = +new Date();var fps = opt.fps || 30;if (useMode === 1) {ctx = drawWrap.getContext('2d');drawWrap.width = opt.width;drawWrap.height = opt.height;}for (var i = 0; i < list.length; i++) {var img = new Image();img.src = list[i];img.crossOrigin = "Anonymous";(function(index) {drawWrap.appendChild(img);img.style.display = 'none';img.onload = function() {sprite[index] = this;loadNumber = index;if (typeof opt.progress === 'function') {opt.progress(loadNumber / (count - 1)); // 更新进度}if (loadNumber === count - 1) {imgsdom = document.querySelectorAll(opt.el + ' img');drawImg();if (typeof opt.complete === 'function') {opt.complete();}}};})(i);}function drawImg() {var newUpdate = +new Date();if (newUpdate - lastUpdate > 1000 / fps) {// 更新帧号frameNumber++;if (frameNumber >= count) {if (opt.loop) {// 循环播放,重置到第一帧frameNumber = 0;} else {// 播放结束,隐藏最后一帧,触发结束回调imgsdom[frameNumber - 1].style.display = 'none';if (typeof opt.playEnd === 'function') {opt.playEnd();}return; // 停止动画}}if (useMode === 2) {// 显示当前帧,隐藏上一帧if (frameNumber > 0) {imgsdom[frameNumber - 1].style.display = 'none';} else {// 如果是循环的第一帧,将最后一帧隐藏imgsdom[count - 1].style.display = 'none';}imgsdom[frameNumber].style.display = 'block';} else {// Canvas 绘制模式ctx.clearRect(0, 0, drawWrap.width, drawWrap.height);ctx.drawImage(sprite[frameNumber], 0, 0, drawWrap.width, drawWrap.height);}lastUpdate = newUpdate;}requestAnimFrame(drawImg);}
}
loadImgList.js
window.loadImgList = ['//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/add-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/close-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/copy-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/appoint-count-bg.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/destory-bg.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/fault/1.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/fault/2.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/fault/3.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/fault/4.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/fault/5.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/float-window.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/inner-shadowing.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/light.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/main-bar.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/mask.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/network-icon.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/notice-bar.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/qq-icon.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/shortcut/cf-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/shortcut/cf.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/shortcut/img-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/shortcut/img.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/shortcut/music-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/shortcut/music.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/shortcut/video-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/shortcut/video.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/source-icon.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/temp.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/window.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/hjLogin/close-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/hjLogin/hj-login-bg.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/hjLogin/hj-subscribe-btn-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/hjLogin/hj-subscribe-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/hjSubscribe/hj-bg.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/hjSubscribe/input-box1.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/hjSubscribe/input-box2.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/hjSubscribe/jddp-name.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/hjSubscribe/mc-tips.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/hjSubscribe/rewards-table.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/hjSubscribe/submit-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/control-bg.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/1.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/10.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/11.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/12.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/13.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/14.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/15.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/16.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/17.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/18.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/19.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/2.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/20.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/21.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/22.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/23.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/24.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/25.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/26.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/27.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/3.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/4.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/5.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/6.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/7.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/8.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/9.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/next-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/next.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/prev-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/prev.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/wrapper-bg.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/invite-bg.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/line.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/loading.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/login-popup.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/login-title.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/close-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/close.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/control-bg1.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/control-bg2.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/divider.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/file.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/list.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/next-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/next.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/pause-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/pause.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/playing-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/playing.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/prev-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/prev.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/process-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/scroll-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/scroll-down.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/scroll-up.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/source-mute-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/source-mute.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/source-open-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/source-open.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/stop-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/stop.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/unknown.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/volume.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/btn/volumn-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/list-bg.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/list-item-hover.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/process-bg-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/process-bg.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/status-bg.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/music/volumn-bg.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/qq-icon-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/qq-icon.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/role.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/start.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/adorn1.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/adorn2.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/bar-next-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/bar-prev-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/close-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/icon-bg1.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/icon-bg2.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/icon-bg3-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/icon-bg3.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/line.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/list-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/logo.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/mute-play-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/mute-stop-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/next-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/pause-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/play-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/prev-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/progress-handle.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/sjx1.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/sjx2.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/stop-btn.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/video-bg.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/video-img.jpg?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/volume-handle.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/video/volume-slider.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/wechat-icon-h.png?=t1735835345270','//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/wechat-icon.png?=t1735835345270'
];window.faultImgList = ["//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/fault/1.png?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/fault/2.png?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/fault/3.png?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/destory/fault/4.png?=t1735835345270",
]window.imageViewList = ["//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/1.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/2.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/3.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/4.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/5.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/6.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/7.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/8.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/9.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/10.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/11.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/12.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/13.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/14.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/15.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/16.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/17.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/18.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/19.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/20.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/21.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/22.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/23.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/24.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/25.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/26.jpg?=t1735835345270","//game.gtimg.cn/images/cf/cp/a20241227reserve/pc/image/list/27.jpg?=t1735835345270",
]
index.js
function openPop(className) {if (!className) return;$(".application").show();$(".application > .pop." + className).show();
}
// openPop('share-popup')// 打开公用弹窗
function commonPop(text) {$(".common-popup .alter-text p").text(text);openPop("common-popup");
}const processWidths = isMobile ? [30, 40] : [22, 44];
const videoWidths = isMobile ? [41, 44] : [41, 44];function changeProgress($progressPlayed, percent, padding, thumbWidth, $input) {const totalWidth = parseInt(($input || $progressPlayed.parent().children("#music-progress")).css("width"));$progressPlayed.css("width",`${Math.floor(percent * (totalWidth - thumbWidth)) +padding +thumbWidth / 2}px`);
}function closePop() {$(".application").hide();$(".application > .pop").hide();
}function initVisualizer() {const visualizer = document.getElementById("visualizer");const barWidth = 2; // Width of each barconst barGap = 3; // Gap between barsconst containerWidth = visualizer.clientWidth;const barCount = Math.floor(containerWidth / (barWidth + barGap)); // Calculate number of barsvisualizer.innerHTML = ""; // Clear existing barsfor (let i = 0; i < barCount; i++) {const bar = document.createElement("div");bar.className = "bar";const isDown = Math.random() < 0.5; // Randomly determine animation direction// Set random initial height between 15% and 50%const minHeight = 15 + Math.random() * 35;const maxHeight = minHeight + 30 + Math.random() * 20;bar.style.setProperty("--min-height",`${isDown ? minHeight : maxHeight}%`);bar.style.setProperty("--max-height",`${isDown ? maxHeight : minHeight}%`);bar.style.animationDuration = `${0.8 + Math.random() * 0.6}s`;// bar.style.marginRight = `${barGap}px`;visualizer.appendChild(bar);}
}function initMusicPlayer() {const playlist = [{name: "Metrohead",url: "https://cf.lv.game.qq.com/dis_kt_b280c0dca695b9f721e7768bab9b2f42_1735811699/0b53zeaccaaatuaehilwbrt6psodeheqaiia.f0.mp3",time: "02:58",},{name: "Cyber Thug",url: "https://cf.lv.game.qq.com/dis_kt_ec180a5af07c28f418f6d898dbafb2bb_1735811692/0b53b4aciaaaliaemrlwyft6od6deqhqajaa.f0.mp3",time: "02:51",},{name: "Unbound",url: "https://cf.lv.game.qq.com/dis_kt_567b23889847372baf4fb478aa60e27d_1735811685/0b53faaceaaapuaeb3lwbrt6okgdeiuaaiqa.f0.mp3",time: "02:01",},{name: "strategy now",url: "https://cf.lv.game.qq.com/dis_kt_0e4a42d1944de32220cf46cd899994c9_1735811678/0b53mmaceaaag4aebn3wdnt6oy6dejrqaiqa.f0.mp3",time: "01:50",},{name: "《穿越火线》游戏主题曲",url: "https://cf.lv.game.qq.com/dis_kt_1587e1a11e613382719dfea73b2d0595_1735888214/0b535macsaaau4akiwtx4zt6p26dfhvqakia.f0.mp3",time: "03:27",},];let currentIndex = 0; // Current track indexlet sound; // Howler.js sound instancefunction loadTrack(index) {if (sound) {sound.unload(); // Unload the current audio}sound = new Howl({src: [playlist[index].url],html5: !isMobile,onplay: function () {playPauseButton.addClass("playing");$("#visualizer").addClass("running");requestAnimationFrame(updateProgress);},onend: nextTrack,onstop: () => {playPauseButton.removeClass("playing");$("#visualizer").removeClass("running");requestAnimationFrame(updateProgress);},onpause: () => {playPauseButton.removeClass("playing");$("#visualizer").removeClass("running");requestAnimationFrame(updateProgress);},});updateNowPlaying(index);requestAnimationFrame(updateProgress);}// Update the currently playing trackfunction updateNowPlaying(index) {$(".now-playing").text(`正在播放 - ${playlist[index].name}`);$(".playlist-item").removeClass("active");$(".playlist-item").eq(index).addClass("active");}// Render the playlistfunction renderPlaylist() {const playlistContainer = $(".playlist");playlistContainer.empty(); // Clear the existing playlistplaylist.forEach((track, index) => {const item = $(`<div class="playlist-item" title="${track.name}" data-index="${index}"><span>${index + 1}. ${track.name}</span><span>${track.time}</span></div>`);item.on("click", function () {const musicName = $(this).attr("title");pttClick.send("btn","clickPlayListItem","点击播放列表-" + musicName);currentIndex = $(this).data("index");loadTrack(currentIndex);sound.play();playPauseButton.addClass("playing");});playlistContainer.append(item);});updateNowPlaying(currentIndex);requestAnimationFrame(updateProgress);}// Initialize controlsconst playPauseButton = $("#playPause");const progress = $("#music-progress");const volume = $("#music-volume");const timeDisplay = $("#music-time-display");const muteButton = $("#mute");const prevButton = $("#prev");const nextButton = $("#next");let previousVolume = 1; // Store previous volume level for mute toggle// Play/pause button eventplayPauseButton.on("click", function () {if (sound.playing()) {sound.pause();pttClick.send("btn", "musicPlayerCtrl", "音乐暂停");// playPauseButton.removeClass('playing');} else {sound.play();// playPauseButton.addClass('playing');pttClick.send("btn", "musicPlayerCtrl", "音乐开始/继续播放");}});// Stop button event$(".music-player #stop").on("click", function () {sound.stop();pttClick.send("btn", "musicPlayerStop", "音乐停止");// playPauseButton.removeClass('playing');// requestAnimationFrame(updateProgress);});$(".music-player .close").on("click", function () {sound.stop();$(".playlist-container").show();// playPauseButton.removeClass('playing');});$(".music-player .window-button").on("click", function () {pttClick.send("btn", "musicPlayerCloseList", "关闭播放列表");$(".playlist-container").hide();});$(".music-player .btn.list").on("click", function () {const display = $(".playlist-container").css("display");$(".playlist-container").css("display",display === "none" ? "block" : "none");pttClick.send("btn", "musicPlayerToggleList", "切换播放列表状态");});// Progress bar eventsprogress.on("input", function () {if (sound.playing()) {sound.pause();// playPauseButton.removeClass('playing');}const seekTime = sound.duration() * (progress.val() / 100);sound.seek(seekTime);});progress.on("change", function () {if (!sound.playing()) {sound.play();pttClick.send("btn", "dragMusicProgress", "拖动音乐进度条");// playPauseButton.addClass('playing');requestAnimationFrame(updateProgress);}});// Volume slider eventvolume.on("input", function () {sound.volume(volume.val());});// Mute button eventmuteButton.on("click", function () {if (!sound.mute()) {previousVolume = sound.volume();sound.mute(true);pttClick.send("btn", "musicPlayerMute", "音乐静音");muteButton.addClass("muted");} else {sound.mute(false);pttClick.send("btn", "musicPlayerUnmute", "音乐取消静音");muteButton.removeClass("muted");}});// Previous track buttonprevButton.on("click", previousTrack);// Next track buttonnextButton.on("click", nextTrack);// Update progress bar and time displayfunction updateProgress() {const seek = sound.seek() || 0;const percent = seek / sound.duration() || 0;progress.val(percent * 100 || 0);changeProgress($(".progress-container .progress-played"),percent,...processWidths);timeDisplay.text(formatTime(seek));if (sound.playing()) {requestAnimationFrame(updateProgress);}}// Format time in mm:ssfunction formatTime(seconds) {const minutes = Math.floor(seconds / 60);const secs = Math.floor(seconds % 60);return `${minutes}:${secs.toString().padStart(2, "0")}`;}// Play the next trackfunction nextTrack() {currentIndex = (currentIndex + 1) % playlist.length;loadTrack(currentIndex);sound.play();// playPauseButton.addClass('playing');}// Play the previous trackfunction previousTrack() {currentIndex = (currentIndex - 1 + playlist.length) % playlist.length;loadTrack(currentIndex);sound.play();// playPauseButton.addClass('playing');}// Initialize the playlist and load the first trackrenderPlaylist();loadTrack(currentIndex);
}function initVideoPlayer() {class VideoPlayer {constructor() {// jQuery选择器this.$videoPlayer = $("#videoPlayer");this.$playPauseBtn = $("#playPauseBtn");this.$stopBtn = $("#stopBtn");this.$prevBtn = $("#prevBtn");this.$nextBtn = $("#nextBtn");this.$progressInput = $("#progressInput");this.$muteBtn = $("#muteBtn");this.$volumeInput = $("#volumeInput");this.$videoList = $("#videoList");this.$rewindBtn = $("#rewindBtn");this.$forwardBtn = $("#forwardBtn");this.currentVideoIndex = 0;this.videos = [{title: "正式官宣!全新FPS网游 《穿越火线》 即将上线",src: "https://cf.lv.game.qq.com/dis_kt_7dec27524b5d90a851e81c6298c73909_1735979808/0b53tqacwaaasmanqkdydft6phgdfooaakya.f0.mp4",},{title: "震撼来袭!《穿越火线》全新CG首发",src: "https://cf.lv.game.qq.com/dis_kt_3b1c33135e38522db3e393d96780c407_1735485126/0b53vaabaaaab4ahm73rfft6pkgdccuaaeaa.f0.mp4",},{title: "轻松一刻!《穿越火线》搞笑CG",src: "https://cf.lv.game.qq.com/dis_kt_161176d63e6b91fefdbf38b327192208_1735485116/0b53veabaaaaaeahm7trfft6pkodccuqaeaa.f0.mp4",},];this.initializePlayer();this.setupEventListeners();// 初始化音量控制this.initializeVolume();this.setupPlayerControls();}initializePlayer() {this.createPlaylist();this.loadVideo(0);}createPlaylist() {const self = this;$.each(this.videos, function (index, video) {const $li = $("<li>").on("click", () =>self.loadVideo(index, true));// 创建标题和时间的容器const $titleSpan = $('<span class="video-title">').text(video.title);const $durationSpan = $('<span class="video-duration">').text("--:--");// 将标题和时间添加到列表项$li.append($titleSpan).append($durationSpan).appendTo(self.$videoList);});}updateDuration(index, duration) {this.$videoList.find("li").eq(index).find(".video-duration").text(duration);}loadVideo(index) {this.currentVideoIndex = index;this.$videoPlayer.attr("src", this.videos[index].src);this.$videoPlayer[0].load();this.updatePlaylistUI();this.$progressInput.val(0);changeProgress($(".video-player .progress-played"),0,...videoWidths,$("#progressInput"));$('.video-player .title').text(this.videos[index].title);// this.$progressInput[0].style.setProperty('--progress', '0%');this.$playPauseBtn.find("i").removeClass("vd-play").addClass("vd-pause");// 添加一个标志来判断是否需要自动播放const shouldAutoPlay =arguments[1] !== undefined ? arguments[1] : false;this.$videoPlayer.one("loadedmetadata", () => {this.updateProgress();const duration = this.$videoPlayer[0].duration;const formattedDuration = this.formatTime(duration);this.updateDuration(index, formattedDuration);this.updatePlaylistUI();this.loadOtherVideosDuration();// 如果需要自动播放if (shouldAutoPlay) {this.$videoPlayer[0].play();this.$playPauseBtn.find("i").addClass("vd-play").removeClass("vd-pause");}});}loadOtherVideosDuration() {this.videos.forEach((video, index) => {if (index !== this.currentVideoIndex) {const tempVideo = document.createElement("video");tempVideo.src = video.src;$(tempVideo).one("loadedmetadata", () => {const duration = tempVideo.duration;const formattedDuration = this.formatTime(duration);this.updateDuration(index, formattedDuration);});}});}formatTime(seconds) {const minutes = Math.floor(seconds / 60);const remainingSeconds = Math.floor(seconds % 60);if (minutes >= 60) {const hours = Math.floor(minutes / 60);const remainingMinutes = minutes % 60;return `${hours}:${remainingMinutes.toString().padStart(2, "0")}:${remainingSeconds.toString().padStart(2, "0")}`;} else {return `${minutes}:${remainingSeconds.toString().padStart(2, "0")}`;}}updatePlaylistUI() {this.$videoList.find("li").removeClass("active").eq(this.currentVideoIndex).addClass("active");}setupEventListeners() {const self = this;// 播放/暂停按钮this.$playPauseBtn.on("click", () => this.togglePlay());// 停止按钮this.$stopBtn.on("click", () => this.stopVideo());// 上一个/下一个视频this.$prevBtn.on("click", () => this.playPrevious());this.$nextBtn.on("click", () => this.playNext());// 进度条控制this.$videoPlayer.on("timeupdate", () => this.updateProgress());this.$progressInput.on("input", (e) => this.setProgress(e));// 修改视频结束事件监听this.$videoPlayer.on("ended", () => {this.$playPauseBtn.find("i").removeClass("vd-play").addClass("vd-pause");// 自动播放下一个视频this.playNext();});// 量控制this.$muteBtn.on("click", () => this.toggleMute());this.$volumeInput.on("input", (e) => this.setVolume(e));// 左右按钮控制进度条this.$rewindBtn.on("click", () => this.skipTime(-3));this.$forwardBtn.on("click", () => this.skipTime(3));}togglePlay() {const video = this.$videoPlayer[0];if (video.paused) {video.play();this.$playPauseBtn.find("i").addClass("vd-play").removeClass("vd-pause");} else {video.pause();this.$playPauseBtn.find("i").addClass("vd-pause").removeClass("vd-play");}}playPrevious() {const newIndex =(this.currentVideoIndex - 1 + this.videos.length) %this.videos.length;this.loadVideo(newIndex, true); // 传入 true 表示需要自动播放}playNext() {// 检查是否是最后一个视频if (this.currentVideoIndex === this.videos.length - 1) {// 如果是后一个,直接切换到第一个视频this.loadVideo(0, true);} else {// 否则切换到下一个视频const newIndex = this.currentVideoIndex + 1;this.loadVideo(newIndex, true);}}updateProgress() {const video = this.$videoPlayer[0];if (video.duration && !isNaN(video.duration)) {const percent = (video.currentTime / video.duration) * 100;this.$progressInput.val(percent);changeProgress($(".video-player .progress-played"),video.currentTime / video.duration,...videoWidths,$("#progressInput"));// this.$progressInput[0].style.setProperty('--progress', `${percent}%`);}}setProgress(e) {const video = this.$videoPlayer[0];const percent = e.target.value;video.currentTime = (percent / 100) * video.duration;changeProgress($(".video-player .progress-played"),percent / 100,...videoWidths,$("#progressInput"));// e.target.style.setProperty('--progress', `${percent}%`);}toggleMute() {const video = this.$videoPlayer[0];video.muted = !video.muted;if (video.muted) {this.$muteBtn.addClass("mute-stop-btn").removeClass("mute-play-btn");this.$volumeInput.val(0);} else {this.$muteBtn.addClass("mute-play-btn").removeClass("mute-stop-btn");// 恢复到静音前的音量值const previousVolume = video.volume * 100;this.$volumeInput.val(previousVolume);}}setVolume(e) {const video = this.$videoPlayer[0];const volume = e.target.value / 100;video.volume = volume;// 更新静音按钮状态if (volume === 0) {this.$muteBtn.addClass("mute-stop-btn").removeClass("mute-play-btn");} else {this.$muteBtn.addClass("mute-play-btn").removeClass("mute-stop-btn");}}skipTime(seconds) {const video = this.$videoPlayer[0];const newTime = video.currentTime + seconds;if (newTime < 0) {video.currentTime = 0;} else if (newTime > video.duration) {video.currentTime = video.duration;} else {video.currentTime = newTime;}}stopVideo() {const video = this.$videoPlayer[0];video.pause();video.currentTime = 0;this.$playPauseBtn.find("i").addClass("vd-pause").removeClass("vd-play");this.updateProgress();}initializeVolume() {const video = this.$videoPlayer[0];video.volume = 1;this.$volumeInput.val(100);}setupPlayerControls() {$(".open-video-player").click(() => {// $('.video-player').fadeIn();// 重新加载第一个视频this.loadVideo(0);// 重置播放器状态this.$videoPlayer[0].currentTime = 0;this.$progressInput.val(0);changeProgress($(".video-player .progress-played"),0,...videoWidths,$("#progressInput"));// this.$progressInput[0].style.setProperty('--progress', '0%');this.$playPauseBtn.find("i").removeClass("vd-play").addClass("vd-pause");});// 关闭播放器$("#closePlayer").click(() => {// $('.video-player').fadeOut();// 停止视频播放this.stopVideo();});}}new VideoPlayer();
}function initImageSwiper() {var $swiper = $(".img-swiper .swiper-container .swiper-wrapper");$swiper.empty();let html = "";imageViewList.forEach(function (uri) {html += `<div class="swiper-slide"><img src="${uri}" alt=""></div>`;});$swiper.append(html);var mySwiper = new Swiper(".img-swiper .swiper-container", {loop: true,prevButton: ".swiper-btn.prev-btn",nextButton: ".swiper-btn.next-btn",observer: true,observeParents: true,resistanceRatio: 0,});
}
function verifyPhoneCode() {let timer = null;const COUNTDOWN = 10;// 手机号验证function isValidPhone(phone) {return /^1[3-9]\d{9}$/.test(phone);}// 验证码验证function isValidCode(code) {return /^\d{6}$/.test(code);}// 倒计时函数function startCountdown($btn) {let count = COUNTDOWN;$btn.prop("disabled", true);$btn.text(`${count}秒后重新获取`);timer = setInterval(() => {count--;if (count <= 0) {clearInterval(timer);timer = null;$btn.prop("disabled", false);$btn.text("获取验证码");} else {$btn.text(`${count}秒后重新获取`);}}, 1000);}// 获取验证码$(".get-code").click(function () {if ($(this).prop("disabled")) {return;}const phone = $('.input-box[type="tel"]').val().trim();sendcode(1);/*接入发送验证码功能*//*if (!isValidPhone(phone)) {alert('请输入正确的手机号码');return;}if (timer) {clearInterval(timer);timer = null;}// 模拟发送验证码setTimeout(() => {alert('验证码已发送到您的手机');startCountdown($(this));}, 500);*/});// 授权手机$(".bind-phone").click(function () {if ($(this).prop("disabled")) {return;}weui.confirm('授权后,您将允许我们通过手机短信语音电话等方式,向您推送CF或CFHD高清竞技大区相关福利活动、最新版本内容等信息', {className: 'diy-weui-dialog',buttons: [{label: '取消',type: 'default',onClick: function () { console.log('no') }}, {label: '确认授权',type: 'primary',onClick: function () {bindphone(1);}}]})});// 提交预约$(".submit-btn").click(function () {//添加功能整合Milo.emit(flow_1098772);});//领取奖励$(".get-gift").click(function () {//添加功能整合Milo.emit(flow_1098978);});$(".verify-input").on("input", function (e) {if (e.target.value.length) {$(".get-auth").removeClass("black");} else {$(".get-auth").addClass("black");}});// 退订链接$(".unsubscribe").click(function () {dmunsubscribe();});// 清理定时器$(window).on("unload", function () {if (timer) {clearInterval(timer);}});var activityLink = {gw: ['https://cf.qq.com/cp/a20241218yuandan/pc/index.html', 'https://cf.qq.com/cp/a20241224jansecond/pc/index.shtml'],nq: ['https://cf.qq.com/cp/a20241218yuandan/pc/neiqian.html', 'https://cf.qq.com/cp/a20241224jansecond/pc/neiqian.shtml'],zh: ['https://cf.qq.com/cp/a20241218yuandan/m/index.html', 'https://cf.qq.com/cp/a20241224jansecond/h5/h5.shtml']}$('.new-activity').css('cursor', 'pointer');$('.new-activity').on('click', function() {var isNQ = window.location.href.indexOf("nq.html") >= 0;var isZH = window.location.href.indexOf("zh.html") >= 0;var link = '';var linkIdx = 0;// 获取当前日期var currentDate = new Date();// 设置1.11的日期var comparisonDate = new Date(currentDate.getFullYear(), 0, 11);// 比较当前日期是否大于等于1.11if (currentDate >= comparisonDate) {linkIdx = 1;} else {linkIdx = 0;}if (isNQ) {link = activityLink.nq[linkIdx];} else if (isZH) {link = activityLink.zh[linkIdx];} else {link = activityLink.gw[linkIdx];}window.open(link, '_blank');})
}function bindEvents() {// 显示用户信息$(".userinfo-arrow-btn").on("click", function () {$(this).toggleClass("active");});$(".shortcut-wrapper .shortcut").on("click", function () {const className = $(this).attr("data-type");const title = $(this).attr("title");pttClick.send("btn", "openPop", title);if (className === "qq") {return}if (className === "ie") {window.open('https://cf.qq.com/main.shtml?ADTAG=EventBlackTop.button.btnav.ecter', '_blank');return}openPop(className);if (className === "music-player") {initVisualizer();}});$(".pop").on("click", ".close", function () {pttClick.send("btn", "closePop", "关闭弹窗");// const popName = $(this).parents('.pop').attr('class');// if(popName.includes('music-player')) {// destroyVisualizer();// }closePop();});//复制链接$("#copy_btn").click(async function () {const linkInput = document.getElementById("link_to_copy");const text = linkInput.value;try {await navigator.clipboard.writeText(text);alert("复制成功");} catch (err) {console.error("复制失败:", err);// 如果 Clipboard API 失败,回退到传统方法try {linkInput.select();document.execCommand("copy");alert("复制成功");} catch (err) {alert("复制失败,请手动复制");}}});//怀旧登录器$(".appot-count-window").on("click", function () {openPop("hj-login-popup");});$('.notice-btn').on('click', function () {weui.toast('授权后,您将允许我们通过手机短信语音电话等方式,向您推送CF或CFHD高清竞技大区相关福利活动、最新版本内容等信息', 3000)})
}
function initMainContent() {initMusicPlayer();initVideoPlayer();initImageSwiper();bindEvents();verifyPhoneCode();
}function desktopContent() {$(".desktop").fadeIn(500, function () {/* sequence({el: "#fault",width: isMobile ? 750 : 1112,height: isMobile ? 1011 : 808,loop: true,fps: 15,list: faultImgList,}); */});
}function initEnterVideo() {const videoPlayer = new MMD.VideoPlayer({videoElement: $("#enterVideo")[0],src: isMobile? "//game.gtimg.cn/images/cf/cp/a20241227reserve/media/video/enter-m.mp4?=t1735893977540": "//game.gtimg.cn/images/cf/cp/a20241227reserve/media/video/enter.mp4?=t1735893977540",visibilityHandle: false,muted: true,});videoPlayer.preload();videoPlayer.on(MMD.VideoEvent.START, () => {$(".loading-page").fadeOut(500, function () {$(".enter-video").show();});});// 视频播放完成;videoPlayer.on(MMD.VideoEvent.END, () => {desktopContent();});return videoPlayer;
}function loadResource(onComplete) {var queue = new createjs.LoadQueue({preferXHR: true,crossOrigin: true,});queue.setMaxConnections(10);queue.loadManifest(loadImgList);queue.on("complete", function () {$(".loading-word").fadeOut(500, function () {$(".start-btn").fadeIn();onComplete();});});
}loadResource(function () {$(document).ready(function () {const videoPlayer = initEnterVideo();initMainContent();const firstEnter = localStorage.getItem("first_enter");if (firstEnter) {$(".loading-page").hide();desktopContent();} else {$(".loading-page").show();}$(".start-btn").on("click", function () {videoPlayer.play();localStorage.setItem("first_enter", "1");});$(".restart-btn").on("click", function () {$(".desktop").fadeOut();// $('.enter-video').fadeIn()videoPlayer.play();});});
});
apptLogic.js
/**是否已预约 */
var isBooked = false;
/**是否已经登录 */
var isLogined = true;//登录成功后
function afterLogin() {//已预约 查看邀请closePop();if (isBooked) {openPop('invite-viewer');$('.pop.login-popup').hide();return;}//未预约openPop('login-popup');$('#logined').show().siblings().hide();
}//预约成功后
function afterBook() {closePop();openPop('login-popup');$('#subscribeSucceed').show().siblings().hide();
}$(document).ready(function () {// //怀旧手机号预约$('#hj_subscribe_btn').on('click', function () {closePop();if (!isLogined) {//未登录openPop('login-popup');$('.hj-login-popup').hide();return;}if (!isBooked) {//未预约openPop('hj-subscribe');$('.hj-login-popup').hide();return;}//已预约,查看邀请openPop('invite-viewer');});$('.pop.invite-viewer .add-btn').on('click', function () {//邀请if (isMobile) {//打开邀请tip弹层} else {openPop('copy-viewer');$('.pop.invite-viewer').hide();}});
})
yuyue.js
//检查是否登录
var nowhref = window.location.href;
if (nowhref.indexOf("nq.html") >= 0) {var isQC = false;
} else {var isQC = true;
}
Milo.checkLogin({iUseQQConnect: isQC, //如果当前活动使用的互联登录,请将改参数设置truesuccess: function (user) {if (Milo.isMobile()) $("#milo-logout").hide();var userInfo = user && user.userInfo;$("#milo-logined").show();$("#milo-unlogin").hide();$("#milo-userUin").text(userInfo.userUin);if (Milo.isMobile()) $("#milo-logout").hide();let nickName = userInfo.nickName;$("#milo-userUin").html(nickName);Milo.emit(flow_1101262);queryBindArea();},fail: function (res) {//todo loginMilo.emit(flow_1101262);$(".userinfo-arrow-btn").addClass("active");},
});
// qq登录
function qqlogin() {if (isQC) {if (Milo.isMobile()) {Milo.mobileLoginByQQConnect();} else {Milo.loginByQQConnect();}} else {if (Milo.isMobile()) {Milo.mobileLoginByQQ();} else {Milo.loginByQQ();}}
}// 退出
$("#milo-logout").click(function () {Milo.logout({callback: function () {$("#milo-logined").hide();$("#milo-unlogin").show();},});window.location.reload();
});/*****************大区********************/// 查询绑定大区
function queryBindArea() {var flow_query = {actId: "693120",token: "68b24f",loading: false, // 开启loading浮层,默认不开启sData: {query: true,},success: function (res) {if (res.data) {$("#milo-binded").show();$("#milo-unbind").hide();$("#milo-areaName,.share-service").text(res.data.areaName);$("#milo-roleName,.share-nickname").text(res.data.roleName);}Milo.emit(flow_1098787);},fail: function (res) {if (res.iRet === -9998 || res.iRet === "-9998") {return;}$("#milo-binded").hide();$("#milo-unbind").show();console.log("查询绑定大区fail", res);},};Milo.emit(flow_query);
}$("#milo-commitArea, #milo-changeArea").click(function () {commitBindArea();
});// 提交绑定大区
function commitBindArea() {var flow_commit = {actId: "693120",token: "f39729",loading: false, // 开启loading浮层,默认不开启sData: {query: false,},success: function (res) {if (res.data) {$("#milo-binded").show();$("#milo-unbind").hide();$("#milo-areaName,.share-service").text(res.data.areaName);$("#milo-roleName,.share-nickname").text(res.data.roleName);}Milo.emit(flow_1098787);},fail: function (res) {if (res.iRet === -9998 || res.iRet === "-9998") {return;}$("#milo-binded").hide();$("#milo-unbind").show();console.log("提交绑定大区fail", res);},};Milo.emit(flow_commit);
}
//预约
var flow_1098772 = {actId: "693120",token: "e6af34",sData: {},success: function (res) {setTimeout(() => {weui.toast('恭喜您预约成功~');}, 500);Milo.emit(flow_1098787);Milo.emit(flow_1101262);},fail: function (res) {if (res.iRet == 101) {qqlogin();} else if (res.iRet == 99998) {commitBindArea();} else {weui.toast(res.sMsg);/* closePop();commonPop(res.sMsg); */}},
};//初始化
var flow_1098787 = {actId: "693120",token: "422093",sData: {},success: function (res) {record.init(); //初始化分享图片if (res.details.modRet.sOutValue1 > 0) {$(".submit-btn").hide();$(".subscribe-disable,.get-gift").show();var yyresult = res.details.modRet.sOutValue5;if (yyresult != 0) {yyrecord = yyresult.split("_");record.descIdx = yyrecord[0];record.picIdx = yyrecord[1];$("#my-file-second").show()$("#my-file-first").hide()record.initDescAndPic();} else {$("#my-file-second").hide()$("#my-file-first").show()}}if (res.details.modRet.sOutValue3 > 0) {$(".get-gift").hide();$(".get-gift-disable").show();} else {$(".get-gift").show();$(".get-gift-disable").hide();}if(res.details.modRet.sOutValue4>0){$(".share-subscribe-number").text("您是怀旧服第" + res.details.modRet.sOutValue4 + "个预约玩家");}},fail: function (res) {if (res.iRet == 101) {qqlogin();} else if (res.iRet == 99998) {commitBindArea();}},
};
//初始化-不带登录
var flow_1101262 = {actId: '693120',token: '35117e',sData: {},success: function(res){$("#appoint-count").text(res.details.modRet.sOutValue2);},fail: function(res){if(res.iRet == 101){//todo 登录态失效,需要重新调登录方法 (开发自行实现)} else if (res.iRet == 99998) {// todo 调用提交绑定大区方法}}
}
//领取预约奖励
var flow_1098978 = {actId: "693120",token: "90d8e2",sData: {},success: function (res) {weui.toast(res.sMsg);Milo.emit(flow_1098787);},fail: function (res) {if (res.iRet == 101) {qqlogin();} else if (res.iRet == 99998) {commitBindArea();} else {weui.toast(res.sMsg);}},
};//领取迷彩套装
var flow_1098775 = {actId: "693120",token: "b502c0",sData: {},success: function (res) {closePop();commonPop(res.sMsg);},fail: function (res) {if (res.iRet == 101) {qqlogin();} else if (res.iRet == 99998) {commitBindArea();} else {weui.toast(res.sMsg);}//console.log(res);},
};
//记录黑话&头像
var flow_1100125 = {actId: "693120",token: "f0bef1",sData: {"dmid":0,"dmid1":1},loading: false,success: function (res) {Milo.emit(flow_1098787);},fail: function (res) {if (res.iRet == 101) {qqlogin();} else if (res.iRet == 99998) {commitBindArea();}else{weui.toast(res.sMsg);}}
};
amsCfg_1004838 = amsCfg_1004839 = {iAMSActivityId: "608967", // AMS活动号activityId: "592766", // 模块实例号sData: { phone: "", code: "", iActId: "", sService: "" },_everyRead: true,sNeedSubmitPopDiv: false,onBeginGetGiftEvent: function () {return 0; // 抽奖前事件,返回0表示成功},onGetGiftFailureEvent: function (callbackObj) {// 抽奖失败事件weui.toast(callbackObj.sMsg);},onGetGiftSuccessEvent: function (callbackObj) {// 抽奖成功事件var packageLen = callbackObj.iPackageId? callbackObj.iPackageId.split(","): "";if (packageLen && packageLen.length > 1) {alert(callbackObj.sMsg);return;}weui.toast(callbackObj.sMsg);},
};
amsCfg_1004837 = {iAMSActivityId: "608967", // AMS活动号activityId: "592766", // 模块实例号sData: { phone: "", code: "", iActId: "", sService: "" },_everyRead: true,sNeedSubmitPopDiv: false,onBeginGetGiftEvent: function () {return 0; // 抽奖前事件,返回0表示成功},onGetGiftFailureEvent: function (callbackObj) {// 抽奖失败事件weui.toast(callbackObj.sMsg);},onGetGiftSuccessEvent: function (callbackObj) {// 抽奖成功事件weui.toast('发送成功~');$(".bind-phone").removeClass("black");},
};
//手机号码填写
function sendcode(id) {var phoneNum = $("#phoneNum" + id).val();if (phoneNum) {amsCfg_1004837.sData.phone = phoneNum;amsSubmit(608967, 1004837);} else {// closePop();// commonPop("请输入正确的手机号码!");weui.toast('请输入正确的手机号码!')}
}
function bindphone(id) {var phoneNum = $("#phoneNum" + id).val();var codeNum = $("#codeNum" + id).val();if (phoneNum && codeNum) {amsCfg_1004838.sData.phone = phoneNum;amsCfg_1004838.sData.code = codeNum;amsCfg_1004838.sData.iActId = 689039;amsCfg_1004838.sData.sService = "CF";amsSubmit(608967, 1004838);} else {weui.toast('请输入正确的手机号码和验证码后再授权!')// closePop();// commonPop("请输入正确的手机号码和验证码后再授权!");}
}function dmunsubscribe() {confirm("您确定要退订吗?", function () {amsSubmit(608967, 1004839);});
}
window.confirm = function (msg, callback, callback1, callback2) {need("util.modalDialog", function (Dialog) {Dialog.confirm(msg, {onConfirm: function () {typeof callback == "function"? callback(): console.log("no callback");},onCancel: function () {typeof callback1 == "function"? callback1(): console.log("no callback1");},onClose: function () {typeof callback1 == "function"? callback2(): console.log("no callback2");},});});
};
record.js
var record = {name: "",arename: "",descIdx: 0, //初始化描述索引picIdx: 1, //初始化头像索引yuyenum: "", //当前预约名次descArr: ["三亿鼠标的枪战梦想","两黄两水","马来狗马来狗 按住左键不放手","银色换大炮 迷彩换大炮","自雷国密","找哥哥收徒弟","战队收人只要90后","爆破三禁","中路对狙","斜角AK","运输船solo","左手狙神","kkkkkkkkk","1861","33主道","按F抢治疗","哥哥发把枪","把ACE踢了","一回合杀10个","网吧五连坐 从来没赢过","一动不动是王八","按G获取加特林",],init: function () {var self = this;if (pageName == "zh") {$(".save-tips").addClass("save-tips-zh");}if (pageName == "nq") {$(".save-tips").hide();}self.bindEvent();self.initDescAndPic();$("#refresh-btn-desc,#refresh-btn-avatar").on("click", function () {var type = $(this).attr("data-type");var index = self.refresh(type);if (type == "avatar") {self.picIdx = index;flow_1100125.sData.dmid1 = self.picIdx;$(".share-avatar img").attr("src","//game.gtimg.cn/images/cf/cp/a20241227reserve/common/avatar/" +index +".jpg");} else {self.descIdx = index;flow_1100125.sData.dmid = self.descIdx;$(".text-items-content .text-items").text(record.descArr[index - 1]);}});},//初始黑话和头像initDescAndPic: function () {const self = this;var url ="https://game.gtimg.cn/images/cf/cp/a20241227reserve/common/avatar/" +self.picIdx +".jpg";$(".share-avatar img").attr("src", url);$(".text-items-content .text-items").text(self.descArr[self.descIdx - 1]);},bindEvent: function () {const self = this;const img = $("#share-popup-img")[0];$(".subscribe-disable").on("click", function () {closePop();const className = $(this).attr("data-type");openPop(className);});$(".my-file").off("click").on("click", function () {closePop();const className = $(this).attr("data-type");openPop(className);console.log("self.picIdx", self.picIdx);console.log("self.descIdx", self.descIdx);if (className == "share-popup") {self.convertToImage(img).then((src) => {console.log("src", src);$("#share-loading").hide();$("#share-img").show();$("#share-img").attr("src", src);});}});//点击生成档案 self.picIdx self.descIdx 两个值保存$(".create-btn").off("click").on("click", function () {// console.log("self.picIdx", self.picIdx);// console.log("self.descIdx", self.descIdx);closePop();const className = $(this).attr("data-type");openPop(className);self.convertToImage(img).then((src) => {console.log("src", src);$("#share-loading").hide();$("#share-img").show();$("#share-img").attr("src", src);});Milo.emit(flow_1100125);});//再次编辑$(".edit-btn").on("click", function () {closePop();const className = $(this).attr("data-type");openPop(className);});},convertToImage: function (container) {const _width = container.offsetWidth;const _height = container.offsetHeight;const ops = {_width,_height,backgroundColor: null,useCORS: true,allowTaint: false,};return html2canvas(container, ops).then((canvas) => {return canvas.toDataURL("image/png");});},getRandomNumber: function (min, max) {return Math.floor(Math.random() * (max - min + 1)) + min;},//刷新文案refresh: function (type) {if (type == "avatar") {//imgreturn this.getRandomNumber(1, 11);} else {//textreturn this.getRandomNumber(1, 22);}},
};
相关文章:
穿越火线怀旧服预约网页vue3版本
源码下载地址: https://github.com/superBiuBiuMan/crossfire-old-vue3版权来自穿越火线,项目仅供参考学习!!! 效果 源码下载地址: https://github.com/superBiuBiuMan/crossfire-old-vue3预览地址: https://crossfire.123916.xyz/官网效果: https://www.cfhuodong.com/2025-…...
《Keras3从头开始的图像分类》
Keras3从头开始的图像分类 作者:fchollet创建日期:2020/04/27最后修改时间:2023/11/09描述:在 Kaggle Cats vs Dogs 数据集上从头开始训练图像分类器。 (i) 此示例使用 Keras 3 在 Colab 中查看 • GitHub…...
Apache Hop从入门到精通 第三课 Apache Hop下载安装
1、下载 官方下载地址:https://hop.apache.org/download/,本教程是基于apache-hop-client-2.11.0.zip进行解压,需要jdk17,小伙伴们可以根据自己的需求下载相应的版本。如下图所示 2、下载jdk17(https://www.microsoft…...
Vue.js组件开发-图片剪裁性能优化最佳方案实例
在Vue.js组件开发中,优化图片剪裁性能的最佳方案通常涉及多个方面的综合考虑。以下是一个结合多个优化策略的图片剪裁组件性能优化实例: 1. 组件设计 首先,设计一个简洁且高效的图片剪裁组件,确保其功能明确且易于使用。组件应包…...
React - router的使用 结合react-redux的路由守卫
web端使用路由安装的是 react-router-dom "react-router-dom": "^5.2.0"在组件中使用路由,我们先设置2个路由,分别是首页、关于 // src/components/RouteSample.jsimport React from react; // 引入路由需要的基础模块 import {Bro…...
day09_kafka高级
文章目录 kafka高级今日课程内容核心概念整理Kafka的数据位移offset**为什么 Kafka 的 offset 就像是“书签”?****实际意义** Kafka的基准/压力测试测试生产的效率测试消费的效率 Kafka的分片与副本机制kafka如何保证数据不丢失生产者端Broker端消费者端相关参数 K…...
【MT32F006】MT32F006之通信协议
本文最后修改时间:2025年01月09日 一、本节简介 本文介绍如何使用MT32F006写一个通信协议。 二、实验平台 库版本:V1.0.0 编译软件:MDK5.37 硬件平台:MT32F006开发板(主芯片MT32F006) 仿真器ÿ…...
CMake学习笔记(2)
1. 嵌套的CMake 如果项目很大,或者项目中有很多的源码目录,在通过CMake管理项目的时候如果只使用一个CMakeLists.txt,那么这个文件相对会比较复杂,有一种化繁为简的方式就是给每个源码目录都添加一个CMakeLists.txt文件ÿ…...
访客机的四个功能
访客机,也被称为访客自动登记安全管理系统或访客一体机,是现代安全管理中不可或缺的一部分。它通过整合计算机技术、射频识别技术、指纹生物识别、触摸屏手写技术、文字识别(OCR)技术、热敏打印技术、条码技术、数码摄像技术、自动…...
【Linux系统】—— vim 的使用
【Linux系统】—— vim 的使用 1 vim 的基本概念2 vim 的多模式3 命令模式下的命令集3.1 进入/退出其他模式3.2 光标移动命令集3.3 复制/剪切/粘贴/删除命令集3.4 撤销命令集3.5 查找命令集3.6 替换命令集3.7 进入与退出替换模式 4 批量化编译5 底行模式6 vim 小技巧7 vim简单配…...
华为C语言编程规范总结
1.头文件更改会导致所有直接或间接包含该头文件的的C文件重新编译,会增加大量编译工作量,延长编译时间,因此: 1.1 头文件里尽量少包含头文件 1.2 头文件应向稳定的方向包含 2.每一个.c文件应有一个同名.h文件,…...
深入学习 Python 量化编程
深入学习 Python 量化编程 第一章:Python 基础与量化编程环境搭建 1.1 安装必要的库 首先,你需要安装一些在量化编程中常用的 Python 库。可以通过以下命令安装这些库: pip install numpy pandas matplotlib yfinance backtrader scikit-…...
初识Java3
目录 一.面向对象与面向过程编程区别 二.类 1.类的定义 2.类一般格式 3.类的实例化具体对象 4.this的使用(习惯经常用) 5.this引用 三.对象 1.初始化对象方法 2.构造方法 四.封装 1.封装: 2.拓展“包” (1).包概念 (…...
uniapp 微信小程序内嵌h5实时通信
描述: 小程序webview内嵌的h5需要向小程序实时发送消息,有人说postMessage可以实现,所以试验一下,结果是实现不了实时,只能在特定时机后退、组件销毁、分享时小程序才能接收到信息(小程序为了安全等考虑做了…...
Blazor开发复杂信息管理系统的优势
随着现代企业信息管理需求的不断提升,开发高效、易维护、可扩展的系统变得尤为重要。在这个过程中,Blazor作为一种新兴的Web开发框架,因其独特的优势,逐渐成为开发复杂信息管理系统的首选技术之一。本文将结合Blazor在开发复杂信息…...
【微服务】面试题 5、分布式系统理论:CAP 与 BASE 详解
分布式系统理论:CAP 与 BASE 详解 一、CAP 定理 背景与定义:1998 年由加州大学科学家埃里克布鲁尔提出,分布式系统存在一致性(Consistency)、可用性(Availability)、分区容错性(Part…...
<论文>时序大模型如何应用于金融领域?
一、摘要 本文介绍2024年的论文《Financial Fine-tuning a Large Time Series Model》,论文探索了主流的时间序列大模型在金融领域的微调应用实践,为时序大模型的领域微调提供了参考。 译文: 大型模型在自然语言处理、图像生成以及近期的时间…...
Oracle 表分区简介
目录 一. 前置知识1.1 什么是表分区1.2 表分区的优势1.3 表分区的使用条件 二. 表分区的方法2.1 范围分区(Range Partitioning)2.2 列表分区(List Partitioning)2.3 哈希分区(Hash Partitioning)2.4 复合分…...
安卓硬件加速hwui
安卓硬件加速 本文基于安卓11。 从 Android 3.0 (API 级别 11) 开始,Android 2D 渲染管道支持硬件加速,这意味着在 View 的画布上执行的所有绘图操作都使用 GPU。由于启用硬件加速所需的资源增加,你的应用程序将消耗更多内存。 软件绘制&am…...
【Bluedroid】HFP连接流程源码分析(二)
接上一篇【Bluedroid】HFP连接流程源码分析(一)-CSDN博客分析。本篇主要围绕RFCOMM Connect 与 RFCOMM UA Frame 的处理流程来展开分析。 RFCOMM Connect RFCOMM(Radio Frequency Communication)作为蓝牙协议栈的关键部分&#…...
基于文件系统分布式锁原理
分布式锁:在一个公共的存储服务上打上一个标记,如Redis的setnx命令,是先到先得方式获得锁,ZooKeeper有点像下面的demo,比较大小的方式判决谁获得锁。 package com.ldj.mybatisflex.demo;import java.util.*; import java.util.co…...
java语法知识(二)
1. class文件可以直接拖动到idea中,显示源码。 2.idea快捷键: sout : System.out.println 输出内容.sout :---》 System.out.println(输出内容); psvm: public static void main() 格式化:ctrl altL 复制粘贴:ctrld 3.注释…...
基于Piquasso的光量子计算机的模拟与编程
一、引言 在科技飞速发展的当下,量子计算作为前沿领域,正以前所未有的态势蓬勃崛起。它凭借独特的量子力学原理,为解决诸多经典计算难以攻克的复杂问题提供了全新路径。从优化物流配送网络,以实现资源高效调配,到药物分子结构的精准模拟,加速新药研发进程;从金融风险的…...
导出文件,能够导出但是文件打不开
背景: 在项目开发中,对于列表的查询,而后会有导出功能,这里导出的是一个excell表格。实现了两种,1.导出的文件,命名是前端传输过去的;2.导出的文件,命名是根据后端返回的文件名获取的…...
【动手学电机驱动】STM32-FOC(4)STM32之UART 串口通信
STM32-FOC(1)STM32 电机控制的软件开发环境 STM32-FOC(2)STM32 导入和创建项目 STM32-FOC(3)STM32 三路互补 PWM 输出 STM32-FOC(4)STM32之UART 串口通信 STM32-FOC(6&am…...
RabbitMQ 高可用方案:原理、构建与运维全解析
文章目录 前言:1 集群方案的原理2 RabbitMQ高可用集群相关概念2.1 设计集群的目的2.2 集群配置方式2.3 节点类型 3 集群架构3.1 为什么使用集群3.2 集群的特点3.3 集群异常处理3.4 普通集群模式3.5 镜像集群模式 前言: 在实际生产中,RabbitM…...
Center Loss 和 ArcFace Loss 笔记
一、Center Loss 1. 定义 Center Loss 旨在最小化类内特征的离散程度,通过约束样本特征与其类别中心之间的距离,提高类内特征的聚合性。 2. 公式 对于样本 xi 和其类别yi,Center Loss 的公式为: xi: 当前样本的特征向量&…...
深度解读微软Speech服务:让语音识别走进现实
大家好,今天我们来探讨一个激动人心的技术话题:微软的语音识别服务如何为我们提供强大的语音识别解决方案,特别是在电话录音中识别出不同的说话人。 场景描绘 想象一下,你有一段电话录音,并需要将其中的多个说话人区分…...
第21篇 基于ARM A9处理器用汇编语言实现中断<三>
Q:怎样编写ARM A9处理器汇编语言代码配置按键端口产生中断? A:使用Intel Monitor Program创建中断程序时,Linker Section Presets下拉菜单中需选择Exceptions。主程序在.vectors代码段为ARM处理器设置异常向量表,在…...
专题 - STM32
基础 基础知识 STM所有产品线(列举型号): STM产品的3内核架构(列举ARM芯片架构): STM32的3开发方式: STM32的5开发工具和套件: 若要在电脑上直接硬件级调试STM32设备,则…...
极客说|Azure AI Agent Service 结合 AutoGen/Semantic Kernel 构建多智能体解决⽅案
作者:卢建晖 - 微软高级云技术布道师 「极客说」 是一档专注 AI 时代开发者分享的专栏,我们邀请来自微软以及技术社区专家,带来最前沿的技术干货与实践经验。在这里,您将看到深度教程、最佳实践和创新解决方案。关注「极客说」&am…...
【C++指南】模板 深度解析
💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《C指南》 期待您的关注 目录 1. 引言 2. 模板的基本概念 3. 函数模板 3.1 定义和语法 3.2 函数模板实例化 3.3 隐式实例化 …...
【traefik】forwadAuth中间件跨namespace请求的问题
前情提要 - fowardAuth鉴权中间件的使用: 【traefik】使用forwardAuth中间件做网关层的全局鉴权 1. 问题 我的 traefik-ingress-controller 所在 namespace: traefik 业务服务所在 namespace: apps 路由与 forwardAuth 中间件配置如下: # 路由 apiV…...
【25考研】西南交通大学软件工程复试攻略!
一、复试内容 复试对考生的既往学业情况、外语听说交流能力、专业素质和科研创新能力,以及综合素质和一贯表现等进行全面考查,主要考核内容包括思想政治素质和道德品质、外语听说能力、专业素质和能力,综合素质及能力。考核由上机考试和面试两部分组成&a…...
在 Safari 浏览器中,快速将页面恢复到 100% 缩放(也就是默认尺寸)Command (⌘) + 0 (零)
在 Safari 浏览器中,没有一个专门的快捷键可以将页面恢复到默认的缩放比例。 但是,你可以使用以下两种方法快速将页面恢复到 100% 缩放(也就是默认尺寸): 方法一:使用快捷键 (最常用) Command (⌘) 0 (零…...
linux的大内核锁与顺序锁
大内核锁 Linux大内核锁(Big Kernel Lock,BKL)是Linux内核中的一种锁机制,用于保护内核资源,以下是关于它的详细介绍: 概念与作用 大内核锁是一种全局的互斥锁,在同一时刻只允许一个进程访问…...
CVE-2025-22777 (CVSS 9.8):WordPress | GiveWP 插件的严重漏洞
漏洞描述 GiveWP 插件中发现了一个严重漏洞,该插件是 WordPress 最广泛使用的在线捐赠和筹款工具之一。该漏洞的编号为 CVE-2025-22777,CVSS 评分为 9.8,表明其严重性。 GiveWP 插件拥有超过 100,000 个活跃安装,为全球无数捐赠平…...
牛客周赛 Round 76题解
小红出题 思路:我们发现,每七天可以获得15元,那么我们可以对7取模,看能有多少7的倍数,然后剩下的就是看是否超过5,超过5就直接15,否则加上天数*3 #include<bits/stdc.h> using namespace…...
【ARM】MDK如何将变量存储到指定内存地址
1、 文档目标 通过MDK的工程配置,将指定的变量存储到指定的内存地址上。 2、 问题场景 在项目工程的开发过程中,对于flash要进行分区,需要规划出一个特定的内存区域来存储变量。 3、软硬件环境 1)、软件版本:MDK 5.…...
解决在arm架构下的欧拉操作系统mysql8.4.2源码安装
目标:在欧拉的22.03 (LTS-SP4)版本操作系统,cpu的架构为ARM,源码安装mysql-8.4.2。 1.查看操作系统 # cat /etc/os-release NAME"openEuler" VERSION"22.03 (LTS-SP4)"# uname -i aarch642.mysql下载地址 mysql的下载…...
SpringAop
SpringAop aop定义核心概念aop基础实现执行流程 aop进阶通知类型切入点表达式的抽取通知的执行顺序切入点表达式execution方式实现annotation注解方式实现示例 笔记链接 aop定义 AOP:Aspect Oriented Programming(面向切面编程、面向方面编程)…...
C++内存泄露排查
内存泄漏是指程序动态分配的内存未能及时释放,导致系统内存逐渐耗尽,最终可能造成程序崩溃或性能下降。在C中,内存泄漏通常发生在使用new或malloc等分配内存的操作时,但没有正确地使用delete或free来释放这块内存。 在日常开发过程…...
Cesium小知识:pointPrimitive collection 详解
Cesium.PointPrimitiveCollection 是 Cesium 中用于高效管理和渲染大量点(points)的一个类。它允许你创建和管理大量的 PointPrimitive 实例,这些实例可以用来表示地理空间中的点数据,如传感器位置、车辆位置、兴趣点等。与直接使用 Cesium.Entity 相比,PointPrimitiveCol…...
从 Conda 到 Pip-tools:Python 依赖管理全景探索20250113
从 Conda 到 Pip-tools:Python 依赖管理全景探索 引言 在 Python 开发中,依赖管理是一个"常见但复杂"的问题:一次简单的版本冲突可能让团队调试数小时;一次不受控的依赖升级可能让生产环境瘫痪。随着项目规模的增加和…...
浅谈云计算01 | 云计算服务的特点
在当今数字化时代,云计算作为一种强大的技术解决方案,正逐渐改变着企业和个人对信息技术的使用方式。本文将详细探讨云计算的五个主要特点,包括按需自助服务、广泛的网络接入、资源池化、快速弹性伸缩以及可计量服务。 一、按需自助服务 云…...
2025年,华为认证HCIA、HCIP、HCIE 该如何选择?
眼看都到 2025 年啦,华为认证还吃香不? 把这问题摆在每个网络工程师跟前,答案可没那么容易说清楚。 到底考不考它值当不值当,重点在于您自己的职业规划,还有对行业走向的领会。 2025 年华为认证仍然值得一考&#…...
使用Selenium进行网页自动化测试
在使用Selenium进行网页自动化测试时,获取网络请求数据(即network数据)并不直接由Selenium库提供。Selenium主要用于与网页内容进行交互(如点击、输入文本、获取页面元素等),但它本身不拦截或记录网络请求。…...
Linux 下 mtrace 的详细介绍
在 Linux 系统中,内存管理是操作系统的一项重要任务,而内存泄漏(Memory Leak)是开发过程中常见且棘手的问题之一。为了帮助开发者追踪和调试内存泄漏问题,mtrace 提供了一种有效的方式来检测和分析内存的分配与释放情况…...
【DB-GPT】开启数据库交互新篇章的技术探索与实践
一、引言:AI原生数据应用开发的挑战与机遇 在数字化转型的浪潮中,企业对于智能化应用的需求日益增长。然而,传统的数据应用开发方式面临着诸多挑战,如技术栈复杂、开发周期长、成本高昂、难以维护等。这些问题限制了智能化应用的…...
深入 Flutter 和 Compose 在 UI 渲染刷新时 Diff 实现对比
众所周知,不管是什么框架,在前端 UI 渲染时,都会有构造出一套相关的渲染树,并且在 UI 更新时,为了尽可能提高性能,一般都只会进行「差异化」更新,而不是对整个 UI Tree 进行刷新,所以…...