'commit'
This commit is contained in:
@@ -40,15 +40,11 @@
|
|||||||
height: 30px;
|
height: 30px;
|
||||||
background: url("hongqi.jpg") no-repeat center/contain;
|
background: url("hongqi.jpg") no-repeat center/contain;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
offset-path: path('M100,350 C150,340 200,320 250,300 300,280 350,260 400,240 450,220 500,200 550,180 600,160 650,140 700,100');
|
transform: translate(-50%, -50%); /* 使红旗中心对准路径 */
|
||||||
offset-distance: 0%;
|
z-index: 10;
|
||||||
animation: move 20s linear paused;
|
/* 添加备用背景样式,以防图片加载失败 */
|
||||||
}
|
background-color: red;
|
||||||
|
border-radius: 50% 0;
|
||||||
@keyframes move {
|
|
||||||
to {
|
|
||||||
offset-distance: 100%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#subtitle {
|
#subtitle {
|
||||||
@@ -98,6 +94,8 @@
|
|||||||
<script>
|
<script>
|
||||||
const flag = document.getElementById("redFlag");
|
const flag = document.getElementById("redFlag");
|
||||||
const subtitle = document.getElementById("subtitle");
|
const subtitle = document.getElementById("subtitle");
|
||||||
|
const route = document.getElementById("route");
|
||||||
|
const map = document.getElementById("map");
|
||||||
|
|
||||||
const timeline = [
|
const timeline = [
|
||||||
{ p: 0, text: "1934年10月 从江西瑞金出发" },
|
{ p: 0, text: "1934年10月 从江西瑞金出发" },
|
||||||
@@ -110,30 +108,92 @@
|
|||||||
{ p: 95, text: "1935年10月 到达吴起镇" }
|
{ p: 95, text: "1935年10月 到达吴起镇" }
|
||||||
];
|
];
|
||||||
|
|
||||||
let interval;
|
let animationId;
|
||||||
|
let startTime;
|
||||||
|
let pausedTime = 0;
|
||||||
|
let isPlaying = false;
|
||||||
|
const duration = 20000; // 20秒
|
||||||
|
|
||||||
|
// 获取SVG路径的总长度
|
||||||
|
const pathLength = route.getTotalLength();
|
||||||
|
|
||||||
|
// 计算SVG坐标系到页面坐标系的转换比例
|
||||||
|
function getScaleFactor() {
|
||||||
|
const viewBox = route.viewBox.baseVal;
|
||||||
|
const svgRect = route.closest('svg').getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
x: svgRect.width / viewBox.width,
|
||||||
|
y: svgRect.height / viewBox.height
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据进度百分比获取路径上的点
|
||||||
|
function getPointOnPath(percent) {
|
||||||
|
const distance = percent * pathLength / 100;
|
||||||
|
const point = route.getPointAtLength(distance);
|
||||||
|
const scale = getScaleFactor();
|
||||||
|
|
||||||
|
// 获取SVG元素相对于页面的位置
|
||||||
|
const svgRect = route.closest('svg').getBoundingClientRect();
|
||||||
|
const mapRect = map.getBoundingClientRect();
|
||||||
|
|
||||||
|
// 计算红旗在页面上的位置
|
||||||
|
return {
|
||||||
|
x: svgRect.left - mapRect.left + point.x * scale.x,
|
||||||
|
y: svgRect.top - mapRect.top + point.y * scale.y
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新红旗位置
|
||||||
|
function updateFlagPosition(percent) {
|
||||||
|
const point = getPointOnPath(percent);
|
||||||
|
flag.style.left = `${point.x}px`;
|
||||||
|
flag.style.top = `${point.y}px`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动画循环
|
||||||
|
function animate(timestamp) {
|
||||||
|
if (!startTime) startTime = timestamp;
|
||||||
|
|
||||||
|
const elapsed = timestamp - startTime + pausedTime;
|
||||||
|
const progress = Math.min(elapsed / duration, 1) * 100;
|
||||||
|
|
||||||
|
updateFlagPosition(progress);
|
||||||
|
updateSubtitle(progress);
|
||||||
|
|
||||||
|
if (progress < 100) {
|
||||||
|
animationId = requestAnimationFrame(animate);
|
||||||
|
} else {
|
||||||
|
isPlaying = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function play() {
|
function play() {
|
||||||
flag.style.animationPlayState = "running";
|
if (!isPlaying) {
|
||||||
interval = setInterval(updateSubtitle, 200);
|
isPlaying = true;
|
||||||
|
startTime = null;
|
||||||
|
animationId = requestAnimationFrame(animate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function pause() {
|
function pause() {
|
||||||
flag.style.animationPlayState = "paused";
|
if (isPlaying) {
|
||||||
clearInterval(interval);
|
isPlaying = false;
|
||||||
|
cancelAnimationFrame(animationId);
|
||||||
|
if (startTime) {
|
||||||
|
pausedTime += performance.now() - startTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
flag.style.animation = "none";
|
pause();
|
||||||
flag.offsetHeight; // 触发重排
|
pausedTime = 0;
|
||||||
flag.style.animation = "move 20s linear paused";
|
updateFlagPosition(0);
|
||||||
subtitle.textContent = timeline[0].text;
|
subtitle.textContent = timeline[0].text;
|
||||||
clearInterval(interval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSubtitle() {
|
function updateSubtitle(percent) {
|
||||||
const computed = window.getComputedStyle(flag);
|
|
||||||
const distance = computed.offsetDistance;
|
|
||||||
const percent = parseFloat(distance);
|
|
||||||
for (let i = timeline.length - 1; i >= 0; i--) {
|
for (let i = timeline.length - 1; i >= 0; i--) {
|
||||||
if (percent >= timeline[i].p) {
|
if (percent >= timeline[i].p) {
|
||||||
subtitle.textContent = timeline[i].text;
|
subtitle.textContent = timeline[i].text;
|
||||||
@@ -141,7 +201,27 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
|
|
||||||
|
// 页面加载完成后初始化红旗位置
|
||||||
|
window.addEventListener('load', function() {
|
||||||
|
// 确保红旗在初始位置可见
|
||||||
|
updateFlagPosition(0);
|
||||||
|
|
||||||
|
// 检查红旗图片是否加载成功
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = function() {
|
||||||
|
// 图片加载成功,使用图片作为背景
|
||||||
|
flag.style.backgroundImage = 'url("hongqi.jpg")';
|
||||||
|
flag.style.backgroundColor = 'transparent';
|
||||||
|
};
|
||||||
|
img.onerror = function() {
|
||||||
|
// 图片加载失败,使用备用样式
|
||||||
|
console.warn('红旗图片加载失败,使用备用样式');
|
||||||
|
flag.style.backgroundImage = 'none';
|
||||||
|
flag.style.backgroundColor = 'red';
|
||||||
|
};
|
||||||
|
img.src = 'hongqi.jpg';
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Reference in New Issue
Block a user