Novi oblik: šestougao
Dodaj u generator oblik „šestougao“: novu opciju u padajućoj listi i crtanje pravilnog šestougla sa centrom u (100, 100) i poluprečnikom 72.
Srce sajta: strana na kojoj korisnik upiše naziv, izabere boju, oblik i font i odmah vidi svoj logo, a zatim ga preuzme kao sliku. Logo crtamo kao SVG – vektorsku sliku koja se pravi od HTML-olikih elemenata, pa je JavaScript menja isto kao ostatak stranice.
<svg viewBox="0 0 300 120" width="300" style="border:1px solid #ccc">
<circle cx="60" cy="60" r="45" fill="#dd0022" /> <!-- krug: centar i poluprečnik -->
<rect x="120" y="20" width="70" height="70" rx="12" fill="#1f5f91" /> <!-- pravougaonik, rx = zaobljenje -->
<polygon points="250,15 290,60 250,105 210,60" fill="#2a9d5c" /> <!-- mnogougao: niz tačaka -->
<text x="60" y="72" text-anchor="middle" font-size="32" font-weight="bold" fill="white">SP</text>
</svg>
Rezultat:
| Element | Atributi |
|---|---|
<svg viewBox="0 0 300 120"> | „platno“ od 300×120 jedinica; slika se uvećava bez gubitka oštrine |
circle | cx, cy – centar, r – poluprečnik |
rect | x, y – gornji levi ugao, width, height, rx |
polygon | points – parovi koordinata |
text | x, y, text-anchor="middle" – centriran oko x |
fill | boja popune |
Koordinatni sistem je kao u matematici, ali y raste naniže – tačka (0, 0) je gornji levi ugao. Isti sistem koriste i Processing i Python turtle/pygame.
Levo je forma (Bootstrap), desno prazan div id="prikaz" u koji JavaScript crta logo:
<!DOCTYPE html>
<html lang="sr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Generator – Logo Kreator</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="css/main.css">
</head>
<body class="bg-light">
<div class="container py-4">
<h1 class="h3 mb-4"><a href="naslovna.html" class="text-decoration-none">Logo Kreator</a> · generator</h1>
<div class="row g-4">
<!-- levo: izbor -->
<form id="forma" class="col-md-5">
<div class="mb-3">
<label for="naziv" class="form-label">Naziv</label>
<input id="naziv" class="form-control" maxlength="20" value="Logo">
</div>
<div class="mb-3">
<label for="slogan" class="form-label">Slogan (nije obavezan)</label>
<input id="slogan" class="form-control" maxlength="30">
</div>
<div class="row g-2 mb-3">
<div class="col">
<label for="boja" class="form-label">Boja</label>
<input id="boja" type="color" class="form-control form-control-color w-100" value="#dd0022">
</div>
<div class="col">
<label for="oblik" class="form-label">Oblik</label>
<select id="oblik" class="form-select">
<option value="krug">krug</option>
<option value="kvadrat">kvadrat</option>
<option value="romb">romb</option>
</select>
</div>
</div>
<div class="mb-3">
<label for="font" class="form-label">Font</label>
<select id="font" class="form-select">
<option value="Arial, sans-serif">Arial</option>
<option value="Georgia, serif">Georgia</option>
<option value="'Courier New', monospace">Courier New</option>
</select>
</div>
<button type="button" id="preuzmiSvg" class="btn btn-danger">Preuzmi SVG</button>
<button type="button" id="preuzmiPng" class="btn btn-outline-danger">Preuzmi PNG</button>
</form>
<!-- desno: živi prikaz -->
<div class="col-md-7 text-center">
<div id="prikaz" class="p-3 bg-white rounded shadow-sm"></div>
</div>
</div>
</div>
<script src="js/generator.js"></script>
</body>
</html>
// ===== js/generator.js – Logo Kreator =====
const NS = "http://www.w3.org/2000/svg"; // SVG elementi se prave sa ovim "imenskim prostorom"
const polja = ["naziv", "slogan", "boja", "oblik", "font"].map(id => document.getElementById(id));
const [naziv, slogan, boja, oblik, font] = polja;
const prikaz = document.getElementById("prikaz");
// 1. naziv iz adrese: generator.html?naziv=Sekcija+Pupin (šalje ga forma sa naslovne)
const izAdrese = new URLSearchParams(location.search).get("naziv");
if (izAdrese) naziv.value = izAdrese.slice(0, 20);
// pomoćna funkcija: napravi SVG element sa atributima
function el(ime, atributi) {
const e = document.createElementNS(NS, ime);
for (const [k, v] of Object.entries(atributi)) e.setAttribute(k, v);
return e;
}
// inicijali: "Sekcija Pupin" -> "SP", "Logo" -> "LO"
function inicijali(tekst) {
const reci = tekst.trim().split(/\s+/).filter(r => r.length > 0);
if (reci.length === 0) return "?";
if (reci.length === 1) return reci[0].slice(0, 2).toUpperCase();
return (reci[0][0] + reci[1][0]).toUpperCase();
}
// 2. nacrtaj logo iz trenutnih vrednosti polja
function nacrtaj() {
const svg = el("svg", { xmlns: NS, viewBox: "0 0 400 200", width: "100%" });
svg.id = "logo";
const b = boja.value;
// znak (levo)
if (oblik.value === "krug") svg.append(el("circle", { cx: 100, cy: 100, r: 70, fill: b }));
else if (oblik.value === "kvadrat") svg.append(el("rect", { x: 30, y: 30, width: 140, height: 140, rx: 24, fill: b }));
else svg.append(el("polygon", { points: "100,25 175,100 100,175 25,100", fill: b }));
const slova = el("text", { x: 100, y: 116, "text-anchor": "middle", "font-size": 46, "font-weight": "bold",
"font-family": font.value, fill: "#fff" });
slova.textContent = inicijali(naziv.value);
svg.append(slova);
// naziv i slogan (desno)
// veličina slova se smanjuje za duži naziv, da stane u preostalih ~200 jedinica širine
const velicina = Math.min(34, Math.floor(200 / (0.6 * Math.max(naziv.value.length, 1))));
const ime = el("text", { x: 195, y: slogan.value ? 100 : 112, "font-size": velicina, "font-weight": "bold",
"font-family": font.value, fill: "#222" });
ime.textContent = naziv.value || "Logo";
svg.append(ime);
if (slogan.value) {
const s = el("text", { x: 197, y: 132, "font-family": font.value, fill: b,
"font-size": Math.min(18, Math.floor(200 / (0.55 * slogan.value.length))) });
s.textContent = slogan.value;
svg.append(s);
}
prikaz.replaceChildren(svg); // zameni stari logo novim
}
// 3. svaka promena u bilo kom polju odmah ponovo crta logo
for (const p of polja) p.addEventListener("input", nacrtaj);
nacrtaj();
| Ideja | Gde u kodu |
|---|---|
naziv sa naslovne strane stiže u adresi (?naziv=...) i čita se sa URLSearchParams | korak 1 |
SVG elementi se prave sa createElementNS (obični createElement ne radi za SVG) | funkcija el |
sav izgled zavisi od vrednosti polja – funkcija nacrtaj svaki put pravi logo iz početka | korak 2 |
događaj input na svim poljima → logo se menja dok kucaš ili biraš boju | korak 3 |
tekst se upisuje sa textContent – bezbedno (lekcija DOM i događaji) | slova, ime, s |
// 4. preuzimanje
function imeFajla(ekstenzija) {
return (naziv.value.trim() || "logo").toLowerCase().replace(/[^a-z0-9]+/g, "_") + "." + ekstenzija;
}
function preuzmi(url, ime) { // privremeni link koji "kliknemo" iz koda
const a = document.createElement("a");
a.href = url;
a.download = ime;
a.click();
}
function svgTekst() {
return new XMLSerializer().serializeToString(document.getElementById("logo"));
}
document.getElementById("preuzmiSvg").addEventListener("click", () => {
const blob = new Blob([svgTekst()], { type: "image/svg+xml" });
const url = URL.createObjectURL(blob);
preuzmi(url, imeFajla("svg"));
URL.revokeObjectURL(url);
});
document.getElementById("preuzmiPng").addEventListener("click", () => {
const slika = new Image();
slika.onload = () => {
const platno = document.createElement("canvas"); // SVG -> crtež na platnu -> PNG
platno.width = 800;
platno.height = 400;
const ctx = platno.getContext("2d");
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, 800, 400);
ctx.drawImage(slika, 0, 0, 800, 400);
preuzmi(platno.toDataURL("image/png"), imeFajla("png"));
};
slika.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svgTekst());
});
| Format | Kako nastaje | Kada |
|---|---|---|
| SVG | tekst SVG elementa (XMLSerializer) → Blob (fajl u memoriji) → link sa atributom download | za štampu i velike formate – oštar u svakoj veličini |
| PNG | SVG se učita kao slika, nacrta na canvas dvostruke veličine i pretvori u PNG | za profilnu sliku, dokumente, društvene mreže |
Ime fajla nastaje iz naziva: mala slova, a sve što nije slovo ili cifra postaje _ („Sekcija Pupin“ → sekcija_pupin.png).
Ceo generator (HTML + JavaScript) radi u okviru ispod. Promeni naziv, slogan, boju, oblik i font. Preuzimanje u ovom okviru je zbog bezbednosti isključeno – radi kada stranu otvoriš kao svoj fajl.
<!DOCTYPE html>
<html lang="sr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Generator – Logo Kreator</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="css/main.css">
</head>
<body class="bg-light">
<div class="container py-4">
<h1 class="h3 mb-4"><a href="naslovna.html" class="text-decoration-none">Logo Kreator</a> · generator</h1>
<div class="row g-4">
<!-- levo: izbor -->
<form id="forma" class="col-md-5">
<div class="mb-3">
<label for="naziv" class="form-label">Naziv</label>
<input id="naziv" class="form-control" maxlength="20" value="Logo">
</div>
<div class="mb-3">
<label for="slogan" class="form-label">Slogan (nije obavezan)</label>
<input id="slogan" class="form-control" maxlength="30">
</div>
<div class="row g-2 mb-3">
<div class="col">
<label for="boja" class="form-label">Boja</label>
<input id="boja" type="color" class="form-control form-control-color w-100" value="#dd0022">
</div>
<div class="col">
<label for="oblik" class="form-label">Oblik</label>
<select id="oblik" class="form-select">
<option value="krug">krug</option>
<option value="kvadrat">kvadrat</option>
<option value="romb">romb</option>
</select>
</div>
</div>
<div class="mb-3">
<label for="font" class="form-label">Font</label>
<select id="font" class="form-select">
<option value="Arial, sans-serif">Arial</option>
<option value="Georgia, serif">Georgia</option>
<option value="'Courier New', monospace">Courier New</option>
</select>
</div>
<button type="button" id="preuzmiSvg" class="btn btn-danger">Preuzmi SVG</button>
<button type="button" id="preuzmiPng" class="btn btn-outline-danger">Preuzmi PNG</button>
</form>
<!-- desno: živi prikaz -->
<div class="col-md-7 text-center">
<div id="prikaz" class="p-3 bg-white rounded shadow-sm"></div>
</div>
</div>
</div>
<script>
// ===== js/generator.js – Logo Kreator =====
const NS = "http://www.w3.org/2000/svg"; // SVG elementi se prave sa ovim "imenskim prostorom"
const polja = ["naziv", "slogan", "boja", "oblik", "font"].map(id => document.getElementById(id));
const [naziv, slogan, boja, oblik, font] = polja;
const prikaz = document.getElementById("prikaz");
// 1. naziv iz adrese: generator.html?naziv=Sekcija+Pupin (šalje ga forma sa naslovne)
const izAdrese = new URLSearchParams(location.search).get("naziv");
if (izAdrese) naziv.value = izAdrese.slice(0, 20);
// pomoćna funkcija: napravi SVG element sa atributima
function el(ime, atributi) {
const e = document.createElementNS(NS, ime);
for (const [k, v] of Object.entries(atributi)) e.setAttribute(k, v);
return e;
}
// inicijali: "Sekcija Pupin" -> "SP", "Logo" -> "LO"
function inicijali(tekst) {
const reci = tekst.trim().split(/\s+/).filter(r => r.length > 0);
if (reci.length === 0) return "?";
if (reci.length === 1) return reci[0].slice(0, 2).toUpperCase();
return (reci[0][0] + reci[1][0]).toUpperCase();
}
// 2. nacrtaj logo iz trenutnih vrednosti polja
function nacrtaj() {
const svg = el("svg", { xmlns: NS, viewBox: "0 0 400 200", width: "100%" });
svg.id = "logo";
const b = boja.value;
// znak (levo)
if (oblik.value === "krug") svg.append(el("circle", { cx: 100, cy: 100, r: 70, fill: b }));
else if (oblik.value === "kvadrat") svg.append(el("rect", { x: 30, y: 30, width: 140, height: 140, rx: 24, fill: b }));
else svg.append(el("polygon", { points: "100,25 175,100 100,175 25,100", fill: b }));
const slova = el("text", { x: 100, y: 116, "text-anchor": "middle", "font-size": 46, "font-weight": "bold",
"font-family": font.value, fill: "#fff" });
slova.textContent = inicijali(naziv.value);
svg.append(slova);
// naziv i slogan (desno)
// veličina slova se smanjuje za duži naziv, da stane u preostalih ~200 jedinica širine
const velicina = Math.min(34, Math.floor(200 / (0.6 * Math.max(naziv.value.length, 1))));
const ime = el("text", { x: 195, y: slogan.value ? 100 : 112, "font-size": velicina, "font-weight": "bold",
"font-family": font.value, fill: "#222" });
ime.textContent = naziv.value || "Logo";
svg.append(ime);
if (slogan.value) {
const s = el("text", { x: 197, y: 132, "font-family": font.value, fill: b,
"font-size": Math.min(18, Math.floor(200 / (0.55 * slogan.value.length))) });
s.textContent = slogan.value;
svg.append(s);
}
prikaz.replaceChildren(svg); // zameni stari logo novim
}
// 3. svaka promena u bilo kom polju odmah ponovo crta logo
for (const p of polja) p.addEventListener("input", nacrtaj);
nacrtaj();
// 4. preuzimanje
function imeFajla(ekstenzija) {
return (naziv.value.trim() || "logo").toLowerCase().replace(/[^a-z0-9]+/g, "_") + "." + ekstenzija;
}
function preuzmi(url, ime) { // privremeni link koji "kliknemo" iz koda
const a = document.createElement("a");
a.href = url;
a.download = ime;
a.click();
}
function svgTekst() {
return new XMLSerializer().serializeToString(document.getElementById("logo"));
}
document.getElementById("preuzmiSvg").addEventListener("click", () => {
const blob = new Blob([svgTekst()], { type: "image/svg+xml" });
const url = URL.createObjectURL(blob);
preuzmi(url, imeFajla("svg"));
URL.revokeObjectURL(url);
});
document.getElementById("preuzmiPng").addEventListener("click", () => {
const slika = new Image();
slika.onload = () => {
const platno = document.createElement("canvas"); // SVG -> crtež na platnu -> PNG
platno.width = 800;
platno.height = 400;
const ctx = platno.getContext("2d");
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, 800, 400);
ctx.drawImage(slika, 0, 0, 800, 400);
preuzmi(platno.toDataURL("image/png"), imeFajla("png"));
};
slika.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svgTekst());
});
</script>
</body>
</html>
Rezultat:
Za svaki zadatak postoji primer, uputstvo i rešenje. Rešenja su provereno ispravna u pregledaču.
Dodaj u generator oblik „šestougao“: novu opciju u padajućoj listi i crtanje pravilnog šestougla sa centrom u (100, 100) i poluprečnikom 72.
Dodaj dugme koje bira nasumičnu boju, oblik i font i ponovo crta logo.
document.createElementNS("http://www.w3.org/2000/svg", ...) – sa običnim createElement se ne prikazuju.input se ne desi – zato se posle toga ručno poziva nacrtaj().1. Kako generator saznaje naziv upisan na naslovnoj strani?
2. Kojom metodom se prave SVG elementi u JavaScript-u?
3. Gde je tačka (0, 0) u SVG-u?
4. Zašto se logo ponovo crta pri svakom događaju input?