Created
January 5, 2022 12:02
-
-
Save XiaoPanPanKevinPan/ee14a0b25d531cdea33c1ff69a608462 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="zh-TW"> | |
<head> | |
<title>期末報告</title> | |
<meta charset="utf-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> | |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/normalize.css" /> | |
<script> | |
let cwbToken = ""; // 氣象局 API 之權杖須自行取得 | |
document.addEventListener("DOMContentLoaded", async()=>{ | |
try{ | |
let displayWeather = (temperature, humidity)=>{ | |
let temperatureMeter = document.querySelector("#weatherInfo .temperature.meter .bar"); | |
let humidityMeter = document.querySelector("#weatherInfo .humidity.meter .bar"); | |
temperatureMeter.innerHTML = `${temperature} °C`; | |
temperatureMeter.style.setProperty("--value", Math.min(Math.max(temperature + 30, 0), 100) / 100); | |
humidityMeter.innerHTML = `${(humidity*100).toFixed(1)} %`; | |
humidityMeter.style.setProperty("--value", humidity); | |
}; | |
let changeWallpaper = async ()=>{ | |
let newWallpaperBlob = URL.createObjectURL(await(await | |
fetch("https://picsum.photos/1080/1920")).blob()); | |
let main = document.querySelector("main"); | |
main.style["background-image"] = `url("${newWallpaperBlob}")`; | |
}; | |
let cwbData = await fetch(`https://opendata.cwb.gov.tw/api/v1/rest/datastore/O-A0001-001?Authorization=${cwbToken}&format=JSON`); | |
let cwbJson = await cwbData.json(); | |
console.log(cwbJson); | |
if(cwbJson.success != "true"){ | |
throw "錯誤:取得之資料不可用。success != \"true\""; | |
} | |
let selector = document.querySelector("#locationNameSelector"); | |
selector.innerHTML = `<option>請選擇監測地點</option>`; | |
let locations = cwbJson.records.location; | |
for(let location of locations){ | |
/* get each ${location.parameter}, which in this form | |
* { | |
* parameterName: ${name}, | |
* parameterValue: ${value} | |
* } | |
* remapped it into this form | |
* ${name}: ${value} | |
*/ | |
let newParameters = {}; | |
for(let param of location.parameter){ | |
newParameters[param.parameterName] = param.parameterValue; | |
} | |
location.parameter = newParameters; | |
/* do the same as above, but do for ${weatherElement} */ | |
let newWeatherElements = {}; | |
for(let elem of location.weatherElement){ | |
newWeatherElements[elem.elementName] = elem.elementValue; | |
} | |
location.weatherElement = newWeatherElements; | |
/* and then create the full name */ | |
location["locationFullName"] = | |
`${location.parameter["CITY"]}${location.parameter["TOWN"]} ${location.locationName}`; | |
} | |
locations.sort((location1, location2)=>{ | |
return location1.locationFullName.localeCompare(location2.locationFullName); | |
}); | |
for(let location of locations){ | |
selector.insertAdjacentHTML( | |
"beforeend", | |
`<option value="${location.stationId}">${location.locationFullName}</option>` | |
); | |
} | |
selector.addEventListener("change", (e)=>{ | |
for(let location of cwbJson.records.location){ | |
if(location.stationId != selector.value) continue; | |
/* "TEMP" stands for temperature, "HUMD" stands for humidity*/ | |
displayWeather( | |
parseFloat(location.weatherElement["TEMP"]), | |
parseFloat(location.weatherElement["HUMD"]) | |
); | |
/*changeWallpaper();*/ | |
} | |
}); | |
}catch(e){ | |
let errNote = document.querySelector("#error"); | |
errNote.innerHTML = e; | |
errNote.style["display"] = ""; | |
} | |
}, {once: true}); | |
</script> | |
<style> | |
#error{ | |
background-color: #FF0000; | |
color: #FFF; | |
text-align: center; | |
padding: 0.5em; | |
} | |
/*input, select, button, textarea...*/ | |
/*styles*/ | |
input, select, button, textarea{ | |
/*en-transparent, sharpen & flatten*/ | |
--bg-opacity: .6; | |
broder-radius: 0; | |
border-style: none; | |
background-color: hsla(0, 0%, 100%, var(--bg-opacity)); | |
/*animation*/ | |
transition: background-color .5s | |
} | |
/*animation*/ | |
input:hover, select:hover, button:hover, textarea:hover{ | |
--bg-opacity: 1; | |
} | |
html, body{ | |
height: 100vh; | |
width: 100vw; | |
/*font-size: 20px;*/ | |
} | |
main{ | |
width: 100%; | |
height: 100%; | |
background-color: hsl(210, 75%, 75%); | |
background-image: url("https://picsum.photos/1080/1920"); | |
background-repeat: no-repeat; | |
background-position: center bottom; | |
background-size: cover; | |
} | |
/*add spaces to most elements*/ | |
p, div, input, select, button, textarea{ | |
padding: 0.5em; | |
} | |
/*css reset*/ | |
*{ | |
boxo-sizing: border-box; | |
} | |
#locationNameSelector{ | |
width: 100%; | |
} | |
#weatherInfo{ | |
text-align: center; | |
} | |
.meter{ | |
display: inline-block; | |
width: clamp(3em, 30%, min(9em, 70%)); | |
padding: 0; | |
} | |
.meter .barContainer{ | |
background-color: hsla(0, 100%, 100%, 60%); | |
height: calc(90vh - 3rem - 1rem); /*3rem left for selector, 1rem for the padding of #weatherInfo*/ | |
padding: 0; | |
position: relative; /*it is like declare the edge for the childrens with "absolute" position*/ | |
} | |
.meter .bar{ | |
width: 100%; | |
height: calc(100% * var(--value)); | |
background-color: #0F0; | |
padding: 0; | |
overflow: hidden; | |
position: absolute; | |
bottom: 0; | |
transition: height .5s; | |
color: white; | |
text-shadow: 2px 2px 2px #000; | |
} | |
.meter .label{ | |
color: white; | |
text-shadow: 2px 2px 2px #000; | |
} | |
#weatherInfo .humidity.meter .bar{ | |
background-color: #2968FFB0; | |
} | |
#weatherInfo .temperature.meter .bar{ | |
background-color: #FF5A19B0; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="error" style="display: none;"></div> | |
<main> | |
<select id="locationNameSelector"></select> | |
<div id="weatherInfo"> | |
<div class="temperature meter"> | |
<div class="barContainer"> | |
<div class="bar"></div> | |
</div> | |
<div class="label">溫度</div> | |
</div> | |
<div class="humidity meter"> | |
<div class="barContainer"> | |
<div class="bar"></div> | |
</div> | |
<div class="label">溼度</div> | |
</div> | |
</div> | |
</main> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment