Was brauchen wir für das Werkzeug:
→ Ordnerstruktur & Dateien (siehe How-to: Basic Setup)
→ OpenAI-API Key (siehe How-to: API)
→ Browser (funktioniert am besten mit Chrome)
→ Browser Erweiterung (siehe How-to: CORS Erweiterung)
→ Text-Editor (zb. SublimeText)
Die index.html beinhaltet u.A.:
→ <h1> Überschrift (optional)
→ <p> Anleitungstext (optional)
→ <input> zum Prompt eingeben und <button> zum Generieren
→ <button> zum Füllen der Zellen
→ <button> zum Löschen der Zellen
→ <canvas> zum Anzeigen der generierten Bilder
→ <div> zum Erstellen des Grids
1. Öffne die index.html
Du kannst den Code kopieren und in deine Datei einfügen:
<!DOCTYPE html>
<html>
<head>
<title>Hintergrund</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<h1>Hintergrund Grid Editor</h1>
<p>Generiere Bilder und platziere sie auf deine ausgewählten Pixel.<br>
Prompt eingeben, generieren, Pixel auf der Leinwand ausmalen und auf Füllen drücken!</p>
<input id="userInput" placeholder="Hier Prompt eingeben">
<button id="generateButton">Generieren</button>
<button id="fill-button">Füllen</button>
<button id="delete-button">Löschen</button>
<canvas id="imageCanvas"></canvas>
<div id="grid"></div>
<script src="js/script.js"></script>
</body>
</html>
2. Speicher die index.html
1. Öffne die style.css
Die style.css beinhaltet:
→ *{} Zücksetzen auf den Default Style
→ h1{}, p{}, input{}, button{} basic Styling (optinal)
→ .grid{}, .cell{} zum Gestalten des Rasters (wichtig)
Du kannst den Code kopieren und in deine style.css Datei einfügen:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
h1 {
margin: 20px;
}
p {
margin-left: 20px;
}
body {
height: 100vh;
width: 100vw;
}
canvas {
position: absolute;
top: 0;
right: 0;
margin: 20px;
width: 130px;
height: 130px;
}
input, button {
margin-left: 20px;
margin-top: 20px;
}
#grid {
margin: 20px;
display: grid;
grid-template-columns: repeat(60, 1fr);
grid-template-rows: repeat(30, 1fr);
height: 76vh;
border: 0.1px solid black;
}
.cell {
background-color: white;
width: 100%;
height: 100%;
image-rendering: pixelated;
}
.cell.active {
background-color: black;
}
2. Speicher die style.css
Die script.js beinhaltet:
→ initializeGrid: Diese Funktion wird aufgerufen, um das Raster zu initialisieren
→ handleCellMouseOver, handleCellMouseDown, handleCellMouseUp: ändern die Klasse und fügen Zellen zur Liste der ausgewählten Zellen hinzu, abhängig davon, ob die Maustaste gedrückt ist oder nicht
→ getImages: Ruft Bilder von einer API ab und fügt sie der Seite hinzu
→ drawImageOnCanvas: Zeichnet das generierte Bild auf ein HTML-Canvas-Element.
→ fillShapeWithImage: Füllt die ausgewählten Zellen mit dem generierten Bild.
→ getBoundingBox: berechnet die Begrenzungen (Bounding Box) der ausgewählten Zellen, um den richtigen Ausschnitt des generierten Bildes für jede Zelle zu bestimmen
1. Öffne die script.js
Du kannst den Code kopieren und in deine script.js Datei einfügen:
const grid = document.getElementById("grid");
const cells = [];
const numColumns = 60;
const numRows = 30;
function initializeGrid() {
for (let i = 0; i < numRows; i++) {
for (let j = 0; j < numColumns; j++) {
const cell = document.createElement("div");
cell.classList.add("cell");
cell.addEventListener("mouseover", handleCellMouseOver);
cell.addEventListener("mousedown", handleCellMouseDown);
cell.addEventListener("mouseup", handleCellMouseUp);
grid.appendChild(cell);
cells.push(cell);
}
}
}
let isMouseDown = false;
const selectedCells = [];
function handleCellMouseOver(event) {
if (isMouseDown) {
const cell = event.target;
if (!cell.classList.contains("active")) {
cell.classList.add("active");
selectedCells.push(cell);
}
}
}
function handleCellMouseDown(event) {
isMouseDown = true;
const cell = event.target;
cell.classList.add("active");
selectedCells.push(cell);
}
function handleCellMouseUp() {
isMouseDown = false;
}
const fillButton = document.getElementById("fill-button");
fillButton.addEventListener("click", fillShapeWithImage);
const imageCanvas = document.getElementById("imageCanvas");
const userInput = document.getElementById("userInput");
const generateButton = document.getElementById("generateButton");
let generatedImage;
const API_KEY = "DEIN_API_KEY";
generateButton.addEventListener("click", getImages);
async function getImages() {
generateButton.textContent = "Lädt...";
const options = {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json",
"origin": window.location.origin
},
body: JSON.stringify({
"prompt": userInput.value,
"n": 1,
"size": "256x256"
})
};
try {
const response = await fetch("https://api.openai.com/v1/images/generations", options);
const data = await response.json();
if (data.data.length > 0) {
const imageUrl = data.data[0].url;
const img = new Image();
img.crossOrigin = "Anonymous";
img.onload = () => {
generatedImage = img;
drawImageOnCanvas();
generateButton.textContent = "Generieren";
};
img.src = imageUrl;
} else {
console.error(error);
generateButton.textContent = "Generieren";
}
} catch (error) {
console.error(error);
generateButton.textContent = "Generieren";
}
}
function drawImageOnCanvas() {
const canvas = imageCanvas;
const canvasContext = canvas.getContext("2d");
canvasContext.clearRect(0, 0, canvas.width, canvas.height);
canvasContext.drawImage(generatedImage, 0, 0, canvas.width, canvas.height);
}
function fillShapeWithImage() {
if (!generatedImage || selectedCells.length === 0) return;
const bbox = getBoundingBox();
const canvas = document.createElement("canvas");
canvas.width = bbox.width;
canvas.height = bbox.height;
const canvasContext = canvas.getContext("2d");
canvasContext.drawImage(generatedImage, 0, 0, bbox.width, bbox.height);
selectedCells.forEach((cell) => {
const rect = cell.getBoundingClientRect();
const cellOffsetX = rect.left - bbox.minX;
const cellOffsetY = rect.top - bbox.minY;
const imageData = canvasContext.getImageData(cellOffsetX, cellOffsetY, rect.width, rect.height);
const cellCanvas = document.createElement("canvas");
cellCanvas.width = rect.width;
cellCanvas.height = rect.height;
const cellContext = cellCanvas.getContext("2d");
cellContext.putImageData(imageData, 0, 0);
const imageUrl = cellCanvas.toDataURL();
cell.style.backgroundImage = `url('${imageUrl}')`;
cell.style.backgroundSize = `${rect.width}px ${rect.height}px`;
cell.style.backgroundPosition = `-${cellOffsetX}px -${cellOffsetY}px`;
});
selectedCells.length = 0;
}
function getBoundingBox() {
let minX = Infinity,
minY = Infinity,
maxX = -Infinity,
maxY = -Infinity;
selectedCells.forEach((cell) => {
const rect = cell.getBoundingClientRect();
minX = Math.min(minX, rect.left);
minY = Math.min(minY, rect.top);
maxX = Math.max(maxX, rect.right);
maxY = Math.max(maxY, rect.bottom);
});
return { minX, minY, width: maxX - minX, height: maxY - minY };
}
const deleteButton = document.getElementById("delete-button");
deleteButton.addEventListener("click", resetCells);
function resetCells() {
selectedCells.forEach((cell) => {
cell.style.backgroundImage = "";
cell.style.backgroundColor = "";
cell.classList.remove("active");
});
selectedCells.length = 0;
}
initializeGrid();
2. Füge deinen API Key in dieses Feld ein: "DEIN_API_KEY"
3. Speicher die script.js