※画像は常識の範囲でご自由にお使いください。
*Please feel free to use the images within the scope of common sense.
เชื่อว่าหลายคนเติบโตมากับการ์ตูนของ Studio Ghibli มีความทรงจำดี ๆ กับเรื่องราวและตัวละครทั้งหลาย ผมเพิ่งได้ดูในยุคที่มี DVD เป็นการนั่งดูพร้อมกับเด็ก ๆ เมื่อค้นหาข้อมูลจากอินเตอร์เน็ต ในเว็บของ Studio Ghibli เองมีข้อมูลผลงาน และรูปภาพจากภาพยนต์ที่อนุญาตให้นำไปใช้ตามความเหมาะสม
นี่คือไอเดียของผม ลองนำรูปภาพเหล่านั้นมาทำเป็น Wallpaper API ที่เปลี่ยนรูปทุกวันเหมือนกับ Bing Wallpaper แนวทางที่คิดไว้มีสองทางเลือก แบบตรงไปตรงมาก็คือ สร้าง list หรือ database เก็บรูปภาพทั้งหมดไว้ก่อน แล้วสุ่มเลือกรูปภาพเหล่านั้นมาใช้ กับอีกวิธีหนึ่ง ทำแบบ dynamic ใช้วิธี web scraping อ่านเนื้อหาจากโค้ด HTML ของหน้าเว็บ แล้วสะกัดเอาเฉพาะส่วนที่เป็น url ของรูปภาพมาสร้างเป็น list เก็บไว้ใช้ ข้อดีของวิธีนี้ หากเว็บต้นทางมีเนื้อหา หรือ รูปภาพใหม่เพิ่มมาก็จะอัพเดท list ได้ แต่ข้อเสียอยู่ที่ต้องเขียนโค้ดซับซ้อนกว่า เสียเวลาตอนเริ่มต้นเซิร์ฟเวอร์นานกว่า เพราะต้องสแกนรายการรูปภาพทั้งหมดทุกครั้ง
เมื่อรวบรวมรูปภาพมาได้แล้ว ขั้นตอนต่อไปคือ การสุ่มเลือกรูปภาพประจำวัน ดูเหมือนจะง่ายแค่ใช้ค่า random เลือกออกมาก็ได้ แต่เนื่องจาก API นี้ตั้งใจให้ทำงานบน serverless ซึ่งในระหว่างวันอาจมีการ shutdown เมื่อไม่มีผู้เรียกใช้ หรือ spawn server เพิ่มขึ้นมาเป็นหลาย instance เมื่อมีผู้เรียกใช้จำนวนมาก ทำอย่างไรภายในวันเดียวกัน server ทุกตัวสามารถสุ่มได้รูปภาพเดียวกัน
ดังนั้นค่าที่เปลี่ยนไปแต่ละวันที่สามารถใช้เป็น seed ก็จะมีตัวเลขที่เลือกใช้คือ วันเดือนปี วันในสัปดาห์ (0 = อาทิตย์, 1 = จันทร์, ..) ค่าสัปดาห์ของปี (1 - 52) ค่าวันของปี (1 - 365) ประมาณนั้น ทุก server จะต้องคำนวณโดยใช้สูตรเดียวกัน จึงจะได้ค่าสุ่มที่ไม่เปลี่ยนแปลงระหว่างวัน
การออกแบบของผมแบ่งการสุ่มเป็น 2 ขั้นตอน เริ่มจากเลือกจาก list ของผลงานซึ่งล่าสุดมีทั้งหมด 24 เรื่อง มีรูปภาพทั้งหมด 1178 ภาพ เพื่อต้องการให้รูปภาพแต่ละวันมาจากภาพยนต์เรื่องไม่ซ้ำกัน หลังจากนั้นจึงเลือกรูปที่อยู่ในอัลบั้มของการ์ตูนเรื่องนั้น
โค้ดที่เขียนก็เลยใช้วิธีมั่ว ๆ ผสมสูตรบวกลบคูณหาร จากตัวเลขที่ใช้เป็น seed ได้ตามที่คิดไว้ข้างต้น แล้วก็ลองทำ loop ตรวจสอบว่า มีโอกาสได้ภาพซ้ำเดิมอย่างไรบ้าง ปรับไปจนได้สูตรที่ภายใน 600 วัน มีโอกาสที่สุ่มได้ภาพซ้ำเดิมน้อยสุดที่ 50 ครั้ง
const ghibliSeed = (date, work) => {
const wknames = Object.keys(GHIBLI_WORKS)
const d = date.toISOString().split('T')[0]
const seed = 0|(+(d.split('-').join('')))
const wkname = work || wknames[seed % wknames.length]
const wkselect = GHIBLI_WORKS[wkname]
if (wkselect && wkselect.images && wkselect.images.length) {
const xseed = ((seed) + (date.getDay() * 3) + date.getMonth() + date.getDate())
const imgid = 0|(xseed % (wkselect.images.length))
return {
wkname,
imgid,
date: d,
wkselect,
copyright: wkselect.title || 'Studio Ghibli',
copyright_link: wkselect.url,
url: wkselect.images[imgid],
}
}
}
สรุปคือ เปลี่ยนสูตรจนหมดแรงแล้วสำหรับวันนั้น สมองตื้อคิดวิธีที่ดีกว่านี้ไม่ออก แต่ก็ยังเชื่อว่ายังมีวิธีสร้าง seed เพื่อให้สามารถคำนวณหาค่าสุ่มภาพประจำวันไม่ซ้ำ แต่วันเดียวกันต้องได้ภาพเหมือนกันทุกครั้ง เป็นเบื้องหลังการคิดทำ API สุ่มภาพแบบประจำวันเอาไว้ใช้เอง ดูเหมือนไม่มีอะไร แต่ก็มีโจทย์ท้าทายให้ลองขบคิดเล่น ๆ กัน
รวมผลงานของ Studio Ghibli
Kommentare