我正試圖創造一個& quot本·伯恩斯& quot使用CSS & quot轉換& quot屬性。目前,我正在使用& quot對象位置& quot來控制動畫,但是我在運動的流暢度上遇到了問題。
我想知道是否有人可以幫助我創建一個更流暢的動畫只使用CSS轉換屬性,如& quot翻譯& quot或者& quotscale & quot。
此外,我還創建了一個演示來展示我當前的實現(或者,如果您愿意,也可以在Codepen上展示):
body {
display: flex;
}
.image-container {
width: 150px;
height: 150px;
border-radius: 10px;
overflow: hidden;
}
.object-position .image-container img {
width: 150px;
height: 150px;
animation: kenBurns-object-position 20s linear infinite;
object-fit: cover;
}
.transform .image-container img {
width: 150px;
height: 150px;
animation: kenBurns-tranform 20s linear infinite;
object-fit: cover;
}
@-webkit-keyframes kenBurns-object-position {
0% {
transform: scale(1.2);
object-position: left top;
}
100% {
transform: scale(1.0);
object-position: center;
}
}
@-webkit-keyframes kenBurns-tranform {
0% {
transform: scale(1.2) translate(-50px,0px);
}
100% {
transform: scale(1.0) translate(0px,0px);
}
}
<div class="object-position">
<h1>Animation using "object-position"</h1>
<label>image ratio: 1x1</label>
<div class="image-container">
<img src="https://source.unsplash.com/featured/500x500">
</div>
<label>image ratio: 2x1</label>
<div class="image-container">
<img src="https://source.unsplash.com/featured/1000x500">
</div>
<label>image ratio: 1x2</label>
<div class="image-container">
<img src="https://source.unsplash.com/featured/500x1000">
</div>
</div>
<div class="transform">
<h1>Animation using "transform"</h1>
<label>image ratio: 1x1</label>
<div class="image-container">
<img src="https://source.unsplash.com/featured/500x500">
</div>
<label>image ratio: 2x1</label>
<div class="image-container">
<img src="https://source.unsplash.com/featured/1000x500">
</div>
<label>image ratio: 1x2</label>
<div class="image-container">
<img src="https://source.unsplash.com/featured/500x1000">
</div>
</div>
良好的...我設法實現了我想要的目標,但我想我可能有點過度了...
如果有人能看看下面的代碼來改進它或者至少簡化它,我仍然會很感激。
基本上,我用javascript解析圖像,并創建一個類來判斷它是風景、肖像還是方形圖像。此外,我收集圖像的尺寸,并將其保存為一個變量,用于動畫計算...
有一點仍然不是100%正確,那就是當動畫到達垂直圖像的頂部或底部,或者水平圖像的右側和左側時。在這種情況下,由于比例效應,它最終沒有接觸到圖像的邊緣,但我決定保持這種方式,以避免該函數中更多的計算和復雜性...
function analyzeImages() {
var images = document.querySelectorAll('.item-image');
images.forEach(function(image) {
var img = new Image();
img.src = image.src;
img.addEventListener('load', function() {
var width = img.naturalWidth;
var height = img.naturalHeight;
var aspectRatio = width / height;
var imageClass = '';
var largeSize = '';
var smallSize = '';
if (aspectRatio > 1) {
imageClass = 'landscape';
largeSize = width + 'px';
smallSize = height;
} else if (aspectRatio < 1) {
imageClass = 'portrait';
largeSize = height + 'px';
smallSize = width;
} else {
imageClass = 'square';
largeSize = width + 'px';
smallSize = height + 'px';
}
image.classList.add(imageClass);
image.style.setProperty('--large-size', largeSize);
image.style.setProperty('--small-size', smallSize);
});
});
}
document.addEventListener('DOMContentLoaded', function() {
analyzeImages();
});
body {
display: flex;
margin: 100px;
}
.image-container {
width: 200px;
height: 200px;
border-radius: 10px;
overflow: hidden;
object-fit: cover;
}
.item-image.square {
width: 200px;
height: 200px;
animation: kenBurns-square 30s linear infinite;
}
.item-image.landscape {
height: 200px;
animation: kenBurns-landscape 30s linear infinite;
}
.item-image.portrait {
width: 200px;
animation: kenBurns-portrait 30s linear infinite;
}
@-webkit-keyframes kenBurns-square {
0% {
transform: scale(1.3);
}
33% {
transform: scale(1.0);
}
66% {
transform: scale(1.0);
}
100% {
transform: scale(1.3);
}
}
@-webkit-keyframes kenBurns-portrait {
0% {
transform: translateY(calc((var(--large-size) / (var(--small-size) / 200) - 200px) / -2)); /* center */
}
10% {
transform: translateY(calc((var(--large-size) / (var(--small-size) / 200) - 200px) / -2)); /* center */
}
20% {
transform: scale(1.0) translateY(0px); /* top */
}
40% {
transform: scale(1.3) translateY(calc((var(--large-size) / (var(--small-size) / 200) - 200px) * -1)); /* bottom */
}
60% {
transform: scale(1.3) translateY(0px); /* top */
}
80% {
transform: scale(1.0) translateY(calc((var(--large-size) / (var(--small-size) / 200) - 200px) * -1)); /* bottom */
}
90% {
transform: translateY(calc((var(--large-size) / (var(--small-size) / 200) - 200px) / -2)); /* center */
}
100% {
transform: translateY(calc((var(--large-size) / (var(--small-size) / 200) - 200px) / -2)); /* center */
}
}
@-webkit-keyframes kenBurns-landscape {
0% {
transform: translateX(calc((var(--large-size) / (var(--small-size) / 200) - 200px) / -2)); /* center */
}
10% {
transform: translateX(calc((var(--large-size) / (var(--small-size) / 200) - 200px) / -2)); /* center */
}
20% {
transform: scale(1.0) translateX(0px); /* left */
}
40% {
transform: scale(1.3) translateX(calc((var(--large-size) / (var(--small-size) / 200) - 200px) * -1)); /* right */
}
60% {
transform: scale(1.3) translateX(0px); /* left */
}
80% {
transform: scale(1.0) translateX(calc((var(--large-size) / (var(--small-size) / 200) - 200px) * -1)); /* right */
}
90% {
transform: translateX(calc((var(--large-size) / (var(--small-size) / 200) - 200px) / -2)); /* center */
}
100% {
transform: translateX(calc((var(--large-size) / (var(--small-size) / 200) - 200px) / -2)); /* center */
}
}
<div class="image-container">
<img class="item-image" src="https://source.unsplash.com/featured/500x500">
</div>
<div class="image-container">
<img class="item-image" src="https://source.unsplash.com/featured/500x1000">
</div>
<div class="image-container">
<img class="item-image" src="https://source.unsplash.com/featured/1000x500">
</div>