---
# System prepended metadata

title: 研究小記
tags: [Html, ngrok, Javascript, CSS]

---

<p class="text-center">
<br><br>-HPS IX-<br><Made by Andel><br>

# 研究方向
我們要將宣傳影片結合垃圾桶的功能按鍵，所以我們必須拆分出【功能】與【影片】，使用前端（Html\Javascript\CSS）來把功能以及外觀做出來，再結合影片串流
    
# 成品簡介
>右邊是一班垃圾、左邊是資源回收（兩個都有加滑鼠移動上去時的動態效果）
點進去兩個不同的功能時會跳轉到不同的影片串流
    
![](https://hackmd.io/_uploads/BkrJu5ej2.png)

[影片DEMO](https://gcdn.2mdn.net/videoplayback?expire=1690536623&ei=LxrDZM_nMMyqlQSOgYKYCQ&ip=0.0.0.0&id=0e55866c3a92a5f0&itag=309&source=web_video_ads&requiressl=yes&susc=aal&mime=video/mp4&vprv=1&gir=yes&clen=17885363&dur=20.885&lmt=1690507733839452&txp=0000224&sparams=expire,ei,ip,id,itag,source,requiressl,susc,mime,vprv,gir,clen,dur,lmt&sig=AOq0QJ8wRQIhAKwNR8Op76Zn8rus_Urg9FljNvn4ADUA-ZOSTqfPvgRjAiAenryia1uAlKSBLUMw6FbOMs7lvg2BX32ptafoMRj5gA==)
    
# 過程紀錄
## python 複習
* 學習資源：
    * Python 複習：https://ithelp.ithome.com.tw/articles/10287193 - 從例外陳述(exception & exception handling) 開始
    * Flask學習:https://ithelp.ithome.com.tw/articles/10258223
    * 前端三寶複習:
        * [HTML](https://www.youtube.com/watch?v=CLUPkcLQm64)
        * [CSS](https://www.youtube.com/watch?v=Ml78vnNTBLw&t=3886s)
        * [JAVASCRIPT](https://www.youtube.com/watch?v=yZwlW5INhgk&t=10548s)
## 資料夾

    - templates
        - index.html #主要頁面
        - videos.html #資源回收
        - videos_2.html #一般垃圾
    - static
        - css
            - style.css
        - js
            -main.js
        - images/
            - videos.mp4 #播放影片檔案
    app.py #實驗架設Flask模組

    
## index.html
>比較特別的地方，會在13三行和19桁的icon，需要引用地8行的Font Awesome 圖示
``` html=
    <!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>資源回收與垃圾分類</title>
  <link rel="stylesheet" href="/static/css/style.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
</head>
<body>
  <div class="container">
    <button id="recycleButton">
      <div class="left-box" id="leftBox">
        <i class="fas fa-recycle fa-3x"></i>
        <h2>♻️資源回收</h2>
      </div>
    </button>
    <button id="trashButton">
      <div class="right-box" id="rightBox">
        <i class="fas fa-trash fa-3x"></i>
        <h2>🚮一般垃圾</h2>
      </div>
    </button>
  </div>
  <script src="/static/js/main.js"></script>
</body>
</html>

```
## style.css
``` css=
    body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
}

.container {
  display: flex;
  justify-content: space-evenly; /* 將方格子水平居中 */
  align-items: center; /* 將方格子垂直居中 */
  height: 100vh; /* 使用視窗高度作為容器高度 */
  padding: 20px;
  box-sizing: border-box; /* 考慮內邊距和邊框在內的計算盒模型 */
}

.left-box, .right-box {
  width: 300px;
  height: 300px;
  padding: 20px;
  text-align: center;
  background-color: #f0f0f0;
  transition: background-color 0.3s ease;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); /* 添加淺淺的黑色邊框 */
}

.left-box {
  background-color: #b5e7a0;
}

.right-box h2 {
  color: #ff0000;
  font-size: 24px; /* 調整文字大小 */
  margin-bottom: 10px; /* 調整文字位置，增加底部間距 */
}

.left-box h2 {
  color: #008000;
  font-size: 24px; /* 調整文字大小 */
  margin-bottom: 10px; /* 調整文字位置，增加底部間距 */
}

.left-box:hover {
  background-color: #97c78d;
}

.right-box:hover {
  background-color: #a5a5a5;
}
button {
  border: none; /* 移除按鈕邊框 */
  padding: 1px 1px; /* 調整按鈕內邊距 */
  background-color: #f0f0f0;
  transition: background-color 0.3s ease;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); /* 添加陰影效果 */
}

```

## main.js
    
>比較沒有學過的就是將滑鼠移到上面時，更改顏色的函式 ，然後我如果只要有點擊一般垃圾或是資源回收，終端機會收到callback

``` javascript=
// 獲取需要操作的HTML元素
const leftBox = document.getElementById('leftBox');
const rightBox = document.getElementById('rightBox');
const recycleButton = document.getElementById('recycleButton');
const trashButton = document.getElementById('trashButton');
const myVideo = document.getElementById('myVideo');

// 當滑鼠移到leftBox上時觸發的事件
leftBox.addEventListener('mouseover', () => {
  darkenColor(leftBox);
});

// 當滑鼠移開leftBox時觸發的事件
leftBox.addEventListener('mouseout', () => {
  lightenColor(leftBox);
});

// 當滑鼠移到rightBox上時觸發的事件
rightBox.addEventListener('mouseover', () => {
  darkenColor(rightBox);
});

// 當滑鼠移開rightBox時觸發的事件
rightBox.addEventListener('mouseout', () => {
  lightenColor(rightBox);
});

// 用於將元素的背景顏色變暗的函式
function darkenColor(box) {
  box.style.backgroundColor = darkenHexColor(box.style.backgroundColor, -20);
}

// 用於將元素的背景顏色變亮的函式
function lightenColor(box) {
  if (box.id === 'leftBox') {
    box.style.backgroundColor = originalLeftColor;
  } else if (box.id === 'rightBox') {
    box.style.backgroundColor = originalRightColor;
  }
}

// 用於將16進位顏色碼進行調整暗化的函式
function darkenHexColor(hex, amount) {
  const color = hex.replace('#', '');
  const num = parseInt(color, 16);
  const r = Math.max((num >> 16) + amount, 0);
  const g = Math.max((num >> 8) + amount, -20);
  const b = Math.max((num & 0x0000FF) + amount, 0);
  const newColor = (g | (b << 8) | (r << 16)).toString(16);
  return "#" + newColor.padStart(6, '0');
}

// 當recycleButton按鈕被點擊時觸發的事件
recycleButton.addEventListener('click', () => {
  // 將網頁重新導向到 '/videos' 路徑
  window.location.href = '/videos';
});

// 當trashButton按鈕被點擊時觸發的事件
trashButton.addEventListener('click', () => {
  // 將網頁重新導向到 '/video_2' 路徑
  window.location.href = '/video_2';
});

// 當myVideo影片元素被點擊時觸發的事件
myVideo.addEventListener('click', () => {
  // 進入全螢幕模式的相容處理
  if (myVideo.requestFullscreen) {
    myVideo.requestFullscreen();
  } else if (myVideo.mozRequestFullScreen) { // Firefox
    myVideo.mozRequestFullScreen();
  } else if (myVideo.webkitRequestFullscreen) { // Chrome, Safari, Opera
    myVideo.webkitRequestFullscreen();
  } else if (myVideo.msRequestFullscreen) { // IE/Edge
    myVideo.msRequestFullscreen();
  }
});


```
## app(Flask python)
### 要先安裝Flask模組

    pip install flask

### 以下程式碼
```python=
from flask import Flask, render_template

app = Flask(__name__, static_folder='static')

@app.route('/')
def index():
    """
    根路徑的處理函式。當用戶訪問根路徑時，會返回名為 "index.html" 的模板頁面。
    """
    return render_template('index.html')

@app.route('/video_2')
def video_2():
    """
    處理路徑 '/video_2' 的函式。當用戶訪問 '/video_2' 路徑時，會返回名為 "video_2.html" 的模板頁面。
    """
    return render_template('video_2.html')

@app.route('/videos')
def videos():
    """
    處理路徑 '/videos' 的函式。當用戶訪問 '/videos' 路徑時，會返回名為 "videos.html" 的模板頁面。
    """
    return render_template('videos.html')

if __name__ == '__main__':
    # 開始運行 Flask 應用程式，並將其設定在1024端口上。
    # 這將使應用程式在您的本地伺服器上運行，並且您可以使用網頁瀏覽器訪問它。
    app.run(port=1024)

```
## 執行
### 因為我把檔案放在Angel所以要先
    cd path/th/Angel
### 再來執行程式碼（運行flask）
    python app.py
### 測試架設到外網(使用ngrok來完成) 
    ngrok http 1024 
:::warning

:bulb: ngrok教學

Ngrok 是一個非常流行的工具，它能夠將您本地端的伺服器或應用程式暴露在公共的互聯網上，讓您可以進行測試、分享或與他人合作，而無需設定複雜的網路設置或佈署到真實的伺服器上。它的主要功能是建立一個反向代理，將您的本地伺服器通過 Ngrok 提供的公共 URL 連接到互聯網。

學習連結：
1.官網paper:https://ngrok.com 
2.step by step:https://askie.today/ngrok-localhost-server-settings/
:::