Animation Anh Huy

https://animista.net
https://ianlunn.github.io/Hover

Nghiên cứu các thuộc tính animation

— animation-duration

Trong CSS, animation-durationthuộc tính xác định thời gian một chu kỳ của animation kéo dài bao lâu (tức là mất bao nhiêu thời gian để hoàn thành một lần chạy của animation).

animation-duration: 2s; → animation kéo dài 2 giây.
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.box {
  animation-name: fadeIn;
  animation-duration: 1.5s;
}
Trong ví dụ trên, .box sẽ chạy animation fadeIn trong vòng 1.5 giây.

— animation-delay

animation-delay trong CSS dùng để chỉ định khoảng thời gian chờ trước khi một animation bắt đầu chạy.

Khi phần tử được áp dụng animation, animation-delay giúp trì hoãn thời điểm animation bắt đầu, thay vì chạy ngay lập tức.

Có thể dùng số âm (-1s) để làm cho animation bắt đầu như thể nó đã chạy được một thời gian rồi.

.box {
  animation-name: slideIn;
  animation-duration: 2s;
  animation-delay: 1s;
}

@keyframes slideIn {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0);
  }
}
.box sẽ chờ 1 giây sau khi được hiển thị, rồi mới bắt đầu chạy animation slideIn.

— animation-direction

animation-direction trong CSS là thuộc tính dùng để xác định hướng mà animation sẽ chạy, đặc biệt khi nó lặp lại nhiều lần.

Nó điều khiển xem animation chạy từ đầu đến cuối (bình thường), ngược lại (từ cuối về đầu), hay luân phiên qua lại mỗi lần lặp.

animation-direction: normal | reverse | alternate | alternate-reverse;
@keyframes move {
  from { transform: translateX(0); }
  to { transform: translateX(200px); }
}

.box {
  animation-name: move;
  animation-duration: 2s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}
 Kết quả: .box sẽ di chuyển qua phải rồi trở lại vị trí ban đầu, lặp đi lặp lại.
Giá trị
Ý nghĩa

normal (mặc định)

Animation chạy từ đầu đến cuối (từ from đến to).

reverse

Animation chạy ngược lại (từ to về from).

alternate

Animation chạy bình thường, rồi ngược lại (lặp luân phiên).

alternate-reverse

Animation chạy ngược lại, rồi bình thường (cũng luân phiên).

— animation-fill-mode

animation-fill-mode trong CSS dùng để xác định trạng thái của phần tử trước khi animation bắt đầu và sau khi animation kết thúc.

Animation thường chỉ “tác động” trong thời gian nó chạy. Nhưng nếu bạn muốn phần tử giữ nguyên hiệu ứng sau khi kết thúc (hoặc trước khi bắt đầu), thì dùng animation-fill-mode.

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.box {
  animation-name: fadeIn;
  animation-duration: 2s;
  animation-fill-mode: forwards;
}
.box sẽ mờ dần từ 0 → 1 (opacity).
Sau khi animation kết thúc, nó vẫn giữ nguyên opacity: 1 nhờ forwards.
.box {
  animation-name: fadeIn;
  animation-duration: 2s;
  animation-delay: 3s;
  animation-fill-mode: backwards;
}

Trong 3 giây delay, phần tử sẽ tạm thời có opacity: 0 (như trong keyframe from) thay vì hiển thị trạng thái ban đầu.

none (mặc định)

Không áp dụng bất kỳ style nào từ animation trước/sau khi nó chạy.

forwards

Sau khi animation kết thúc, giữ lại trạng thái của keyframe cuối cùng.

backwards

Trước khi animation bắt đầu, tạm thời áp dụng trạng thái keyframe đầu tiên (đặc biệt khi có animation-delay).

both

Kết hợp cả forwardsbackwards.

— animation-play-state

animation-play-state trong CSS dùng để tạm dừng hoặc tiếp tục một animation đang chạy.

Nó giống như nút pause/play cho animation: bạn có thể dừng animation lại rồi cho nó chạy tiếp bất cứ lúc nào.

animation-play-state: running | paused;
@keyframes move {
  from { transform: translateX(0); }
  to { transform: translateX(300px); }
}

.box {
  animation-name: move;
  animation-duration: 4s;
  animation-iteration-count: infinite;
  animation-play-state: running;
}

Nếu bạn thêm animation-play-state: paused; → phần tử sẽ không di chuyển dù có animation.

Dùng với JavaScript hoặc hover:

.box:hover {
  animation-play-state: paused;
}

👉 Khi bạn hover vào .box, animation sẽ tạm dừng, khi bỏ hover sẽ chạy tiếp.

— animation-name

animation-name trong CSS dùng để chỉ định tên của animation (được định nghĩa bằng @keyframes) sẽ áp dụng cho phần tử.

animation-name là cách bạn nói với CSS: “Ê, dùng cái animation nào cho phần tử này đi!”

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.box {
  animation-name: fadeIn;
  animation-duration: 2s;
}
  • fadeIn là tên animation bạn đã định nghĩa.

  • .box sẽ được áp dụng animation đó và mờ dần trong 2 giây.

— animation-timeline

animation-timeline là một thuộc tính mới trong CSS (hiện đang được chuẩn hóa theo CSS Scroll-Linked Animations), dùng để điều khiển tiến trình animation dựa trên một "timeline" tùy chỉnh — ví dụ: theo vị trí cuộn (scroll position) thay vì thời gian.

Thay vì animation chạy theo thời gian (animation-duration: 2s), bạn có thể cho nó chạy theo tiến độ scroll của trang, phần tử, hoặc một timeline khác.

Giá trị
Ý nghĩa

auto (mặc định)

Dùng timeline mặc định (thường là theo thời gian như bình thường).

none

Không gắn animation với timeline nào cả.

scroll()

Gắn animation theo tiến độ scroll (rất hay dùng với scroll-driven effects).

<custom-name>

Dùng một timeline bạn đã khai báo thủ công (dùng với @scroll-timeline).

Đây là ví dụ (giả lập - chỉ hỗ trợ trong một số trình duyệt như Chrome 115+ và cần bật experimental flags):

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@scroll-timeline myScrollTimeline {
  source: auto;
  orientation: block;
  scroll-offsets: start 0%, end 100%;
}

.box {
  animation-name: fadeIn;
  animation-duration: 1s;
  animation-timeline: myScrollTimeline;
}
  • Animation fadeIn không chạy theo thời gian mà chạy dựa trên vị trí scroll của người dùng.

  • Khi cuộn từ đầu đến cuối, .box sẽ mờ dần vào.

Nghiên cứu các thuộc tính transition

— transition-behavior

transition-behavior là một thuộc tính CSS dùng để kiểm soát hành vi của transition khi thuộc tính bị thay đổi, đặc biệt là khi sử dụng JavaScript hoặc khi thay đổi giữa các trạng thái lớp (class) trong DOM.

transition-behavior: normal | allow-discrete;
Giá trị
Ý nghĩa

normal (default)

Chỉ áp dụng transition cho những thuộc tính hỗ trợ hoạt ảnh liên tục (continuous transitions), như opacity, transform, v.v.

allow-discrete

Cho phép các thuộc tính không liên tục (discrete) như display, visibility, hoặc content cũng có thể "hiển thị theo cách chuyển tiếp" nếu trình duyệt hỗ trợ.

.box {
  transition: opacity 0.3s ease, visibility 0.3s ease;
  transition-behavior: allow-discrete;
}

Nếu visibility được thay đổi (visiblehidden), trình duyệt có thể xử lý nó một cách mượt nếu hỗ trợ allow-discrete.

  • Hiện tại (2024–2025), transition-behavior: allow-discrete chưa được hỗ trợ rộng rãi ở tất cả các trình duyệt. Chủ yếu có mặt trên Chrome, Edge với các flag thử nghiệm.

  • Không có tác dụng nếu dùng với các thuộc tính vốn đã hỗ trợ transition như opacity, transform.

Khi nào dùng?

  • Khi bạn muốn một số thuộc tính như visibility, content, hoặc display có thể chuyển đổi mượt thay vì bật tắt đột ngột (nếu trình duyệt hỗ trợ).

  • Dùng kết hợp với @starting-style (trong CSS animation phức tạp).

transition-behavior là một tính năng tiềm năng, giúp kiểm soát tốt hơn cách transition hoạt động – đặc biệt cho những thuộc tính trước giờ không thể chuyển tiếp mượt. Nhưng bạn nên kiểm tra khả năng hỗ trợ trình duyệt trước khi dùng trong sản phẩm thực tế.


Nếu bạn đang làm animation mượt khi cuộn (với IntersectionObserver), bạn không cần dùng transition-behavior trừ khi bạn đang xử lý thuộc tính "cứng đầu" như visibility.

— transition-duration

transition-duration là một thuộc tính CSS dùng để xác định thời gian (tính bằng giây hoặc mili giây) mà transition sẽ mất để hoàn thành, tức là thời gian diễn ra hiệu ứng chuyển tiếp giữa hai trạng thái của một thuộc tính.

.box {
  transition-property: opacity;
  transition-duration: 0.5s;
}

Ở đây, khi .box thay đổi opacity, hiệu ứng mờ dần sẽ mất 0.5 giây để hoàn tất.

Bạn cũng có thể viết gọn:

.box {
  transition: opacity 0.5s ease;
}
opacity: là thuộc tính cần chuyển tiếp
0.5s: chính là transition-duration
ease: là transition-timing-function (kiểu chuyển động)

Bạn có thể chỉ định nhiều thời gian nếu đang transition nhiều thuộc tính:

transition-property: opacity, transform;
transition-duration: 0.5s, 1s;
// opacity mất 0.5 giây
// transform mất 1 giây

Nếu không khai báo transition-duration? Trình duyệt sẽ mặc định là 0skhông có hiệu ứng chuyển tiếp gì cả, chuyển đổi xảy ra ngay lập tức.

transition-duration

Thời gian chuyển tiếp (mượt hay tức thì)

Đơn vị

s (giây), ms (mili giây)

Mặc định

0s (không có chuyển tiếp)

— transition-timing-function

transition-timing-function là thuộc tính CSS dùng để xác định cách tốc độ của transition thay đổi trong suốt quá trình thực hiện — hay nói cách khác, nó điều khiển nhịp điệu (chuyển động nhanh/chậm/đều) của hiệu ứng.

transition-timing-function: ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(...) | steps(...);
Giá trị
Mô tả

ease

Mặc định – bắt đầu chậm, tăng tốc, rồi chậm lại ở cuối

linear

Tốc độ đều từ đầu đến cuối

ease-in

Bắt đầu chậm, sau đó nhanh dần

ease-out

Bắt đầu nhanh, chậm dần về cuối

ease-in-out

Chậm ở cả đầu và cuối, nhanh ở giữa

cubic-bezier(x1, y1, x2, y2)

Tùy chỉnh đường cong tốc độ (chi tiết bên dưới)

`steps(n, start

end)`

.box {
  transition: transform 0.5s ease-in-out;
}
Khi .box bị transform (ví dụ translate, scale...), nó sẽ:
Chuyển động chậm ban đầu → nhanh ở giữa → chậm ở cuối.

Minh họa trực quan (tưởng tượng):

Giả sử bạn đang animate một khối vuông sang phải:

Hàm
Cảm giác chuyển động

ease

tự nhiên, giống vật thật

linear

tốc độ máy móc, đều đặn

ease-in

như xe tăng tốc từ điểm dừng

ease-out

như xe đang phanh lại dần

ease-in-out

mềm mại cả hai đầu

Tùy chỉnh nâng cao với cubic-bezier

cssCopyEdittransition-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55);
  • Tạo chuyển động như "bật nảy" (springy)

  • Bạn có thể thử trực tiếp ở trang cubic-bezier.com

Tổng kết:

Thuộc tính
Chức năng

transition-timing-function

Điều khiển tốc độ diễn ra hiệu ứng

Tác động

Làm hiệu ứng mượt, tự nhiên hơn

Dùng kèm

transition-duration, transition-property, v.v.

— transition-delay

transition-delay là thuộc tính CSS dùng để chỉ định khoảng thời gian chờ trước khi hiệu ứng chuyển tiếp (transition) bắt đầu sau khi thuộc tính thay đổi.

.box {
  transition: opacity 0.5s ease;
  transition-delay: 0.3s;
}

👉 Khi .box thay đổi opacity, trình duyệt sẽ:

  • Đợi 0.3 giây, rồi

  • Thực hiện hiệu ứng mờ trong 0.5 giây

Dùng gộp:

.box {
  transition: opacity 0.5s ease 0.3s;
}

giá trị trong transition:

  1. opacity → thuộc tính cần chuyển tiếp

  2. 0.5s → thời gian thực hiện (transition-duration)

  3. ease → nhịp độ (transition-timing-function)

  4. 0.3s → thời gian chờ trước khi bắt đầu (transition-delay)

Ứng dụng thực tế

Hiệu ứng hover bắt đầu trễ:

.button {
  transition: background-color 0.4s ease-in-out 0.2s;
}
.button:hover {
  background-color: #ff6600;
}

Khi người dùng hover:

  • Chờ 0.2s rồi mới đổi màu nền

  • Tạo cảm giác phản hồi có "độ trễ tự nhiên"

Nhiều thuộc tính

Khi bạn chuyển tiếp nhiều thuộc tính, bạn có thể đặt delay riêng:

transition-property: opacity, transform;
transition-duration: 0.3s, 0.5s;
transition-delay: 0s, 0.2s;

opacity sẽ chạy ngay lập tức, còn transform sẽ chạy sau 0.2s.

Thuộc tính
Chức năng

transition-delay

Trì hoãn thời gian bắt đầu của hiệu ứng chuyển tiếp

Đơn vị

s hoặc ms

Mặc định

0s (không chờ – hiệu ứng bắt đầu ngay lập tức)

— transition-property

transition-property: none | all | <property-name> [, <property-name>, ...];
Giá trị
Ý nghĩa

all (mặc định)

Áp dụng transition cho mọi thuộc tính có thể chuyển tiếp

none

Không áp dụng transition cho bất kỳ thuộc tính nào

opacity, transform, background-color, v.v.

Chỉ áp dụng transition cho các thuộc tính cụ thể

.box {
  transition-property: opacity;
  transition-duration: 0.5s;
}

👉 Khi opacity thay đổi, sẽ có hiệu ứng mờ trong 0.5 giây. 📌 Nếu bạn thay đổi thuộc tính khác như transform, sẽ không có hiệu ứng gì cả, vì không nằm trong transition-property.

Ví dụ nhiều thuộc tính:

.box {
  transition-property: opacity, transform;
  transition-duration: 0.5s, 1s;
}
  • opacity mất 0.5 giây

  • transform mất 1 giây

Gộp đầy đủ:

.box {
  transition: opacity 0.3s ease-in, transform 0.5s ease-out;
}

Tương đương với:

transition-property: opacity, transform;
transition-duration: 0.3s, 0.5s;
transition-timing-function: ease-in, ease-out;

Khi nào nên dùng transition-property?

Khi dùng transition: all ... gây lỗi

Tránh animate những thuộc tính không mong muốn

transition-property

Xác định thuộc tính CSS nào sẽ có hiệu ứng transition

Dùng kèm với

transition-duration, transition-timing-function, transition-delay

Mặc định

all (mọi thuộc tính có thể transition)

📙 Dưới đây là một mini map ghi nhớ các thuộc tính CSS liên quan đến transition để bạn dễ hình dung và ghi nhớ:

Mind Map: Các thuộc tính CSS Transitio

transition-property là thuộc tính CSS dùng để chỉ định tên của (những) thuộc tính CSS sẽ được áp dụng hiệu ứng chuyển tiếp (transition) khi giá trị của chúng thay đổi.

app\app.css

@import "tailwindcss";
.spacer {
  height: 100vh;
}
.box {
  width: 120px;
  height: 120px;
  border-radius: 12px;
  color: white;
  font-weight: bold;
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
.box-red {
  background-color: #e74c3c;
}
.box-blue {
  background-color: #3498db;
}
.box-green {
  background-color: #2ecc71;
}
.box-purple {
  background-color: #9b59b6;
}
.box.show {
  opacity: 1;
  transform: translateY(0);
}

app\welcome\welcome.tsx

import { useEffect } from 'react';
export function Welcome() {
  useEffect(() => {
    const boxes = document.querySelectorAll('.box');
    const timeoutMap = new Map();
    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach(entry => {
          const el = entry.target;
          if (entry.isIntersecting) {
            clearTimeout(timeoutMap.get(el)); // Hủy bỏ nếu có timeout đang chờ xóa
            el.classList.add('show');
          } else {
            // Trì hoãn việc xóa class
            const timeoutId = setTimeout(() => {
              el.classList.remove('show');
            }, 300); // ví dụ 300ms sau mới xóa
            timeoutMap.set(el, timeoutId);
          }
        });
      },
      {
        threshold: Array.from({ length: 11 }, (_, i) => i / 10),
      }
    );
    boxes.forEach(box => observer.observe(box));
    return () => {
      boxes.forEach(box => observer.unobserve(box));
      timeoutMap.forEach(timeoutId => clearTimeout(timeoutId));
    };
  }, []);
  return (
    <main className="items-center pt-16 pb-4">
      <div className="spacer"></div>
      <div className="container-flex">
        <div className="box box-red">Đỏ</div>
        <div className="box box-blue">Xanh</div>
        <div className="box box-green">Lá</div>
        <div className="box box-purple">Tím</div>
      </div>
    </main>
  );
}
:root {
  --animate-duration: 1s;
  --animate-delay: 1s;
  --animate-repeat: 1;
}
@mixin mp-duration($time) {
  -webkit-animation-duration: $time;
  animation-duration: $time;
}
@mixin mp-delay($time) {
  -webkit-animation-delay: $time;
  animation-delay: $time;
}
@mixin mp-name($name) {
  -webkit-animation-name: $name;
  animation-name: $name;
}
@mixin mp-fillMode($fmode){
  -webkit-animation-fill-mode: $fmode;
  animation-fill-mode: $fmode;
}
.mp-animation{
    opacity:0;
    -webkit-animation-duration: 1s;
    animation-duration: 1s;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both;
}
.mp-animated{
    opacity: 1; 
}
//--------------------------- Pulse---------------------------------//
@-webkit-keyframes mp-pulse {
  from {
    opacity:0;
    -webkit-transform: scale3d(1.05, 1.05, 1.05);
    transform: scale3d(1.05, 1.05, 1.05);
  }

  50% {
    opacity:1;
    -webkit-transform: scale3d(1.05, 1.05, 1.05);
    transform: scale3d(1.05, 1.05, 1.05);
  }

  to {
    opacity:1;
    -webkit-transform: scale3d(1, 1, 1);
    transform: scale3d(1, 1, 1);
  }
}
@keyframes mp-pulse {
  from {
      opacity:0;
    -webkit-transform: scale3d(1.05, 1.05, 1.05);
    transform: scale3d(1.05, 1.05, 1.05);
  }

  50% {
    opacity:1;
    -webkit-transform: scale3d(1.05, 1.05, 1.05);
    transform: scale3d(1.05, 1.05, 1.05);
  }

  to {
    opacity:1;
    -webkit-transform: scale3d(1, 1, 1);
    transform: scale3d(1, 1, 1);
  }
}
.mp-pulse {
  -webkit-animation-name: mp-pulse;
  animation-name: mp-pulse;
  -webkit-animation-timing-function: ease-in-out;
  animation-timing-function: ease-in-out;
}
//--------------------------- Fade In---------------------------------//
@-webkit-keyframes mp-fadeIn {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}
@keyframes mp-fadeIn {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}
.mp-fadeIn {
  -webkit-animation-name: mp-fadeIn;
  animation-name: mp-fadeIn;
}
//--------------------------- Fade In Up---------------------------------//
@-webkit-keyframes mp-fadeInUp {
  from {
    opacity: 0;
    -webkit-transform: translate3d(0, 100%, 0);
    transform: translate3d(0, 100%, 0);
  }

  to {
    opacity: 1;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}
@keyframes mp-fadeInUp {
  from {
    opacity: 0;
    -webkit-transform: translate3d(0, 100%, 0);
    transform: translate3d(0, 100%, 0);
  }

  to {
    opacity: 1;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}
.mp-fadeInUp {
  -webkit-animation-name: mp-fadeInUp;
  animation-name: mp-fadeInUp;
}
//--------------------------- Fade In Down---------------------------------//
@-webkit-keyframes mp-fadeInDown {
  from {
    opacity: 0;
    -webkit-transform: translate3d(0, -100%, 0);
    transform: translate3d(0, -100%, 0);
  }

  to {
    opacity: 1;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}
@keyframes mp-fadeInDown {
  from {
    opacity: 0;
    -webkit-transform: translate3d(0, -100%, 0);
    transform: translate3d(0, -100%, 0);
  }

  to {
    opacity: 1;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}
.mp-fadeInDown {
  -webkit-animation-name: mp-fadeInDown;
  animation-name: mp-fadeInDown;
}
//--------------------------- Fade In Left---------------------------------//
@-webkit-keyframes mp-fadeInLeft {
  from {
    opacity: 0;
    -webkit-transform: translate3d(-100%, 0, 0);
    transform: translate3d(-100%, 0, 0);
  }

  to {
    opacity: 1;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}
@keyframes mp-fadeInLeft {
  from {
    opacity: 0;
    -webkit-transform: translate3d(-100%, 0, 0);
    transform: translate3d(-100%, 0, 0);
  }

  to {
    opacity: 1;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}
.mp-fadeInLeft {
  -webkit-animation-name: mp-fadeInLeft;
  animation-name: mp-fadeInLeft;
}
//--------------------------- Fade In Right---------------------------------//
@-webkit-keyframes mp-fadeInRight {
  from {
    opacity: 0;
    -webkit-transform: translate3d(100%, 0, 0);
    transform: translate3d(100%, 0, 0);
  }

  to {
    opacity: 1;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}
@keyframes mp-fadeInRight {
  from {
    opacity: 0;
    -webkit-transform: translate3d(100%, 0, 0);
    transform: translate3d(100%, 0, 0);
  }

  to {
    opacity: 1;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}
.mp-fadeInRight {
  -webkit-animation-name: mp-fadeInRight;
  animation-name: mp-fadeInRight;
}
//--------------------------- Fade Out Right---------------------------------//
@-webkit-keyframes mp-fadeOutRight {
  from {
    opacity: 1;
  }

  to {
    opacity: 0;
    -webkit-transform: translate3d(100%, 0, 0);
    transform: translate3d(100%, 0, 0);
  }
}
@keyframes mp-fadeOutRight {
  from {
    opacity: 1;
  }

  to {
    opacity: 0;
    -webkit-transform: translate3d(100%, 0, 0);
    transform: translate3d(100%, 0, 0);
  }
}
.mp-fadeOutRight {
  -webkit-animation-name: mp-fadeOutRight;
  animation-name: mp-fadeOutRight;
}
//--------------------------- Fade Zoom---------------------------------//
@-webkit-keyframes mp-fadeZoom {
   from {
    opacity:0;
    -webkit-transform: scale(1.1);
    transform: scale(1.1);
  }
  to {
    opacity:1;
    -webkit-transform: scale(1);
    transform:scale(1);
  }
}
@keyframes mp-fadeZoom {
    from {
    opacity:0;
    -webkit-transform: scale(1.1);
    transform: scale(1.1);
  }
    to{
    opacity:1;
    -webkit-transform: scale(1);
    transform:scale(1);
  }
}
.mp-fadeZoom {
  -webkit-animation-name: mp-fadeZoom;
  animation-name: mp-fadeZoom;
}
//--------------------------- Fade Zoom Big---------------------------------//
@-webkit-keyframes mp-fadeZoomBig {
   from {
    opacity:0;
    -webkit-transform: scale(1.3);
    transform: scale(1.3);
  }
  to {
    opacity:1;
    -webkit-transform: scale(1);
    transform:scale(1);
  }
}
@keyframes mp-fadeZoomBig {
    from {
    opacity:0;
    -webkit-transform: scale(1.3);
    transform: scale(1.3);
  }
    to{
    opacity:1;
    -webkit-transform: scale(1);
    transform:scale(1);
  }
}
.mp-fadeZoomBig {
  -webkit-animation-name: mp-fadeZoomBig;
  animation-name: mp-fadeZoomBig;
}
//--------------------------- Bounce Big---------------------------------//
@-webkit-keyframes mp-bounceBig {
  from,
  20%,
  53%,
  to {
    opacity: 1;
    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }

  40%,
  43% {
    -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
    animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
    -webkit-transform: translate3d(0, -30px, 0) scaleY(1.1);
    transform: translate3d(0, -30px, 0) scaleY(1.1);
  }

  70% {
    -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
    animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
    -webkit-transform: translate3d(0, -15px, 0) scaleY(1.05);
    transform: translate3d(0, -15px, 0) scaleY(1.05);
  }

  80% {
    -webkit-transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    -webkit-transform: translate3d(0, 0, 0) scaleY(0.95);
    transform: translate3d(0, 0, 0) scaleY(0.95);
  }

  90% {
    -webkit-transform: translate3d(0, -4px, 0) scaleY(1.02);
    transform: translate3d(0, -4px, 0) scaleY(1.02);
  }
}
@keyframes mp-bounceBig {
  from,
  20%,
  53%,
  to {
    opacity: 1;
    -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }

  40%,
  43% {
    -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
    animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
    -webkit-transform: translate3d(0, -30px, 0) scaleY(1.1);
    transform: translate3d(0, -30px, 0) scaleY(1.1);
  }

  70% {
    -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
    animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
    -webkit-transform: translate3d(0, -15px, 0) scaleY(1.05);
    transform: translate3d(0, -15px, 0) scaleY(1.05);
  }

  80% {
    -webkit-transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    -webkit-transform: translate3d(0, 0, 0) scaleY(0.95);
    transform: translate3d(0, 0, 0) scaleY(0.95);
  }

  90% {
    -webkit-transform: translate3d(0, -4px, 0) scaleY(1.02);
    transform: translate3d(0, -4px, 0) scaleY(1.02);
  }
}
.mp-bounceBig{
  -webkit-animation-name: mp-bounceBig;
  animation-name: mp-bounceBig;
  -webkit-transform-origin: center bottom;
  transform-origin: center bottom;
}
//--------------------------- Bounce---------------------------------//
@-webkit-keyframes mp-bounce{
  from,20%,53%,80%,to{
    opacity: 1;
    -webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);
    animation-timing-function:cubic-bezier(.215,.61,.355,1);
    -webkit-transform:translateZ(0);
    transform:translateZ(0);
  }
  40%,43%{
    -webkit-transform:translate3d(0,-15px,0);
    transform:translate3d(0,-15px,0);
  }
  40%,43%,70%{
    -webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);
    animation-timing-function:cubic-bezier(.755,.05,.855,.06);
  }
  70%{
    -webkit-transform:translate3d(0,-10px,0);
    transform:translate3d(0,-10px,0);
  }
  90%{
    -webkit-transform:translate3d(0,-4px,0);
    transform:translate3d(0,-4px,0);
  }
}
@keyframes mp-bounce{
  from,20%,53%,80%,to{
    opacity: 1;
    -webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);
    animation-timing-function:cubic-bezier(.215,.61,.355,1);
    -webkit-transform:translateZ(0);
    transform:translateZ(0);
  }40%,43%{
    -webkit-transform:translate3d(0,-15px,0);
    transform:translate3d(0,-15px,0);
  }
  40%,43%,70%{
    -webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);
    animation-timing-function:cubic-bezier(.755,.05,.855,.06);
  }
  70%{
    -webkit-transform:translate3d(0,-10px,0);
    transform:translate3d(0,-10px,0);
  }
  90%{
    -webkit-transform:translate3d(0,-4px,0);
    transform:translate3d(0,-4px,0);
  }
}
.mp-bounce {
  -webkit-animation-name: mp-bounce;
  animation-name: mp-bounce;
  -webkit-transform-origin: center bottom;
  transform-origin: center bottom;
}
//--------------------------- Flash---------------------------------//
@-webkit-keyframes mp-flash {
  from,
  50%,
  to {
    opacity: 1;
  }

  25%,
  75% {
    opacity: 0;
  }
}
@keyframes mp-flash {
  from,
  50%,
  to {
    opacity: 1;
  }

  25%,
  75% {
    opacity: 0;
  }
}
.mp-flash {
  -webkit-animation-name: mp-flash;
  animation-name: mp-flash;
}
//--------------------------- clipY---------------------------------//
@-webkit-keyframes mp-clipY{
    0%
    { 
        opacity: 1;
        -webkit-transform: scale(0, 1);
    }
    100%
    {
        opacity: 1;
        -webkit-transform: scale(1, 1);
    }
}
@keyframes mp-clipY{
    0%
    {
        opacity: 1;
        transform: scale(0, 1);
    }
    100%
    {
        opacity: 1;
        transform: scale(1, 1);
    }
}
.mp-clipY
{ 
    -webkit-animation-name: mp-clipY;
    animation-name: mp-clipY;
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
}
//--------------------------- clipX---------------------------------//
@-webkit-keyframes mp-clipX{
    0%
    { 
        opacity: 1;
        -webkit-transform: scale(1, 0);
    }
    100%
    {
        opacity: 1;
        -webkit-transform: scale(1, 1);
    }
}
@keyframes mp-clipX{
    0%
    {
        opacity: 1;
        transform: scale(1, 0);
    }
    100%
    {
        opacity: 1;
        transform: scale(1, 1);
    }
}
.mp-clipX
{ 
    -webkit-animation-name: mp-clipX;
    animation-name: mp-clipX;
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
}
//--------------------------- clipXY---------------------------------//
@-webkit-keyframes mp-clipXY{
    0%
    { 
        opacity: 1;
        -webkit-transform: scale(0, 0);
    }
    100%
    {
        opacity: 1;
        -webkit-transform: scale(1, 1);
    }
}
@keyframes mp-clipXY{
    0%
    {
        opacity: 1;
        transform: scale(0, 0);
    }
    100%
    {
        opacity: 1;
        transform: scale(1, 1);
    }
}
.mp-clipYY
{ 
    -webkit-animation-name: mp-clipXY;
    animation-name: mp-clipXY;
    -webkit-animation-timing-function: ease-out;
    animation-timing-function: ease-out;
}
//--------------------------- Back In Up---------------------------------//
@-webkit-keyframes mp-backInUp{
    0%
    {
        -webkit-transform: translateY(1200px) scale(.7);
        opacity: .5;
    }
    80%
    {
        -webkit-transform: translateY(0px) scale(.7);
        opacity: .7;
    }
    100%
    {
        -webkit-transform: scale(1);
        opacity: 1;
    }
}
@keyframes mp-backInUp{
    0%
    {
        transform: translateY(1200px) scale(.7);
        opacity: .5;
    }
    80%
    {
        transform: translateY(0px) scale(.7);
        opacity: .7;
    }
    100%
    {
        transform: scale(1);
        opacity: 1;
    }
}
.mp-backInUp{
    -webkit-animation: mp-backInUp;
            animation: mp-backInUp;
    -webkit-animation-timing-function: ease-out;
            animation-timing-function: ease-out;
}
//--------------------------- Zoom In---------------------------------//
@-webkit-keyframes mp-zoomIn {
  from {
    opacity: 0;
    -webkit-transform: scale3d(0.5, 0.5, 0.5);
    transform: scale3d(0.5, 0.5, 0.5);
  }

  50% {
    opacity: 1;
  }
  to{
    opacity: 1;
  }
}
@keyframes mp-zoomIn {
  from {
    opacity: 0;
    -webkit-transform: scale3d(0.5, 0.5, 0.5);
    transform: scale3d(0.5, 0.5, 0.5);
  }

  50% {
    opacity: 1;
  }
  to{
    opacity: 1;
  }
}
.mp-zoomIn {
  -webkit-animation-name: mp-zoomIn;
  animation-name: mp-zoomIn;
}
//--------------------------- Zoom In Down---------------------------------//
@-webkit-keyframes mp-zoomInDown {
  from {
    opacity: 0;
    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0);
    transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0);
    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
  }

  60% {
    opacity: 1;
    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
    transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
  }
  to{
    opacity: 1;
  }
}
@keyframes mp-zoomInDown {
  from {
    opacity: 0;
    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0);
    transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0);
    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
  }

  60% {
    opacity: 1;
    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
    transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
  }
  to{
    opacity: 1;
  }
}
.mp-zoomInDown {
  -webkit-animation-name: mp-zoomInDown;
  animation-name: mp-zoomInDown;
}
//--------------------------- Zoom In Up---------------------------------//
@-webkit-keyframes mp-zoomInUp {
  from {
    opacity: 0;
    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0);
    transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0);
    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
  }

  60% {
    opacity: 1;
    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
    transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
  }
  to{
    opacity: 1;
  }
}
@keyframes mp-zoomInUp {
  from {
    opacity: 0;
    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0);
    transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0);
    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
  }

  60% {
    opacity: 1;
    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
    transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
  }
  to{
    opacity: 1;
  }
}
.mp-zoomInUp {
  -webkit-animation-name: mp-zoomInUp;
  animation-name: mp-zoomInUp;
}
//--------------------------- Zoom In Left---------------------------------//
@-webkit-keyframes mp-zoomInLeft {
  from {
    opacity: 0;
    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0);
    transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0);
    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
  }

  60% {
    opacity: 1;
    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0);
    transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0);
    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
  }
  to{
    opacity: 1;
  }
}
@keyframes mp-zoomInLeft {
  from {
    opacity: 0;
    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0);
    transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0);
    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
  }

  60% {
    opacity: 1;
    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0);
    transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0);
    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
  }
  to{
    opacity: 1;
  }
}
.mp-zoomInLeft {
  -webkit-animation-name: mp-zoomInLeft;
  animation-name: mp-zoomInLeft;
}
//--------------------------- Zoom In Right---------------------------------//
@-webkit-keyframes mp-zoomInRight {
  from {
    opacity: 0;
    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0);
    transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0);
    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
  }

  60% {
    opacity: 1;
    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0);
    transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0);
    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
  }
  to{
    opacity: 1;
  }
}
@keyframes mp-zoomInRight {
  from {
    opacity: 0;
    -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0);
    transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0);
    -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
    animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
  }

  60% {
    opacity: 1;
    -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0);
    transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0);
    -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
    animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
  }
  to{
    opacity: 1;
  }
}
.mp-zoomInRight {
  -webkit-animation-name: mp-zoomInRight;
  animation-name: mp-zoomInRight;
}
//--------------------------- Typing---------------------------------//
@-webkit-keyframes mp-typing{
    0% { width: 0%; }
    30%{ width: 0%; }
    100%{ width: 100%;}
}
@keyframes mp-typing{
    0% { width: 0%; }
    30%{ width: 0%; }
    100%{ width: 100%;}
}
.mp-typing{
    -webkit-animation: mp-typing;
            animation: mp-typing;
}
//--------------------------- Pulsate---------------------------------//
@-webkit-keyframes mp-pulsate {
  0% {
    -webkit-transform: scale(0.62);
    transform: scale(0.62);
    opacity: 1;
    box-shadow: inset 0px 0px 25px 3px rgba(207, 172, 114, 0.75), 0px 0px 25px 10px rgba(207, 172, 114, 0.75);
  }
  100% {
    -webkit-transform: scale(1);
    transform: scale(1);
    opacity: 0;
    box-shadow: none;

  }
}
@keyframes mp-pulsate {
    0% {
        -webkit-transform: scale(0.62);
        transform: scale(0.62);
        opacity: 1;
        box-shadow: inset 0px 0px 25px 3px rgba(207, 172, 114, 0.75), 0px 0px 25px 10px rgba(207, 172, 114, 0.75);
    }
    100% {
        -webkit-transform: scale(1, 1);
        transform: scale(1);
        opacity: 0;
        box-shadow: none;

    }
}
.mp-pulsate{
    -webkit-animation: mp-pulsate;
            animation: mp-pulsate;
}
//--------------------------- Hotspot Pulse---------------------------------//
@-webkit-keyframes hotspot-pulse {
    0% {
        -webkit-transform: scale(1);
        box-shadow: 0 0 0 0 rgba($color: #fff, $alpha: .8);
    }
    70% {
        -webkit-transform: scale(1.1);
        box-shadow: 0 0 0 12px rgba(255, 255, 255, 0);
    }
    100% {
        -webkit-transform: scale(1);
        box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);
    }
}
@keyframes hotspot-pulse {
    0% {
        transform: scale(1);
        box-shadow: 0 0 0 0 rgba($color: #fff, $alpha: .8);
    }
    70% {
        transform: scale(1.1);
        box-shadow: 0 0 0 12px rgba(255, 255, 255, 0);
    }
    100% {
        transform: scale(1);
        box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);
    }
}

Last updated

Was this helpful?