วิธีย้อนกลับภาพเคลื่อนไหวเมื่อเมาส์ออกหลังจากวางเมาส์เหนือ


92

ดังนั้นจึงเป็นไปได้ที่จะมีภาพเคลื่อนไหวย้อนกลับบนเมาส์เช่น:

.class{
   transform: rotate(0deg);

}
.class:hover{
   transform: rotate(360deg);
}

แต่เมื่อใช้แอนิเมชั่น @keyframes ฉันไม่สามารถใช้งานได้เช่น:

.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);}
}

ทางออกที่ดีที่สุดคืออะไรเมื่อรู้ว่าฉันต้องการการทำซ้ำและการเคลื่อนไหวเอง

http://jsfiddle.net/khalednabil/eWzBm/


จะไม่ดีกว่าถ้าใช้การเปลี่ยนเช่นที่นี่ - jsfiddle.net/HQFby ?
piatek

คำตอบถูกโพสต์บน stackoverflow แล้ว ใส่คำอธิบายลิงค์ที่นี่
watereffect

คำตอบ:


61

ฉันคิดว่าถ้าคุณมีtoคุณต้องใช้ไฟล์from. ฉันคิดว่า:

@keyframe in {
    from: transform: rotate(0deg);
    to: transform: rotate(360deg);
}

@keyframe out {
    from: transform: rotate(360deg);
    to: transform: rotate(0deg);
}

แน่นอนต้องตรวจสอบอยู่แล้ว แต่ฉันพบว่าแปลกที่คุณใช้transformคุณสมบัตินี้เท่านั้นเนื่องจาก CSS3 ไม่ได้ใช้งานอย่างสมบูรณ์ทุกที่ อาจจะทำงานได้ดีขึ้นด้วยการพิจารณาต่อไปนี้:

  • ใช้ Chrome @-webkit-keyframesโดยไม่จำเป็นต้องมีเวอร์ชันพิเศษ
  • Safari ใช้@-webkit-keyframesตั้งแต่เวอร์ชัน 5+
  • Firefox ใช้@keyframesตั้งแต่เวอร์ชัน 16 (ใช้ v5-15 @-moz-keyframes)
  • Opera ใช้@-webkit-keyframesเวอร์ชัน 15-22 (ใช้เฉพาะ v12 @-o-keyframes)
  • Internet Explorer ใช้@keyframesตั้งแต่เวอร์ชัน 10+

แก้ไข:

ฉันคิดซอนั้นขึ้นมา:

http://jsfiddle.net/JjHNG/35/

ใช้โค้ดขั้นต่ำ เข้าใกล้สิ่งที่คุณคาดหวังหรือไม่?


1
IE 10 รองรับภาพเคลื่อนไหวแบบคีย์เฟรม
dlev

4
ซึ่งจะย้อนกลับการเปลี่ยนแปลง แต่ปัญหาคือถ้าเมาส์หมดก่อนสิ้นสุดการเปลี่ยนแบบโฮเวอร์เราจะได้ "กระโดด" นี้ หลังจากการค้นหาบางส่วนเห็นได้ชัดว่าสถานะขององค์ประกอบจะต้อง "คงอยู่" เพื่อที่เราจะสามารถเปลี่ยนกลับจากตำแหน่งสิ้นสุดการหมุนสำหรับ "โหมดเติมภาพเคลื่อนไหว: ไปข้างหน้า" นั้น สามารถใช้ได้ แต่ดูเหมือนจะไม่ได้ผล
Khaled

24
@Xaltar เมื่อคุณโหลดแอปเป็นครั้งแรกภาพเคลื่อนไหวแรกจะเล่นโดยไม่ต้องวางเมาส์เหนือช่องสี่เหลี่ยม จะมีการหยุดการเคลื่อนไหวของการโหลดครั้งแรกหรือไม่?
jlewkovich

3
มีใครหาวิธีแก้ภาพเคลื่อนไหวเรื่องแรกที่เล่นเองหลังจากรีเฟรชไหม ชนิดที่สำคัญ
user2619824

2
คำตอบนี้จะไร้ประโยชน์ในที่สุดหากคุณไม่สามารถระงับการเล่นภาพเคลื่อนไหวในครั้งแรกได้
NearHuscarl

23

ง่ายกว่าทั้งหมดนี้: เพียงแค่เปลี่ยนคุณสมบัติเดียวกันในองค์ประกอบของคุณ

.earth { width:  0.92%;    transition: width 1s;  }
.earth:hover { width: 50%; transition: width 1s;  }

https://codepen.io/lafland/pen/MoEaoG


4
ใช่ แต่จะใช้ได้ก็ต่อเมื่อมีการเปลี่ยนแปลงคุณสมบัติเพียงรายการเดียว
Marcus

