我正在用JavaScript创建一个图像拼图。 我在2行中创建了14个div元素,然后我给它们添加了背景图像,设置了它们的位置和宽度等。。。 运转良好。 但是当我重新定位它们(洗牌)时,不需要的空白出现了。 不总是,不是每个图像,也不是同一个地方。 我同时只改变两个元素。
下面是我的更改函数:
let original_pos = [];
// I choose two element randomly, and pushing the first element positions into the original_pos array
// and I pass the second element to the shuffle_elem() function
function shuffle() {
let random_elem = document.querySelectorAll(".bg-elem");
for(let i = 0; i <= 50; i++) {
let random_num = Math.floor(Math.random() * random_elem.length);
let random_num2 = Math.floor(Math.random() * random_elem.length);
original_pos.push(random_elem[random_num].offsetTop);
original_pos.push(random_elem[random_num].offsetLeft);
cserel_elem(random_elem[random_num],random_elem[random_num2]);
}
// Here are the positions change
function shuffle_elem(elem1, elem2) {
elem1.style.left = elem2.offsetLeft+'px';
elem1.style.top = elem2.offsetTop+'px';
elem2.style.top = original_pos[0]+'px';
elem2.style.left = original_pos[1]+'px';
original_pos = [];
}
一切工作都很好,所以我可以更改这两个元素,但是会有一点空白。 在这张图中,你可以看到两个紧挨着的元素,但有时根本没有空白,或者只有一个元素有,或者几乎每个元素都有。。。 完全随机。
只有1个像素,但它在那里,非常令人沮丧。 请帮我找出这一个像素藏在哪里。 请不要jQuery
一些附加信息(CSS):
// the main holder div where my elements are
.PlayGround {
position: relative;
overflow: hidden;
}
// one element
.bg-elem {
position: absolute;
margin: 0;
padding: 0;
}
与您的链接提供,我能够重现问题,检查您的代码,并找到一个或两个修复。
是的,您可以看到由javascript定位的原始元素,然后我等待1.5秒,然后将它们洗牌。 这里!
-Bálint Gácsfalvy
注释引用,用于文档。
问题相当简单:
您的图像可能大小相同,但它们没有四舍五入到全像素,如代码所示:
// ratio is already already not an integers
let new_width = imgwidth * ratio;
let new_height = imgheight * ratio;
// and then some lines later you do divide by 7 and 2.
element[i].style.width = new_width/7+'px';
element[i].style.height = new_height/2+'px';
除此之外,您还将left
和top
设置为不是整数像素。
所有这些都会导致这些奇怪的背景线在图像之间闪烁。 因为浏览器的呈现引擎只能显示由整数像素位置和大小定义的“框”的图像,所以浏览器通过舍入到最接近的像素来拟合图像。
如果舍入错误,可能会发生相邻的图像正好相隔一个像素的情况。 (它们也可以重叠一个像素,但通常会被忽略。)
现在您知道为什么了,让我们来解决这个问题:
有很多方法可以解决这个问题,最好是在设置大小和偏移量(left
和top
)时自己将舍入到全像素,而不是依赖于渲染引擎的舍入。 但这需要花费更多的时间,我相信如果你想这样做的话,你会自己想出来的。
我选择在这里向您展示的快速而肮脏的方法是,在您使用new_widts
和new_height
值之前,将它们除以整数的个数。 这超级容易,只要这样做:
let new_width = Math.floor(imgwidth * ratio / 7) * 7;
let new_height = Math.floor(imgheight * ratio / 2) * 2;
取而代之的是:
let new_width = imgwidth * ratio;
let new_height = imgheight * ratio;
这个修复的缺点是:你最多会在水平方向和垂直方向上松掉6个像素。 (我知道,糟透了。)
看看这里的固定代码是如何工作的!
如果你有问题,请在评论中提问。 如果这对您有帮助,并且您使用此答案来解决您的问题,那么将此答案标记为已接受将是很好的。 这不仅对我有帮助,对其他有同样问题的人也有帮助,并且在搜索时遇到这个问题。