Javascript 带有网格的拖放闪烁效果
Javascript drag and drop flickering effect with grids
我正在尝试为 tilemap 图像创建一个 selection 系统。添加图像,每当用户 selects 一个图块并将鼠标移动到 select 多个图块时,selection 容器的大小会随着图块大小的增加而增加。
不知何故,这会在按住鼠标按钮并四处移动时产生闪烁效果。是什么原因导致此问题?
var tilesetImageContainer = document.getElementById("tileMapContainer");
var tileSize = 32;
let startSelection = [];
var selectionWidth = 32;
var selectionHeight = 32;
let endSelection = [];
function getCoordinates(e) {
const { x, y } = e.target.getBoundingClientRect();
const mouseX = e.clientX - x;
const mouseY = e.clientY - y;
return [Math.floor(mouseX / tileSize), Math.floor(mouseY / tileSize)];
}
const mouseDownHandler = function (e) {
if (e.which === 1) {
e.preventDefault();
selectedTileMapPositions = [];
tileMapSelector.style.width = tileSize + "px";
tileMapSelector.style.height = tileSize + "px";
tilesetImageContainer.style.cursor = 'crosshair';
tilesetImageContainer.style.userSelect = 'none';
startSelection = getCoordinates(e);
tileMapSelector.style.left = startSelection[0] * tileSize + "px";
tileMapSelector.style.top = startSelection[1] * tileSize + "px";
tilesetImageContainer.addEventListener('mousemove', mouseMoveSelectionHandler);
tilesetImageContainer.addEventListener('mouseup', mouseUpSelectionHandler);
}
};
const mouseMoveSelectionHandler = function (e) {
currentPositionCoordinates = getCoordinates(e);
endSelection = getCoordinates(e);
if (currentPositionCoordinates[0] > startSelection[0] || currentPositionCoordinates[1] < startSelection[1]) {
// selected more then 1 tile
selectionWidth = ((currentPositionCoordinates[0] - startSelection[0]) * tileSize);
selectionHeight = ((currentPositionCoordinates[1] - startSelection[1]) * tileSize);
}
tileMapSelector.style.width = selectionWidth + tileSize + "px";
tileMapSelector.style.height = selectionHeight + tileSize + "px";
console.log("start: " + startSelection);
console.log("current: " + currentPositionCoordinates);
};
const mouseUpSelectionHandler = function (e) {
for (var x = startSelection[0]; x <= endSelection[0]; x++) {
for (var y = startSelection[1]; y <= endSelection[1]; y++) {
selectedTileMapPositions.push([x,y]);
}
}
console.log(selectedTileMapPositions);
tilesetImageContainer.removeEventListener('mousemove', mouseMoveSelectionHandler);
tilesetImageContainer.removeEventListener('mouseup', mouseUpSelectionHandler);
tilesetImageContainer.style.cursor = 'default';
tilesetImageContainer.style.removeProperty('user-select');
startSelection = [];
endSelection = [];
};
tilesetImageContainer.addEventListener('mousedown', mouseDownHandler);
这是一个 JsFiddle:https://jsfiddle.net/6kv3pj1n/19/
如无必要,不要重新分配变量。
在顶部声明 currentPositionCoordinates
修复 getCoordinates 函数不使用 x 和 y
let currentPositionCoordinates
function getCoordinates(e) {
const mouseX = e.clientX;
const mouseY = e.clientY;
return [Math.floor(mouseX / tileSize), Math.floor(mouseY / tileSize)];
}
if (currentPositionCoordinates) {
if (currentPositionCoordinates[0] === getCoordinates(e)[0] && currentPositionCoordinates[1] === getCoordinates(e)[1]) {
return
}
}
if (selectionWidth + tileSize + "px" !== tileMapSelector.style.width) {
tileMapSelector.style.width = selectionWidth + tileSize + "px"
}
if (selectionHeight + tileSize + "px" !== tileMapSelector.style.height) {
tileMapSelector.style.height = selectionHeight + tileSize + "px"
}
https://jsfiddle.net/2Lx740vg/2/
最新的编辑应该完全符合您的预期
我正在尝试为 tilemap 图像创建一个 selection 系统。添加图像,每当用户 selects 一个图块并将鼠标移动到 select 多个图块时,selection 容器的大小会随着图块大小的增加而增加。
不知何故,这会在按住鼠标按钮并四处移动时产生闪烁效果。是什么原因导致此问题?
var tilesetImageContainer = document.getElementById("tileMapContainer");
var tileSize = 32;
let startSelection = [];
var selectionWidth = 32;
var selectionHeight = 32;
let endSelection = [];
function getCoordinates(e) {
const { x, y } = e.target.getBoundingClientRect();
const mouseX = e.clientX - x;
const mouseY = e.clientY - y;
return [Math.floor(mouseX / tileSize), Math.floor(mouseY / tileSize)];
}
const mouseDownHandler = function (e) {
if (e.which === 1) {
e.preventDefault();
selectedTileMapPositions = [];
tileMapSelector.style.width = tileSize + "px";
tileMapSelector.style.height = tileSize + "px";
tilesetImageContainer.style.cursor = 'crosshair';
tilesetImageContainer.style.userSelect = 'none';
startSelection = getCoordinates(e);
tileMapSelector.style.left = startSelection[0] * tileSize + "px";
tileMapSelector.style.top = startSelection[1] * tileSize + "px";
tilesetImageContainer.addEventListener('mousemove', mouseMoveSelectionHandler);
tilesetImageContainer.addEventListener('mouseup', mouseUpSelectionHandler);
}
};
const mouseMoveSelectionHandler = function (e) {
currentPositionCoordinates = getCoordinates(e);
endSelection = getCoordinates(e);
if (currentPositionCoordinates[0] > startSelection[0] || currentPositionCoordinates[1] < startSelection[1]) {
// selected more then 1 tile
selectionWidth = ((currentPositionCoordinates[0] - startSelection[0]) * tileSize);
selectionHeight = ((currentPositionCoordinates[1] - startSelection[1]) * tileSize);
}
tileMapSelector.style.width = selectionWidth + tileSize + "px";
tileMapSelector.style.height = selectionHeight + tileSize + "px";
console.log("start: " + startSelection);
console.log("current: " + currentPositionCoordinates);
};
const mouseUpSelectionHandler = function (e) {
for (var x = startSelection[0]; x <= endSelection[0]; x++) {
for (var y = startSelection[1]; y <= endSelection[1]; y++) {
selectedTileMapPositions.push([x,y]);
}
}
console.log(selectedTileMapPositions);
tilesetImageContainer.removeEventListener('mousemove', mouseMoveSelectionHandler);
tilesetImageContainer.removeEventListener('mouseup', mouseUpSelectionHandler);
tilesetImageContainer.style.cursor = 'default';
tilesetImageContainer.style.removeProperty('user-select');
startSelection = [];
endSelection = [];
};
tilesetImageContainer.addEventListener('mousedown', mouseDownHandler);
这是一个 JsFiddle:https://jsfiddle.net/6kv3pj1n/19/
如无必要,不要重新分配变量。 在顶部声明 currentPositionCoordinates 修复 getCoordinates 函数不使用 x 和 y
let currentPositionCoordinates
function getCoordinates(e) {
const mouseX = e.clientX;
const mouseY = e.clientY;
return [Math.floor(mouseX / tileSize), Math.floor(mouseY / tileSize)];
}
if (currentPositionCoordinates) {
if (currentPositionCoordinates[0] === getCoordinates(e)[0] && currentPositionCoordinates[1] === getCoordinates(e)[1]) {
return
}
}
if (selectionWidth + tileSize + "px" !== tileMapSelector.style.width) {
tileMapSelector.style.width = selectionWidth + tileSize + "px"
}
if (selectionHeight + tileSize + "px" !== tileMapSelector.style.height) {
tileMapSelector.style.height = selectionHeight + tileSize + "px"
}
https://jsfiddle.net/2Lx740vg/2/
最新的编辑应该完全符合您的预期