νλ‘μ νΈλͺ : μΈλ€μΌ λ©μ΄μ»€ (Thumbnail-Maker) κΈ°ν λ° μ μ :
WONKOOK LEE
λΆλ₯ : ν μ΄ νλ‘μ νΈ (κ°μΈ) μ μ κΈ°κ° | λ°°ν¬μΌ : 2021.08.09 (1-day) μ£Όμ κΈ°λ₯ : κ°νΈν μΈλ€μΌ ꡬμ±, νΈμ§, μ΄λ―Έμ§ ν¬λ§·(PNG) 컨λ²ν νκ² μ μ : ν¬ν μ΅ λ± νΈμ§ νλ‘κ·Έλ¨μ΄ μ΅μμΉ μκ±°λ μΈλ€μΌ λ§λλκ² λ²κ±°λ‘μ΄ μ μ μ¬μ© ν΄ :HTML
,CSS
,JavaScript
,HTML2CANVAS(JS-Library)
λ§ν¬ : μΈλ€μΌ λ©μ΄μ»€ - 벨λ‘κ·Έ ν¬λ§· v 1.2.1
λꡬλ μ§ 10μ΄ μμ 무λν 벨λ‘κ·Έ μΈλ€μΌμ λ§λ€ μ μμ΅λλ€. μ΄λλΉ, μ€νΌμ€ μμ΄λ λ©λλ€. λΉμ μ κ°λ°κ³Ό κΈμ°κΈ°μλ§ μ§μ€νμΈμ.
κ°μ΄ 곡λΆνλ κΈ°μ λΆλ€ μ€μ ν¬ν μ΅ κ°μ νΈμ§ νλ‘κ·Έλ¨μ΄ μ΅μμΉ μμ λΆλ€λ κ³μ€ κ²μ΄λ€. 벨λ‘κ·Έμ κΈ°μ λΈλ‘κ·Έλ₯Ό κΎΈμ€ν μ°λκ²λ μΌμΈλ° μΈλ€μΌ λ§λλλ° μν μκ°μ λΊκΈ°μ§ μμκΉ μκ°μ΄ λ€μλ€.
μΈλ€μΌ λ©μ΄μ»€λ 'λ°°κ²½μ λλ€ μμ±κ³Ό νλ μ λ ₯ κ°μ ν€λμ μΆλ ₯νλ μ λμ κ°λ¨ν κΈ°μ λ‘ λ¬΄λν μΈλ€μΌ μ λλ λ§λ€ μ μμ§ μμκΉ' λΌλ μκ°μμ μμλλ€. DOM APIλ‘ HTMLκ³Ό CSS μ‘°μνλ κ²λ λ°°μ λλ° μΈλͺ¨μλ κ²μ λ§λ€μ΄λ³΄κ³ μΆμκ³ μμ΄λμ΄λ₯Ό μ€μ λ‘ κ΅¬ννλ μ°μ΅λ νμνκΈ°μ κ·Έλ₯ ν λ² λ§λ€μλ€.
λ¨μ§ κΈ°λ₯μ ꡬννλ κ²μ λͺ©νλ‘ λ§λ€μ΄μ μ½λ ν리ν°λ μ λ 보μ₯ν μ μλ€ (μ¬μ§μ΄ λͺ¨λ μ μ μ κ·Ό κ°λ₯). Release Notes μ λλ²κ³Ό λ°°ν¬ λ°©λ² μ‘°μ°¨ λͺ¨λ₯΄κ³ κ³΅λΆ μΌμ λ§λ€μκΈ° λλ¬Έμ ν
μ€νΈμ© MVP(minimum viable product)λ‘μ μλ―Έλ§ μλ€. μ΄ μ κ°μνμ¬ λ΄μ£Όμ
¨μΌλ©΄ μ’κ² λ€.
μΈλ€μΌ λ©μ΄μ»€μ λͺ©νλ ννμ λ€μμ± λμ μ νμ§λ₯Ό μ€μ¬ μ¬μ©μμ κ³ λ―Όμ λμ΄μ£Όλ κ²μ΄λ€. κΈ°λ³Έμ μΈ ν μ€νΈ ꡬμ±κ³Ό λλ€ λ°°κ²½μ, μ΄λ―Έμ§ λ°±κ·ΈλΌμ΄λ μ€μ λ± νμν κΈ°λ₯ μΈμ λͺ¨λ λμ΄λ΄κΈ° μν΄ κ³ λ―Όνλ€.
λͺ©ν μ¬μ©μλ νΈμ§ νλ‘κ·Έλ¨μ΄ μ΅μνμ§ μμλ° μΈλ€μΌμ΄ νμν λΆλ€μ΄λ€. μΈλ€μΌ μ μμ ν¬ν μ΅, μΌλ¬μ€νΈλ μ΄ν° κ°μ νλ‘κ·Έλ¨μ μ¬μ©νλ λΆλ€μ΄μΌ μνλλλ‘ κ°μ±μλ μΈλ€μΌμ λ§λ€ μ μκ³ , μμ μ λ§μμ λλ μΈλ€μΌμ΄ λμ¬ λ κΉμ§ λ§λ€κ³ μ νλ μμ§κ° μλ€. λ§μ½ μ¬μ©μκ° μΈλ€μΌμ΄λΌλ κ°λ
μ‘°μ°¨ μμνλ€λ©΄ μ€νλ € μ νμ§λ₯Ό μ€μ΄κ³ , μΌλ₯ μ μ΄λλΌλ 무λν ν
νλ¦ΏμΌλ‘ ꡬμ±νλ κ²μ΄ μ’κ² λ€κ³ μκ°νλ€.
μΈλ€μΌμ λΈλ‘κ·Έ ν¬λ§·μ λ£μμλ μ΄λ»κ² 보μΌμ§ μ§μν μ μλ νλ©΄ ꡬμ±μ΄ μ’μ§ μμκΉ?
μΈλ€μΌμ κ²°κ΅ νλ«νΌμ ν¬μ€ν μ©λλ‘ μ¬μ©λκΈ° λλ¬Έμ, νλ«νΌμ νλ©΄ ꡬμ±κ³Ό μΈλ€μΌμ μ΄μ§κ°μ΄ μλμ§ μ€μκ°μΌλ‘ 보μ¬μ ΈμΌ νλ€λ κ²°λ‘ μΌλ‘ κ·κ²°λμλ€.
λ°λΌμ μΈν°νμ΄μ€ λμμΈμ 벨λ‘κ·Έμ νλ©΄ κ΅¬μ± μ€ #νκ·Έ κ²μνμλ λνλλ λ μ΄μμμ μ°Έκ³ νκ³ κ°κ°μ μ»΄ν¬λμΈ λ€μ΄ νλ«νΌμ λμμΈ μ»¨ν μ€νΈμ κΆ€λ₯Ό ν¨κ» νλλ‘ μλνμλ€. μ¬μ©μ νλ‘ν μΈλ€μΌ, μ¬μ©μ μμ΄λμ κ°μ΄ κΉ¨μκ°μ μμλ€μ λ°μνλ κ²μ λ§λλ μ¬λ―Έλ₯Ό λνλ€.
μ¬μ©μλ μ λͺ©κ³Ό λΆμ λͺ©, λΆλ₯λ₯Ό μΈνμ°½μ ν΅ν΄ μ
λ ₯νκ² λλ€. addEventListener
λ‘ input
μ΄λ²€νΈλ₯Ό κ°μ§νμ¬ μ
λ ₯ νλμ νμ΄νμ΄ λ λλ§λ€ textContent
λ₯Ό κ°±μ νλ λ°©λ²μ μ¬μ©νλ€.
const inputFields = document.querySelectorAll('.input__field');
const updateInputValue = function(e) {
const target = e.target.dataset.set;
document.querySelector(`.${target}`).textContent = e.target.value;
};
inputFields.forEach(e => {
e.addEventListener('input', updateInputValue);
});
리ν©ν λ§ ν λ input
μμλ§λ€ κ°κ°μ μ΄λ²€νΈ νΈλ€λ¬λ₯Ό μμ±νλ λμ μ΄λ²€νΈ μμ(Event Delegation)μΌλ‘ κ°κ²°νκ² μμ ν μμ .
μ¬μ©μκ° κ³ λ―Όνλ μκ°μ μ΅λν μ€μ¬μ£Όκ³ μΆμλ€. μμ¦μ²λΌ μ νμ₯μ λΌλ λ§μ΄ μμ£Ό μΈκΈλλ λλ μμ κ²μ΄λ€. μ΄λ€ μμμΌλ‘ μ리μ¦, ν¬μ€νΈ μΈλ€μΌμ λ§λ€κΉ κ³ λ―ΌνκΈ° μ μ μ¬μ©μμκ² μμμ λ§κ΅¬ μ§μ΄λμ§λ κΈ°λ₯μ΄ λμ΄λ²λ Έλ€.
λ²νΌμ λλ₯΄λ©΄ 무μμμ μμ μ½λκ° λ§λ€μ΄μ Έμ μ¬μ©μλ λ§μμ λλ μμμ΄ λμ¬λκΉμ§ ν΄λ¦νλ©΄ λλ€. μ΄μ€μνλλμ¬μ©μμ·¨ν₯μ΄κ² μ§
λλ€ μ»¬λ¬λΌκ³ ν΄μ λ무 μΉμΉν μμ΄ λμλ²λ¦¬λ©΄ μλκΈ° λλ¬Έμ RGB
κ° κ°κ° 0μμ 255κΉμ§μ λ²μ μ€ μ΅μ 150 μ΄μ, λ무 λ°μΌλ©΄ κΈμκ° μ보μ΄λ 150κ³Ό 240 μ¬μ΄μ λ²μμμ κ°μ΄ μμ±λλλ‘ Math.random
ν¨μλ₯Ό λ§λ€μλ€.
λν DOMμΌλ‘ λ°±κ·ΈλΌμ΄λ μμ μ½λ μ λ¬ν λ rgb(??, ??, ??)
λ μ μ©μ΄ μλμ΄ 16μ§λ² hex μ½λλ‘ κ°κ° λ³ν ν μ΄μ΄λΆμ¬μ€¬λ€. μ΄λ μ¬μ©ν λ©μλλ toString(16)
.
const randomRGB = function() {
let rgb = '';
rgb += (Math.floor(Math.random() * 90 + 1)+150).toString(16).padStart(2, '0');
rgb += (Math.floor(Math.random() * 90 + 1)+150).toString(16).padStart(2, '0');
rgb += (Math.floor(Math.random() * 90 + 1)+150).toString(16).padStart(2, '0');
return rgb;
}
λ°°κ²½μλ§ μμΌλ©΄ νμ©λκ° λ무 λ¨μ΄μ§ κ² κ°μ μ νμ§λ₯Ό μΆκ°νλ€. λ°λ‘ μ΄λ―Έμ§ μ£Όμλ₯Ό μ
λ ₯ν΄μ λ°°κ²½μ μ΄λ―Έμ§λ₯Ό μ½μ
νλ κΈ°λ₯μ΄λ€. prompt
λ‘ μ£Όμκ°μ μ λ¬νμ¬ DOMμ style
νλ‘νΌν°λ‘ κ°λ¨νκ² λ§λ€μλ€.
μΈλ€μΌμ΄ λ§λ€μ΄μ§λ νλ μ λΏλ§ μλλΌ body
μλ λΈλ¬ μ²λ¦¬λ μ΄λ―Έμ§λ₯Ό κΉμμ£Όμ΄ μ¬μ©μκ° μΈλ€μΌμ ν
λ§λ₯Ό κ²½νν μ μλλ‘ κ³ λ €ν΄λ΄€λ€.
DOMμΌλ‘ νλ©΄μμ κΎΈλ―Έλ κ²μ μ΄λ»κ²λ ν΄κ²°μ΄ λλ€μ§λ§, νΉμ νλ©΄μ μ΄λ―Έμ§λ‘ μΊ‘μ³ν΄μ νμΌλ‘ μ μ₯νλ κ²μ μ§κΈ λ΄κ° ꡬνν μ μλ κΈ°μ μ΄μλ€.
HTML2CANVAS λΌλ μλ°μ€ν¬λ¦½νΈ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ¬ ν΄κ²°νμλ€. μ΄ λΌμ΄λΈλ¬λ¦¬λ HTML λ΄μ νΉμ DOM μμμ μμμ μΊ‘μ³ν΄μ μ΄λ―Έμ§ ν¬λ§·μΌλ‘ μΆλ ₯, μ μ₯μ΄ κ°λ₯νλλ‘ λ§λ€μ΄μ€λ€.
μλλ λΌμ΄λΈλ¬λ¦¬μ μ¬μ© μμ μ€λν«
<!-- HTML -->
<div id="capture" style="padding: 10px; background: #f5da55">
<h4 style="color: #000; ">Hello world!</h4>
</div>
// JavaScript
html2canvas(document.querySelector("#capture")).then(canvas => {
document.body.appendChild(canvas)
});
capture
λΌλ id
κ°μ κ°μ§ μμλ₯Ό μΊ‘μ³νμ¬ ν΄λΉ μ΄λ―Έμ§λ₯Ό λ΄μ canvas
λ₯Ό body
μ μμ μμλ‘ μΆκ°νλ€. μ΅μ
κΈ°λ₯μ μ λͺ°λΌμ μ΄λ―Έμ§ λ°°κ²½μ΄ μ΅μ’
κ²°κ³Όμ λ°μλμ§ μμ λ§μ΄ ν΄λ©μμ§λ§ λ€νν StackOverflowμμ λ΅μ μ°Ύμ ν΄κ²°ν μ μμλ€.
λ΄κ° λ§λ μΈλ€μΌ λ©μ΄μ»€μ ν΅μ¬μ λ€μν 컀μ€ν°λ§μ΄μ§ κΈ°λ₯μ μ 곡νλ κ²μ΄ μλλ€. μ΅λν λ¨μν μ¬μ©μ±μ μΆκ΅¬νλ κ²μ΄ λͺ©μ μ΄κΈ° λλ¬Έμ λͺ μλλ κ°λ¨ν λ μ΄μμ, ν μ€νΈ μ€νμΌ μ΅μ μ λ§λ€μ΄ ν μ€νΈκ° λ°°κ²½μ 묻νμ§ μλλ‘ κ³ λ €νλ€.
κ° μ€νμΌ μ΅μ
λ³λ‘ λΆλͺ¨ μμμ νΉμ id
λ₯Ό λΆμ¬νκ³ μμ μμλ€μ id
κ°μ λ°λΌ CSS μ€νμΌμ΄ λ¬λΌμ§λλ‘, μ΅μ
κ°μ λ§κ² λ°λ‘ ν리μ
μ λ§λ€μλ€.
μ΅μνμ μ΅μ μΌλ‘ μ΅λνμ λ°λ¦¬μμ΄μ μ λ§λ€ μ μλλ‘ μλν΄λ³΄μλ€. μλλ μμ λ‘ λ§λ μνλ€μ΄λ€.
μΌλ¨ λ§λλ κ²μ λ¬μ±νμΌλ μ΄μ μ½λλ₯Ό κΉλνκ² μ 리νμ¬ ν¨μ¨μ λμ΄λ μΌμ΄ λ¨μλ€. νμ§λ§ μ΄κ² λ§λλ κ² λ³΄λ€ λ μ΄λ €μΈ κ² κ°λ€.
κΈνκ² λ§λ€λ€λ³΄λ μ€λ³΅λλ μμλ λ§κ³ , λ³μ μ μΈκ³Ό ν¨μλ λ무νλ€. DRY(Don't Repeat Yourself) μμΉμ λ§κ² 리ν©ν λ§ νλ κ³Όμ μ΄ λ¨μλλ°, μ΄ κ³Όμ μ΄ λ΄κ° λ°μ ν μ μλ μ§μ§ κ³κΈ°κ° λμ§ μμκΉ μκ°νλ€.
-
Encapsulation (Private Variables, Functions)
-
Implementing JS Module Pattern or ππ»
-
Organizing Properties in Prototypes
-
Implementing CSS cross-browsing (e.g. web-kit)
-
Undo / Redo (5 steps)
-
More Vivid Color Range π
RGB λͺ¨λ κ°μ λ²μ λ΄μμ μμ±λ λμμ΄κΈ° λλ¬Έμ μ¨ν μκ° λμ λ°λ°ν μμμ΄ λμ€κΈ°λ νλ€. νΈλ λν νμ€ν
ν€ κ·ΈλΌλμΈνΈλ₯Ό λͺ©νλ‘ λ§λ€μλλ°, λͺ¨νΈν μμ΄ μ κ² λμ€λλ‘ λΉλΉλ, νμ€ν
ν€μ μμ μμ£Όλ‘ κ°μ ν μμ μ΄λ€.
- CORS μ μ± μ λ°λ₯΄λ μ¬μ΄νΈμ μ΄λ―Έμ§ URLμ CANVAS μΆλ ₯μ΄ μλλ€. μ΄λ²μ μ²μ μκ²λ CORSμ κ°λ μ μ΄ν΄λ³΄μλ€. κΈ°μ μ μΌλ‘ νΌν΄κ°λ€κ³ νλλΌλ μ€λ¦¬μ μλ°°λλ μΌμ΄κΈ° λλ¬Έμ μ΄λ―Έμ§λ Unsplash κ°μ CC-0 License μ¬μ΄νΈλ₯Ό μ΄μ©ν κ²μ κΆκ³ νλκ²μ΄ λμ μλ μκ² λ€.
보μ μμ μ΄μ λ‘ JavaScriptμμ 보λ΄λ κ΅μ°¨ μΆμ²(μμ κ³Ό λ€λ₯Έ μΆμ²) HTTP μμ²μ μ ννκΈ° μν μ μ± [μΆμ²] CORS (Cross-Origin Resource Sharing)κ° λ¬΄μμΌκΉ | μμ±μ μ΄λ Έκ·Έλ¦¬λ
Boram Kim λκ»μ μ¬μ©μ± κ°μ μ견(issue
)μ 보λ΄μ£Όμ
¨μ΅λλ€. (κ°μ¬ν©λλ€ π₯°)
골μλ μ΄λ―Έμ§ λ§ν¬ κ°μ΄ falsy
μΌλ alert
λ₯Ό λμ΄ ν ν¨μκ° μ’
λ£λλ validation
μ μ°¨μμ λΆνμν alert
μ μ κ±°μ λν μ견μ
λλ€.
λ΅λ³
μμ€ν μ견 μ£Όμ
μ μ λ§μ λ§ κ°μ¬ν©λλ€. λΆνμνκ² alert
μ λμ μ¬μ©μμ λΆνΈκ°μ μΌκΈ°νλ κ²μ λ§μνμ λ°μ κ°μ΄ μ’μ λ°©μμ΄ μλ κ² κ°μ΅λλ€. alert
λ€μ΄μΌλ‘κ·Έ λμ λ²νΌ μμ μκ² ν΄ν κ°μ λ©μμ§(e.g. 'μλͺ»λ νμμ μ£Όμμ
λλ€')λ₯Ό λμ°λ λ°©λ²μΌλ‘ κ΅μ²΄νκ³ , μ΄λ―Έμ§μ μ ν¨μ±μ λΉλκΈ°μ μΌλ‘ νμΈν μ μλ λ³λμ validation processλ₯Ό μ°κ΅¬νκ² μ΅λλ€. κ°μ¬ν©λλ€ ππ»
μ²μ λ§λ€μ΄μ λκΈ° μ±λμ μ²μμΌλ‘ λ°°ν¬ν λ―Έλ νλ‘μ νΈλΌμ λ³ κΈ°λλ μνλ€. λ무λ κ°μ¬νκ²λ λ΄κ° λ§λ μ±μ μ¬μ©νμ¬ λΈλ‘κ·Έ μΈλ€μΌλ‘ νμ©νλ λΆλ€μ΄ κ³μ ¨λ€.
λμμ΄λλ κ°λ°μλ μμ μ΄ λ§λ μ νκ³Ό μλΉμ€λ₯Ό κΈ°κΊΌμ΄ μ¬μ©ν΄μ£Όμλ κ³ λ§μ΄ λΆλ€μ΄ κ³μκΈ°μ μ§μ μ 보λμ λλΌμ§ μμκΉ μκ°νκ² λλ€. μ΄ μ리λ₯Ό λΉμ΄ λ€μ νλ² κ°μ¬νλ€λ λ§μ νννκ³ μΆλ€. π€
μμ€ν λΆλ€μ κ΄μ¬ λλΆμ μΈλ€μΌ λ©μ΄μ»€ ν¬μ€ν μ΄ λ²¨λ‘κ·Έ μ£Όκ° νΈλ λ© ν¬μ€νΈ μλ¨μ μ¬λΌκ°μ΅λλ€. π₯° μ κ° λ§λ 컨ν μΈ κ° λ§μ λΆλ€μκ² λ³΄μ¬μ§ μ μλ κΈ°νλ₯Ό μ»μ κ²μ κ·Έμ κ°μ¬ν λ°λ¦μ λλ€.
ππ» μΈλ€μΌ λ©μ΄μ»€ ꡬ경νκΈ°
κΈκ³Ό μ΄λ―Έμ§ Wonkook Lee β All Rights Reserved
Thumbnail-Maker is the simplest thumbnail generator for blogging. Thumbnail-Maker has been built as part of a toy project which in my very first phase of being a web developer. credit:
Wonkook Lee (@oneook)
contact:[email protected]
Thank you.