4
@Marcustransition: border-color 0.3s, background-color 0.3s, color 0.3s;
Scoots

4
ว้าว CSS มาไกลตั้งแต่ครั้งที่แล้วที่ฉันเขียนโปรแกรมบนเว็บ: D
Franz D.

5
เขาถามเรื่องแอนิเมชั่น !!
iKamy

18

ฉันไม่คิดว่าจะทำได้โดยใช้เพียงภาพเคลื่อนไหว CSS ฉันสมมติว่าการเปลี่ยน CSS ไม่เป็นไปตามกรณีการใช้งานของคุณเนื่องจาก (ตัวอย่างเช่น) คุณต้องการเชื่อมโยงภาพเคลื่อนไหวสองภาพเข้าด้วยกันใช้การหยุดหลายครั้งการทำซ้ำหรือในทางอื่น ๆ การใช้ประโยชน์จากภาพเคลื่อนไหวกำลังเพิ่มเติมที่ให้คุณ

ฉันไม่พบวิธีใดในการทริกเกอร์ภาพเคลื่อนไหว CSS โดยเฉพาะเมื่อวางเมาส์ออกโดยไม่ต้องใช้ JavaScript เพื่อแนบคลาส "over" และ "out" แม้ว่าคุณจะสามารถใช้การประกาศ CSS พื้นฐานทริกเกอร์ภาพเคลื่อนไหวเมื่อ: โฮเวอร์สิ้นสุดลง แต่ภาพเคลื่อนไหวเดียวกันนั้นจะทำงานในการโหลดหน้าเว็บ การใช้คลาส "over" และ "out" คุณสามารถแบ่งคำจำกัดความออกเป็นคำประกาศฐาน (โหลด) และการประกาศทริกเกอร์แอนิเมชันสองรายการ

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 syntax) เพื่อผูกคลาสเข้ากับเหตุการณ์:

$(".class").hover(
    function () {
        $(this).removeClass('out').addClass('over');
    },
    function () {
        $(this).removeClass('over').addClass('out');
    }
);

10

การสร้างแอนิเมชั่นแบบย้อนกลับนั้นค่อนข้างเกินความจำเป็นสำหรับปัญหาง่ายๆสิ่งที่คุณต้องการคือ

animation-direction: reverse

อย่างไรก็ตามสิ่งนี้จะไม่ทำงานด้วยตัวเองเนื่องจากข้อมูลจำเพาะของแอนิเมชั่นถูกถ่ายโอนข้อมูลมากจนลืมเพิ่มวิธีการรีสตาร์ทแอนิเมชั่นดังนั้นนี่คือวิธีที่คุณทำได้ด้วยความช่วยเหลือของ 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>



4

เราสามารถใช้ requestAnimationFrame เพื่อรีเซ็ตภาพเคลื่อนไหวและย้อนกลับได้เมื่อเบราว์เซอร์วาดในเฟรมถัดไป

ใช้ตัวจัดการเหตุการณ์ onmouseenter และ onmouseout เพื่อย้อนกลับทิศทางของภาพเคลื่อนไหว

ตาม

rAF ใด ๆ ที่อยู่ในคิวในตัวจัดการเหตุการณ์ของคุณจะถูกดำเนินการในเฟรมเดียวกัน rAF ใด ๆ ที่อยู่ในคิวใน RAF จะถูกดำเนินการในเฟรมถัดไป

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>


0

ลองสิ่งนี้:

@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+


0

ลองใช้วิธีแก้ปัญหาหลายอย่างที่นี่ไม่มีอะไรทำงานได้อย่างไม่มีที่ติ จากนั้นค้นหาเว็บอีกเล็กน้อยเพื่อค้นหาGSAPที่https://greensock.com/ (ขึ้นอยู่กับใบอนุญาต แต่ก็ค่อนข้างอนุญาต) เมื่อคุณอ้างอิง lib ...

 <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();
  });

และจะทำงานได้อย่างไม่มีที่ติ


0

ฮ่า ๆ มันมีวิธีแก้ปัญหาที่ง่ายมากด้วย CSS เท่านั้น จัดให้เลย

#thing {ช่องว่างภายใน: 10px; เส้นขอบรัศมี: 5px;

/ * HOVER OFF * / -webkit-transition: padding 2s; }

#thing: hover {padding: 20px; เส้นขอบรัศมี: 15px;

/ * HOVER ON * / -webkit-transition: border-radius 2s; }


"lol"คุณยังไม่ได้อ่านคำถามเดิม OP รู้แล้วว่าการเปลี่ยนผ่านทำงานอย่างไรเมื่อ 7+ ปีก่อน
Zsolt Meszaros
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.