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
→ <input> zum Steuern der Linienstärke
→ <button> zum Löschen der Zeichnung
→ <button> zum Ändern der Pinselform
→ <canvas> zum Anzeigen des generierten Bildes
→ <canvas> zum Zeichnen
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>Zeichenwerkzeug</h1>
<p>Schreibe einen Prompt mit dem gewünschten Farbstil den du haben möchtest.<br>
Sobald dein Stift generiert wurde kannst du zeichnen.</p>
<input type="text" id="userInput" placeholder="Neongrüne Sonne">
<button id="generateButton">Generieren</button> <br> <br>
<input type="range" id="lineWidth" min="1" max="200" value="5">
<button id="deleteButton">Löschen</button>
<button id="lineCapButton">Pinsel: Eckig</button> <br>
<canvas id="imageCanvas"></canvas>
<canvas id="drawingCanvas"></canvas>
<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{}, #lineWidth{} basic Styling (optinal)
→ #imageCanvas{}, #drawingCanvas{} zum Gestalten der Canvases (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;
user-select: none;
}
p {
margin-left: 20px;
margin-bottom: 20px;
user-select: none;
}
#imageCanvas, #drawingCanvas {
position: absolute;
top: 0;
left: 0;
z-index: -9999;
}
#imageCanvas {
display: none;
}
input {
margin-left: 20px;
}
#lineWidth {
left: 30vw;
}
2. Speicher die style.css
Die script.js beinhaltet:
→ initializeApp: wird definiert und ruft die Funktion auf, um den Text des "Generate"-Buttons zu setzen
→ getImages: Ruft Bilder von einer API ab und f ügt sie der Seite hinzu
→ preloadImage: Wird definiert und lädt das empfangene Bild vor, indem sie ein Image-Objekt erstellt, dessen Quelle auf die URL des Bildes gesetzt wird
→ drawImageOnCanvas: Zeichnet das Bild auf dem Image-Canvas
→ draw, startDrawing, stopDrawing, deleteDrawing: Implementieren die Logik für das Zeichnen auf dem Zeichen-Canvas
→ toggleLineCap: Wechselt zwischen den beiden Linienabschlussstilen
→ getViewportDimensions: Gibt die Breite und Höhe des sichtbaren Bereichs des Fensters zück.
→ getImageColorData: Gibt die Farbwerte des Bildes an einer bestimmten Position zur ück
1. Öffne die script.js
Du kannst den Code kopieren und in deine script.js Datei einfügen:
let img = null;
let drawingData = null;
let lastPos = null;
let lastColor = null;
let lineCap = 'butt';
const imageCanvas = document.getElementById('imageCanvas');
const drawingCanvas = document.getElementById('drawingCanvas');
const lineWidthSlider = document.getElementById('lineWidth');
const userInput = document.getElementById('userInput');
const deleteButton = document.getElementById('deleteButton');
const lineCapButton = document.getElementById('lineCapButton');
const generateButton = document.getElementById('generateButton');
const API_KEY = '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';
lineCapButton.addEventListener('click', toggleLineCap);
drawingCanvas.addEventListener('mousedown', startDrawing);
drawingCanvas.addEventListener('mousemove', draw);
document.addEventListener('mouseup', stopDrawing);
deleteButton.addEventListener('click', deleteDrawing);
generateButton.addEventListener('click', handleGenerateButtonClick);
function initializeApp() {
generateButton.textContent = 'Generieren';
}
async function handleGenerateButtonClick() {
generateButton.textContent = 'Lädt...';
await getImages();
generateButton.textContent = 'Generieren';
}
async function getImages() {
const options = {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
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();
await preloadImage(data);
} catch (error) {
console.error(error);
}
}
function preloadImage(data) {
return new Promise((resolve, reject) => {
img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = () => {
const { width, height } = getViewportDimensions();
imageCanvas.width = width;
imageCanvas.height = height;
drawingCanvas.width = width;
drawingCanvas.height = height;
drawImageOnCanvas();
resolve();
};
img.onerror = reject;
img.src = data?.data[0].url;
});
}
function drawImageOnCanvas() {
const ctxImage = imageCanvas.getContext('2d');
ctxImage.drawImage(img, 0, 0, imageCanvas.width, imageCanvas.height);
if (drawingData) {
const ctxDraw = drawingCanvas.getContext('2d');
ctxDraw.putImageData(drawingData, 0, 0);
}
}
function startDrawing(e) {
lastPos = {
x: e.offsetX,
y: e.offsetY
};
const imageData = getImageColorData(lastPos.x, lastPos.y);
lastColor = `rgb(${imageData[0]}, ${imageData[1]}, ${imageData[2]})`;
}
function draw(e) {
if (!lastPos) return;
if (e.buttons !== 1) {
lastPos = null;
lastColor = null;
return;
}
const x = e.offsetX;
const y = e.offsetY;
const imageData = getImageColorData(x, y);
const color = `rgb(${imageData[0]}, ${imageData[1]}, ${imageData[2]})`;
const ctxDraw = drawingCanvas.getContext('2d');
ctxDraw.lineWidth = lineWidthSlider.value;
ctxDraw.lineJoin = 'butt';
ctxDraw.lineCap = lineCap;
if (lastPos) {
const grad = ctxDraw.createLinearGradient(lastPos.x, lastPos.y, x, y);
grad.addColorStop(0, lastColor);
grad.addColorStop(1, color);
ctxDraw.strokeStyle = grad;
ctxDraw.beginPath();
ctxDraw.moveTo(lastPos.x, lastPos.y);
ctxDraw.lineTo(x, y);
ctxDraw.stroke();
}
lastPos = { x, y };
lastColor = color;
drawingData = ctxDraw.getImageData(0, 0, drawingCanvas.width, drawingCanvas.height);
}
function stopDrawing() {
lastPos = null;
lastColor = null;
}
function deleteDrawing() {
const ctxDraw = drawingCanvas.getContext('2d');
ctxDraw.clearRect(0, 0, drawingCanvas.width, drawingCanvas.height);
lastPos = null;
lastColor = null;
drawingData = null;
}
function toggleLineCap() {
if (lineCap === 'butt') {
lineCap = 'round';
lineCapButton.textContent = 'Pinsel: Rund';
} else {
lineCap = 'butt';
lineCapButton.textContent = 'Pinsel: Eckig';
}
}
function getViewportDimensions() {
return {
width: Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0),
height: Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
};
}
function getImageColorData(x, y) {
const ctxImage = imageCanvas.getContext('2d');
const imageData = ctxImage.getImageData(x, y, 1, 1).data;
return imageData;
}
initializeApp();
2. Füge deinen API Key in dieses Feld ein: "DEIN_API_KEY"
3. Speicher die script.js