我在 .svg 文件中创建了一个用于学习的世界地图,并希望使用 panzoom 库来启用缩放。然而,我遇到了一个似乎无法解决的问题。
我创建了一个简单的游戏,您需要单击正确的国家或岛屿。其中一些非常小,因此需要缩放或平移地图。出现此问题的原因是,通过单击并按住鼠标按钮平移地图时,释放按钮会触发该国家/地区的单击事件,该事件被视为玩家的尝试。
对于如何在平移地图时释放鼠标后防止这种点击,您有什么建议吗?
// Tooltip
const tooltip = document.getElementById('tooltip');
const svgContainer = document.getElementById('panzoom-container');
// Add hover and tooltip only to selected elements
idsToHighlight.forEach(id => {
const element = document.getElementById(id);
if (element) {
// Add hover
element.addEventListener('click', (event) => {
element.classList.add('region-hover');
const title = element.getAttribute('title') || 'No title';
tooltip.textContent = title;
tooltip.style.opacity = '1';
});
// Remove hover
element.addEventListener('mouseleave', () => {
element.classList.remove('region-hover');
tooltip.style.opacity = '0';
});
// Update tooltip position
element.addEventListener('mousemove', (event) => {
const bounds = svgContainer.getBoundingClientRect();
tooltip.style.left = `${event.clientX - bounds.left + 10}px`;
tooltip.style.top = `${event.clientY - bounds.top + 10}px`;
});
}
});
// Panzoom Initialization with zoom limits
const svgMap = document.getElementById('svg1');
const panzoom = Panzoom(svgMap, {
contain: 'outside',
minScale: 0.5, // Minimum zoom level
maxScale: 300 // Maximum zoom level
});
svgContainer.addEventListener('wheel', panzoom.zoomWithWheel);
// Button controls
document.getElementById('zoom-in').addEventListener('click', () => panzoom.zoomIn());
document.getElementById('zoom-out').addEventListener('click', () => panzoom.zoomOut());
document.getElementById('reset').addEventListener('click', () => panzoom.reset());
// Global attempts
const correctAnswers = [];
const incorrectAnswers = [];
const attempts = {};
let numberOfSelectedCountries = 0;
// Function to initialize map interactions
function initMapInteraction() {
// Initialize number of selected countries
numberOfSelectedCountries = 1;
document.getElementById('liczba_wylosowanych_krajow').innerText = `${numberOfSelectedCountries}`;
// Select random country
currentTarget = idsToHighlight[Math.floor(Math.random() * idsToHighlight.length)];
document.getElementById('losowy_kraj').innerText = "Choose country: " + document.getElementById(currentTarget).getAttribute('title'); // Display the selected country
console.log(`Current target: ${currentTarget}`);
// Add click listeners for each country
idsToHighlight.forEach((id) => {
const element = document.getElementById(id);
if (element) {
attempts[id] = 0; // Initialize attempt count
element.addEventListener("click", () => {
console.log(`Clicked on country: ${id}`);
if (id === currentTarget) {
// Mark correct answer
if (attempts[currentTarget] >= 2) {
// If there were more than 2 attempts, remove flashing and mark in red
element.classList.remove('migajacy');
element.style.fill = "red";
incorrectAnswers.push(currentTarget);
console.log(`Added to incorrect answers: ${currentTarget}`);
let incorrectCount = incorrectAnswers.length;
document.getElementById('bledne_kraje').innerText = "incorrect: " + incorrectCount;
} else if (attempts[currentTarget] === 1) {
// On the second attempt
element.style.fill = "orange"; // Orange mark
incorrectAnswers.push(currentTarget);
console.log(`Added to incorrect answers: ${currentTarget}`);
let incorrectCount = incorrectAnswers.length;
document.getElementById('bledne_kraje').innerText = "incorrect: " + incorrectCount;
} else {
// On the first attempt
element.style.fill = "white"; // White mark
correctAnswers.push(currentTarget);
console.log(`Added to correct answers: ${currentTarget}`);
let correctCount = correctAnswers.length;
document.getElementById('Poprawne_kraje').innerText = "Correct: " + correctCount;
}
element.style.pointerEvents = "none"; // Disable clicks
correctAnswers.push(currentTarget);
console.log(`Country ${id} marked as correct.`);
numberOfSelectedCountries++; // Increase selected countries count
document.getElementById('liczba_wylosowanych_krajow').innerText = `${numberOfSelectedCountries}`;
// Check if there are still countries to choose
const remaining = idsToHighlight.filter(
(country) => !correctAnswers.includes(country) && !incorrectAnswers.includes(country)
);
if (remaining.length > 0) {
currentTarget = remaining[Math.floor(Math.random() * remaining.length)];
document.getElementById('losowy_kraj').innerText = document.getElementById(currentTarget).getAttribute('title'); // Update the selected country
attempts[currentTarget] = 0; // Reset attempts for new country
} else {
console.log("Game finished. All countries marked correctly.");
alert("All countries have been marked correctly!");
}
} else {
// Handle incorrect selection
attempts[currentTarget]++; // Increase attempts globally
console.log(`Attempts for ${currentTarget}: ${attempts[currentTarget]}`);
if (attempts[currentTarget] === 2) {
// After 2 attempts, add flashing
document.getElementById(currentTarget).classList.add('migajacy');
}
}
});
} else {
console.error(`Element with id ${id} does not exist.`);
}
});
}
// CSS for flashing effect
const style = document.createElement('style');
style.textContent = `
@keyframes blink-red {
0%, 100% { fill: red; }
50% { fill: white; }
}
.migajacy {
animation: blink-red 1s infinite;
}
`;
document.head.appendChild(style);
// Initialize interactions after DOM is loaded
window.addEventListener("DOMContentLoaded", initMapInteraction);
const occurrences = [];
function checkIdOccurrences() {
const allElements = document.querySelectorAll('[id]');
const idCounts = {};
allElements.forEach((element) => {
const id = element.id.toUpperCase(); // Use uppercase for consistency
if (idsToHighlight.includes(id)) {
if (idCounts[id]) {
idCounts[id]++;
} else {
idCounts[id] = 1;
}
}
});
// Find the div with id `wszystkie_kraje`
const allCountriesDiv = document.getElementById('wszystkie_kraje');
if (allCountriesDiv) {
allCountriesDiv.innerHTML = `${Object.keys(idCounts).length} `;
}
}
// Call the function after DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
checkIdOccurrences();
});
您可以“设置计时器”。如果 mousedown 和 mouseup 事件的时间戳之间的差异大于 x,则停止单击事件。
let mouseevents = {};
document.addEventListener('mousedown', e => {
mouseevents.down = e.timeStamp;
console.log('mousedown', e.timeStamp);
});
document.addEventListener('mouseup', e => {
mouseevents.up = e.timeStamp;
console.log('mouseup', e.timeStamp);
});
document.addEventListener('click', e => {
let diff = mouseevents.up - mouseevents.down;
if (diff > 250) {
e.stopImmediatePropagation();
}
mouseevents = {};
});
// the "real" click event callback
document.addEventListener('click', e => {
console.log('click', e.timeStamp);
});
<p>Click somewhere</p>