{ isImageLoaded = true; // 图像加载完成 imgLoadingSuccess(); }; function imgLoadingSuccess() { initializeCanvas(); animateTo(90, 5000, easeInQuad); } // 初始化函数,设置初始百分比为 0 function initializeCanvas() { const canvas = document.getElementById("loadingCanvas"); canvas.style.display = "block"; // 确保 canvas 可见 const ctx = canvas.getContext("2d"); const devicePixelRatio = window.devicePixelRatio || 1; const canvasSize = 700; // 目标尺寸 canvas.width = canvasSize * devicePixelRatio; // 设置实际像素宽度 canvas.height = canvasSize * devicePixelRatio; // 设置实际像素高度 ctx.scale(devicePixelRatio, devicePixelRatio); // 缩放上下文 ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除 Canvas 内容 ctx.fillStyle = window.cms_common?.variables?.["--cms-primary-text-color"]; // 字体颜色 ctx.font = "12px Arial"; // 调整字体大小 ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillText("0%", canvas.width / 2, canvas.height / 2); // 显示初始百分比为 0% } function drawCircle(showPercentage, percentage) { const canvas = document.getElementById("loadingCanvas"); const ctx = canvas.getContext("2d"); const total = 100; // 总进度 const canvasSize = 700; // 目标尺寸 canvas.width = canvasSize * devicePixelRatio; // 设置实际像素宽度 canvas.height = canvasSize * devicePixelRatio; // 设置实际像素高度 ctx.scale(devicePixelRatio, devicePixelRatio); // 缩放上下文 ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除 Canvas 内容 const centerX = canvasSize / 2; const centerY = canvasSize / 2; const radius = 40; // 圆的半径 // 设置线条样式 ctx.lineJoin = "round"; // 设置连接样式为圆角 ctx.lineCap = "round"; // 设置端点样式为圆角 // 绘制背景圆 ctx.beginPath(); ctx.arc(centerX, centerY, radius, 0, Math.PI * 2); ctx.lineWidth = 3; // 保持线宽不变 ctx.strokeStyle = "transparent"; // 背景色 ctx.stroke(); // 计算进度条的结束角度 const endAngle = -Math.PI / 2 + Math.PI * 2 * (percentage / total); // 绘制绿色进度圆 ctx.beginPath(); ctx.arc(centerX, centerY, radius, -Math.PI / 2, endAngle); ctx.strokeStyle = window.cms_common?.variables?.["--cms-primary-color"]; // 进度条颜色 ctx.stroke(); // 绘制外圆(红色边框) ctx.beginPath(); ctx.arc(centerX, centerY, radius + 3, 0, Math.PI * 2); // 使用相同的半径 ctx.lineWidth = 3; // 外圆的线宽 ctx.strokeStyle = "#dddddd"; // 外圆颜色设置为红色 ctx.stroke(); // 计算文本位置 const textX = centerX + Math.cos(endAngle) * (radius + 15); // 文本 X 坐标 const textY = centerY + Math.sin(endAngle) * (radius + 15); // 文本 Y 坐标 // 绘制百分比文本 ctx.fillStyle = window.cms_common?.variables?.["--cms-primary-text-color"]; // 字体颜色 ctx.font = "12px Arial"; // 调整字体大小 ctx.textAlign = "center"; ctx.textBaseline = "middle"; // 保存当前状态 ctx.save(); // 移动到文本位置并旋转 ctx.translate(textX, textY); ctx.rotate(endAngle + Math.PI / 2); // 旋转文本,使其与进度条平行 // 绘制文本 if (showPercentage) { ctx.fillText(Math.min(percentage, 100) + "%", 0, 0); // 绘制文本 } // 恢复状态 ctx.restore(); // 绘制红色背景圆 ctx.beginPath(); ctx.arc(centerX, centerY, 30, 0, Math.PI * 2); // 红色背景圆的半径 ctx.fillStyle = window.cms_common?.variables?.["--cms-primary-color"]; // 红色背景 ctx.fill(); // 绘制缩小的足球图像 if (ballImage.src) { // 仅在图像存在时绘制 ctx.drawImage(ballImage, centerX - 20, centerY - 20, 40, 40); // 调整足球位置和大小 } } let currentPercentage = 0; let animating = false; let animationFrameId = null; function animateTo(targetPercentage, duration = 2000, easing = easeInQuad, callback) { if (animating) { cancelAnimationFrame(animationFrameId); } animating = true; const start = performance.now(); const from = currentPercentage; const to = targetPercentage; function step(timestamp) { const elapsed = timestamp - start; const progress = Math.min(elapsed / duration, 1); const eased = easing(progress); const value = Math.floor(from + (to - from) * eased); currentPercentage = value; drawCircle(true, currentPercentage); if (progress < 1) { animationFrameId = requestAnimationFrame(step); } else { animating = false; if (typeof callback === "function") { setTimeout(() => callback(value), 300); } } } animationFrameId = requestAnimationFrame(step); } window.animateSuccess = function (callback) { setTimeout(() => { animateTo(100, 200, easeOutQuad, callback); }, 100); }; function easeInQuad(t) { return t * t; } function easeOutQuad(t) { return t * (2 - t); } } }