---
# System prepended metadata

title: 兩種 滑鼠點擊愛心特效
tags: [HTML & CSS, JavaScript]

---

# 滑鼠點擊愛心特效
### **撰寫程式：HTML ｜ CSS ｜ JS**
###### codepen：https://codepen.io/liu_0821/pen/ExOeqez
![](https://hackmd.io/_uploads/Syj5CU1sh.png)



## HTML 擷取片段
> ######　基本上兩種方法的`HTML`都差不多，差異在ID的命名，為了方便在這裡擷取第一個做為介紹。
```
<div class="box" id="box">
  <a class="collect" id="Collect">
    <svg xmlns="http://www.w3.org/2000/svg"
         fill="currentColor"
         class="bi bi-heart-fill"
         viewBox="0 0 16 16">
      <path fill-rule="evenodd"
            d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z" />
    </svg>
  </a>
</div>
```

## CSS 擷取片段
#### 第一種
```
.collect {
  color: #d5d1d1;
  cursor: pointer;
  width: 50px;
  height: 50px;
  display:flex;
  align-items: center;
  justify-content: center;
  border:2px solid #d5d1d1;
  border-radius: 50%;
  box-shadow: 2px 2px 6px #c3bdbd; // 陰影
}

.collect:hover {
  // 滑鼠移入呈現的畫面
  color: #d12525 !important;
  border:2px solid #d12525;
  box-shadow: 2px 2px 6px #d12525;
  opacity: .8; // 透明度
}

.collect > svg {
  width: 24px;
}

```
> ###### 愛心飛起來的動畫
```
.heart{
  position: absolute;
  color: #d12525;
  animation: fly 1s linear forwards; // 動畫
}
.heart> svg {
  width: 20px;
}

@keyframes fly {
    from{
     opacity:1; // 透明度
    }
    to {
      opacity: 0;
    }
}
```

#### 第二種

```
.pulse-box{  // 第二個愛心樣式
  border:2px solid #d12525;
  box-shadow: 2px 2px 6px #d12525;
}
.pulse-box-pink{ // 第二個愛心點擊下去的樣式
  color:#d52a2ac4;
  border:2px solid #d52a2ac4;
  box-shadow:2px 2px 6px #d52a2ac4;
}
.heart2{ // 那些漂浮小愛心
  position: absolute;
  color: #d12525;
  animation: fly 1s linear forwards;
}
.heart2 > svg{
  width: 12px;
}
```

> ###### 愛心縮放的動畫
```
.pulse{
   animation:  pulse 1s linear infinite;
}
@keyframes pulse {
    0% {
            transform: scale(1);
    }
    10% {
            transform: scale(1.1);
    }
    20% {
            transform: scale(0.9);
    }
    30% {
            transform: scale(1);
    }
    40% {
            transform: scale(0.9);
    }
    50% {
            transform: scale(1.1);
    }
    60% {
            transform: scale(0.9);
    }
    70% {
            transform: scale(1);
    }
}

```

## JS
> ######  透過計算偏移位置增減偏移量製造出往上飛的感覺

#### 第一種
```
let collect = document.getElementById("Collect");
$("#Collect").on("click",(e)=>{
  let div = document.createElement("div");
  $(div).append(`
    <svg xmlns="http://www.w3.org/2000/svg"
           fill="currentColor"
           class="bi bi-heart-fill"
           viewBox="0 0 16 16">
        <path fill-rule="evenodd"
              d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z" />
      </svg>
  `);
  div.className = "heart";
  // 計算 collect 寬度與高度
  let x = collect.offsetWidth/2;
  let y = collect.offsetHeight/2;
  // 計算 collect 相對畫面的水平/垂直偏移量
  div.style.left =collect.offsetLeft + x/2 + "px";
  $("#Collect").append(div)
  var i =0;
  let timer = setInterval(()=>{
    i = i+4 ; 
    // 讓他往上飛的部分
    div.style.top = collect.offsetTop + y/2 - i + "px";
    
    if(i >=36){
      // 大於等於36會清空timer，並且移除上方新建立的div
      clearInterval(timer)
      div.remove();
    }
  },100)
  
  
});
```
#### 第二種
```
let collect2 = document.getElementById("Collect2");
// 當滑鼠滑過去新增/移除ClassName
$("#Collect2").hover(function(){
    $("#Collect2 > svg").addClass("pulse");
    $(collect2).addClass("pulse-box");
  },function(){
    $("#Collect2 > svg").removeClass("pulse");
    $(collect2).removeClass("pulse-box");
});
// 滑鼠點擊下去
$("#Collect2").on("click",(e)=>{
  $(collect2).addClass("pulse-box-pink"); // 新增樣式
  for(var i =0; i <=20 ; i++){
  // 從這開始製作小愛心(20個)
    setTimeout(() => {
      let div = document.createElement("div");
      $(div).append(`
          <svg xmlns="http://www.w3.org/2000/svg"
                 fill="currentColor"
                 class="bi bi-heart-fill"
                 viewBox="0 0 16 16">
              <path fill-rule="evenodd"
                    d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z" />
            </svg>
        `);
      div.className = "heart2";
      let x = collect2.offsetWidth/2;
      let y = collect2.offsetHeight/2;
      
      // 透過亂數 製造出左右不同位置
      div.style.left = collect2.offsetLeft + getRandom(-25,25) + x/2 + 3 + 'px';
      div.style.transform = `scale(${Math.random()+0.3}) `
      // 透過亂數 製造出上下不同位置
      div.style.top = collect2.offsetTop + getRandom(-15,15) + i - y/2 + 'px';
      collect2.appendChild(div);
      
      // 製造出往上飛的感覺
      let z=0;
      let timer = setInterval(()=>{
        z = z+4 ; 
        div.style.top = collect.offsetTop + getRandom(-15,15) + i - y/2 - z + "px";

        if(z >=40){
          clearInterval(timer)
        }
      },300)
      
      // 3秒之後清空 
      setTimeout(() => {
        div.remove();
        $(collect2).removeClass("pulse-box-pink");
      }, 3000);
    }, i * 100)
  };
 
});

function getRandom(min,max){
    return Math.floor(Math.random()*(max-min+1))+min;
};
```

### 如果遇到重複點擊或只能捕捉點擊第一次？
  1. `$('#collect')`的函式中使用`one`可確保只執行一次，避免重複讀取值。
  2. 其他可以參考我的另一篇筆記 https://hackmd.io/@LindaLiu/Skihk3_Hn
---

##### ヽ(∀ﾟ )人(ﾟ∀)人( ﾟ∀)人(∀ﾟ )人(ﾟ∀)人( ﾟ∀)ﾉヽ(∀ﾟ )人(ﾟ∀ﾟ)人( ﾟ∀)人(∀ﾟ )人(ﾟ∀ﾟ)人( ﾟ∀)人(∀ﾟ )人( ﾟ∀)人

##### 以上 如果註解哪裡有錯誤或有問題，歡迎提出來一起討論~~~~