Skip to content

Commit

Permalink
feat: add code-to-image tools.
Browse files Browse the repository at this point in the history
  • Loading branch information
jaywcjlove committed Sep 7, 2022
1 parent 45e43e6 commit 43d07de
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 0 deletions.
28 changes: 28 additions & 0 deletions packages/code-to-image/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "@wcj/tools-react-code-to-image",
"version": "1.9.4",
"main": "./cjs/index.js",
"module": "./esm/index.js",
"scripts": {
"build": "tsbb build",
"watch": "tsbb watch"
},
"keywords": [],
"files": [
"cjs",
"esm",
"src"
],
"author": "Kenny Wong <wowohoo@qq.com>",
"license": "MIT",
"dependencies": {
"@uiw/codemirror-extensions-langs": "^4.12.2",
"@uiw/codemirror-themes-all": "^4.12.1",
"@wcj/tools-react-components": "1.9.4",
"dom-to-image-more": "^2.6.0"
},
"peerDependencies": {
"react": ">=16.14.0",
"react-dom": ">=16.14.0"
}
}
124 changes: 124 additions & 0 deletions packages/code-to-image/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import React, { useState, Fragment, useRef } from 'react';
import { Wrapper, StyledLayout, Button } from '@wcj/tools-react-components';
import CodeMirror from '@uiw/react-codemirror';
import { langs, langNames, LanguageName } from '@uiw/codemirror-extensions-langs';
import * as themes from '@uiw/codemirror-themes-all';
import styled from 'styled-components';
import { EditorView } from '@codemirror/view';
import domToImage from 'dom-to-image-more';

const sample = `<h2>Web tool</h2>
<p>Hello World</p>
<pre><code class="language-css">body { color: 'red'; }
</code></pre>
`;

const Canvas = styled.div`
border: 3px dashed #e3ebf6;
display: inline-block;
&::before {
content: 'CANVAS';
top: -21px;
left: -4px;
position: absolute;
font-size: 0.8rem;
}
`;
const EditorWarpper = styled.div`
padding: 50px;
& > * {
box-shadow: rgb(0 0 0 / 55%) 0px 10px 30px 0px;
border-radius: 5px;
display: inline-block;
overflow: hidden;
}
`;

const HeaderTools = styled.div`
padding-bottom: 10px;
`;

export default function Html2Markdown() {
const $dom = useRef<HTMLDivElement>(null);
const [markdown, setMarkdown] = useState<string>(sample);
const [languge, setLanguge] = useState<LanguageName>('javascript');
const [theme, setTheme] = useState<keyof typeof themes>('githubDark');
const handleInput = () => setMarkdown(sample);
const handleChange = (value: string) => setMarkdown(value);
const borderRadius = EditorView.theme({
'.cm-scroller, &': {
borderRadius: '6px',
},
'& .cm-gutters': {
borderRight: '0',
},
});
const selectLangChange = (ev: React.ChangeEvent<HTMLSelectElement>) => {
setLanguge(ev.target.value as LanguageName);
};
const selectThemeChange = (ev: React.ChangeEvent<HTMLSelectElement>) => {
console.log('ev.target.value:::', ev.target.value);
setTheme(ev.target.value as keyof typeof themes);
};
const downloadHandel = () => {
const scale = 2;
const elm = $dom.current;
domToImage
.toPng($dom.current, {
height: elm!.offsetHeight * scale,
style: {
transform: `scale(${scale}) translate(${elm!.offsetWidth / 2 / scale}px, ${elm!.offsetHeight / 2 / scale}px)`,
},
width: elm!.offsetWidth * scale,
})
.then((dataUrl) => {
const link = document.createElement('a');
link.download = 'image.png';
link.href = dataUrl;
link.click();
});
};
const extensions = [borderRadius];
if (langs[languge]) {
extensions.push(langs[languge]());
}
return (
<Wrapper>
<StyledLayout
title="Code To Image"
extra={
<Fragment>
<Button onClick={handleInput}>Sample</Button>
<Button onClick={downloadHandel}>DownLoad</Button>
</Fragment>
}
>
<HeaderTools>
<select value={languge} onChange={selectLangChange}>
{langNames.sort().map((keyname, index) => {
return (
<option value={keyname} key={index}>
{keyname}
</option>
);
})}
</select>
<select value={theme} onChange={selectThemeChange}>
{Object.keys(themes).map((keyname, index) => {
return (
<option value={keyname} key={index}>
Theme: {keyname}
</option>
);
})}
</select>
</HeaderTools>
<Canvas>
<EditorWarpper ref={$dom}>
<CodeMirror theme={themes[theme]} value={markdown} extensions={extensions} onChange={handleChange} />
</EditorWarpper>
</Canvas>
</StyledLayout>
</Wrapper>
);
}
9 changes: 9 additions & 0 deletions packages/code-to-image/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig",
"include": ["src"],
"compilerOptions": {
"baseUrl": ".",
"outDir": "cjs",
"noEmit": false
}
}
1 change: 1 addition & 0 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@wcj/tools-react-amount-in-rmb": "1.9.4",
"@wcj/tools-react-base64-encoder": "1.9.4",
"@wcj/tools-react-chinese-pinyin-conversion": "1.9.4",
"@wcj/tools-react-code-to-image": "1.9.4",
"@wcj/tools-react-css-easing-animation": "1.9.4",
"@wcj/tools-react-css-formatter": "1.9.4",
"@wcj/tools-react-exif-viewer": "1.9.4",
Expand Down
3 changes: 3 additions & 0 deletions website/public/locales/cn/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
"/image-to-base64": {
"label": "图片转换 Base64"
},
"/code-to-image": {
"label": "代码转换图片"
},
"/hash": {
"label": "哈希 Hash"
},
Expand Down
3 changes: 3 additions & 0 deletions website/public/logo/code-image.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions website/src/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const HTMLEscape = Loadable(lazy(() => import('@wcj/tools-react-html-escape')));
const Base64Encoder = Loadable(lazy(() => import('@wcj/tools-react-base64-encoder')));
const QRCodeGenerator = Loadable(lazy(() => import('@wcj/tools-react-qrcode-generator')));
const ChinesePinyinConversion = Loadable(lazy(() => import('@wcj/tools-react-chinese-pinyin-conversion')));
const CodeToImage = Loadable(lazy(() => import('@wcj/tools-react-code-to-image')));
// @ts-ignore
const GenerateGithubBadges = Loadable(lazy(() => import('@wcj/tools-react-generate-github-badges')));
// @ts-ignore
Expand Down Expand Up @@ -91,6 +92,10 @@ export let routes: RouteObject[] = [
path: 'image-to-base64',
element: <ImageToBase64 title="Image To Base64 - Web Tools" />,
},
{
path: 'code-to-image',
element: <CodeToImage title="Code To Image - Web Tools" />,
},
{
path: 'hash',
element: <Hash title="Hash - Web Tools" />,
Expand Down
5 changes: 5 additions & 0 deletions website/src/menus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ export function useMenus() {
logo: 'image',
label: t('menu./image-to-base64.label'),
},
{
href: '/code-to-image',
logo: 'code-image',
label: t('menu./code-to-image.label'),
},
{
href: '/hash',
logo: 'hash',
Expand Down

0 comments on commit 43d07de

Please sign in to comment.