# Giải thích dễ hiểu onEnter, onLeave, sử dụng start, end như nào FULL  Phần 1 (ok)

```typescript
ScrollTrigger.create({
  trigger: ".section",
  start: "top center",
  end: "bottom top",
  pin: true,
  scrub: true,
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});

```

Nghiên cứu các chỉ số start, end

### **Scroller Start 1:** "top *<mark style="color:red;">**top**</mark>*" và end: "bottom *<mark style="color:red;">**bottom**</mark>*"

```typescript
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "top top",
  end: "bottom bottom",
  pin: true,
  pinSpacing: false,
  markers: true,
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
```

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FYOS8Lcr3uGTuRZUViMNs%2Fimage.png?alt=media&#x26;token=57778fe9-5c2e-4a7a-84a1-5975013f99bb" alt=""><figcaption></figcaption></figure>

### **Scroller Start 2:** "top <mark style="color:red;">center</mark>" và end: "bottom *<mark style="color:red;">**bottom**</mark>*"

```typescript
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "top center",
  end: "bottom bottom",
  pin: true,
  pinSpacing: false,
  markers: true,
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
```

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FZjkKvte7GNeI72HpFWTo%2Fimage.png?alt=media&#x26;token=b3b86e3d-ced9-480c-b053-921f8812a0c0" alt=""><figcaption></figcaption></figure>

### **Scroller Start 3:** "top <mark style="color:red;">250</mark>" và end: "bottom *<mark style="color:red;">**bottom**</mark>*"

```
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "top 250",
  end: "bottom bottom",
  pin: true,
  pinSpacing: false,
  markers: true,
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
```

### **Start 1:** "<mark style="color:red;">top</mark> 150" và end: "<mark style="color:red;">bottom</mark> bottom"

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FXpAp2xIRGwtwddnHiERY%2Fimage.png?alt=media&#x26;token=821251d0-8415-4505-ba68-d4d01ab0fc2d" alt=""><figcaption></figcaption></figure>

```typescript
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "top 150",
  end: "bottom bottom",
  pin: true,
  pinSpacing: false,
  markers: true,
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
```

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FVeGnQZlNFoHKj8iHWI8F%2Fimage.png?alt=media&#x26;token=46ef30d5-94ba-4be4-935a-d5441391ed0c" alt=""><figcaption></figcaption></figure>

### **Start 2:** "<mark style="color:red;">center</mark> 150" và end: "<mark style="color:red;">bottom</mark> bottom"

```typescript
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "center 150",
  end: "bottom bottom",
  pin: true,
  pinSpacing: false,
  markers: true,
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
```

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FTJvlxch3RhDBWwjPSVCn%2Fimage.png?alt=media&#x26;token=92f8adc2-1c2d-4cee-a1bd-f604ebdbb0b8" alt=""><figcaption></figcaption></figure>

### **Start 3:** "<mark style="color:red;">100</mark> 150" và end: "<mark style="color:red;">bottom</mark> bottom"

```typescript
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "100 150",
  end: "bottom bottom",
  pin: true,
  pinSpacing: false,
  markers: true,
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
```

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FBFBiS3zqdE3vTSJphr4Z%2Fimage.png?alt=media&#x26;token=1000043b-0983-4187-9db4-f80b5244bbc9" alt=""><figcaption></figcaption></figure>

### Cách hoạt động của **onEnter**, **onLeave**&#x20;

