mirror of
https://github.com/lucide-icons/lucide.git
synced 2025-12-14 20:17:40 +01:00
feat(preview-comment): add symmetry preview (#3823)
This commit is contained in:
55
docs/.vitepress/api/gh-icon/symmetry/[...data].get.ts
Normal file
55
docs/.vitepress/api/gh-icon/symmetry/[...data].get.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { eventHandler, setResponseHeader, defaultContentType } from 'h3';
|
||||
import { renderToString } from 'react-dom/server';
|
||||
import { createElement } from 'react';
|
||||
import Diff from '../../../lib/SvgPreview/Diff.tsx';
|
||||
|
||||
export default eventHandler((event) => {
|
||||
const { params } = event.context;
|
||||
|
||||
const pathData = params.data.split('/');
|
||||
const data = pathData.at(-1).slice(0, -4);
|
||||
const [operation] = pathData;
|
||||
|
||||
const newSrc = Buffer.from(data, 'base64')
|
||||
.toString('utf8')
|
||||
.replaceAll('\n', '')
|
||||
.replace(/<svg[^>]*>|<\/svg>/g, '');
|
||||
|
||||
const width = parseInt(
|
||||
(newSrc.includes('<svg ') ? newSrc.match(/width="(\d+)"/)?.[1] : null) ?? '24',
|
||||
);
|
||||
const height = parseInt(
|
||||
(newSrc.includes('<svg ') ? newSrc.match(/height="(\d+)"/)?.[1] : null) ?? '24',
|
||||
);
|
||||
|
||||
const children = [];
|
||||
|
||||
let oldSrc = '';
|
||||
if (operation.startsWith('rotate-')) {
|
||||
const degrees = parseInt(operation.replace('rotate-', ''));
|
||||
if (isNaN(degrees)) return '';
|
||||
oldSrc = `<g transform="rotate(${degrees} ${width / 2} ${height / 2})">${newSrc}</g>`;
|
||||
} else if (operation === 'flip-horizontal') {
|
||||
oldSrc = `<g transform="scale(1, -1) translate(0, -${height})">${newSrc}</g>`;
|
||||
} else if (operation === 'flip-vertical') {
|
||||
oldSrc = `<g transform="scale(-1, 1) translate(-${width}, 0)">${newSrc}</g>`;
|
||||
} else if (operation === 'flip-backslash') {
|
||||
oldSrc = `<g transform="rotate(90, ${width / 2}, ${height / 2}) scale(1, -1) translate(0, -${height})">${newSrc}</g>`;
|
||||
} else if (operation === 'flip-slash') {
|
||||
oldSrc = `<g transform="rotate(90, ${width / 2}, ${height / 2}) scale(-1, 1) translate(-${width}, 0)">${newSrc}</g>`;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
|
||||
const svg = Buffer.from(
|
||||
// We can't use jsx here, is not supported here by nitro.
|
||||
renderToString(
|
||||
createElement(Diff, { oldSrc, newSrc, showGrid: true, height, width }, children),
|
||||
),
|
||||
).toString('utf8');
|
||||
|
||||
defaultContentType(event, 'image/svg+xml');
|
||||
setResponseHeader(event, 'Cache-Control', 'public,max-age=31536000');
|
||||
|
||||
return svg;
|
||||
});
|
||||
@@ -52,7 +52,8 @@ const getImageTagsByFiles = (
|
||||
const svgFiles = await readSvgDirectory(ICONS_DIR);
|
||||
const svgFilePaths = svgFiles.map((file) => `icons/${file}`);
|
||||
|
||||
const iconsFilteredByName = (search: string) => svgFilePaths.filter((file) => file.includes(search));
|
||||
const iconsFilteredByName = (search: string) =>
|
||||
svgFilePaths.filter((file) => file.includes(search));
|
||||
|
||||
const cohesionRandomImageTags = getImageTagsByFiles(
|
||||
shuffleArray(svgFilePaths).slice(0, changedFiles.length),
|
||||
@@ -120,6 +121,30 @@ const changeFilesDiffImageTags = getImageTagsByFiles(
|
||||
400,
|
||||
).join(' ');
|
||||
|
||||
const changeFilesSymmetryImageTagsRotate180 = getImageTagsByFiles(
|
||||
changedFiles,
|
||||
() => `${BASE_URL}/symmetry/rotate-180`,
|
||||
400,
|
||||
).join(' ');
|
||||
|
||||
const changeFilesSymmetryImageTagsFlipHorizontal = getImageTagsByFiles(
|
||||
changedFiles,
|
||||
() => `${BASE_URL}/symmetry/flip-horizontal`,
|
||||
400,
|
||||
).join(' ');
|
||||
|
||||
const changeFilesSymmetryImageTagsFlipVertical = getImageTagsByFiles(
|
||||
changedFiles,
|
||||
() => `${BASE_URL}/symmetry/flip-vertical`,
|
||||
400,
|
||||
).join(' ');
|
||||
|
||||
const changeFilesSymmetryImageTagsFlipSlash = getImageTagsByFiles(
|
||||
changedFiles,
|
||||
() => `${BASE_URL}/symmetry/flip-slash`,
|
||||
400,
|
||||
).join(' ');
|
||||
|
||||
const readyToUseCode = changedFiles
|
||||
.map((changedFile) => {
|
||||
const svgContent = fs.readFileSync(path.join(process.cwd(), changedFile), 'utf-8');
|
||||
@@ -179,6 +204,17 @@ ${changeFilesXRayImageTags}
|
||||
${changeFilesDiffImageTags}
|
||||
</details>
|
||||
<details>
|
||||
<summary>Icon Symmetry</summary>
|
||||
<h4>Flip Horizontal</h4>
|
||||
${changeFilesSymmetryImageTagsFlipHorizontal}
|
||||
<h4>Flip Vertical</h4>
|
||||
${changeFilesSymmetryImageTagsFlipVertical}
|
||||
<h4>Flip Diagonal</h4>
|
||||
${changeFilesSymmetryImageTagsFlipSlash}
|
||||
<h4>Rotate 180°</h4>
|
||||
${changeFilesSymmetryImageTagsRotate180}
|
||||
</details>
|
||||
<details>
|
||||
<summary>Icons as code</summary>
|
||||
|
||||
Works for: \`lucide-react\`, \`lucide-react-native\`, \`lucide-preact\`, \`lucide-vue-next\`
|
||||
|
||||
Reference in New Issue
Block a user