天天看點

css過渡 取消過渡_純CSS中的3D威尼斯式盲圖像過渡

css過渡 取消過渡

Prompted by a question from a 2nd year student, I was inspired to explore the visual effect you can see above. Variations on this transition have long been a mainstay of JQuery carousels; I was interested in working out if it could be achieved in pure CSS, with the condition that the result should also be responsive: most JavaScript solutions are not.

在第二年級學生提出的一個問題的提示下,我受到啟發去探索上面可以看到的視覺效果。 長期以來,這種過渡的變體一直是JQuery輪播的主體。 我有興趣研究是否可以在純CSS中實作,條件是結果也應該響應 :大多數JavaScript解決方案都不能。

It’s certainly doable, albeit with a bit of markup: the solution requires as many copies of the image as we would like “shutters” at the bitmap’s maximum dimensions. In this case, I wanted 10 vertical “blinds” for images that would have a maximum width of 1000 pixels. This required 10 copies of each photograph, arranged inside a

<figure>

container. At the same time, I needed 10 copies of the alternate image on the reverse side. Each image set would have a different class:

盡管有一點标記,但它當然是可行的:該解決方案需要在位圖的最大尺寸上像我們希望的“快門”一樣多的圖像副本。 在這種情況下,我要為最大寬度為1000像素的圖像設定10個垂直“盲點”。 每張照片需要10份副本,并放置在

<figure>

容器中。 同時,我需要在背面列印10張備用圖檔。 每個圖像集将具有不同的類:

<figure id="blinds">
	<img src="autumn-face.jpg" alt class="first">
	<img src="autumn-face.jpg" alt class="first">
	…
	<img src="autumn-face.jpg" alt class="first">
	…
	<img src="julia.jpg" alt class="second">
	<img src="julia.jpg" alt class="second">
	…
	<img src="julia.jpg" alt class="second">
</figure>
           

In reality, only two images will be loaded, with copies duplicated in the browser. All images are exactly the same size, in the same absolute position. The

<figure>

element will be 100% of the width of its container, with the correct height provided by using the same trick I use for responsive video:

實際上,将僅加載兩個圖像,并且副本在浏覽器中重複。 所有圖像在相同的絕對位置上均具有完全相同的尺寸。

<figure>

元素将是其容器寬度的100%,并使用與響應視訊相同的技巧提供正确的高度:

#blinds {
	margin: 0;
	position: relative;
	padding-bottom: 56.5%;
	perspective: 1800px;
	transform-style: preserve-3d;
	max-width: 1000px;
}
#blinds img {
	top: 0; left: 0;
	position: absolute;
	transition: 1s;
}
           

Every copy of the second image is rotated 180 degrees and placed behind the others by using a slight

translate

value:

第二個圖像的每個副本都旋轉180度,并使用輕微的

translate

值放置在其他圖像的後面:

#blinds img.first {
	transform: rotateY(0deg);
}
#blinds img.second {
	transform: rotateY(-180deg) translateZ(1px);
}
           

To create the slices, I use

clip

, with

nth-child

as a selector. As you can see, both image’s

clip

left and right values increase by 100 after each iteration:

要建立切片,我使用

clip

,将

nth-child

作為選擇器。 如您所見,每次疊代後,圖像的

clip

左右值都增加了100:

#blinds img:nth-child(1),
	#blinds img:nth-child(11) {
		clip: rect(0px, 100px, 840px, 0px);
}
#blinds img:nth-child(2),
	#blinds img:nth-child(12) {
		clip: rect(0px, 200px, 840px, 100px);
}
#blinds img:nth-child(3),
	#blinds img:nth-child(13) {
		clip: rect(0px, 300px, 840px, 200px);
}
…
#blinds img:nth-child(10n) {
	clip: rect(0px, 1000px, 840px, 900px);
}
           

Even after using

clip

, the image’s

transform-origin

– the point around which the image will be transformed – remains the center of the element. To counter that, we set the

