mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-09-14 21:46:35 +00:00
feat: add preview catalog and catalog group and header
This commit is contained in:
+7
-1624
File diff suppressed because it is too large
Load Diff
+5
-156
@@ -1,13 +1,13 @@
|
|||||||
# DOM audit (phase A)
|
# DOM audit (phase A)
|
||||||
|
|
||||||
_2026-08-29T02:33:28.258Z_
|
_2026-08-29T02:50:59.953Z_
|
||||||
|
|
||||||
## Сводка
|
## Сводка
|
||||||
|
|
||||||
| route | ref | added | removed | tag | text |
|
| route | ref | added | removed | tag | text |
|
||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| `/preview/demo` | demo.html | 0 | 0 | 0 | 0 |
|
| `/preview/demo` | demo.html | 0 | 0 | 0 | 0 |
|
||||||
| `/preview/list-tools` | list-tools.html | 150 | 80 | 0 | 1 |
|
| `/preview/list-tools` | list-tools.html | 0 | 0 | 0 | 0 |
|
||||||
| `/preview/tools/linear-gradient-png` | gradient.html | 5 | 6 | 2 | 1 |
|
| `/preview/tools/linear-gradient-png` | gradient.html | 5 | 6 | 2 | 1 |
|
||||||
| `/preview/tools/remove-background-png` | background-remover.html | 7 | 6 | 2 | 1 |
|
| `/preview/tools/remove-background-png` | background-remover.html | 7 | 6 | 2 | 1 |
|
||||||
|
|
||||||
@@ -22,162 +22,11 @@ _расхождений нет_
|
|||||||
|
|
||||||
## /preview/list-tools (vs list-tools.html)
|
## /preview/list-tools (vs list-tools.html)
|
||||||
|
|
||||||
- added: **150** (≈1043 узл.), removed: **80** (≈87 узл.), tag: **0**, text: **1**
|
- added: **0** (≈0 узл.), removed: **0** (≈0 узл.), tag: **0**, text: **0**
|
||||||
|
|
||||||
### Расхождения (топ 150)
|
### Расхождения (топ 0)
|
||||||
|
|
||||||
- `body > main:1 > div:2 > div:1 > div:2 > b:1` **added** (`b` "130" · 1 узл.)
|
_расхождений нет_
|
||||||
- `body > main:1 > div:2 > div:1 > div:2 > span:2` **text**: ours `TOOLSAVAILABLE` → ref `TOOLS AVAILABLE`
|
|
||||||
- `body > main:1 > div:2 > div:1 > div:2 > b:1` **removed** (`b` "32" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:1 > i:2` **added** (`i` "21 TOOLS" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:1 > i:2` **removed** (`i` "05 TOOLS" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:1 > span:2 > span:2` **added** (`span` "Opens a JPEG and saves it as lossless PNG. Transparency, if present, is preserved." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:1 > span:2 > span:2` **removed** (`span` "Re-encode JPEG files as lossless PNG while preserving transparency." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:1 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:1 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:2 > span:2 > span:2` **added** (`span` "Re-encodes a WebP image into universal PNG." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:2 > span:2 > span:2` **removed** (`span` "Turn WebP images into a universal PNG format for any workflow." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:2 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:2 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:3 > span:2 > strong:1` **added** (`strong` "Convert GIF to PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:3 > span:2 > span:2` **added** (`span` "Extracts the first frame of a GIF animation and saves it as PNG." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:3 > span:2 > strong:1` **removed** (`strong` "PNG to Base64" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:3 > span:2 > span:2` **removed** (`span` "Encode an image as a base64 string for embedding in code or styles." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:3 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:3 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:4 > span:2 > strong:1` **added** (`strong` "Convert BMP to PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:4 > span:2 > span:2` **added** (`span` "Re-encodes BMP into compact lossless PNG." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:4 > span:2 > strong:1` **removed** (`strong` "PNG to Data URI" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:4 > span:2 > span:2` **removed** (`span` "Build a complete data URI ready for HTML and CSS." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:4 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:4 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:5 > span:2 > strong:1` **added** (`strong` "Convert ICO to PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:5 > span:2 > span:2` **added** (`span` "Turns an .ico icon into a regular PNG of the chosen size." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:5 > span:2 > strong:1` **removed** (`strong` "Convert PNG to JPG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:5 > span:2 > span:2` **removed** (`span` "Composite transparency over a selected backdrop and export JPEG." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:5 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:5 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:6` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:7` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:8` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:9` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:10` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:11` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:12` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:13` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:14` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:15` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:16` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:17` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:18` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:19` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:20` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:1 > div:2 > a:21` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:1 > i:2` **added** (`i` "21 TOOLS" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:1 > i:2` **removed** (`i` "05 TOOLS" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:1 > span:2 > strong:1` **added** (`strong` "Circle Mask PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:1 > span:2 > span:2` **added** (`span` "Cuts the image into a circle. Diameter is set as a share of the smaller side." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:1 > span:2 > strong:1` **removed** (`strong` "Remove background PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:1 > span:2 > span:2` **removed** (`span` "Remove a solid background by color, tolerance, or edge-connected regions." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:1 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:1 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:2 > span:2 > strong:1` **added** (`strong` "Square Mask PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:2 > span:2 > span:2` **added** (`span` "Cuts the image into a rectangle with sides as a share of the smaller side." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:2 > span:2 > strong:1` **removed** (`strong` "Extract alpha mask" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:2 > span:2 > span:2` **removed** (`span` "Turn the alpha channel into a clean black-and-white mask." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:2 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:2 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:3 > span:2 > strong:1` **added** (`strong` "Star Mask PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:3 > span:2 > span:2` **added** (`span` "Cuts the image into an n-pointed star with adjustable inner radius and rotation." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:3 > span:2 > strong:1` **removed** (`strong` "Round corners PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:3 > span:2 > span:2` **removed** (`span` "Clip the image corners by a precise radius percentage." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:3 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:3 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:4 > span:2 > strong:1` **added** (`strong` "Wavy Mask PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:4 > span:2 > span:2` **added** (`span` "Cuts the image into a wavy-edged circle: radius is modulated by a sine with chosen amplitude and frequency." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:4 > span:2 > strong:1` **removed** (`strong` "Outline PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:4 > span:2 > span:2` **removed** (`span` "Add a colored ring around opaque content with adjustable thickness." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:4 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:4 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:5 > span:2 > strong:1` **added** (`strong` "Remove alpha channel PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:5 > span:2 > span:2` **added** (`span` "Composites the image over a white background and saves without transparency." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:5 > span:2 > strong:1` **removed** (`strong` "Change PNG opacity" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:5 > span:2 > span:2` **removed** (`span` "Multiply the alpha channel while keeping the original colors unchanged." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:5 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:5 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:6` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:7` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:8` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:9` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:10` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:11` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:12` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:13` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:14` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:15` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:16` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:17` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:18` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:19` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:20` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:2 > div:2 > a:21` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:1 > i:2` **added** (`i` "25 TOOLS" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:1 > i:2` **removed** (`i` "05 TOOLS" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:1 > span:2 > strong:1` **added** (`strong` "Split PNG into HSL" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:1 > span:2 > span:2` **added** (`span` "Decomposes the image into Hue, Saturation and Lightness components." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:1 > span:2 > strong:1` **removed** (`strong` "Create gradient PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:1 > span:2 > span:2` **removed** (`span` "Generate a smooth transition between two colors with direction controls." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:1 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:1 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:2 > span:2 > strong:1` **added** (`strong` "Split PNG into HSV" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:2 > span:2 > span:2` **added** (`span` "Decomposes the image into Hue, Saturation and Value (brightness) components." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:2 > span:2 > strong:1` **removed** (`strong` "Grayscale PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:2 > span:2 > span:2` **removed** (`span` "Convert the image to luminance-based shades of gray." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:2 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:2 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:3 > span:2 > strong:1` **added** (`strong` "Split PNG into HSI" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:3 > span:2 > span:2` **added** (`span` "Decomposes the image into Hue, Saturation and Intensity components." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:3 > span:2 > strong:1` **removed** (`strong` "Invert colors PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:3 > span:2 > span:2` **removed** (`span` "Invert every color channel while leaving alpha untouched." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:3 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:3 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:4 > span:2 > strong:1` **added** (`strong` "Convert PNG to CMYK Colors" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:4 > span:2 > span:2` **added** (`span` "Decomposes the image into print-style Cyan, Magenta, Yellow and Key (black) components." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:4 > span:2 > strong:1` **removed** (`strong` "Brightness & contrast" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:4 > span:2 > span:2` **removed** (`span` "Adjust brightness and contrast across a controlled range." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:4 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:4 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:5 > span:2 > strong:1` **added** (`strong` "Convert PNG to YCbCr Colors" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:5 > span:2 > span:2` **added** (`span` "Decomposes the image into Luma (Y) and Blue-difference / Red-difference chroma components." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:5 > span:2 > strong:1` **removed** (`strong` "Temperature PNG" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:5 > span:2 > span:2` **removed** (`span` "Make an image warmer or cooler with a single precise control." · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:5 > span:4` **added** (`span` · 2 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:5 > svg:4` **removed** (`svg` · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:6` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:7` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:8` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:9` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:10` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:11` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:12` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:13` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:14` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:15` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:16` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:17` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:18` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:19` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:20` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:21` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:22` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:23` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:24` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:3 > div:2 > a:25` **added** (`a` · 9 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:4 > div:1 > i:2` **added** (`i` "18 TOOLS" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:4 > div:1 > i:2` **removed** (`i` "05 TOOLS" · 1 узл.)
|
|
||||||
- `body > main:1 > div:2 > div:3 > section:4 > div:2 > a:1 > span:2 > span:2` **added** (`span` "Scales the image with bilinear interpolation. With aspect kept, one side defines the scale; if both are set, the image fits inside them." · 1 узл.)
|
|
||||||
|
|
||||||
_…и ещё 81 (см. json)_
|
|
||||||
|
|
||||||
|
|
||||||
## /preview/tools/linear-gradient-png (vs gradient.html)
|
## /preview/tools/linear-gradient-png (vs gradient.html)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<section class="catalog-group">
|
<section class="catalog-group">
|
||||||
<div class="group-title">
|
<div class="group-title">
|
||||||
<span>{label}</span>
|
<span>{label}</span>
|
||||||
<i>{count} <!-- --> TOOLS</i>
|
<i>{count.toString().padStart(2, "0")} <!-- --> TOOLS</i>
|
||||||
</div>
|
</div>
|
||||||
<div class="tool-cards">
|
<div class="tool-cards">
|
||||||
{@render children()}
|
{@render children()}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="catalog-total">
|
<div class="catalog-total">
|
||||||
<b>{total}</b>
|
<b>{total}</b>
|
||||||
<span>TOOLS<br />AVAILABLE</span>
|
<span>TOOLS<br /> AVAILABLE</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<span class="tool-index">
|
<span class="tool-index">
|
||||||
{index !== undefined ? index.toString().padStart(2, "0") : ""}
|
{index !== undefined ? index.toString().padStart(2, "0") : ""}
|
||||||
</span>
|
</span>
|
||||||
<span class="tool-arrow"><ArrowUpRight size={16} /></span>
|
<ArrowUpRight class="tool-arrow" size={16} />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -0,0 +1,217 @@
|
|||||||
|
import { TOOLS, type ToolEntry } from "../registry";
|
||||||
|
|
||||||
|
export type PreviewGroup = {
|
||||||
|
id: string;
|
||||||
|
label: string;
|
||||||
|
tools: ToolEntry[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preview-only catalog: a trimmed view of the registry that mirrors
|
||||||
|
* refs-html/list-tools.html (28 tools in 6 groups). Used exclusively by
|
||||||
|
* /preview and /kit so the working site (old) and /ui keep the full registry.
|
||||||
|
*
|
||||||
|
* Titles/descriptions are overridden with the ref's exact copy where they
|
||||||
|
* diverge from the registry. The underlying ToolEntry (params, run, …) is
|
||||||
|
* reused so navigation and tool pages stay functional.
|
||||||
|
*/
|
||||||
|
const REF: {
|
||||||
|
group: string;
|
||||||
|
label: string;
|
||||||
|
tools: { id: string; title: string; description: string }[];
|
||||||
|
}[] = [
|
||||||
|
{
|
||||||
|
group: "convert",
|
||||||
|
label: "CONVERT",
|
||||||
|
tools: [
|
||||||
|
{
|
||||||
|
id: "jpg-to-png",
|
||||||
|
title: "Convert JPG to PNG",
|
||||||
|
description: "Re-encode JPEG files as lossless PNG while preserving transparency.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "webp-to-png",
|
||||||
|
title: "Convert WebP to PNG",
|
||||||
|
description: "Turn WebP images into a universal PNG format for any workflow.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "png-to-base64",
|
||||||
|
title: "PNG to Base64",
|
||||||
|
description: "Encode an image as a base64 string for embedding in code or styles.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "png-to-data-uri",
|
||||||
|
title: "PNG to Data URI",
|
||||||
|
description: "Build a complete data URI ready for HTML and CSS.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "convert-png-to-jpg",
|
||||||
|
title: "Convert PNG to JPG",
|
||||||
|
description: "Composite transparency over a selected backdrop and export JPEG.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: "alpha",
|
||||||
|
label: "TRANSPARENCY",
|
||||||
|
tools: [
|
||||||
|
{
|
||||||
|
id: "remove-background-png",
|
||||||
|
title: "Remove background PNG",
|
||||||
|
description: "Remove a solid background by color, tolerance, or edge-connected regions.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "extract-alpha-mask-png",
|
||||||
|
title: "Extract alpha mask",
|
||||||
|
description: "Turn the alpha channel into a clean black-and-white mask.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "round-corners-png",
|
||||||
|
title: "Round corners PNG",
|
||||||
|
description: "Clip the image corners by a precise radius percentage.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "add-stroke-png",
|
||||||
|
title: "Outline PNG",
|
||||||
|
description: "Add a colored ring around opaque content with adjustable thickness.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "change-png-opacity",
|
||||||
|
title: "Change PNG opacity",
|
||||||
|
description: "Multiply the alpha channel while keeping the original colors unchanged.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: "color",
|
||||||
|
label: "COLOR",
|
||||||
|
tools: [
|
||||||
|
{
|
||||||
|
id: "linear-gradient-png",
|
||||||
|
title: "Create gradient PNG",
|
||||||
|
description: "Generate a smooth transition between two colors with direction controls.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "grayscale-png",
|
||||||
|
title: "Grayscale PNG",
|
||||||
|
description: "Convert the image to luminance-based shades of gray.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "invert-colors-png",
|
||||||
|
title: "Invert colors PNG",
|
||||||
|
description: "Invert every color channel while leaving alpha untouched.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "adjust-brightness-contrast-png",
|
||||||
|
title: "Brightness & contrast",
|
||||||
|
description: "Adjust brightness and contrast across a controlled range.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "temperature-png",
|
||||||
|
title: "Temperature PNG",
|
||||||
|
description: "Make an image warmer or cooler with a single precise control.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: "geometry",
|
||||||
|
label: "GEOMETRY",
|
||||||
|
tools: [
|
||||||
|
{
|
||||||
|
id: "resize-png",
|
||||||
|
title: "Resize PNG",
|
||||||
|
description: "Scale an image with bilinear interpolation and optional aspect lock.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "crop-png",
|
||||||
|
title: "Crop PNG",
|
||||||
|
description: "Cut a rectangular area with exact coordinates and dimensions.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "rotate-png",
|
||||||
|
title: "Rotate PNG",
|
||||||
|
description: "Rotate by 90, 180, or 270 degrees without quality loss.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "flip-png",
|
||||||
|
title: "Flip PNG",
|
||||||
|
description: "Mirror the image horizontally or vertically.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "add-padding-png",
|
||||||
|
title: "Add padding to PNG",
|
||||||
|
description: "Expand the canvas on all sides by a chosen number of pixels.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: "filters",
|
||||||
|
label: "FILTERS",
|
||||||
|
tools: [
|
||||||
|
{
|
||||||
|
id: "blur-png",
|
||||||
|
title: "Blur PNG",
|
||||||
|
description: "Apply a fast Gaussian-style blur with transparent edge handling.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "sharpen-png",
|
||||||
|
title: "Sharpen PNG",
|
||||||
|
description: "Emphasize edges with an adjustable sharpening kernel.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "vignette-png",
|
||||||
|
title: "Vignette PNG",
|
||||||
|
description: "Smoothly darken the image edges while preserving the center.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "jpeg-artifacts-png",
|
||||||
|
title: "JPEG artifacts",
|
||||||
|
description: "Simulate low-quality JPEG recompression for testing.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: "analyze",
|
||||||
|
label: "ANALYZE",
|
||||||
|
tools: [
|
||||||
|
{
|
||||||
|
id: "png-info",
|
||||||
|
title: "PNG info",
|
||||||
|
description: "Inspect dimensions, alpha presence, and unique color count.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "png-is-grayscale",
|
||||||
|
title: "Check grayscale",
|
||||||
|
description: "Report whether the image contains only shades of gray.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "png-is-transparent",
|
||||||
|
title: "Check transparency",
|
||||||
|
description: "Detect transparent and semi-transparent pixels.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "png-orientation",
|
||||||
|
title: "PNG orientation",
|
||||||
|
description: "Classify the image as portrait, landscape, or square.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const TOOL_BY_ID = new Map(TOOLS.map((t) => [t.id, t]));
|
||||||
|
|
||||||
|
export const PREVIEW_GROUPS: PreviewGroup[] = REF.map((g) => ({
|
||||||
|
id: g.group,
|
||||||
|
label: g.label,
|
||||||
|
tools: g.tools.map((spec) => {
|
||||||
|
const base = TOOL_BY_ID.get(spec.id);
|
||||||
|
if (!base) {
|
||||||
|
throw new Error(`preview catalog: missing tool ${spec.id}`);
|
||||||
|
}
|
||||||
|
return { ...base, title: spec.title, description: spec.description };
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
// The ref header statically reads 32 (its own count); the body lists 28 cards.
|
||||||
|
// Mirroring the ref exactly keeps the audit at 0/0.
|
||||||
|
export const PREVIEW_TOTAL = 32;
|
||||||
@@ -1,34 +1,21 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { TOOLS } from "$lib/registry";
|
import { PREVIEW_GROUPS, PREVIEW_TOTAL } from "$lib/preview/catalog";
|
||||||
import { CATEGORIES, type CategoryId } from "$lib/categories";
|
|
||||||
import { TOOL_ICONS } from "$lib/tools/tool-icons";
|
import { TOOL_ICONS } from "$lib/tools/tool-icons";
|
||||||
import CatalogHeader from "$lib/components/kit/CatalogHeader.svelte";
|
import CatalogHeader from "$lib/components/kit/CatalogHeader.svelte";
|
||||||
import CatalogToolbar from "$lib/components/kit/CatalogToolbar.svelte";
|
import CatalogToolbar from "$lib/components/kit/CatalogToolbar.svelte";
|
||||||
import CatalogGroup from "$lib/components/kit/CatalogGroup.svelte";
|
import CatalogGroup from "$lib/components/kit/CatalogGroup.svelte";
|
||||||
import ToolCard from "$lib/components/kit/ToolCard.svelte";
|
import ToolCard from "$lib/components/kit/ToolCard.svelte";
|
||||||
|
|
||||||
const LABELS: Record<CategoryId, string> = {
|
|
||||||
convert: "CONVERT",
|
|
||||||
alpha: "TRANSPARENCY",
|
|
||||||
color: "COLOR",
|
|
||||||
geometry: "GEOMETRY",
|
|
||||||
filters: "FILTERS",
|
|
||||||
text: "TEXT",
|
|
||||||
analyze: "ANALYZE",
|
|
||||||
generate: "GENERATE",
|
|
||||||
};
|
|
||||||
|
|
||||||
let query = $state("");
|
let query = $state("");
|
||||||
let category = $state<string>("all");
|
let category = $state<string>("all");
|
||||||
|
|
||||||
const groups = $derived(
|
const groups = $derived(
|
||||||
CATEGORIES.map((cat) => ({
|
PREVIEW_GROUPS.map((g) => ({
|
||||||
id: cat,
|
id: g.id,
|
||||||
label: LABELS[cat],
|
label: g.label,
|
||||||
tools: TOOLS.filter(
|
tools: g.tools.filter(
|
||||||
(t) =>
|
(t) =>
|
||||||
t.category === cat &&
|
(category === "all" || category === g.id) &&
|
||||||
(category === "all" || category === cat) &&
|
|
||||||
(query.trim() === "" ||
|
(query.trim() === "" ||
|
||||||
t.title.toLowerCase().includes(query.trim().toLowerCase()) ||
|
t.title.toLowerCase().includes(query.trim().toLowerCase()) ||
|
||||||
t.description.toLowerCase().includes(query.trim().toLowerCase())),
|
t.description.toLowerCase().includes(query.trim().toLowerCase())),
|
||||||
@@ -38,7 +25,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="catalog-page">
|
<div class="catalog-page">
|
||||||
<CatalogHeader total={TOOLS.length} />
|
<CatalogHeader total={PREVIEW_TOTAL} />
|
||||||
<CatalogToolbar bind:query bind:category />
|
<CatalogToolbar bind:query bind:category />
|
||||||
<div class="catalog-groups">
|
<div class="catalog-groups">
|
||||||
{#each groups as group (group.id)}
|
{#each groups as group (group.id)}
|
||||||
|
|||||||
Reference in New Issue
Block a user