**— Cách hoạt động của onEnter dựa vào start tràn ra mốc Scroller-Start (**&#x63;hý ý tràn phía dưới Scroller-End không có tác dụn&#x67;**)**\\

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FZFQiMa4mnlRrAn780yXk%2Fimage.png?alt=media&#x26;token=d12a13d7-c4a4-40cf-a0a0-72e6c9cd10fb" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FDLijRl9241iAlcNAeUnk%2Fimage.png?alt=media&#x26;token=c51788c9-1dde-48fe-81f9-58561af977f5" alt=""><figcaption></figcaption></figure>

**— Cách hoạt động của onLeave dựa vào end tràn ra mốc Scroller-End (**&#x63;hý ý tràn phía dưới Scroller-Start không có tác dụn&#x67;**)**

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2F7MB8NssWingCMSLWgLpR%2Fimage.png?alt=media&#x26;token=9ffd76c3-eefa-4302-93c1-59dcbf8acfd0" alt=""><figcaption></figcaption></figure>

### Đặc biệt 1: khi sử dụng đảo chiều nhau.  (trường hợp này chỉ hoạt động duy nhất khi start vượt qua Scroller Start)

Nó chỉ sảy ra khi **Start** vượt qua **Scroller Start** (không sảy ra khi end vượt qua **Scroll End** hoặc **Start** vượt qua **Scroll End** tóm lại **Start** chỉ làm việc với **Scroller Start**)&#x20;

```typescript
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "bottom 450",
  end: "top 690",
  // endTrigger: ".spacer",
  pin: true,
  pinSpacing: false,
  markers: true,
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
```

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FD09oaYxVPx4z24yw77Uh%2Fimage.png?alt=media&#x26;token=bb350786-df6d-4060-803a-c1d720740df9" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FhTv1S3IN0UAmyVCfvTAG%2Fimage.png?alt=media&#x26;token=0478277b-0587-48b0-a673-5a58b0ccf3ae" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2Fsne8yGUp6dOGZf0EEshG%2Fimage.png?alt=media&#x26;token=36a00673-5f2c-459d-ae08-7b853cdd8eb1" alt=""><figcaption></figcaption></figure>

### Đặc biệt 2: Sử dụng endTrigger&#x20;

```typescript
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "top top",
  end: "bottom bottom",
  endTrigger: ".spacer",
  pin: true,
  pinSpacing: false,
  markers: true,
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
```

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FeJ3pT3TxX0aXO36hiNa3%2Fimage.png?alt=media&#x26;token=ed24de04-944f-4dd1-92f5-c7cf6cfd2378" alt=""><figcaption></figcaption></figure>

### Đặc biệt 3: Sử dụng endTrigger dạng đảo chiều (khi này ta thấy start, end đều hoạt động)

```typescript
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "bottom 250",
  end: "top bottom",
  endTrigger: ".spacer",
  pin: true,
  pinSpacing: false,
  markers: true,
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
```

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FfIbt0VsUC7zFF2AA1Y3j%2Fimage.png?alt=media&#x26;token=37e3373c-38a5-4270-a3dc-31359d74bf4d" alt=""><figcaption></figcaption></figure>

### &#x20;

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FRZ0kyTyRkTL46j8zM1xk%2Fimage.png?alt=media&#x26;token=ed968d03-4599-4d7d-936c-37417361689e" alt=""><figcaption></figcaption></figure>

### Tiếp tục nghiên cứu hành động sau khi trả về kết quả thứ nhất 1

```typescript
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "bottom 250",
  end: "top bottom",
  endTrigger: ".spacer",
  pin: true,
  pinSpacing: false,
  markers: true,
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
console.log(heroSt);
```

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FeKUDnRClu52dAXF5E1Nt%2Fimage.png?alt=media&#x26;token=35bf5735-ae51-42f4-89ec-8b5baeb014a8" alt=""><figcaption></figcaption></figure>

Sử dụng **start**, **end** trong kết quả đề sử dụng luôn cho đồng thời khối áp dụng sau

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FO3ckBrPcSn4JWBFEe9A9%2Fimage.png?alt=media&#x26;token=91c00f48-fb10-4e56-af5f-0c648dd9539c" alt=""><figcaption></figcaption></figure>

```typescript
// pin the image
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "bottom 250",
  end: "top bottom",
  endTrigger: ".spacer",
  pin: true,
  pinSpacing: false,
  markers: true,
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
console.log(heroSt);
// // Pin left column
ScrollTrigger.create({
  trigger: ".left-row",
  start: () => heroSt.start,
  end: () => heroSt.end,
  pin: true,
  pinSpacing: false,
  // markers: { indent: 150 },
  id: "lft"
});
```

### Chú ý 1.1: Nếu không định nghĩa **Start** hoặc **End** thì mặc định **Scroller Start, Scroller End** sẽ ở phía cuối cùng tức là tương ứng **"bottom bottom" (**&#x78;em ảnh **👇)**

```typescript
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "bottom 250",
  end: "top bottom",
  endTrigger: ".spacer",
  pin: true,
  pinSpacing: false,
  markers: true,
  // onEnter: () => console.log("Entered!"),
  // onLeave: () => console.log("Leaved!")
});
ScrollTrigger.create({
  trigger: ".left-row",
  start: () => 300,
  end: () => 500,
  pin: true,
  pinSpacing: false,
  markers: { indent: 350 },
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
```

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2Fp6QM5QBPOMe5yB4l1G6a%2Fimage.png?alt=media&#x26;token=118b4538-a9e4-4776-95dc-db19a158fc8d" alt=""><figcaption></figcaption></figure>

Do **Scroller Start, Scroller End** đã trùng nhau ở dưới "**bottom bottom**" nên start: 0 thì nó sẽ trùng với  **Scroller Start, Scroller End** (xem ảnh 👇) và nếu sử dụng start: 300 thì nó sẽ bị lui xuống phía dưới 300px xem ảnh ở trên (xem ảnh 👆)&#x20;

```typescript
// pin the image
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "bottom 250",
  end: "top bottom",
  endTrigger: ".spacer",
  pin: true,
  pinSpacing: false,
  markers: true,
  // onEnter: () => console.log("Entered!"),
  // onLeave: () => console.log("Leaved!")
});
// console.log(heroSt);
// // Pin left column
ScrollTrigger.create({
  trigger: ".left-row",
  start: () => 0,
  end: () => heroSt.end,
  pin: true,
  pinSpacing: false,
  markers: { indent: 350 },
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
```

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2Fgh878HQinJuAFj118LVJ%2Fimage.png?alt=media&#x26;token=804bc218-be86-4563-93ab-d48dd9e80ad6" alt=""><figcaption></figcaption></figure>

### Chú ý 1-2: Con số Start được tính như nào?

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FEnmkIZijNlt2XHGlmKD2%2Fimage.png?alt=media&#x26;token=cbe0f9ea-355e-4529-862d-203b163c8eeb" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FkvVDpIULmcIOsQ5FB8bV%2Fimage.png?alt=media&#x26;token=1cc045be-6c1f-4e44-95bc-2c7cfc2b1552" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2F2Q5M6kfdP7MfFpz8LcOk%2Fimage.png?alt=media&#x26;token=b545124b-1e16-4743-b029-fb0eb9bd4f9e" alt=""><figcaption></figcaption></figure>

### Chú ý 2: Hiện tại heroSt.start: 332 do đó nó sẽ phía cách phía "bottom bottom" làm 332px nếu chưa hiểu đọc chú ý 1

```typescript
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "bottom 250",
  end: "top bottom",
  endTrigger: ".spacer",
  pin: true,
  pinSpacing: false,
  markers: true,
  // onEnter: () => console.log("Entered!"),
  // onLeave: () => console.log("Leaved!")
});
console.log(heroSt);
// // Pin left column
ScrollTrigger.create({
  trigger: ".left-row",
  start: () => heroSt.start,
  end: () => heroSt.end,
  pin: true,
  pinSpacing: false,
  markers: { indent: 350 },
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
```

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2F10o3Bm5rC0G316FEyMZI%2Fimage.png?alt=media&#x26;token=091ec0fe-585b-43be-bebe-7e0617da05c6" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FdCjV9BYQGbAefP9GvksV%2Fimage.png?alt=media&#x26;token=4c96a098-2591-4d2c-a67b-6b1200f61a39" alt=""><figcaption></figcaption></figure>

### Tiếp tục nghiên cứu hành động sau khi trả về kết quả thứ nhất 2

### — Nếu sử dụng khối **.left-row, .right-row** giống nhau **heroSt.start, heroSt.end**  thì nó trở thành 2 khối như thông thường không có gì nổi bật

```typescript
// pin the image
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "bottom 250",
  end: "top bottom",
  endTrigger: ".spacer",
  pin: true,
  pinSpacing: false,
  // markers: true,
  // onEnter: () => console.log("Entered!"),
  // onLeave: () => console.log("Leaved!")
});
console.log(heroSt);
// // Pin left column
ScrollTrigger.create({
  trigger: ".left-row",
  start: () => heroSt.start,
  end: () => heroSt.end,
  pin: true,
  pinSpacing: false,
  markers: { indent: 200 },
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
// // Pin right column
ScrollTrigger.create({
  trigger: ".right-row",
  start: heroSt.start,
  end: heroSt.end,
  pin: true,
  pinSpacing: false,
  markers: { indent: 300 },
  id: "rgt"
});
```

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FnuTLreEVLjPl2lLrJRpO%2Fimage.png?alt=media&#x26;token=d58c7854-7dc1-4c90-997b-7f62e38a5a06" alt=""><figcaption></figcaption></figure>

### — Nếu sử dụng khối **.right-row** khác nhau start: "top 250"**, heroSt.end**  thì nó trở thành 2 khối vô cùng đặc biệt (có nghĩa **right-row định nghĩa lại viewPosition 👌)**

```typescript
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "bottom 250",
  end: "top bottom",
  endTrigger: ".spacer",
  pin: true,
  pinSpacing: false,
  // markers: true,
  // onEnter: () => console.log("Entered!"),
  // onLeave: () => console.log("Leaved!")
});
console.log(heroSt);
// // Pin left column
ScrollTrigger.create({
  trigger: ".left-row",
  start: () => heroSt.start,
  end: () => heroSt.end,
  pin: true,
  pinSpacing: false,
  markers: { indent: 200 },
  onEnter: () => console.log("Entered!"),
  onLeave: () => console.log("Leaved!")
});
// // Pin right column
ScrollTrigger.create({
  trigger: ".right-row",
  start: "top 250",
  end: heroSt.end,
  pin: true,
  pinSpacing: false,
  markers: { indent: 300 },
  id: "rgt"
});
```

<figure><img src="https://2494213435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LYjAG13rAPdbArSfRyB%2Fuploads%2FMBHZqXJmf2D05n1Q4AT1%2Fimage.png?alt=media&#x26;token=4f12f959-f8e4-4c10-9838-2971afcd7281" alt=""><figcaption></figcaption></figure>

Đây làm toàn bộ code để hiểu nó một cách hoàn toàn chúng ta phải đọc đi đọc lại nhiều lần

```html
<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title>CodePen - Hero &amp; Column Pin</title>
  <link rel='stylesheet' href='https://codepen.io/GreenSock/pen/xxmzBrw.css'>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    .header {
      position: fixed;
      width: 100%;
      height: 200px;
      background-color: #a0a0a0;
      z-index: 10;
    }
    .wrapper {
      padding-top: 200px;
    }
    .hero {
      width: 100%;
      height: 40vh;
    }
    .row {
      display: flex;
      justify-content: flex-start;
      width: 100%;
      height: 100vh;
    }
    .right-row {
      justify-content: flex-end;
    }
    .column {
      width: 50%;
      height: 100%;
    }
    .spacer {
      width: 100%;
      height: 100vh;
    }
  </style>
</head>
<body>
<!-- partial:index.partial.html -->
<div class="header"></div>
<div class="wrapper">
  <div class="hero gradient-purple"></div>
  <div class="row left-row">
    <div class="column gradient-green">
      <h1>Lorem ipsum dolor sit amet.</h1>
    </div>
  </div>
  <div class="row right-row">
    <div class="column gradient-blue">
      <h1>Lorem ipsum dolor sit amet.</h1>
    </div>
  </div>
</div>
<div class="spacer gradient-red"></div>
<!-- partial -->
  <script src='https://unpkg.com/gsap@3/dist/gsap.min.js'></script>
<script src='https://unpkg.com/gsap@3/dist/ScrollTrigger.min.js'></script>
<script>
  gsap.registerPlugin(ScrollTrigger);
// pin the image
const heroSt = ScrollTrigger.create({
  trigger: ".hero",
  start: "bottom 250",
  end: "top bottom",
  endTrigger: ".spacer",
  pin: true,
  pinSpacing: false,
  // markers: true,
  id: "hero"
});
// Pin left column
ScrollTrigger.create({
  trigger: ".left-row",
  start: () => heroSt.start,
  end: () => heroSt.end,
  pin: true,
  pinSpacing: false,
  // markers: { indent: 150 },
  id: "lft"
});
// Pin right column
ScrollTrigger.create({
  trigger: ".right-row",
  start: "top 250",
  end: heroSt.end,
  pin: true,
  pinSpacing: false,
  // markers: { indent: 300 },
  id: "rgt"
});
</script>
</body>
</html>
```