transform-origin

for each slice so that it is at the halfway point. Think of the position of the central axes in a set of vertical blinds:

即使在使用

clip

,圖像的

transform-origin

(将在其周圍

transform-origin

圖像的點)仍然是元素的中心。 為了解決這個問題,我們為每個切片設定了

transform-origin

,以使其位于中間點。 考慮一下一組垂直百葉窗中軸的位置:

css過渡 取消過渡_純CSS中的3D威尼斯式盲圖像過渡

transform-origin

for clipped “venetian blind” images

transform-origin

邏輯位置

In CSS:

在CSS中:

#blinds img:nth-child(1),
	#blinds img:nth-child(11) {
		clip: rect(0px, 100px, 840px, 0px);
		transform-origin: 50px 0px;
}
#blinds img:nth-child(2),
	#blinds img:nth-child(12) {
		clip: rect(0px, 200px, 840px, 100px);
		transform-origin: 150px 0px;
}
#blinds img:nth-child(3),
	#blinds img:nth-child(13) {
		clip: rect(0px, 300px, 840px, 200px);
		transform-origin: 250px 0px;
}
…
#blinds img:nth-child(10n) {
	clip: rect(0px, 1000px, 840px, 900px);
	transform-origin: 950px 0px;
}
           

Then we can rotate the image sets 180° on

:hover

, distinguished by their

class

:

然後我們可以将圖像集在

:hover

上旋轉180°,按其

class

區分:

#blinds:hover img.first {
	transform: rotateY(180deg);
}
#blinds:hover img.second {
	transform: rotateY(0deg) translateZ(1px);
}
           

As written, all the “blinds” will rotate at the same time. To create a “ripple” effect, we delay the transition of each slice:

如所寫,所有“百葉窗”将同時旋轉。 要建立“漣漪”效果,我們延遲每個切片的過渡:

#blinds img:nth-child(1),
	#blinds img:nth-child(11) {
		clip: rect(0px, 100px, 840px, 0px);
		transform-origin: 50px 0px;
}
#blinds img:nth-child(2),
	#blinds img:nth-child(12) {
		clip: rect(0px, 200px, 840px, 100px);
		transform-origin: 150px 0px;
		transition-delay: 100ms;
}
#blinds img:nth-child(3),
	#blinds img:nth-child(13) {
		clip: rect(0px, 300px, 840px, 200px);
		transform-origin: 250px 0px;
		transition-delay: 200ms;
}
…
#blinds img:nth-child(10n)  {
	clip: rect(0px, 1000px, 840px, 900px);
	transform-origin: 950px 0px;
	transition-delay: 900ms;
}
           

One nice feature of using

clip

is that the result is automatically responsive: if the image narrows, the number of slices is reduced also. Try narrowing your browser window: if the viewport is 500px wide, the images are animated as five even slices.

使用

clip

一個不錯的功能是結果是自動響應的:如果圖像變窄,切片的數量也會減少。 嘗試縮小浏覽器視窗的範圍:如果視口為500px寬,則圖像将被動畫化為五個偶數切片。

替代方法 (Alternative Approaches)

The repetitive nature of the code cries out for a more efficient approach: either a pre-processor, or some JavaScript to automatically create the CSS. I’ll tackle both approaches in the very near future. For right now, this is a good start, although not yet perfect: due to browser rendering issues, it’s possible to see the occasional “kinked” or overlapping image slice during the transition.

代碼的重複性要求更有效的方法:預處理器或一些JavaScript自動建立CSS。 我将在不久的将來解決這兩種方法。 目前,這是一個不錯的開始,盡管還不是很完美:由于浏覽器渲染問題,過渡期間偶爾會出現“扭曲”或重疊的圖像切片。

翻譯自: https://thenewcode.com/776/3D-Venetian-Blind-Image-Transition-In-Pure-CSS

css過渡 取消過渡

繼續閱讀