如何制作一个动画,从四面八方聚集在一起的相同尺寸的碎片构建最终图像?
How to make an animation that constructs a final image from pieces of equal dimensions that come together from all sides?
动画类似于 PowerPoint 中的幻灯片切换。我会使用 skew
和 translate
(从页面边缘的随机位置)转换来完成。我开始使用 CSS sprites 和 CSS 网格。我遇到的第一个问题是网格之间的间距,Chrome DevTools 中没有解释间距。我可以使用 anime.js
或其他库。
下面的问题是碎片之间的间距,它们没有显示所需的图像的完整部分。原图为here.
/* The photo resolution: 2400 x 1600 */
.slideshow {
display: grid;
grid-template-rows: auto auto auto;
grid-template-columns: auto auto auto;
}
.tile {
background-image: url(https://unsplash.com/photos/hzgs56Ze49s/download?force=true&w=2400);
/* width: 800px;
height: 533px; */
width: calc(800px / 2);
height: calc(533px / 2);
transform: scale(0.5, 0.5);
}
.piece1 {
background-position: 0 0;
grid-row: 1/1;
grid-column: 1/1;
}
.piece2 {
background-position: -800px 0;
grid-row: 1/1;
grid-column: 2/2;
}
.piece3 {
background-position: -1600px 0;
grid-row: 1/1;
grid-column: 3/3;
}
.piece4 {
background-position: 0 -533px;
grid-row: 2/2;
grid-column: 1/1;
}
.piece5 {
background-position: -800px -533px;
grid-row: 2/2;
grid-column: 2/2;
}
.piece6 {
background-position: -1600px -533px;
grid-row: 2/2;
grid-column: 3/3;
}
.piece7 {
background-position: 0 -1066px;
grid-row: 3/3;
grid-column: 1/1;
}
.piece8 {
background-position: -800px -1066px;
grid-row: 3/3;
grid-column: 2/2;
}
.piece9 {
background-position: -1600px -1066px;
grid-row: 3/3;
grid-column: 3/3;
}
<div class="slideshow">
<div class="tile piece1"></div>
<div class="tile piece2"></div>
<div class="tile piece3"></div>
<div class="tile piece4"></div>
<div class="tile piece5"></div>
<div class="tile piece6"></div>
<div class="tile piece7"></div>
<div class="tile piece8"></div>
<div class="tile piece9"></div>
</div>
我还不确定我开始走的路是否行得通。
谢谢。
一种方法,只需进行一些更改:
1) background-position, 应为"left top", "top", "right top", "left", "center", "right", "bottom left"、"bottom center" 和 "bottom right" 将图像切成 9 块。
https://www.w3schools.com/cssref/pr_background-position.asp
2) 由于原图尺寸为2400 x 1600,将"background-size"设置小一点,然后根据较小的尺寸用calc计算,比如:
width: calc(600px / 3);
height: calc(600px / 3);
3) 将图块位置设置为绝对位置。
4) 使用顶部和左侧指定每个图块的绝对位置。
5) 为每个图块指定唯一的 ID。
6) 使用javascript 的setInterval 和if else 语句来改变元素的绝对位置,使用每个元素的id 来决定它们的top 和left 属性应该如何超时改变。
7) 在示例中,我使用按钮 "Click Me" 来执行脚本,但您可以使用 onload 或任何您想调用 moveElements()
函数来执行此操作。
<style>
/* The photo resolution: 2400 x 1600 */
.slideshow {
display: grid;
grid-template-rows: auto auto auto;
grid-template-columns: auto auto auto;
}
.tile {
background-image: url(https://unsplash.com/photos/hzgs56Ze49s/download?force=true&w=2400);
background-size: 600px 600px;
/* width: 800px;
height: 533px; */
width: calc(600px / 3);
height: calc(600px / 3);
transform: scale(0.5, 0.5);
position:absolute;
}
.piece1 {
background-position: left top;
grid-row: 1/1;
grid-column: 1/1;
top:0;
left:0;
}
.piece2 {
background-position: top;
grid-row: 1/1;
grid-column: 2/2;
top:0;
left:250;
}
.piece3 {
background-position: right top;
grid-row: 1/1;
grid-column: 3/3;
top:0;
left:500;
}
.piece4 {
background-position: left;
grid-row: 2/2;
grid-column: 1/1;
top:250;
left:0;
}
.piece5 {
background-position: center;
grid-row: 2/2;
grid-column: 2/2;
top:250;
left: 250;
}
.piece6 {
background-position: right;
grid-row: 2/2;
grid-column: 3/3;
top:250;
left:500;
}
.piece7 {
background-position: bottom left;
grid-row: 3/3;
grid-column: 1/1;
top:500;
left:0;
}
.piece8 {
background-position: bottom center;
grid-row: 3/3;
grid-column: 2/2;
top:500;
left:250;
}
.piece9 {
background-position: bottom right;
grid-row: 3/3;
grid-column: 3/3;
top:500;
left:500;
}
</style>
<p><button onclick="moveElements()">Click Me</button></p>
<div class="slideshow">
<div id="topleft" class="tile piece1"></div>
<div id="top" class="tile piece2"></div>
<div id="topright" class="tile piece3"></div>
<div id="left" class="tile piece4"></div>
<div id="center" class="tile piece5"></div>
<div id="right" class="tile piece6"></div>
<div id="bottomleft" class="tile piece7"></div>
<div id="bottomcenter" class="tile piece8"></div>
<div id="bottomright" class="tile piece9"></div>
</div>
<script>
function moveElements() {
var elem1 = document.getElementById("topleft");
var pos1 = 0;
var id1 = setInterval(frame1, 5);
function frame1() {
if (pos1 == 151) {
clearInterval(id1);
} else {
pos1++;
elem1.style.top = pos1 + "px";
elem1.style.left = pos1 + "px";
}
}
var elem2 = document.getElementById("top");
var pos2 = 0;
var id2 = setInterval(frame2, 5);
function frame2() {
if (pos2 == 151) {
clearInterval(id2);
} else {
pos2++;
elem2.style.top = pos2 + "px";
}
}
var elem3 = document.getElementById("topright");
var pos3t = 0;
var pos3l = 500;
var id3 = setInterval(frame3, 5);
function frame3() {
if (pos3t == 151) {
clearInterval(id3);
} else {
pos3t++;
pos3l--;
elem3.style.top = pos3t + "px";
elem3.style.left = pos3l + "px";
}
}
var elem4 = document.getElementById("left");
var pos4 = 0;
var id4 = setInterval(frame4, 5);
function frame4() {
if (pos4 == 151) {
clearInterval(id4);
} else {
pos4++;
elem4.style.left = pos4 + "px";
}
}
// element5, the center tile stays still
var elem6 = document.getElementById("right");
var pos6 = 500;
var id6 = setInterval(frame6, 5);
function frame6() {
if (pos6 == 349) {
clearInterval(id6);
} else {
pos6--;
elem6.style.left = pos6 + "px";
}
}
var elem7 = document.getElementById("bottomleft");
var pos7t = 500;
var pos7l = 0;
var id7 = setInterval(frame7, 5);
function frame7() {
if (pos7t == 349) {
clearInterval(id7);
} else {
pos7t--;
pos7l++;
elem7.style.top = pos7t + "px";
elem7.style.left = pos7l + "px";
}
}
var elem8 = document.getElementById("bottomcenter");
var pos8 = 500;
var id8 = setInterval(frame8, 5);
function frame8() {
if (pos8 == 349) {
clearInterval(id8);
} else {
pos8--;
elem8.style.top = pos8 + "px";
}
}
var elem9 = document.getElementById("bottomright");
var pos9 = 500;
var id9 = setInterval(frame9, 5);
function frame9() {
if (pos9 == 349) {
clearInterval(id9);
} else {
pos9--;
elem9.style.top = pos9 + "px";
elem9.style.left = pos9 + "px";
}
}
}
</script>
我会考虑使用 position:absolute
将所有图像层放在彼此之上,我将依靠 mask
(或剪辑路径)仅显示其中的一部分。然后你就可以轻松应用翻译了。
悬停查看效果:
.slideshow {
width: 400px;
height: 261px;
margin:100px auto;
position:relative;
background-image: url(https://unsplash.com/photos/hzgs56Ze49s/download?force=true&w=2400);
background-size: 0 0;
}
.tile {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: inherit;
background-size: cover;
-webkit-mask:linear-gradient(#fff,#fff) no-repeat;
-webkit-mask-size:33.4% 33.4%;
-webkit-mask-position:var(--p);
mask:linear-gradient(#fff,#fff) no-repeat;
mask-size:33.4% 33.4%;
mask-position:var(--p);
transition:0.5s;
}
.piece1 {--p:top left; --t:-10%, -10%;}
.piece2 {--p:center left; --t:-10%, 0%;}
.piece3 {--p:bottom left; --t:-10%, 10%;}
.piece4 {--p:top center;--t: 0%, -10%;}
.piece5 {--p:center center;--t: 0%, 0%;}
.piece6 {--p:bottom center;--t: 0%, 10%;}
.piece7 {--p:top right; --t: 10%, -10%;}
.piece8 {--p:center right; --t: 10%, 0%;}
.piece9 {--p:bottom right; --t: 10%, 10%;}
.slideshow:hover .tile{
transform:translate(var(--t));
}
body {
background:#f2f2f2;
}
<div class="slideshow">
<div class="tile piece1"></div>
<div class="tile piece2"></div>
<div class="tile piece3"></div>
<div class="tile piece4"></div>
<div class="tile piece5"></div>
<div class="tile piece6"></div>
<div class="tile piece7"></div>
<div class="tile piece8"></div>
<div class="tile piece9"></div>
</div>
您可以使用不需要大量代码的规模效应进行优化,并且可以将 mask-position
与 transform-origin
重用
.slideshow {
width: 400px;
height: 261px;
margin:50px auto;
position:relative;
background-image: url(https://unsplash.com/photos/hzgs56Ze49s/download?force=true&w=2400);
background-size: 0 0;
transition:0.5s;
}
.tile {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: inherit;
background-size: cover;
-webkit-mask:linear-gradient(#fff,#fff) no-repeat;
-webkit-mask-size:33.4% 33.4%;
-webkit-mask-position:var(--p);
mask:linear-gradient(#fff,#fff) no-repeat;
mask-size:33.4% 33.4%;
mask-position:var(--p);
transition:inherit;
transform-origin:var(--p);
}
.piece1 {--p:top left;}
.piece2 {--p:center left;}
.piece3 {--p:bottom left;}
.piece4 {--p:top center;}
.piece5 {--p:center center;}
.piece6 {--p:bottom center;}
.piece7 {--p:top right;}
.piece8 {--p:center right;}
.piece9 {--p:bottom right;}
.slideshow:hover .tile{
transform:scale(0.8);
}
.slideshow:hover {
transform:scale(1.25);
}
body {
background:#f2f2f2;
}
<div class="slideshow">
<div class="tile piece1"></div>
<div class="tile piece2"></div>
<div class="tile piece3"></div>
<div class="tile piece4"></div>
<div class="tile piece5"></div>
<div class="tile piece6"></div>
<div class="tile piece7"></div>
<div class="tile piece8"></div>
<div class="tile piece9"></div>
</div>
您可以轻松缩放到 4x4 或任何 NxN 网格:
.slideshow {
--n:4;
width: 400px;
height: 261px;
margin:100px auto;
position:relative;
background-image: url(https://unsplash.com/photos/hzgs56Ze49s/download?force=true&w=2400);
background-size: 0 0;
transition:0.5s;
}
.tile {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: inherit;
background-size: cover;
-webkit-mask:linear-gradient(#fff,#fff) no-repeat;
-webkit-mask-size:calc(100%/var(--n) + 1px) calc(100%/var(--n) + 1px);
-webkit-mask-position:var(--p);
mask:linear-gradient(#fff,#fff) no-repeat;
mask-size:calc(100%/var(--n) + 1px) calc(100%/var(--n) + 1px);
mask-position:var(--p);
transition:inherit;
transform-origin:var(--p);
}
.tile:nth-child(1) {--p:calc(0*100%/(var(--n) - 1)) calc(0*100%/(var(--n) - 1));}
.tile:nth-child(2) {--p:calc(1*100%/(var(--n) - 1)) calc(0*100%/(var(--n) - 1));}
.tile:nth-child(3) {--p:calc(2*100%/(var(--n) - 1)) calc(0*100%/(var(--n) - 1));}
.tile:nth-child(4) {--p:calc(3*100%/(var(--n) - 1)) calc(0*100%/(var(--n) - 1));}
.tile:nth-child(5) {--p:calc(0*100%/(var(--n) - 1)) calc(1*100%/(var(--n) - 1));}
.tile:nth-child(6) {--p:calc(1*100%/(var(--n) - 1)) calc(1*100%/(var(--n) - 1));}
.tile:nth-child(7) {--p:calc(2*100%/(var(--n) - 1)) calc(1*100%/(var(--n) - 1));}
.tile:nth-child(8) {--p:calc(3*100%/(var(--n) - 1)) calc(1*100%/(var(--n) - 1));}
.tile:nth-child(9) {--p:calc(0*100%/(var(--n) - 1)) calc(2*100%/(var(--n) - 1));}
.tile:nth-child(10) {--p:calc(1*100%/(var(--n) - 1)) calc(2*100%/(var(--n) - 1));}
.tile:nth-child(11) {--p:calc(2*100%/(var(--n) - 1)) calc(2*100%/(var(--n) - 1));}
.tile:nth-child(12) {--p:calc(3*100%/(var(--n) - 1)) calc(2*100%/(var(--n) - 1));}
.tile:nth-child(13) {--p:calc(0*100%/(var(--n) - 1)) calc(3*100%/(var(--n) - 1));}
.tile:nth-child(14) {--p:calc(1*100%/(var(--n) - 1)) calc(3*100%/(var(--n) - 1));}
.tile:nth-child(15) {--p:calc(2*100%/(var(--n) - 1)) calc(3*100%/(var(--n) - 1));}
.tile:nth-child(16) {--p:calc(3*100%/(var(--n) - 1)) calc(3*100%/(var(--n) - 1));}
.slideshow:hover > *{
transform:scale(0.8);
}
.slideshow:hover {
transform:scale(1.25);
}
body {
background:#f2f2f2;
}
<div class="slideshow">
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
</div>
动画类似于 PowerPoint 中的幻灯片切换。我会使用 skew
和 translate
(从页面边缘的随机位置)转换来完成。我开始使用 CSS sprites 和 CSS 网格。我遇到的第一个问题是网格之间的间距,Chrome DevTools 中没有解释间距。我可以使用 anime.js
或其他库。
下面的问题是碎片之间的间距,它们没有显示所需的图像的完整部分。原图为here.
/* The photo resolution: 2400 x 1600 */
.slideshow {
display: grid;
grid-template-rows: auto auto auto;
grid-template-columns: auto auto auto;
}
.tile {
background-image: url(https://unsplash.com/photos/hzgs56Ze49s/download?force=true&w=2400);
/* width: 800px;
height: 533px; */
width: calc(800px / 2);
height: calc(533px / 2);
transform: scale(0.5, 0.5);
}
.piece1 {
background-position: 0 0;
grid-row: 1/1;
grid-column: 1/1;
}
.piece2 {
background-position: -800px 0;
grid-row: 1/1;
grid-column: 2/2;
}
.piece3 {
background-position: -1600px 0;
grid-row: 1/1;
grid-column: 3/3;
}
.piece4 {
background-position: 0 -533px;
grid-row: 2/2;
grid-column: 1/1;
}
.piece5 {
background-position: -800px -533px;
grid-row: 2/2;
grid-column: 2/2;
}
.piece6 {
background-position: -1600px -533px;
grid-row: 2/2;
grid-column: 3/3;
}
.piece7 {
background-position: 0 -1066px;
grid-row: 3/3;
grid-column: 1/1;
}
.piece8 {
background-position: -800px -1066px;
grid-row: 3/3;
grid-column: 2/2;
}
.piece9 {
background-position: -1600px -1066px;
grid-row: 3/3;
grid-column: 3/3;
}
<div class="slideshow">
<div class="tile piece1"></div>
<div class="tile piece2"></div>
<div class="tile piece3"></div>
<div class="tile piece4"></div>
<div class="tile piece5"></div>
<div class="tile piece6"></div>
<div class="tile piece7"></div>
<div class="tile piece8"></div>
<div class="tile piece9"></div>
</div>
我还不确定我开始走的路是否行得通。
谢谢。
一种方法,只需进行一些更改:
1) background-position, 应为"left top", "top", "right top", "left", "center", "right", "bottom left"、"bottom center" 和 "bottom right" 将图像切成 9 块。
https://www.w3schools.com/cssref/pr_background-position.asp
2) 由于原图尺寸为2400 x 1600,将"background-size"设置小一点,然后根据较小的尺寸用calc计算,比如:
width: calc(600px / 3);
height: calc(600px / 3);
3) 将图块位置设置为绝对位置。
4) 使用顶部和左侧指定每个图块的绝对位置。
5) 为每个图块指定唯一的 ID。
6) 使用javascript 的setInterval 和if else 语句来改变元素的绝对位置,使用每个元素的id 来决定它们的top 和left 属性应该如何超时改变。
7) 在示例中,我使用按钮 "Click Me" 来执行脚本,但您可以使用 onload 或任何您想调用 moveElements()
函数来执行此操作。
<style>
/* The photo resolution: 2400 x 1600 */
.slideshow {
display: grid;
grid-template-rows: auto auto auto;
grid-template-columns: auto auto auto;
}
.tile {
background-image: url(https://unsplash.com/photos/hzgs56Ze49s/download?force=true&w=2400);
background-size: 600px 600px;
/* width: 800px;
height: 533px; */
width: calc(600px / 3);
height: calc(600px / 3);
transform: scale(0.5, 0.5);
position:absolute;
}
.piece1 {
background-position: left top;
grid-row: 1/1;
grid-column: 1/1;
top:0;
left:0;
}
.piece2 {
background-position: top;
grid-row: 1/1;
grid-column: 2/2;
top:0;
left:250;
}
.piece3 {
background-position: right top;
grid-row: 1/1;
grid-column: 3/3;
top:0;
left:500;
}
.piece4 {
background-position: left;
grid-row: 2/2;
grid-column: 1/1;
top:250;
left:0;
}
.piece5 {
background-position: center;
grid-row: 2/2;
grid-column: 2/2;
top:250;
left: 250;
}
.piece6 {
background-position: right;
grid-row: 2/2;
grid-column: 3/3;
top:250;
left:500;
}
.piece7 {
background-position: bottom left;
grid-row: 3/3;
grid-column: 1/1;
top:500;
left:0;
}
.piece8 {
background-position: bottom center;
grid-row: 3/3;
grid-column: 2/2;
top:500;
left:250;
}
.piece9 {
background-position: bottom right;
grid-row: 3/3;
grid-column: 3/3;
top:500;
left:500;
}
</style>
<p><button onclick="moveElements()">Click Me</button></p>
<div class="slideshow">
<div id="topleft" class="tile piece1"></div>
<div id="top" class="tile piece2"></div>
<div id="topright" class="tile piece3"></div>
<div id="left" class="tile piece4"></div>
<div id="center" class="tile piece5"></div>
<div id="right" class="tile piece6"></div>
<div id="bottomleft" class="tile piece7"></div>
<div id="bottomcenter" class="tile piece8"></div>
<div id="bottomright" class="tile piece9"></div>
</div>
<script>
function moveElements() {
var elem1 = document.getElementById("topleft");
var pos1 = 0;
var id1 = setInterval(frame1, 5);
function frame1() {
if (pos1 == 151) {
clearInterval(id1);
} else {
pos1++;
elem1.style.top = pos1 + "px";
elem1.style.left = pos1 + "px";
}
}
var elem2 = document.getElementById("top");
var pos2 = 0;
var id2 = setInterval(frame2, 5);
function frame2() {
if (pos2 == 151) {
clearInterval(id2);
} else {
pos2++;
elem2.style.top = pos2 + "px";
}
}
var elem3 = document.getElementById("topright");
var pos3t = 0;
var pos3l = 500;
var id3 = setInterval(frame3, 5);
function frame3() {
if (pos3t == 151) {
clearInterval(id3);
} else {
pos3t++;
pos3l--;
elem3.style.top = pos3t + "px";
elem3.style.left = pos3l + "px";
}
}
var elem4 = document.getElementById("left");
var pos4 = 0;
var id4 = setInterval(frame4, 5);
function frame4() {
if (pos4 == 151) {
clearInterval(id4);
} else {
pos4++;
elem4.style.left = pos4 + "px";
}
}
// element5, the center tile stays still
var elem6 = document.getElementById("right");
var pos6 = 500;
var id6 = setInterval(frame6, 5);
function frame6() {
if (pos6 == 349) {
clearInterval(id6);
} else {
pos6--;
elem6.style.left = pos6 + "px";
}
}
var elem7 = document.getElementById("bottomleft");
var pos7t = 500;
var pos7l = 0;
var id7 = setInterval(frame7, 5);
function frame7() {
if (pos7t == 349) {
clearInterval(id7);
} else {
pos7t--;
pos7l++;
elem7.style.top = pos7t + "px";
elem7.style.left = pos7l + "px";
}
}
var elem8 = document.getElementById("bottomcenter");
var pos8 = 500;
var id8 = setInterval(frame8, 5);
function frame8() {
if (pos8 == 349) {
clearInterval(id8);
} else {
pos8--;
elem8.style.top = pos8 + "px";
}
}
var elem9 = document.getElementById("bottomright");
var pos9 = 500;
var id9 = setInterval(frame9, 5);
function frame9() {
if (pos9 == 349) {
clearInterval(id9);
} else {
pos9--;
elem9.style.top = pos9 + "px";
elem9.style.left = pos9 + "px";
}
}
}
</script>
我会考虑使用 position:absolute
将所有图像层放在彼此之上,我将依靠 mask
(或剪辑路径)仅显示其中的一部分。然后你就可以轻松应用翻译了。
悬停查看效果:
.slideshow {
width: 400px;
height: 261px;
margin:100px auto;
position:relative;
background-image: url(https://unsplash.com/photos/hzgs56Ze49s/download?force=true&w=2400);
background-size: 0 0;
}
.tile {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: inherit;
background-size: cover;
-webkit-mask:linear-gradient(#fff,#fff) no-repeat;
-webkit-mask-size:33.4% 33.4%;
-webkit-mask-position:var(--p);
mask:linear-gradient(#fff,#fff) no-repeat;
mask-size:33.4% 33.4%;
mask-position:var(--p);
transition:0.5s;
}
.piece1 {--p:top left; --t:-10%, -10%;}
.piece2 {--p:center left; --t:-10%, 0%;}
.piece3 {--p:bottom left; --t:-10%, 10%;}
.piece4 {--p:top center;--t: 0%, -10%;}
.piece5 {--p:center center;--t: 0%, 0%;}
.piece6 {--p:bottom center;--t: 0%, 10%;}
.piece7 {--p:top right; --t: 10%, -10%;}
.piece8 {--p:center right; --t: 10%, 0%;}
.piece9 {--p:bottom right; --t: 10%, 10%;}
.slideshow:hover .tile{
transform:translate(var(--t));
}
body {
background:#f2f2f2;
}
<div class="slideshow">
<div class="tile piece1"></div>
<div class="tile piece2"></div>
<div class="tile piece3"></div>
<div class="tile piece4"></div>
<div class="tile piece5"></div>
<div class="tile piece6"></div>
<div class="tile piece7"></div>
<div class="tile piece8"></div>
<div class="tile piece9"></div>
</div>
您可以使用不需要大量代码的规模效应进行优化,并且可以将 mask-position
与 transform-origin
.slideshow {
width: 400px;
height: 261px;
margin:50px auto;
position:relative;
background-image: url(https://unsplash.com/photos/hzgs56Ze49s/download?force=true&w=2400);
background-size: 0 0;
transition:0.5s;
}
.tile {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: inherit;
background-size: cover;
-webkit-mask:linear-gradient(#fff,#fff) no-repeat;
-webkit-mask-size:33.4% 33.4%;
-webkit-mask-position:var(--p);
mask:linear-gradient(#fff,#fff) no-repeat;
mask-size:33.4% 33.4%;
mask-position:var(--p);
transition:inherit;
transform-origin:var(--p);
}
.piece1 {--p:top left;}
.piece2 {--p:center left;}
.piece3 {--p:bottom left;}
.piece4 {--p:top center;}
.piece5 {--p:center center;}
.piece6 {--p:bottom center;}
.piece7 {--p:top right;}
.piece8 {--p:center right;}
.piece9 {--p:bottom right;}
.slideshow:hover .tile{
transform:scale(0.8);
}
.slideshow:hover {
transform:scale(1.25);
}
body {
background:#f2f2f2;
}
<div class="slideshow">
<div class="tile piece1"></div>
<div class="tile piece2"></div>
<div class="tile piece3"></div>
<div class="tile piece4"></div>
<div class="tile piece5"></div>
<div class="tile piece6"></div>
<div class="tile piece7"></div>
<div class="tile piece8"></div>
<div class="tile piece9"></div>
</div>
您可以轻松缩放到 4x4 或任何 NxN 网格:
.slideshow {
--n:4;
width: 400px;
height: 261px;
margin:100px auto;
position:relative;
background-image: url(https://unsplash.com/photos/hzgs56Ze49s/download?force=true&w=2400);
background-size: 0 0;
transition:0.5s;
}
.tile {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: inherit;
background-size: cover;
-webkit-mask:linear-gradient(#fff,#fff) no-repeat;
-webkit-mask-size:calc(100%/var(--n) + 1px) calc(100%/var(--n) + 1px);
-webkit-mask-position:var(--p);
mask:linear-gradient(#fff,#fff) no-repeat;
mask-size:calc(100%/var(--n) + 1px) calc(100%/var(--n) + 1px);
mask-position:var(--p);
transition:inherit;
transform-origin:var(--p);
}
.tile:nth-child(1) {--p:calc(0*100%/(var(--n) - 1)) calc(0*100%/(var(--n) - 1));}
.tile:nth-child(2) {--p:calc(1*100%/(var(--n) - 1)) calc(0*100%/(var(--n) - 1));}
.tile:nth-child(3) {--p:calc(2*100%/(var(--n) - 1)) calc(0*100%/(var(--n) - 1));}
.tile:nth-child(4) {--p:calc(3*100%/(var(--n) - 1)) calc(0*100%/(var(--n) - 1));}
.tile:nth-child(5) {--p:calc(0*100%/(var(--n) - 1)) calc(1*100%/(var(--n) - 1));}
.tile:nth-child(6) {--p:calc(1*100%/(var(--n) - 1)) calc(1*100%/(var(--n) - 1));}
.tile:nth-child(7) {--p:calc(2*100%/(var(--n) - 1)) calc(1*100%/(var(--n) - 1));}
.tile:nth-child(8) {--p:calc(3*100%/(var(--n) - 1)) calc(1*100%/(var(--n) - 1));}
.tile:nth-child(9) {--p:calc(0*100%/(var(--n) - 1)) calc(2*100%/(var(--n) - 1));}
.tile:nth-child(10) {--p:calc(1*100%/(var(--n) - 1)) calc(2*100%/(var(--n) - 1));}
.tile:nth-child(11) {--p:calc(2*100%/(var(--n) - 1)) calc(2*100%/(var(--n) - 1));}
.tile:nth-child(12) {--p:calc(3*100%/(var(--n) - 1)) calc(2*100%/(var(--n) - 1));}
.tile:nth-child(13) {--p:calc(0*100%/(var(--n) - 1)) calc(3*100%/(var(--n) - 1));}
.tile:nth-child(14) {--p:calc(1*100%/(var(--n) - 1)) calc(3*100%/(var(--n) - 1));}
.tile:nth-child(15) {--p:calc(2*100%/(var(--n) - 1)) calc(3*100%/(var(--n) - 1));}
.tile:nth-child(16) {--p:calc(3*100%/(var(--n) - 1)) calc(3*100%/(var(--n) - 1));}
.slideshow:hover > *{
transform:scale(0.8);
}
.slideshow:hover {
transform:scale(1.25);
}
body {
background:#f2f2f2;
}
<div class="slideshow">
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
<div class="tile"></div>
</div>