Some more tools around Android icons
All checks were successful
/ publish (push) Successful in 1m48s
All checks were successful
/ publish (push) Successful in 1m48s
This commit is contained in:
parent
7f6dcac154
commit
c7ff8597aa
15 changed files with 644 additions and 2 deletions
50
site/gradient-image/index.html
Normal file
50
site/gradient-image/index.html
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Gradient Image - Tools</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body class="container">
|
||||
<header>
|
||||
<hgroup>
|
||||
<h1>Gradient Image</h1>
|
||||
<p>Generate gradient images as downloadable PNGs</p>
|
||||
</hgroup>
|
||||
</header>
|
||||
<main class="grid">
|
||||
<section class="controls">
|
||||
<label for="from-color">From Colour</label>
|
||||
<input type="color" id="from-color" value="#ff0000">
|
||||
|
||||
<label for="to-color">To Colour</label>
|
||||
<input type="color" id="to-color" value="#0000ff">
|
||||
|
||||
<label for="gradient-type">Gradient Type</label>
|
||||
<select id="gradient-type">
|
||||
<option value="linear">Linear</option>
|
||||
<option value="radial">Radial</option>
|
||||
</select>
|
||||
|
||||
<label for="rotation">Rotation: <span id="rotation-value">0</span>°</label>
|
||||
<input type="range" id="rotation" min="0" max="360" step="45" value="0">
|
||||
|
||||
<label for="image-size">Image Size</label>
|
||||
<select id="image-size">
|
||||
<option value="64">64 × 64</option>
|
||||
<option value="128">128 × 128</option>
|
||||
<option value="192">192 × 192</option>
|
||||
<option value="256" selected>256 × 256</option>
|
||||
<option value="512">512 × 512</option>
|
||||
</select>
|
||||
</section>
|
||||
<section class="preview">
|
||||
<canvas id="preview-canvas" width="256" height="256"></canvas>
|
||||
<button id="download-btn">Download</button>
|
||||
</section>
|
||||
</main>
|
||||
<script src="main.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
70
site/gradient-image/main.js
Normal file
70
site/gradient-image/main.js
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
const PREVIEW_SIZE = 256;
|
||||
|
||||
const fromColorEl = document.getElementById("from-color");
|
||||
const toColorEl = document.getElementById("to-color");
|
||||
const gradientTypeEl = document.getElementById("gradient-type");
|
||||
const rotationEl = document.getElementById("rotation");
|
||||
const rotationValueEl = document.getElementById("rotation-value");
|
||||
const imageSizeEl = document.getElementById("image-size");
|
||||
const canvas = document.getElementById("preview-canvas");
|
||||
const downloadBtn = document.getElementById("download-btn");
|
||||
|
||||
function drawGradient(ctx, size) {
|
||||
const fromColor = fromColorEl.value;
|
||||
const toColor = toColorEl.value;
|
||||
const type = gradientTypeEl.value;
|
||||
const rotation = parseInt(rotationEl.value);
|
||||
|
||||
const cx = size / 2;
|
||||
const cy = size / 2;
|
||||
|
||||
let gradient;
|
||||
if (type === "radial") {
|
||||
const radius = size / 2;
|
||||
gradient = ctx.createRadialGradient(cx, cy, 0, cx, cy, radius);
|
||||
} else {
|
||||
const angle = (rotation * Math.PI) / 180;
|
||||
const len = size / 2;
|
||||
const dx = Math.cos(angle) * len;
|
||||
const dy = Math.sin(angle) * len;
|
||||
gradient = ctx.createLinearGradient(cx - dx, cy - dy, cx + dx, cy + dy);
|
||||
}
|
||||
|
||||
gradient.addColorStop(0, fromColor);
|
||||
gradient.addColorStop(1, toColor);
|
||||
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, size, size);
|
||||
}
|
||||
|
||||
function renderPreview() {
|
||||
canvas.width = PREVIEW_SIZE;
|
||||
canvas.height = PREVIEW_SIZE;
|
||||
const ctx = canvas.getContext("2d");
|
||||
drawGradient(ctx, PREVIEW_SIZE);
|
||||
}
|
||||
|
||||
function download() {
|
||||
const size = parseInt(imageSizeEl.value);
|
||||
const offscreen = document.createElement("canvas");
|
||||
offscreen.width = size;
|
||||
offscreen.height = size;
|
||||
const ctx = offscreen.getContext("2d");
|
||||
drawGradient(ctx, size);
|
||||
|
||||
const link = document.createElement("a");
|
||||
link.download = `gradient-${size}x${size}.png`;
|
||||
link.href = offscreen.toDataURL("image/png");
|
||||
link.click();
|
||||
}
|
||||
|
||||
fromColorEl.addEventListener("input", renderPreview);
|
||||
toColorEl.addEventListener("input", renderPreview);
|
||||
gradientTypeEl.addEventListener("input", renderPreview);
|
||||
rotationEl.addEventListener("input", () => {
|
||||
rotationValueEl.textContent = rotationEl.value;
|
||||
renderPreview();
|
||||
});
|
||||
downloadBtn.addEventListener("click", download);
|
||||
|
||||
renderPreview();
|
||||
22
site/gradient-image/style.css
Normal file
22
site/gradient-image/style.css
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
.controls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.preview {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
#preview-canvas {
|
||||
width: 256px;
|
||||
height: 256px;
|
||||
border: 1px solid var(--pico-muted-border-color);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
#download-btn {
|
||||
width: 100%;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue