Hast du eine Frage?


How-to: Zeichenwerkzeug


Willkommen zum How-to: Zeichenwerkzeug.
Hier lernst du, wie du ein Werkzeug programmierst mit dem du
dein Zeichenwerkzeug prompten und personalisieren kannst.

Falls du etwas nicht verstehst, nutze den Chatbot auf der rechten Seite.
Kopiere den Teil vom Code, den du erklärt haben möchtest und stelle deine Frage dazu.



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)

HTML index.html

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

CSS style.css

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


JS script.js

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


Du kannst jetzt die index.html in deinem Browser öffnen und das Tool testen :)