因此,鼠標(biāo)離開(kāi)時(shí)可能會(huì)出現(xiàn)反向動(dòng)畫(huà),例如:
.class{
transform: rotate(0deg);
}
.class:hover{
transform: rotate(360deg);
}
但是,當(dāng)使用@keyframes動(dòng)畫(huà)時(shí),我無(wú)法讓它工作,例如:
.class{
animation-name: out;
animation-duration:2s;
}
.class:hover{
animation-name: in;
animation-duration:5s;
animation-iteration-count:infinite;
}
@keyframe in{
to {transform: rotate(360deg);}
}
@keyframe out{
to {transform: rotate(0deg);}
}
知道我需要迭代和動(dòng)畫(huà)本身,最佳解決方案是什么?
http://jsfiddle.net/khalednabil/eWzBm/
我認(rèn)為如果你有to,你必須使用from。 我會(huì)想到這樣的事情:
@keyframe in {
from: transform: rotate(0deg);
to: transform: rotate(360deg);
}
@keyframe out {
from: transform: rotate(360deg);
to: transform: rotate(0deg);
}
當(dāng)然肯定已經(jīng)檢查過(guò)了,但是我發(fā)現(xiàn)奇怪的是你只使用了transform屬性,因?yàn)镃SS3并不是在所有地方都完全實(shí)現(xiàn)的。如果考慮以下因素,可能會(huì)更好:
Chrome使用@-WebKit-關(guān)鍵幀,不需要特定版本 從版本5+開(kāi)始,Safari使用@-WebKit-關(guān)鍵幀 Firefox從版本16開(kāi)始使用@關(guān)鍵幀(v5-15使用@-moz-關(guān)鍵幀) Opera使用@-webkit-keyframes版本15-22(只有版本12使用@-o-keyframes) 從版本10+開(kāi)始,Internet Explorer使用@關(guān)鍵幀 編輯:
我想到了那把小提琴:
http://jsfiddle.net/JjHNG/35/
使用最少的代碼。它接近你所期望的嗎?
這要簡(jiǎn)單得多:只需在元素上轉(zhuǎn)換相同的屬性
.earth { width: 0.92%; transition: width 1s; }
.earth:hover { width: 50%; transition: width 1s; }
https://codepen.io/lafland/pen/MoEaoG
我不認(rèn)為只用CSS動(dòng)畫(huà)就能做到這一點(diǎn)。我假設(shè)CSS轉(zhuǎn)換不滿(mǎn)足您的用例,因?yàn)?例如)您想要將兩個(gè)動(dòng)畫(huà)鏈接在一起,使用多次停止、迭代或以其他方式利用動(dòng)畫(huà)賦予您的額外功能。
我還沒(méi)有找到任何不使用JavaScript附加“over”和“out”類(lèi)就能觸發(fā)CSS動(dòng)畫(huà)的方法。雖然您可以使用基本CSS聲明在:hover結(jié)束時(shí)觸發(fā)動(dòng)畫(huà),但是相同的動(dòng)畫(huà)將在頁(yè)面加載時(shí)運(yùn)行。使用“over”和“out”類(lèi),您可以將定義分成基本(加載)聲明和兩個(gè)動(dòng)畫(huà)觸發(fā)聲明。
此解決方案的CSS將是:
.class {
/* base element declaration */
}
.class.out {
animation-name: out;
animation-duration:2s;
}
.class.over {
animation-name: in;
animation-duration:5s;
animation-iteration-count:infinite;
}
@keyframes in {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes out {
from {
transform: rotate(360deg);
}
to {
transform: rotate(0deg);
}
}
并使用JavaScript (jQuery語(yǔ)法)將類(lèi)綁定到事件:
$(".class").hover(
function () {
$(this).removeClass('out').addClass('over');
},
function () {
$(this).removeClass('over').addClass('out');
}
);
對(duì)于一個(gè)簡(jiǎn)單的問(wèn)題來(lái)說(shuō),創(chuàng)建一個(gè)反向動(dòng)畫(huà)有點(diǎn)矯枉過(guò)正。你需要的是:
animation-direction: reverse
然而,這本身不會(huì)起作用,因?yàn)閍nimation spec忘了添加一個(gè)重啟動(dòng)畫(huà)的方法,所以這里是你如何在JS的幫助下做這件事
let item = document.querySelector('.item')
// play normal
item.addEventListener('mouseover', () => {
item.classList.add('active')
})
// play in reverse
item.addEventListener('mouseout', () => {
item.style.opacity = 0 // avoid showing the init style while switching the 'active' class
item.classList.add('in-active')
item.classList.remove('active')
// force dom update
setTimeout(() => {
item.classList.add('active')
item.style.opacity = ''
}, 5)
item.addEventListener('animationend', onanimationend)
})
function onanimationend() {
item.classList.remove('active', 'in-active')
item.removeEventListener('animationend', onanimationend)
}
@keyframes spin {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(180deg);
}
}
div {
background: black;
padding: 1rem;
display: inline-block;
}
.item {
/* because span cant be animated */
display: block;
color: yellow;
font-size: 2rem;
}
.item.active {
animation: spin 1s forwards;
animation-timing-function: ease-in-out;
}
.item.in-active {
animation-direction: reverse;
}
<div>
<span class="item">ABC</span>
</div>
我們可以使用requestAnimationFrame來(lái)重置動(dòng)畫(huà),并在瀏覽器繪制下一幀時(shí)反轉(zhuǎn)動(dòng)畫(huà)。
還可以使用onmouseenter和onmouseout事件處理程序來(lái)反轉(zhuǎn)動(dòng)畫(huà)方向
按照
在事件處理程序中排隊(duì)的任何RAF都將在同一個(gè) 框架。在rAF中排隊(duì)的任何rAF將在下一幀中執(zhí)行。
function fn(el, isEnter) {
el.className = "";
requestAnimationFrame(() => {
requestAnimationFrame(() => {
el.className = isEnter? "in": "out";
});
});
}
.in{
animation: k 1s forwards;
}
.out{
animation: k 1s forwards;
animation-direction: reverse;
}
@keyframes k
{
from {transform: rotate(0deg);}
to {transform: rotate(360deg);}
}
<div style="width:100px; height:100px; background-color:red"
onmouseenter="fn(this, true)"
onmouseleave="fn(this, false)"
></div>
如果只有一個(gè)動(dòng)畫(huà),但把它反過(guò)來(lái),你會(huì)更好嗎?
animation-direction: reverse
將變換與過(guò)渡結(jié)合使用對(duì)我來(lái)說(shuō)完美無(wú)缺:
.ani-grow {
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
-ms-transition: all 0.5s ease;
transition: all 0.5s ease;
}
.ani-grow:hover {
transform: scale(1.01);
}
我用一個(gè)只修復(fù)CSS的CodePen和一個(gè)包含兩行jQuery的code pen來(lái)修復(fù)頁(yè)面加載問(wèn)題。繼續(xù)閱讀,以更簡(jiǎn)單的方式理解這兩種解決方案。
https://codepen.io/MateoStabio/pen/jOVvwrM
如果你正在尋找如何只用CSS做到這一點(diǎn),Xaltar的答案簡(jiǎn)單明了,是正確的解決方案。唯一的缺點(diǎn)是當(dāng)頁(yè)面加載時(shí),鼠標(biāo)離開(kāi)的動(dòng)畫(huà)將會(huì)播放。發(fā)生這種情況的原因是,為了使這種方法有效,您用出動(dòng)畫(huà)和入動(dòng)畫(huà)來(lái)設(shè)置元素的樣式。
svg path{
animation: animateLogoOut 1s;
}
svg:hover path{
animation: animateLogoIn 1s;
}
@keyframes animateLogoIn {
from {stroke-dashoffset: -510px;}
to {stroke-dashoffset: 0px;}
}
@keyframes animateLogoOut {
from {stroke-dashoffset: 0px;}
to {stroke-dashoffset: -510px;}
}
有些人發(fā)現(xiàn)這種解決方案是無(wú)用的,因?yàn)樗陧?yè)面加載播放。對(duì)我來(lái)說(shuō),這是完美的解決方案。但是我用這兩種解決方案做了一個(gè)代碼筆,因?yàn)槲铱赡茉诓痪玫膶?lái)需要它們。
如果您不希望在頁(yè)面加載時(shí)顯示CSS動(dòng)畫(huà),您將需要使用一個(gè)很小的JS腳本,該腳本僅在元素第一次被懸停后使用外部動(dòng)畫(huà)來(lái)樣式化元素。我們將通過(guò)添加一個(gè)。覆蓋到元素,并用外部動(dòng)畫(huà)樣式化添加的類(lèi)。
jQuery:
$("svg").mouseout(function() {
$(this).addClass("wasHovered");
});
CSS:
svg path{
}
svg.wasHovered path{
animation: animateLogoOut 1s;
}
svg:hover path{
animation: animateLogoIn 1s;
}
@keyframes animateLogoIn {
from {stroke-dashoffset: -510px;}
to {stroke-dashoffset: 0px;}
}
@keyframes animateLogoOut {
from {stroke-dashoffset: 0px;}
to {stroke-dashoffset: -510px;}
}
瞧啊。你可以在我的codepen上找到所有這些和更多的內(nèi)容,它用一個(gè)SVG logo懸停動(dòng)畫(huà)詳細(xì)展示了2個(gè)選項(xiàng)。
https://codepen.io/MateoStabio/pen/jOVvwrM
在這里嘗試了幾種解決方案,沒(méi)有一個(gè)是完美的;然后在網(wǎng)上搜索了一下,在https://greensock.com/找到了GSAP(需要許可,但相當(dāng)寬松);一旦你引用了庫(kù)...
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.4/gsap.min.js"></script>
...你可以去:
var el = document.getElementById('divID');
// create a timeline for this element in paused state
var tl = new TimelineMax({paused: true});
// create your tween of the timeline in a variable
tl
.set(el,{willChange:"transform"})
.to(el, 1, {transform:"rotate(60deg)", ease:Power1.easeInOut});
// store the tween timeline in the javascript DOM node
el.animation = tl;
//create the event handler
$(el).on("mouseenter",function(){
//this.style.willChange = 'transform';
this.animation.play();
}).on("mouseleave",function(){
//this.style.willChange = 'auto';
this.animation.reverse();
});
它將完美地工作。
[OP在這里特別詢(xún)問(wèn)動(dòng)畫(huà),但是如果你所需要的是基于懸停狀態(tài)啟動(dòng)和反向旋轉(zhuǎn),而沒(méi)有特定的動(dòng)畫(huà)迭代計(jì)數(shù)(盡管你可以計(jì)算角度來(lái)模仿它),你可以使用下面的。]
截至2023年5月,我們只需一個(gè)單獨(dú)的轉(zhuǎn)變(相關(guān)的CanIUse)和一個(gè)過(guò)渡就能實(shí)現(xiàn)這一目標(biāo)。
.box {
rotate: 0deg;
transition: rotate 2s;
}
.box:hover {
rotate: 360deg;
}
一些需要注意的事項(xiàng):
單個(gè)轉(zhuǎn)換的移動(dòng)實(shí)現(xiàn)是非常新的(就在本文發(fā)表前兩周),所以為了獲得完全支持,要么回到原來(lái)的語(yǔ)法,要么使用LightningCSS/Autoprefixer 查看下面或Codepen上的示例:
.box {
transition: rotate 2s;
rotate: 0deg;
}
.box:hover {
rotate: 360deg;
}
.box:nth-of-type(5):hover {
rotate: 1080deg;
}
/* visuals (ignore) */
.box {
--d: 90px;
height: var(--d);
width: var(--d);
border: 2px solid;
display: flex;
align-items: center;
justify-content: center;
}
.container {
display: flex;
flex-wrap: wrap;
gap: 3px;
}
<div class="container">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
</div>
試試這個(gè):
@keyframe in {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframe out {
from {
transform: rotate(360deg);
}
to {
transform: rotate(0deg);
}
}
在Firefox 5+,IE 10+,Chrome,Safari 4+,Opera 12+中支持