├── docs
└── packages
│ ├── README.md
│ ├── .nojekyll
│ ├── modules.md
│ ├── interfaces
│ ├── svg_drawing_core
│ │ └── ConvertOption.md
│ └── svg_drawing_img_trace
│ │ ├── BlurOption.md
│ │ ├── FromImageDataOptions.md
│ │ ├── Rgba.md
│ │ └── ImgTraceOption.md
│ ├── modules
│ ├── svg_drawing_img_trace.md
│ ├── svg_drawing_animation.md
│ └── svg_drawing_react.md
│ └── classes
│ ├── svg_drawing_core
│ ├── Renderer.md
│ ├── Vector.md
│ ├── ResizeHandler.md
│ ├── Convert.md
│ ├── DrawHandler.md
│ ├── Point.md
│ ├── Path.md
│ ├── Command.md
│ ├── Svg.md
│ └── SvgDrawing.md
│ ├── svg_drawing_img_trace
│ ├── Blur.md
│ ├── ImgLoader.md
│ ├── Palette.md
│ └── ImgTrace.md
│ └── svg_drawing_animation
│ └── SvgAnimation.md
├── .gitattributes
├── examples
├── react
│ ├── .eslintignore
│ ├── config
│ │ ├── paths.ts
│ │ └── theme.ts
│ ├── public
│ │ └── img_trace
│ │ │ ├── cat.jpg
│ │ │ ├── kuma.jpg
│ │ │ ├── risu.jpg
│ │ │ ├── panda.png
│ │ │ ├── tanuki.jpg
│ │ │ └── harinezumi.jpg
│ ├── .babelrc.js
│ ├── modules.d.ts
│ ├── next.config.js
│ ├── next-env.d.ts
│ ├── pages
│ │ ├── _app.tsx
│ │ ├── _document.tsx
│ │ └── demo
│ │ │ ├── animation.tsx
│ │ │ └── img-trace.tsx
│ ├── lib
│ │ ├── gtag.ts
│ │ └── example-svg.ts
│ ├── tsconfig.json
│ ├── package.json
│ └── components
│ │ └── Layout.tsx
└── html
│ └── index.html
├── packages
├── react
│ ├── src
│ │ ├── index.ts
│ │ ├── types.ts
│ │ └── useDrawing.ts
│ ├── tsconfig.lib.json
│ ├── rollup.config.js
│ ├── tsconfig.json
│ ├── package.json
│ └── README.md
├── animation
│ ├── src
│ │ ├── index.ts
│ │ ├── types.ts
│ │ ├── __snapshots__
│ │ │ └── animation.test.ts.snap
│ │ ├── animation.test.ts
│ │ └── animation.ts
│ ├── tsconfig.lib.json
│ ├── rollup.config.js
│ ├── tsconfig.json
│ └── package.json
├── img-trace
│ ├── src
│ │ ├── __test__
│ │ │ ├── panda.png
│ │ │ └── loadPngData.ts
│ │ ├── index.ts
│ │ ├── utils
│ │ │ └── convertRGBAImage.ts
│ │ ├── palette.test.ts
│ │ ├── trace.test.ts
│ │ ├── imgloader.ts
│ │ ├── blur.ts
│ │ └── palette.ts
│ ├── tsconfig.lib.json
│ ├── rollup.config.js
│ ├── tsconfig.json
│ ├── package.json
│ └── README.md
└── core
│ ├── tsconfig.lib.json
│ ├── rollup.config.js
│ ├── src
│ ├── index.ts
│ ├── convert.test.ts
│ ├── utils.ts
│ ├── throttle.ts
│ ├── convert.ts
│ ├── __snapshots__
│ │ ├── drawing.test.ts.snap
│ │ └── svg.test.ts.snap
│ ├── drawing.test.ts
│ ├── renderer.ts
│ ├── types.ts
│ ├── download.ts
│ ├── drawing.ts
│ └── handler.ts
│ ├── tsconfig.json
│ ├── package.json
│ └── README.md
├── lerna.json
├── prettier.config.js
├── .npmignore
├── config
└── rollup
│ ├── globals.js
│ ├── banner.js
│ ├── ts-lib.js
│ ├── ts-react-lib.js
│ └── build.js
├── .editorconfig
├── babel.config.js
├── jest.config.js
├── generate-docs
└── package.json
├── .gitignore
├── .github
└── workflows
│ ├── gh-pages.yml
│ └── ci.yml
├── turbo.json
├── tsconfig.json
├── renovate.json
├── LICENSE
├── .eslintrc.js
├── README.md
└── package.json
/docs/packages/README.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.js linguist-vendored
2 | *.html linguist-vendored
3 |
--------------------------------------------------------------------------------
/examples/react/.eslintignore:
--------------------------------------------------------------------------------
1 | **/node_modules/*
2 | **/out/*
3 | **/.next/*
4 |
--------------------------------------------------------------------------------
/examples/react/config/paths.ts:
--------------------------------------------------------------------------------
1 | export const basePath = process.env.BASE_PATH || ''
2 |
--------------------------------------------------------------------------------
/packages/react/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './useDrawing'
2 | export * from './types'
3 |
--------------------------------------------------------------------------------
/packages/animation/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './animation'
2 | export * from './types'
3 |
--------------------------------------------------------------------------------
/examples/react/public/img_trace/cat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kmkzt/svg-drawing/HEAD/examples/react/public/img_trace/cat.jpg
--------------------------------------------------------------------------------
/examples/react/public/img_trace/kuma.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kmkzt/svg-drawing/HEAD/examples/react/public/img_trace/kuma.jpg
--------------------------------------------------------------------------------
/examples/react/public/img_trace/risu.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kmkzt/svg-drawing/HEAD/examples/react/public/img_trace/risu.jpg
--------------------------------------------------------------------------------
/examples/react/public/img_trace/panda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kmkzt/svg-drawing/HEAD/examples/react/public/img_trace/panda.png
--------------------------------------------------------------------------------
/examples/react/public/img_trace/tanuki.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kmkzt/svg-drawing/HEAD/examples/react/public/img_trace/tanuki.jpg
--------------------------------------------------------------------------------
/packages/img-trace/src/__test__/panda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kmkzt/svg-drawing/HEAD/packages/img-trace/src/__test__/panda.png
--------------------------------------------------------------------------------
/examples/react/.babelrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['next/babel'],
3 | plugins: [['styled-components', { ssr: true }]],
4 | }
5 |
--------------------------------------------------------------------------------
/examples/react/public/img_trace/harinezumi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kmkzt/svg-drawing/HEAD/examples/react/public/img_trace/harinezumi.jpg
--------------------------------------------------------------------------------
/packages/img-trace/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './blur'
2 | export * from './imgloader'
3 | export * from './palette'
4 | export * from './trace'
5 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "npmClient": "yarn",
3 | "useWorkspaces": true,
4 | "registry": "https://registry.npmjs.org",
5 | "version": "4.2.5"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/core/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["node_modules", "**/*.test.ts", "**/__test__/**/*"]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/react/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["node_modules", "**/*.test.ts", "**/__test__/**/*"]
4 | }
5 |
--------------------------------------------------------------------------------
/prettier.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['prettier-plugin-jsdoc'],
3 | semi: false,
4 | singleQuote: true,
5 | tsdoc: true,
6 | }
7 |
--------------------------------------------------------------------------------
/packages/animation/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["node_modules", "**/*.test.ts", "**/__test__/**/*"]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/img-trace/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["node_modules", "**/*.test.ts", "**/__test__/**/*"]
4 | }
5 |
--------------------------------------------------------------------------------
/examples/react/modules.d.ts:
--------------------------------------------------------------------------------
1 | declare module '@rebass/forms/styled-components' {
2 | export type * from '@types/rebass__forms' // eslint-disable-line
3 | }
4 |
--------------------------------------------------------------------------------
/docs/packages/.nojekyll:
--------------------------------------------------------------------------------
1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false.
--------------------------------------------------------------------------------
/examples/react/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | // For gh-pages
3 | basePath: process.env.BASE_PATH || '',
4 | assetPrefix: process.env.BASE_PATH || '',
5 | }
6 |
--------------------------------------------------------------------------------
/packages/core/rollup.config.js:
--------------------------------------------------------------------------------
1 | import tsLib from '../../config/rollup/ts-lib'
2 | import pkg from './package.json'
3 |
4 | export default tsLib({ input: './src/index.ts', pkg })
5 |
--------------------------------------------------------------------------------
/packages/animation/rollup.config.js:
--------------------------------------------------------------------------------
1 | import tsLib from '../../config/rollup/ts-lib'
2 | import pkg from './package.json'
3 |
4 | export default tsLib({ input: './src/index.ts', pkg })
5 |
--------------------------------------------------------------------------------
/packages/img-trace/rollup.config.js:
--------------------------------------------------------------------------------
1 | import tsLib from '../../config/rollup/ts-lib'
2 | import pkg from './package.json'
3 |
4 | export default tsLib({ input: './src/index.ts', pkg })
5 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | *.env
2 | node_modules
3 | .vscode
4 | template.html
5 | webpack.*.js
6 | renovate.json
7 | .travis.yml
8 | src
9 | prettier.config.js
10 | rollup.config.js
11 | tsconfig.json
12 |
--------------------------------------------------------------------------------
/config/rollup/globals.js:
--------------------------------------------------------------------------------
1 | export const packageGlobals = {
2 | '@svg-drawing/core': 'SVGDCore',
3 | '@svg-drawing/animation': 'SVGDAnimation',
4 | '@svg-drawing/img-trace': 'SVGDImgTrace',
5 | }
6 |
--------------------------------------------------------------------------------
/packages/react/rollup.config.js:
--------------------------------------------------------------------------------
1 | import tsReactLib from '../../config/rollup/ts-react-lib'
2 | import pkg from './package.json'
3 |
4 | export default tsReactLib({ input: './src/index.ts', pkg })
5 |
--------------------------------------------------------------------------------
/examples/react/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/packages/animation/src/types.ts:
--------------------------------------------------------------------------------
1 | import type { RendererOption, Path } from '@svg-drawing/core'
2 | export type AnimationOption = RendererOption & {
3 | ms: number
4 | }
5 | export type FrameAnimation = (origin: Path[], loopIndex?: number) => Path[]
6 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_size = 2
6 | end_of_line = lf
7 | indent_style = space
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/config/rollup/banner.js:
--------------------------------------------------------------------------------
1 | export const createBanner = ({ name, version, author, license }) =>
2 | `/*\n` +
3 | ` * ${name} v${version} \n` +
4 | ` * \n` +
5 | ` * Copyright (C) ${author}.\n` +
6 | ` * This source code is licensed under the ${license} license.\n` +
7 | ' */'
8 |
--------------------------------------------------------------------------------
/packages/core/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './drawing'
2 | export * from './convert'
3 | export * from './renderer'
4 | export * from './svg'
5 | export * from './throttle'
6 | export * from './utils'
7 | export * from './handler'
8 | export * from './types'
9 | export * from './download'
10 |
--------------------------------------------------------------------------------
/docs/packages/modules.md:
--------------------------------------------------------------------------------
1 | # Documentation
2 |
3 | ## Modules
4 |
5 | - [@svg-drawing/animation](modules/svg_drawing_animation.md)
6 | - [@svg-drawing/core](modules/svg_drawing_core.md)
7 | - [@svg-drawing/img-trace](modules/svg_drawing_img_trace.md)
8 | - [@svg-drawing/react](modules/svg_drawing_react.md)
9 |
--------------------------------------------------------------------------------
/packages/core/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./lib",
6 | "declaration": true,
7 | "declarationDir": "./lib",
8 | "emitDeclarationOnly": true
9 | },
10 | "include": ["src/**/*"],
11 | "references": []
12 | }
13 |
--------------------------------------------------------------------------------
/packages/react/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./lib",
6 | "declaration": true,
7 | "declarationDir": "./lib",
8 | "emitDeclarationOnly": true
9 | },
10 | "include": ["src/**/*"],
11 | "references": []
12 | }
13 |
--------------------------------------------------------------------------------
/packages/animation/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./lib",
6 | "declaration": true,
7 | "declarationDir": "./lib",
8 | "emitDeclarationOnly": true
9 | },
10 | "include": ["src/**/*"],
11 | "references": []
12 | }
13 |
--------------------------------------------------------------------------------
/packages/img-trace/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "rootDir": "./src",
5 | "outDir": "./lib",
6 | "declaration": true,
7 | "declarationDir": "./lib",
8 | "emitDeclarationOnly": true
9 | },
10 | "include": ["src/**/*"],
11 | "references": []
12 | }
13 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * For babel-jest
3 | */
4 | module.exports = (api) => {
5 | api.cache(false)
6 | return {
7 | presets: [
8 | [
9 | '@babel/preset-env',
10 | {
11 | targets: { node: 'current' },
12 | },
13 | ],
14 | '@babel/preset-typescript',
15 | ],
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/docs/packages/interfaces/svg_drawing_core/ConvertOption.md:
--------------------------------------------------------------------------------
1 | # Interface: ConvertOption
2 |
3 | [@svg-drawing/core](../../modules/svg_drawing_core.md).ConvertOption
4 |
5 | Convert options
6 |
7 | ## Properties
8 |
9 | ### ratio
10 |
11 | • `Optional` **ratio**: `number`
12 |
13 | #### Defined in
14 |
15 | [core/src/types.ts:49](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/types.ts#L49)
16 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | verbose: true,
3 | transform: {
4 | '^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
5 | },
6 | transformIgnorePatterns: ['/node_modules/'],
7 | testEnvironment: 'jest-environment-jsdom',
8 | testRegex: '(\\.|/)(test|spec)\\.(t|j)sx?$',
9 | moduleNameMapper: {},
10 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
11 | collectCoverage: true,
12 | collectCoverageFrom: ['/packages/**/src/**/**.(t|j)s?(x)'],
13 | }
14 |
--------------------------------------------------------------------------------
/examples/react/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import App from 'next/app'
2 | import { StrictMode } from 'react'
3 | import { ThemeProvider } from 'styled-components'
4 | import theme from '../config/theme'
5 | export default class MyApp extends App {
6 | render() {
7 | const { Component, pageProps } = this.props
8 |
9 | return (
10 |
11 |
12 |
13 |
14 |
15 | )
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/core/src/convert.test.ts:
--------------------------------------------------------------------------------
1 | import { Convert } from './convert'
2 |
3 | describe('convert.ts', () => {
4 | describe('Convert', () => {
5 | it('bezierCurve', () => {
6 | const convert = new Convert()
7 | expect(
8 | convert
9 | .bezierCurve(
10 | { x: 0, y: 0 },
11 | { x: 1, y: 1 },
12 | { x: 2, y: 1 },
13 | { x: 3, y: 0 }
14 | )
15 | .toString()
16 | ).toBe('C 1.4 1.2 1.6 1.2 2 1')
17 | })
18 | })
19 | })
20 |
--------------------------------------------------------------------------------
/packages/core/src/utils.ts:
--------------------------------------------------------------------------------
1 | export const camel2kebab = (str: string): string =>
2 | str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()
3 |
4 | export const roundUp = (num: number, digits = 2): number => +num.toFixed(digits)
5 |
6 | export const kebab2camel = (str: string): string =>
7 | str.replace(/-([a-z])/g, (a: string, b: string) => b.toUpperCase())
8 |
9 | export const isAlmostSameNumber = (a: number, b: number) =>
10 | Math.trunc(a) === Math.trunc(b)
11 |
12 | export const isNaN = (num: number) => num !== num
13 |
--------------------------------------------------------------------------------
/examples/react/lib/gtag.ts:
--------------------------------------------------------------------------------
1 | export const GA_TRACKING_ID = 'UA-91428067-3'
2 |
3 | // https://developers.google.com/analytics/devguides/collection/gtagjs/pages
4 | export const pageview = (url: any) => {
5 | // @ts-ignore
6 | window.gtag('config', GA_TRACKING_ID, {
7 | page_path: url,
8 | })
9 | }
10 |
11 | // https://developers.google.com/analytics/devguides/collection/gtagjs/events
12 | export const event = ({ action, category, label, value }: any) => {
13 | // @ts-ignore
14 | window.gtag('event', action, {
15 | event_category: category,
16 | event_label: label,
17 | value: value,
18 | })
19 | }
20 |
--------------------------------------------------------------------------------
/docs/packages/interfaces/svg_drawing_img_trace/BlurOption.md:
--------------------------------------------------------------------------------
1 | # Interface: BlurOption
2 |
3 | [@svg-drawing/img-trace](../../modules/svg_drawing_img_trace.md).BlurOption
4 |
5 | ## Properties
6 |
7 | ### delta
8 |
9 | • `Optional` **delta**: `number`
10 |
11 | #### Defined in
12 |
13 | [img-trace/src/blur.ts:20](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/blur.ts#L20)
14 |
15 | ___
16 |
17 | ### radius
18 |
19 | • `Optional` **radius**: `number`
20 |
21 | #### Defined in
22 |
23 | [img-trace/src/blur.ts:19](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/blur.ts#L19)
24 |
--------------------------------------------------------------------------------
/packages/img-trace/src/utils/convertRGBAImage.ts:
--------------------------------------------------------------------------------
1 | export const convertRGBAImage = (imgd: ImageData): ImageData => {
2 | const pixelnum = imgd.width * imgd.height
3 | const isRGB = imgd.data.length < pixelnum * 4
4 | if (!isRGB) return imgd
5 |
6 | const rgbaImgd = new Uint8ClampedArray(pixelnum * 4)
7 | for (let pxcnt = 0; pxcnt < pixelnum; pxcnt++) {
8 | rgbaImgd[pxcnt * 4] = imgd.data[pxcnt * 3]
9 | rgbaImgd[pxcnt * 4 + 1] = imgd.data[pxcnt * 3 + 1]
10 | rgbaImgd[pxcnt * 4 + 2] = imgd.data[pxcnt * 3 + 2]
11 | rgbaImgd[pxcnt * 4 + 3] = 255
12 | }
13 | return {
14 | ...imgd,
15 | data: rgbaImgd,
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/generate-docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svg-drawing-generate-docs",
3 | "private": true,
4 | "version": "4.2.5",
5 | "scripts": {
6 | "build": "typedoc --entryPointStrategy packages ../ --out ../docs/packages --excludePrivate --plugin typedoc-plugin-markdown --hideInPageTOC --hideBreadcrumbs --filenameSeparator \"/\""
7 | },
8 | "dependencies": {
9 | "@svg-drawing/animation": "4.2.5",
10 | "@svg-drawing/core": "4.2.5",
11 | "@svg-drawing/img-trace": "4.2.5",
12 | "@svg-drawing/react": "4.2.5"
13 | },
14 | "devDependencies": {
15 | "typedoc": "0.22.17",
16 | "typedoc-plugin-markdown": "3.12.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/docs/packages/modules/svg_drawing_img_trace.md:
--------------------------------------------------------------------------------
1 | # Module: @svg-drawing/img-trace
2 |
3 | ## Classes
4 |
5 | - [Blur](../classes/svg_drawing_img_trace/Blur.md)
6 | - [ImgLoader](../classes/svg_drawing_img_trace/ImgLoader.md)
7 | - [ImgTrace](../classes/svg_drawing_img_trace/ImgTrace.md)
8 | - [Palette](../classes/svg_drawing_img_trace/Palette.md)
9 |
10 | ## Interfaces
11 |
12 | - [BlurOption](../interfaces/svg_drawing_img_trace/BlurOption.md)
13 | - [FromImageDataOptions](../interfaces/svg_drawing_img_trace/FromImageDataOptions.md)
14 | - [ImgTraceOption](../interfaces/svg_drawing_img_trace/ImgTraceOption.md)
15 | - [Rgba](../interfaces/svg_drawing_img_trace/Rgba.md)
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # ignore
2 | *.DS_Store
3 | .cache
4 |
5 | # Trubo
6 | .turbo
7 |
8 | # dependencies
9 | node_modules
10 | .pnp
11 | .pnp.js
12 |
13 | # testing
14 | /coverage
15 |
16 | # production,distfile
17 | build
18 | dist
19 | lib
20 | .size-snapshot.json
21 | .changelog
22 |
23 | # log
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 | lerna-debug.log*
28 | __debug__
29 |
30 | # configuration for editor
31 | .vscode
32 | .node-version
33 |
34 | # npm lock files
35 | package-lock.json
36 | # yarn.lock
37 |
38 | # next.js
39 | !examples/**/lib
40 | .next
41 | out
42 | .vercel
43 |
44 | # TypeScript
45 | tsconfig.tsbuildinfo
46 | tsconfig.*.tsbuildinfo
47 |
--------------------------------------------------------------------------------
/docs/packages/interfaces/svg_drawing_img_trace/FromImageDataOptions.md:
--------------------------------------------------------------------------------
1 | # Interface: FromImageDataOptions
2 |
3 | [@svg-drawing/img-trace](../../modules/svg_drawing_img_trace.md).FromImageDataOptions
4 |
5 | ## Properties
6 |
7 | ### colorQuantCycles
8 |
9 | • `Optional` **colorQuantCycles**: `number`
10 |
11 | #### Defined in
12 |
13 | [img-trace/src/palette.ts:13](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/palette.ts#L13)
14 |
15 | ___
16 |
17 | ### numberOfColors
18 |
19 | • `Optional` **numberOfColors**: `number`
20 |
21 | #### Defined in
22 |
23 | [img-trace/src/palette.ts:12](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/palette.ts#L12)
24 |
--------------------------------------------------------------------------------
/.github/workflows/gh-pages.yml:
--------------------------------------------------------------------------------
1 | name: deploy github pages
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | deploy-ghpages:
10 | runs-on: macos-10.15
11 | steps:
12 | - uses: actions/checkout@master
13 | - name: Setup Node
14 | uses: actions/setup-node@v3
15 | with:
16 | node-version: 16.13.1
17 | - name: Build
18 | run: |
19 | yarn install --frozen-lockfile
20 | yarn build:gh-page
21 | - name: Deploy
22 | uses: peaceiris/actions-gh-pages@v3
23 | with:
24 | github_token: ${{ secrets.GITHUB_TOKEN }}
25 | publish_branch: gh-pages
26 | publish_dir: ./examples/react/out
27 |
--------------------------------------------------------------------------------
/examples/react/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "include": ["next-env.d.ts", "modules.d.ts", "**/*.ts", "**/*.tsx"],
4 | "compilerOptions": {
5 | "allowJs": true,
6 | "noEmit": true,
7 | "resolveJsonModule": true,
8 | "isolatedModules": true,
9 | "jsx": "preserve",
10 | "lib": ["dom", "dom.iterable", "esnext"],
11 | "incremental": true
12 | },
13 | "exclude": ["node_modules"],
14 | "references": [
15 | {
16 | "path": "../../packages/animation"
17 | },
18 | {
19 | "path": "../../packages/core"
20 | },
21 | {
22 | "path": "../../packages/img-trace"
23 | },
24 | {
25 | "path": "../../packages/react"
26 | }
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/packages/react/src/types.ts:
--------------------------------------------------------------------------------
1 | import type { download, SvgDrawing, DrawingOption } from '@svg-drawing/core'
2 | import type { RefObject } from 'react'
3 |
4 | export type UseSvgDrawing = {
5 | ref: RefObject
6 | clear: () => void
7 | undo: () => void
8 | changePenColor: (penColor: DrawingOption['penColor']) => void
9 | changePenWidth: (penwidth: DrawingOption['penWidth']) => void
10 | changeFill: (penColor: DrawingOption['fill']) => void
11 | changeClose: (penwidth: DrawingOption['close']) => void
12 | changeDelay: (penColor: DrawingOption['delay']) => void
13 | changeCurve: (penwidth: DrawingOption['curve']) => void
14 | getSvgXML: () => string | null
15 | download: (opt: Parameters[1]) => void
16 | }
17 |
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turborepo.org/schema.json",
3 | "baseBranch": "origin/main",
4 | "pipeline": {
5 | "clear": {
6 | "dependsOn": ["^clear"],
7 | "outputs": ["lib/**", "**/*.tsbuildinfo"]
8 | },
9 | "build": {
10 | "dependsOn": ["^clear", "^build"],
11 | "outputs": ["lib/**", "./next/**", "./out/**"]
12 | },
13 | "test": {
14 | "dependsOn": ["^build"],
15 | "outputs": ["snapshots/**"]
16 | },
17 | "typecheck": {
18 | "dependsOn": ["^build"],
19 | "outputs": []
20 | },
21 | "lint": {
22 | "dependsOn": ["^build"],
23 | "outputs": []
24 | },
25 | "dev": {
26 | "cache": false
27 | },
28 | "dev:tsc": {
29 | "cache": false
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/img-trace/src/__test__/loadPngData.ts:
--------------------------------------------------------------------------------
1 | import { readFile } from 'fs'
2 | // @ts-ignore
3 | // eslint-disable-next-line import/no-unresolved
4 | import PNGReader from 'png.js'
5 | interface PngData {
6 | width: number
7 | height: number
8 | data: any
9 | }
10 |
11 | export const loadPngData = (filepath: string, cb: (png: PngData) => void) => {
12 | readFile(filepath, (err: any, bytes: any) => {
13 | if (err) {
14 | console.log(err)
15 | throw err
16 | }
17 |
18 | const reader = new PNGReader(bytes)
19 |
20 | reader.parse((err: any, png: any) => {
21 | if (err) {
22 | console.log(err)
23 | throw err
24 | }
25 |
26 | cb({
27 | width: png.width,
28 | height: png.height,
29 | data: png.pixels,
30 | })
31 | })
32 | })
33 | }
34 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "target": "es6", // TODO: change esnext
5 | "module": "esnext",
6 | "lib": ["esnext", "es2020", "es2019", "es2018", "es2017", "dom"],
7 | "jsx": "react",
8 | "moduleResolution": "node",
9 | "composite": true,
10 | "allowSyntheticDefaultImports": true,
11 | "esModuleInterop": true,
12 | "experimentalDecorators": true,
13 | "downlevelIteration": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noEmitOnError": true,
16 | "noUnusedLocals": false,
17 | "removeComments": false,
18 | "skipLibCheck": true,
19 | "strict": true,
20 | "strictNullChecks": true,
21 | "suppressImplicitAnyIndexErrors": true,
22 | "plugins": [],
23 | "typeRoots": ["node_modules/@types"]
24 | },
25 | "exclude": ["node_modules"]
26 | }
27 |
--------------------------------------------------------------------------------
/config/rollup/ts-lib.js:
--------------------------------------------------------------------------------
1 | import build from './build'
2 |
3 | export default build({
4 | getBabelOptions: ({ esm, extensions, targets }) => ({
5 | extensions,
6 | babelrc: false,
7 | exclude: '**/node_modules/**',
8 | runtimeHelpers: true,
9 | presets: [
10 | [
11 | '@babel/preset-env',
12 | {
13 | targets,
14 | loose: true,
15 | modules: false,
16 | },
17 | ],
18 | '@babel/preset-typescript',
19 | ],
20 | plugins: [
21 | // TODO: optimize bundle size
22 | // 'babel-plugin-annotate-pure-calls',
23 | [
24 | '@babel/plugin-transform-runtime',
25 | { useESModules: esm, regenerator: true },
26 | ],
27 | ['@babel/plugin-proposal-class-properties', { loose: false }],
28 | ['@babel/plugin-proposal-private-methods', { loose: false }],
29 | ['@babel/plugin-proposal-private-property-in-object', { loose: false }],
30 | ],
31 | }),
32 | })
33 |
--------------------------------------------------------------------------------
/docs/packages/modules/svg_drawing_animation.md:
--------------------------------------------------------------------------------
1 | # Module: @svg-drawing/animation
2 |
3 | ## Classes
4 |
5 | - [SvgAnimation](../classes/svg_drawing_animation/SvgAnimation.md)
6 |
7 | ## Type Aliases
8 |
9 | ### AnimationOption
10 |
11 | Ƭ **AnimationOption**: `RendererOption` & { `ms`: `number` }
12 |
13 | #### Defined in
14 |
15 | [animation/src/types.ts:2](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/animation/src/types.ts#L2)
16 |
17 | ___
18 |
19 | ### FrameAnimation
20 |
21 | Ƭ **FrameAnimation**: (`origin`: `Path`[], `loopIndex?`: `number`) => `Path`[]
22 |
23 | #### Type declaration
24 |
25 | ▸ (`origin`, `loopIndex?`): `Path`[]
26 |
27 | ##### Parameters
28 |
29 | | Name | Type |
30 | | :------ | :------ |
31 | | `origin` | `Path`[] |
32 | | `loopIndex?` | `number` |
33 |
34 | ##### Returns
35 |
36 | `Path`[]
37 |
38 | #### Defined in
39 |
40 | [animation/src/types.ts:5](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/animation/src/types.ts#L5)
41 |
--------------------------------------------------------------------------------
/docs/packages/interfaces/svg_drawing_img_trace/Rgba.md:
--------------------------------------------------------------------------------
1 | # Interface: Rgba
2 |
3 | [@svg-drawing/img-trace](../../modules/svg_drawing_img_trace.md).Rgba
4 |
5 | ## Properties
6 |
7 | ### a
8 |
9 | • **a**: `number`
10 |
11 | #### Defined in
12 |
13 | [img-trace/src/palette.ts:7](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/palette.ts#L7)
14 |
15 | ___
16 |
17 | ### b
18 |
19 | • **b**: `number`
20 |
21 | #### Defined in
22 |
23 | [img-trace/src/palette.ts:6](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/palette.ts#L6)
24 |
25 | ___
26 |
27 | ### g
28 |
29 | • **g**: `number`
30 |
31 | #### Defined in
32 |
33 | [img-trace/src/palette.ts:5](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/palette.ts#L5)
34 |
35 | ___
36 |
37 | ### r
38 |
39 | • **r**: `number`
40 |
41 | #### Defined in
42 |
43 | [img-trace/src/palette.ts:4](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/palette.ts#L4)
44 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": ["config:base"],
4 | "labels": ["renovate", "dependencies"],
5 | "major": { "groupName": "all major dependencies" },
6 | "minor": { "groupName": "all minor dependencies" },
7 | "patch": { "groupName": "all patch dependencies", "automerge": true },
8 | "npm": {
9 | "packageRules": [
10 | {
11 | "groupName": "TypeScript",
12 | "matchPackageNames": ["typescript"],
13 | "matchPaths": ["package.json"]
14 | },
15 | {
16 | "groupName": "ESLint and Prettier",
17 | "matchPackageNames": ["eslint", "prettier"],
18 | "matchPackagePatterns": ["^eslint-config-", "^eslint-plugin-", "^@typescript-eslint"],
19 | "matchPaths": ["package.json"]
20 | },
21 | {
22 | "groupName": "Typedoc",
23 | "matchPackageNames": ["typedoc"],
24 | "matchPackagePatterns": ["^typedoc-plugin-"],
25 | "matchPaths": ["package.json"]
26 | }
27 | ]
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/docs/packages/classes/svg_drawing_core/Renderer.md:
--------------------------------------------------------------------------------
1 | # Class: Renderer
2 |
3 | [@svg-drawing/core](../../modules/svg_drawing_core.md).Renderer
4 |
5 | ## Constructors
6 |
7 | ### constructor
8 |
9 | • **new Renderer**(`el`, `__namedParameters?`)
10 |
11 | #### Parameters
12 |
13 | | Name | Type |
14 | | :------ | :------ |
15 | | `el` | `HTMLElement` |
16 | | `__namedParameters` | [`RendererOption`](../../modules/svg_drawing_core.md#rendereroption) |
17 |
18 | #### Defined in
19 |
20 | [core/src/renderer.ts:74](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/renderer.ts#L74)
21 |
22 | ## Properties
23 |
24 | ### el
25 |
26 | • **el**: `HTMLElement`
27 |
28 | ## Methods
29 |
30 | ### update
31 |
32 | ▸ **update**(`svgObj`): `void`
33 |
34 | #### Parameters
35 |
36 | | Name | Type |
37 | | :------ | :------ |
38 | | `svgObj` | [`SvgObject`](../../modules/svg_drawing_core.md#svgobject) |
39 |
40 | #### Returns
41 |
42 | `void`
43 |
44 | #### Defined in
45 |
46 | [core/src/renderer.ts:80](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/renderer.ts#L80)
47 |
--------------------------------------------------------------------------------
/examples/react/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@svg-drawing-example/react",
3 | "private": true,
4 | "version": "4.2.5",
5 | "scripts": {
6 | "clear": "rimraf .next out *.tsbuildinfo",
7 | "start": "next start",
8 | "dev": "next",
9 | "build": "next build; next export",
10 | "lint": "eslint . --ext .js,.ts,.tsx",
11 | "fmt": "yarn lint --fix",
12 | "prepare": "build"
13 | },
14 | "dependencies": {
15 | "@styled-icons/octicons": "10.6.0",
16 | "@svg-drawing/animation": "4.2.5",
17 | "@svg-drawing/core": "4.2.5",
18 | "@svg-drawing/img-trace": "4.2.5",
19 | "@svg-drawing/react": "4.2.5",
20 | "next": "12.1.6",
21 | "react": "18.1.0",
22 | "react-dom": "18.1.0",
23 | "rebass": "4.0.7",
24 | "regenerator-runtime": "0.13.9",
25 | "styled-components": "5.1.1",
26 | "styled-system": "5.1.5"
27 | },
28 | "devDependencies": {
29 | "@types/rebass": "4.0.6",
30 | "@types/styled-components": "5.1.1",
31 | "@types/styled-system": "5.1.1",
32 | "babel-plugin-styled-components": "1.10.7",
33 | "raw-loader": "4.0.1"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 kazuto kamei
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/config/rollup/ts-react-lib.js:
--------------------------------------------------------------------------------
1 | import build from './build'
2 |
3 | export default build({
4 | getBabelOptions: ({ esm, extensions, targets }) => ({
5 | extensions,
6 | babelrc: false,
7 | exclude: '**/node_modules/**',
8 | runtimeHelpers: true,
9 | presets: [
10 | [
11 | '@babel/preset-env',
12 | {
13 | targets,
14 | loose: true,
15 | modules: false,
16 | },
17 | ],
18 | ['@babel/preset-react', { useBuiltIns: true }],
19 | '@babel/preset-typescript',
20 | ],
21 | plugins: [
22 | ['transform-react-remove-prop-types', { removeImport: true }],
23 | // TODO: optimize bundle size
24 | // 'babel-plugin-annotate-pure-calls',
25 | [
26 | '@babel/plugin-transform-runtime',
27 | { useESModules: esm, regenerator: true },
28 | ],
29 | ['@babel/plugin-proposal-class-properties', { loose: false }],
30 | ['@babel/plugin-proposal-private-methods', { loose: false }],
31 | ['@babel/plugin-proposal-private-property-in-object', { loose: false }],
32 | ],
33 | }),
34 | globals: {
35 | react: 'React',
36 | },
37 | })
38 |
--------------------------------------------------------------------------------
/docs/packages/classes/svg_drawing_img_trace/Blur.md:
--------------------------------------------------------------------------------
1 | # Class: Blur
2 |
3 | [@svg-drawing/img-trace](../../modules/svg_drawing_img_trace.md).Blur
4 |
5 | ## Constructors
6 |
7 | ### constructor
8 |
9 | • **new Blur**(`__namedParameters`)
10 |
11 | #### Parameters
12 |
13 | | Name | Type |
14 | | :------ | :------ |
15 | | `__namedParameters` | [`BlurOption`](../../interfaces/svg_drawing_img_trace/BlurOption.md) |
16 |
17 | #### Defined in
18 |
19 | [img-trace/src/blur.ts:25](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/blur.ts#L25)
20 |
21 | ## Properties
22 |
23 | ### delta
24 |
25 | • **delta**: `number`
26 |
27 | #### Defined in
28 |
29 | [img-trace/src/blur.ts:24](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/blur.ts#L24)
30 |
31 | ___
32 |
33 | ### radius
34 |
35 | • **radius**: `number`
36 |
37 | #### Defined in
38 |
39 | [img-trace/src/blur.ts:23](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/blur.ts#L23)
40 |
41 | ## Methods
42 |
43 | ### apply
44 |
45 | ▸ **apply**(`argimgd`): `ImageData`
46 |
47 | #### Parameters
48 |
49 | | Name | Type |
50 | | :------ | :------ |
51 | | `argimgd` | `ImageData` |
52 |
53 | #### Returns
54 |
55 | `ImageData`
56 |
57 | #### Defined in
58 |
59 | [img-trace/src/blur.ts:30](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/blur.ts#L30)
60 |
--------------------------------------------------------------------------------
/packages/core/src/throttle.ts:
--------------------------------------------------------------------------------
1 | interface Options {
2 | leading?: boolean
3 | trailing?: boolean
4 | }
5 |
6 | export function throttle any>(
7 | func: T,
8 | wait: number,
9 | options: Options = {}
10 | ): (...args: Parameters) => ReturnType | null {
11 | let context: any | null
12 | let args: any | null
13 | let result: ReturnType | null
14 | let timeout: any | null = null
15 | let previous = 0
16 |
17 | const later = (): void => {
18 | previous = options.leading === false ? 0 : Date.now()
19 | timeout = null
20 | result = func.apply(context, args)
21 | if (!timeout) {
22 | context = null
23 | args = null
24 | }
25 | }
26 |
27 | const stop = () => {
28 | if (timeout) {
29 | clearTimeout(timeout)
30 | timeout = null
31 | }
32 | }
33 |
34 | return function wrap(
35 | this: typeof func,
36 | ...wraparg: Parameters
37 | ): ReturnType | null {
38 | const now = Date.now()
39 | if (!previous && options.leading === false) previous = now
40 | const remaining = wait - (now - previous)
41 | context = this
42 | args = wraparg
43 | if (remaining <= 0 || remaining > wait) {
44 | stop()
45 | previous = now
46 | result = func.apply(context, args)
47 | if (!timeout) {
48 | context = null
49 | args = null
50 | }
51 | } else if (!timeout && options.trailing !== false) {
52 | timeout = setTimeout(later, remaining)
53 | }
54 | return result
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/docs/packages/classes/svg_drawing_core/Vector.md:
--------------------------------------------------------------------------------
1 | # Class: Vector
2 |
3 | [@svg-drawing/core](../../modules/svg_drawing_core.md).Vector
4 |
5 | ## Constructors
6 |
7 | ### constructor
8 |
9 | • **new Vector**(`v`, `a`)
10 |
11 | #### Parameters
12 |
13 | | Name | Type |
14 | | :------ | :------ |
15 | | `v` | `number` |
16 | | `a` | `number` |
17 |
18 | #### Defined in
19 |
20 | [core/src/svg.ts:129](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/svg.ts#L129)
21 |
22 | ## Properties
23 |
24 | ### angle
25 |
26 | • **angle**: `number`
27 |
28 | #### Defined in
29 |
30 | [core/src/svg.ts:127](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/svg.ts#L127)
31 |
32 | ___
33 |
34 | ### value
35 |
36 | • **value**: `number`
37 |
38 | #### Defined in
39 |
40 | [core/src/svg.ts:128](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/svg.ts#L128)
41 |
42 | ## Methods
43 |
44 | ### scale
45 |
46 | ▸ **scale**(`r`): [`Vector`](Vector.md)
47 |
48 | #### Parameters
49 |
50 | | Name | Type |
51 | | :------ | :------ |
52 | | `r` | `number` |
53 |
54 | #### Returns
55 |
56 | [`Vector`](Vector.md)
57 |
58 | #### Defined in
59 |
60 | [core/src/svg.ts:140](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/svg.ts#L140)
61 |
62 | ___
63 |
64 | ### toPoint
65 |
66 | ▸ **toPoint**(): [`Point`](Point.md)
67 |
68 | #### Returns
69 |
70 | [`Point`](Point.md)
71 |
72 | #### Defined in
73 |
74 | [core/src/svg.ts:134](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/svg.ts#L134)
75 |
--------------------------------------------------------------------------------
/packages/core/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@svg-drawing/core",
3 | "version": "4.2.5",
4 | "license": "MIT",
5 | "description": "svg drawing library.",
6 | "author": {
7 | "name": "Kazuto Kamei",
8 | "email": "kmkzt0927@gmail.com"
9 | },
10 | "keywords": [
11 | "svg",
12 | "drawing"
13 | ],
14 | "type": "module",
15 | "types": "./lib/index.d.ts",
16 | "main": "./lib/index.js",
17 | "browser": "./lib/index.umd.js",
18 | "exports": {
19 | "import": "./lib/index.js",
20 | "require": "./lib/index.cjs",
21 | "development": "./lib/index.dev.js"
22 | },
23 | "files": [
24 | "lib/**/*"
25 | ],
26 | "typedocMain": "src/index.ts",
27 | "repository": {
28 | "type": "git",
29 | "url": "https://github.com/kmkzt/svg-drawing.git",
30 | "directory": "packages/core"
31 | },
32 | "homepage": "https://github.com/kmkzt/svg-drawing#readme",
33 | "bugs": {
34 | "url": "https://github.com/kmkzt/svg-drawing/issues"
35 | },
36 | "scripts": {
37 | "dev": "NODE_ENV=development rollup -w -c",
38 | "dev:tsc": "NODE_ENV=development tsc -w",
39 | "build": "npm-run-all -p lib:*",
40 | "lib:rollup": "NODE_ENV=production rollup -c",
41 | "lib:tsc": "NODE_ENV=production tsc -p ./tsconfig.lib.json",
42 | "clear": "rimraf lib/* *.tsbuildinfo",
43 | "typecheck": "tsc",
44 | "lint": "eslint ./src --ext .js,.ts,.tsx",
45 | "fmt": "yarn lint --fix",
46 | "prepare": "yarn build"
47 | },
48 | "publishConfig": {
49 | "access": "public"
50 | },
51 | "gitHead": "6811d0236e51e0204ffbf64a6124ca5469079373"
52 | }
53 |
--------------------------------------------------------------------------------
/docs/packages/modules/svg_drawing_react.md:
--------------------------------------------------------------------------------
1 | # Module: @svg-drawing/react
2 |
3 | ## Type Aliases
4 |
5 | ### UseSvgDrawing
6 |
7 | Ƭ **UseSvgDrawing**: `Object`
8 |
9 | #### Type declaration
10 |
11 | | Name | Type |
12 | | :------ | :------ |
13 | | `ref` | `RefObject`<`SvgDrawing` \| ``null``\> |
14 | | `changeClose` | (`penwidth`: `undefined` \| `boolean`) => `void` |
15 | | `changeCurve` | (`penwidth`: `undefined` \| `boolean`) => `void` |
16 | | `changeDelay` | (`penColor`: `undefined` \| `number`) => `void` |
17 | | `changeFill` | (`penColor`: `undefined` \| `string`) => `void` |
18 | | `changePenColor` | (`penColor`: `undefined` \| `string`) => `void` |
19 | | `changePenWidth` | (`penwidth`: `undefined` \| `number`) => `void` |
20 | | `clear` | () => `void` |
21 | | `download` | (`opt`: `undefined` \| `DownloadOption`) => `void` |
22 | | `getSvgXML` | () => ``null`` \| `string` |
23 | | `undo` | () => `void` |
24 |
25 | #### Defined in
26 |
27 | [react/src/types.ts:4](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/react/src/types.ts#L4)
28 |
29 | ## Functions
30 |
31 | ### useSvgDrawing
32 |
33 | ▸ **useSvgDrawing**(`option?`): [`MutableRefObject`<``null`` \| `HTMLDivElement`\>, [`UseSvgDrawing`](svg_drawing_react.md#usesvgdrawing)]
34 |
35 | #### Parameters
36 |
37 | | Name | Type |
38 | | :------ | :------ |
39 | | `option?` | `Partial`<`DrawingOption`\> |
40 |
41 | #### Returns
42 |
43 | [`MutableRefObject`<``null`` \| `HTMLDivElement`\>, [`UseSvgDrawing`](svg_drawing_react.md#usesvgdrawing)]
44 |
45 | #### Defined in
46 |
47 | [react/src/useDrawing.ts:7](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/react/src/useDrawing.ts#L7)
48 |
--------------------------------------------------------------------------------
/packages/animation/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@svg-drawing/animation",
3 | "version": "4.2.5",
4 | "license": "MIT",
5 | "description": "svg drawing library.",
6 | "author": {
7 | "name": "Kazuto Kamei",
8 | "email": "kmkzt0927@gmail.com"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/kmkzt/svg-drawing.git",
13 | "directory": "packages/animation"
14 | },
15 | "homepage": "https://github.com/kmkzt/svg-drawing/tree/master/packages/animation#readme",
16 | "bugs": {
17 | "url": "https://github.com/kmkzt/svg-drawing/issues"
18 | },
19 | "keywords": [
20 | "svg",
21 | "drawing",
22 | "animation"
23 | ],
24 | "type": "module",
25 | "types": "./lib/index.d.ts",
26 | "main": "./lib/index.js",
27 | "browser": "./lib/index.umd.js",
28 | "exports": {
29 | "import": "./lib/index.js",
30 | "require": "./lib/index.cjs",
31 | "development": "./lib/index.dev.js"
32 | },
33 | "files": [
34 | "lib/**/*"
35 | ],
36 | "typedocMain": "src/index.ts",
37 | "scripts": {
38 | "dev": "NODE_ENV=development rollup -w -c",
39 | "dev:tsc": "NODE_ENV=development tsc -w",
40 | "build": "npm-run-all -p lib:*",
41 | "lib:rollup": "NODE_ENV=production rollup -c",
42 | "lib:tsc": "NODE_ENV=production tsc -p ./tsconfig.lib.json",
43 | "clear": "rimraf lib/* *.tsbuildinfo",
44 | "typecheck": "tsc",
45 | "lint": "eslint ./src --ext .js,.ts,.tsx",
46 | "fmt": "yarn lint --fix",
47 | "prepare": "yarn build"
48 | },
49 | "optionalDependencies": {
50 | "@svg-drawing/core": "4.2.5"
51 | },
52 | "publishConfig": {
53 | "access": "public"
54 | },
55 | "gitHead": "6811d0236e51e0204ffbf64a6124ca5469079373"
56 | }
57 |
--------------------------------------------------------------------------------
/packages/react/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@svg-drawing/react",
3 | "version": "4.2.5",
4 | "description": "React svg drawing library. This library is a React extension of svg-drawing.",
5 | "author": {
6 | "name": "Kazuto Kamei",
7 | "email": "kmkzt0927@gmail.com"
8 | },
9 | "homepage": "https://github.com/kmkzt/svg-drawing/tree/master/packages/react#readme",
10 | "license": "MIT",
11 | "type": "module",
12 | "types": "./lib/index.d.ts",
13 | "main": "./lib/index.js",
14 | "browser": "./lib/index.umd.js",
15 | "exports": {
16 | "import": "./lib/index.js",
17 | "require": "./lib/index.cjs",
18 | "development": "./lib/index.dev.js"
19 | },
20 | "files": [
21 | "lib/**/*"
22 | ],
23 | "typedocMain": "src/index.ts",
24 | "publishConfig": {
25 | "access": "public"
26 | },
27 | "repository": {
28 | "type": "git",
29 | "url": "https://github.com/kmkzt/svg-drawing.git",
30 | "directory": "packages/react"
31 | },
32 | "bugs": {
33 | "url": "https://github.com/kmkzt/svg-drawing/issues"
34 | },
35 | "scripts": {
36 | "dev": "NODE_ENV=development rollup -w -c",
37 | "dev:tsc": "NODE_ENV=development tsc -w",
38 | "build": "npm-run-all -p lib:*",
39 | "lib:rollup": "NODE_ENV=production rollup -c",
40 | "lib:tsc": "NODE_ENV=production tsc -p ./tsconfig.lib.json",
41 | "clear": "rimraf lib/* *.tsbuildinfo",
42 | "typecheck": "tsc",
43 | "lint": "eslint ./src --ext .js,.ts,.tsx",
44 | "fmt": "yarn lint --fix",
45 | "prepare": "yarn build"
46 | },
47 | "peerDependencies": {
48 | "react": ">= 16.8.0"
49 | },
50 | "optionalDependencies": {
51 | "@svg-drawing/core": "4.2.5",
52 | "@svg-drawing/img-trace": "4.2.5"
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/docs/packages/classes/svg_drawing_core/ResizeHandler.md:
--------------------------------------------------------------------------------
1 | # Class: ResizeHandler
2 |
3 | [@svg-drawing/core](../../modules/svg_drawing_core.md).ResizeHandler
4 |
5 | ## Constructors
6 |
7 | ### constructor
8 |
9 | • **new ResizeHandler**(`_el`, `__namedParameters`)
10 |
11 | #### Parameters
12 |
13 | | Name | Type |
14 | | :------ | :------ |
15 | | `_el` | `HTMLElement` |
16 | | `__namedParameters` | [`ResizeHandlerCallback`](../../modules/svg_drawing_core.md#resizehandlercallback) |
17 |
18 | #### Defined in
19 |
20 | [core/src/handler.ts:183](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/handler.ts#L183)
21 |
22 | ## Properties
23 |
24 | ### resize
25 |
26 | • **resize**: (`rect`: `DOMRect` \| { `height`: `number` ; `left`: `number` ; `top`: `number` ; `width`: `number` }) => `void`
27 |
28 | #### Type declaration
29 |
30 | ▸ (`rect`): `void`
31 |
32 | ##### Parameters
33 |
34 | | Name | Type |
35 | | :------ | :------ |
36 | | `rect` | `DOMRect` \| { `height`: `number` ; `left`: `number` ; `top`: `number` ; `width`: `number` } |
37 |
38 | ##### Returns
39 |
40 | `void`
41 |
42 | #### Defined in
43 |
44 | [core/src/handler.ts:182](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/handler.ts#L182)
45 |
46 | ## Methods
47 |
48 | ### off
49 |
50 | ▸ **off**(): `void`
51 |
52 | #### Returns
53 |
54 | `void`
55 |
56 | #### Defined in
57 |
58 | [core/src/handler.ts:188](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/handler.ts#L188)
59 |
60 | ___
61 |
62 | ### on
63 |
64 | ▸ **on**(): `void`
65 |
66 | #### Returns
67 |
68 | `void`
69 |
70 | #### Defined in
71 |
72 | [core/src/handler.ts:192](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/handler.ts#L192)
73 |
--------------------------------------------------------------------------------
/packages/img-trace/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@svg-drawing/img-trace",
3 | "version": "4.2.5",
4 | "license": "MIT",
5 | "description": "svg drawing library.",
6 | "author": {
7 | "name": "Kazuto Kamei",
8 | "email": "kmkzt0927@gmail.com"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/kmkzt/svg-drawing.git",
13 | "directory": "packages/img-trace"
14 | },
15 | "homepage": "https://github.com/kmkzt/svg-drawing/tree/master/packages/img-trace#readme",
16 | "bugs": {
17 | "url": "https://github.com/kmkzt/svg-drawing/issues"
18 | },
19 | "keywords": [
20 | "svg",
21 | "jpg",
22 | "png",
23 | "tracer"
24 | ],
25 | "type": "module",
26 | "types": "./lib/index.d.ts",
27 | "main": "./lib/index.js",
28 | "browser": "./lib/index.umd.js",
29 | "exports": {
30 | "import": "./lib/index.js",
31 | "require": "./lib/index.cjs",
32 | "development": "./lib/index.dev.js"
33 | },
34 | "files": [
35 | "lib/**/*"
36 | ],
37 | "typedocMain": "src/index.ts",
38 | "scripts": {
39 | "dev": "NODE_ENV=development rollup -w -c",
40 | "dev:tsc": "NODE_ENV=development tsc -w",
41 | "build": "npm-run-all -p lib:*",
42 | "lib:rollup": "NODE_ENV=production rollup -c",
43 | "lib:tsc": "NODE_ENV=production tsc -p ./tsconfig.lib.json",
44 | "clear": "rimraf lib/* *.tsbuildinfo",
45 | "typecheck": "tsc",
46 | "lint": "eslint ./src --ext .js,.ts,.tsx",
47 | "fmt": "yarn lint --fix",
48 | "prepare": "yarn build"
49 | },
50 | "optionalDependencies": {
51 | "@svg-drawing/animation": "4.2.5",
52 | "@svg-drawing/core": "4.2.5"
53 | },
54 | "publishConfig": {
55 | "access": "public"
56 | },
57 | "gitHead": "6811d0236e51e0204ffbf64a6124ca5469079373"
58 | }
59 |
--------------------------------------------------------------------------------
/docs/packages/classes/svg_drawing_img_trace/ImgLoader.md:
--------------------------------------------------------------------------------
1 | # Class: ImgLoader
2 |
3 | [@svg-drawing/img-trace](../../modules/svg_drawing_img_trace.md).ImgLoader
4 |
5 | ## Constructors
6 |
7 | ### constructor
8 |
9 | • **new ImgLoader**(`options`)
10 |
11 | #### Parameters
12 |
13 | | Name | Type |
14 | | :------ | :------ |
15 | | `options` | `Partial`<`ImgLoaderOption`\> |
16 |
17 | #### Defined in
18 |
19 | [img-trace/src/imgloader.ts:8](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/imgloader.ts#L8)
20 |
21 | ## Properties
22 |
23 | ### corsenabled
24 |
25 | • **corsenabled**: `boolean`
26 |
27 | #### Defined in
28 |
29 | [img-trace/src/imgloader.ts:6](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/imgloader.ts#L6)
30 |
31 | ## Methods
32 |
33 | ### fromImageElement
34 |
35 | ▸ **fromImageElement**(`img`, `callback?`): `void` \| `Promise`<`ImageData`\>
36 |
37 | #### Parameters
38 |
39 | | Name | Type |
40 | | :------ | :------ |
41 | | `img` | `HTMLImageElement` |
42 | | `callback?` | (`imgd`: `ImageData`) => `void` |
43 |
44 | #### Returns
45 |
46 | `void` \| `Promise`<`ImageData`\>
47 |
48 | #### Defined in
49 |
50 | [img-trace/src/imgloader.ts:65](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/imgloader.ts#L65)
51 |
52 | ___
53 |
54 | ### fromUrl
55 |
56 | ▸ **fromUrl**(`url`, `callback?`): `void` \| `Promise`<`ImageData`\>
57 |
58 | #### Parameters
59 |
60 | | Name | Type |
61 | | :------ | :------ |
62 | | `url` | `string` |
63 | | `callback?` | (`imgd`: `ImageData`) => `void` |
64 |
65 | #### Returns
66 |
67 | `void` \| `Promise`<`ImageData`\>
68 |
69 | #### Defined in
70 |
71 | [img-trace/src/imgloader.ts:14](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/imgloader.ts#L14)
72 |
--------------------------------------------------------------------------------
/docs/packages/interfaces/svg_drawing_img_trace/ImgTraceOption.md:
--------------------------------------------------------------------------------
1 | # Interface: ImgTraceOption
2 |
3 | [@svg-drawing/img-trace](../../modules/svg_drawing_img_trace.md).ImgTraceOption
4 |
5 | ## Properties
6 |
7 | ### commandOmit
8 |
9 | • `Optional` **commandOmit**: `number`
10 |
11 | #### Defined in
12 |
13 | [img-trace/src/trace.ts:70](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L70)
14 |
15 | ___
16 |
17 | ### ltres
18 |
19 | • `Optional` **ltres**: `number`
20 |
21 | #### Defined in
22 |
23 | [img-trace/src/trace.ts:65](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L65)
24 |
25 | ___
26 |
27 | ### palettes
28 |
29 | • `Optional` **palettes**: [`Rgba`](Rgba.md)[]
30 |
31 | #### Defined in
32 |
33 | [img-trace/src/trace.ts:73](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L73)
34 |
35 | ___
36 |
37 | ### pathAttrs
38 |
39 | • `Optional` **pathAttrs**: `PathObject`
40 |
41 | #### Defined in
42 |
43 | [img-trace/src/trace.ts:72](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L72)
44 |
45 | ___
46 |
47 | ### pathOmit
48 |
49 | • `Optional` **pathOmit**: `number`
50 |
51 | #### Defined in
52 |
53 | [img-trace/src/trace.ts:69](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L69)
54 |
55 | ___
56 |
57 | ### qtres
58 |
59 | • `Optional` **qtres**: `number`
60 |
61 | #### Defined in
62 |
63 | [img-trace/src/trace.ts:66](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L66)
64 |
65 | ___
66 |
67 | ### rightangleenhance
68 |
69 | • `Optional` **rightangleenhance**: `boolean`
70 |
71 | #### Defined in
72 |
73 | [img-trace/src/trace.ts:67](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L67)
74 |
--------------------------------------------------------------------------------
/packages/animation/src/__snapshots__/animation.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`animation.ts SvgAnimation toAnimationElement 1`] = `
4 |
56 | `;
57 |
--------------------------------------------------------------------------------
/packages/img-trace/src/palette.test.ts:
--------------------------------------------------------------------------------
1 | import { resolve } from 'path'
2 | import { loadPngData } from './__test__/loadPngData'
3 | import { Palette } from './palette'
4 | import type { Rgba } from './palette'
5 |
6 | const TEST_NUMBER_OF_COLORS = [undefined, 2, 4, 7, 8, 27, 64]
7 | const TEST_COLOR_QUANT_CYCLES = [undefined, 1, 8]
8 | const getTestResult = (pal: Rgba[]) =>
9 | pal.map((c) => `rgba(${c.r}, ${c.g}, ${c.b}, ${c.a / 255})`)
10 |
11 | describe('palette.ts', () => {
12 | const testimage = resolve(__dirname, '__test__/panda.png')
13 | describe('Palette', () => {
14 | describe('Palette.imageData', () => {
15 | TEST_COLOR_QUANT_CYCLES.map((colorQuantCycles: number | undefined) => {
16 | TEST_NUMBER_OF_COLORS.map((numberOfColors: number | undefined) => {
17 | it(`colorQuantCycles: ${
18 | colorQuantCycles || 'default'
19 | } ;numberOfColors: ${numberOfColors || 'default'}`, (done) => {
20 | loadPngData(testimage, (imgd: any) => {
21 | expect(
22 | getTestResult(
23 | Palette.imageData(imgd, { colorQuantCycles, numberOfColors })
24 | )
25 | ).toMatchSnapshot()
26 | done()
27 | })
28 | })
29 | })
30 | })
31 | })
32 | describe('Palette.number', () => {
33 | // TODO: Rest colors
34 | ;[8, 27].map((arg: number | undefined) => {
35 | it(`numberOfColors: ${arg || 'default'}`, () => {
36 | expect(getTestResult(Palette.number(arg))).toMatchSnapshot()
37 | })
38 | })
39 | })
40 | describe('Palette.gray', () => {
41 | ;[2, 7, 16].map((arg: number | undefined) => {
42 | it(`numberOfColors: ${arg || 'default'}`, () => {
43 | expect(getTestResult(Palette.grey(arg))).toMatchSnapshot()
44 | })
45 | })
46 | })
47 | })
48 | })
49 |
--------------------------------------------------------------------------------
/packages/core/src/convert.ts:
--------------------------------------------------------------------------------
1 | import { Point, Command, COMMAND_TYPE } from './svg'
2 | import type { PointObject, ConvertOption } from './types'
3 |
4 | export class Convert {
5 | public ratio: number
6 | constructor({ ratio }: ConvertOption = {}) {
7 | this.ratio = ratio ?? 0.2
8 | }
9 | private _controlPoint(
10 | pr: PointObject,
11 | st: PointObject,
12 | ne: PointObject
13 | ): [number, number] {
14 | const prev = new Point(pr.x, pr.y)
15 | const start = new Point(st.x, st.y)
16 | const next = new Point(ne.x, ne.y)
17 | const vector = next.sub(prev).toVector().scale(this.ratio).toPoint()
18 | const po = start.add(vector)
19 | return [po.x, po.y]
20 | }
21 |
22 | public bezierCurve(
23 | p1: PointObject,
24 | p2: PointObject,
25 | p3: PointObject,
26 | p4: PointObject
27 | ): Command {
28 | const value = [
29 | ...this._controlPoint(p1, p2, p3),
30 | ...this._controlPoint(p4, p3, p2),
31 | p3.x,
32 | p3.y,
33 | ]
34 | return new Command(COMMAND_TYPE.CURVE, value)
35 | }
36 |
37 | public lineCommands(points: PointObject[]): Command[] {
38 | return points.map(
39 | (p, i) =>
40 | new Command(i === 0 ? COMMAND_TYPE.MOVE : COMMAND_TYPE.LINE, [p.x, p.y])
41 | )
42 | }
43 |
44 | public bezierCurveCommands(p: PointObject[]): Command[] {
45 | const commands: Command[] = []
46 | if (p.length < 3) {
47 | return this.lineCommands(p)
48 | }
49 | for (let i = 0; i < p.length; i += 1) {
50 | if (i === 0) {
51 | commands.push(new Command(COMMAND_TYPE.MOVE, [p[i].x, p[i].y]))
52 | continue
53 | }
54 | commands.push(
55 | this.bezierCurve(
56 | p[i - 2 < 0 ? 0 : i - 2],
57 | p[i - 1],
58 | p[i],
59 | i < p.length - 1 ? p[i + 1] : p[i]
60 | )
61 | )
62 | }
63 | return commands
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/docs/packages/classes/svg_drawing_img_trace/Palette.md:
--------------------------------------------------------------------------------
1 | # Class: Palette
2 |
3 | [@svg-drawing/img-trace](../../modules/svg_drawing_img_trace.md).Palette
4 |
5 | ## Constructors
6 |
7 | ### constructor
8 |
9 | • **new Palette**()
10 |
11 | ## Methods
12 |
13 | ### grey
14 |
15 | ▸ `Static` **grey**(`numberofcolors?`): [`Rgba`](../../interfaces/svg_drawing_img_trace/Rgba.md)[]
16 |
17 | #### Parameters
18 |
19 | | Name | Type | Default value |
20 | | :------ | :------ | :------ |
21 | | `numberofcolors` | `number` | `DEFAULT_NUMBER_OF_COLORS` |
22 |
23 | #### Returns
24 |
25 | [`Rgba`](../../interfaces/svg_drawing_img_trace/Rgba.md)[]
26 |
27 | #### Defined in
28 |
29 | [img-trace/src/palette.ts:152](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/palette.ts#L152)
30 |
31 | ___
32 |
33 | ### imageData
34 |
35 | ▸ `Static` **imageData**(`argimgd`, `__namedParameters?`): [`Rgba`](../../interfaces/svg_drawing_img_trace/Rgba.md)[]
36 |
37 | #### Parameters
38 |
39 | | Name | Type |
40 | | :------ | :------ |
41 | | `argimgd` | `ImageData` |
42 | | `__namedParameters` | [`FromImageDataOptions`](../../interfaces/svg_drawing_img_trace/FromImageDataOptions.md) |
43 |
44 | #### Returns
45 |
46 | [`Rgba`](../../interfaces/svg_drawing_img_trace/Rgba.md)[]
47 |
48 | #### Defined in
49 |
50 | [img-trace/src/palette.ts:17](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/palette.ts#L17)
51 |
52 | ___
53 |
54 | ### number
55 |
56 | ▸ `Static` **number**(`numberofcolors?`): [`Rgba`](../../interfaces/svg_drawing_img_trace/Rgba.md)[]
57 |
58 | #### Parameters
59 |
60 | | Name | Type | Default value |
61 | | :------ | :------ | :------ |
62 | | `numberofcolors` | `number` | `DEFAULT_NUMBER_OF_COLORS` |
63 |
64 | #### Returns
65 |
66 | [`Rgba`](../../interfaces/svg_drawing_img_trace/Rgba.md)[]
67 |
68 | #### Defined in
69 |
70 | [img-trace/src/palette.ts:116](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/palette.ts#L116)
71 |
--------------------------------------------------------------------------------
/packages/img-trace/src/trace.test.ts:
--------------------------------------------------------------------------------
1 | import { writeFileSync } from 'fs'
2 | import { resolve } from 'path'
3 | import { svgObjectToElement } from '@svg-drawing/core'
4 | import { loadPngData } from './__test__/loadPngData'
5 | import { Palette } from './palette'
6 | import { ImgTrace } from './trace'
7 | import type { ImgTraceOption } from './trace'
8 |
9 | const testPattern: {
10 | [key: string]: Partial
11 | } = {
12 | default: {},
13 | curvy: { rightangleenhance: false },
14 | ltres: { ltres: 0.01 },
15 | qtres: { qtres: 0.01 },
16 | pathomit_20: { pathOmit: 20 },
17 | commandOmit: { commandOmit: 3 },
18 | palettes_custom: {
19 | palettes: [
20 | { r: 0, g: 0, b: 100, a: 255 },
21 | { r: 255, g: 255, b: 255, a: 255 },
22 | ],
23 | },
24 | }
25 |
26 | describe('trace.ts', () => {
27 | const testimage = resolve(__dirname, '__test__/panda.png')
28 | it('TestPattern', () => {
29 | // TestPattern
30 | expect(testPattern).toMatchSnapshot()
31 | })
32 | describe('ImgTrace', () => {
33 | Object.entries(testPattern).map(([testname, testopts]) => {
34 | it(`${testname}`, (done) => {
35 | loadPngData(testimage, (png) => {
36 | const svg = new ImgTrace({
37 | palettes: Palette.imageData(png as any),
38 | ...testopts,
39 | }).load(png as any)
40 |
41 | const data = svgObjectToElement(svg.toJson()).outerHTML
42 | /** DEBUG * */
43 | if (process.env.DEBUG === 'debug') {
44 | writeFileSync(
45 | resolve(__dirname, `__debug__/${testname}-${Date.now()}.svg`),
46 | data
47 | )
48 | }
49 |
50 | // TODO: visual regression
51 |
52 | // Effect Image
53 | // TODO: visual regression
54 | // expect(imgd).toMatchSnapshot()
55 |
56 | // SvgString
57 | expect(data).toMatchSnapshot()
58 | done()
59 | })
60 | })
61 | })
62 | })
63 | })
64 |
--------------------------------------------------------------------------------
/packages/core/src/__snapshots__/drawing.test.ts.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`drawing.ts SvgDrawing clear() 1`] = `
4 |
11 | `;
12 |
13 | exports[`drawing.ts SvgDrawing close 1`] = `
14 |
30 | `;
31 |
32 | exports[`drawing.ts SvgDrawing curve = false 1`] = `
33 |
49 | `;
50 |
51 | exports[`drawing.ts SvgDrawing default 1`] = `
52 |
68 | `;
69 |
70 | exports[`drawing.ts SvgDrawing undo() 1`] = `
71 |
87 | `;
88 |
--------------------------------------------------------------------------------
/examples/react/components/Layout.tsx:
--------------------------------------------------------------------------------
1 | import { MarkGithub } from '@styled-icons/octicons/MarkGithub'
2 | import Head from 'next/head'
3 | import Link from 'next/link'
4 | import { Fragment } from 'react'
5 | import { Flex, Box, Text, Link as RELink } from 'rebass/styled-components'
6 | import { createGlobalStyle } from 'styled-components'
7 |
8 | const GlobalStyle = createGlobalStyle`
9 | body, * {
10 | margin: 0;
11 | box-sizing: border-box;
12 | }
13 |
14 | a {
15 | color: initial;
16 | text-decoration: initial;
17 | }
18 | `
19 |
20 | const GlobalHeader = () => (
21 |
22 |
23 |
24 |
25 |
26 |
33 | svg-drawing
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | drawing
42 |
43 |
44 |
45 |
46 | animation
47 |
48 |
49 |
50 |
51 | img-trace
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | )
63 |
64 | const Layout = ({
65 | children,
66 | title = '',
67 | }: {
68 | title?: string
69 | children: React.ReactNode
70 | }) => {
71 | return (
72 |
73 |
74 | {`svg-drawing ${title}`}
75 |
76 |
77 |
78 |
79 | {children}
80 |
81 |
82 | )
83 | }
84 |
85 | export default Layout
86 |
--------------------------------------------------------------------------------
/packages/core/README.md:
--------------------------------------------------------------------------------
1 | # `@svg-drawing/core`
2 |
3 | [](https://www.npmjs.com/package/@svg-drawing/core) [](https://www.npmjs.com/package/@svg-drawing/core)
4 |
5 | ## How to use
6 |
7 | ### npm
8 |
9 | Install
10 |
11 | ```shell
12 | yarn add @svg-drawing/core
13 | # or
14 | # npm i svg-drawing
15 | ```
16 |
17 | Example code is [here](/examples/docs/pages/demo/drawing.tsx)
18 |
19 | This example renders the drawing area.
20 |
21 | ```javascript
22 | import { SvgDrawing } from '@svg-drawing/core'
23 |
24 | const el = document.createElement('div')
25 |
26 | // Drawing area will be resized to fit the rendering area
27 | el.setAttribute(
28 | 'style',
29 | `
30 | border: 1px solid #ddd;
31 | width: 500px;
32 | height: 500px;
33 | `
34 | )
35 | document.body.appendChid(el)
36 | new SvgDrawing(el)
37 | ```
38 |
39 | SvgDrawing methods.
40 |
41 | ```javascript
42 | const draw = new SvgDrawing(el)
43 |
44 | // change parameter. There are other changeable parameters like fill, close, curve, etc.
45 | draw.penColor = '#00b'
46 | draw.penWidth = 10
47 |
48 | // drawing deactivate
49 | draw.off()
50 | // drawing reactivate
51 | draw.on()
52 |
53 | // drawing all clear
54 | draw.clear()
55 | // undo drawing
56 | draw.undo()
57 |
58 | // Download image. Also available in SvgAnimation, Renderer
59 | draw.download() // Default download is svg.
60 | draw.download({ extension: 'jpg', filename: 'example.jpg' })
61 | draw.download({ extension: 'png', filename: 'example.png' })
62 |
63 | // Load svg data. Only the path element.
64 | // SVG exported by this library can be read.
65 | draw.svg.parseSVGString(
66 | ''
67 | )
68 | draw.svg.parseSVGElement(document.getElementByID('loadSVG'))
69 | ```
70 |
71 | ### CDN
72 |
73 | ```html
74 |
75 |
76 |
79 | ```
80 |
81 | [Here](/example/html/) is an example for Html only.
82 |
--------------------------------------------------------------------------------
/packages/core/src/drawing.test.ts:
--------------------------------------------------------------------------------
1 | import { SvgDrawing } from './drawing'
2 | import { svgObjectToElement } from './renderer'
3 |
4 | describe('drawing.ts', () => {
5 | describe('SvgDrawing', () => {
6 | it('default', () => {
7 | const draw: SvgDrawing = new SvgDrawing(document.createElement('div'))
8 | draw.drawStart()
9 | draw.drawMove({ x: 0, y: 0 })
10 | draw.drawMove({ x: 1, y: 1 })
11 | draw.drawMove({ x: 2, y: 1 })
12 | draw.drawMove({ x: 3, y: 0 })
13 | draw.drawEnd()
14 | expect(svgObjectToElement(draw.svg.toJson())).toMatchSnapshot()
15 | })
16 | it('close', () => {
17 | const draw: SvgDrawing = new SvgDrawing(document.createElement('div'))
18 | draw.close = true
19 | draw.drawStart()
20 | draw.drawMove({ x: 0, y: 0 })
21 | draw.drawMove({ x: 1, y: 1 })
22 | draw.drawMove({ x: 2, y: 1 })
23 | draw.drawMove({ x: 3, y: 0 })
24 | draw.drawEnd()
25 | const el = svgObjectToElement(draw.svg.toJson())
26 | expect(el).toMatchSnapshot()
27 | })
28 | it('curve = false', () => {
29 | const draw: SvgDrawing = new SvgDrawing(document.createElement('div'))
30 | draw.curve = false
31 | draw.drawStart()
32 | draw.drawMove({ x: 0, y: 0 })
33 | draw.drawMove({ x: 1, y: 1 })
34 | draw.drawMove({ x: 2, y: 1 })
35 | draw.drawMove({ x: 3, y: 0 })
36 | draw.drawEnd()
37 | const el = svgObjectToElement(draw.svg.toJson())
38 | expect(el).toMatchSnapshot()
39 | })
40 | it('clear()', () => {
41 | const draw: SvgDrawing = new SvgDrawing(document.createElement('div'))
42 | draw.curve = false
43 | draw.drawStart()
44 | draw.drawMove({ x: 0, y: 0 })
45 | draw.drawEnd()
46 | draw.clear()
47 | const el = svgObjectToElement(draw.svg.toJson())
48 | expect(el).toMatchSnapshot()
49 | })
50 |
51 | // TODO: Fix NaN
52 | it('undo()', () => {
53 | const draw: SvgDrawing = new SvgDrawing(document.createElement('div'))
54 | draw.drawStart()
55 | draw.drawMove({ x: 0, y: 0 })
56 | draw.drawEnd()
57 | draw.drawStart()
58 | draw.drawMove({ x: 0, y: 0 })
59 | draw.drawEnd()
60 | draw.undo()
61 | const el = svgObjectToElement(draw.svg.toJson())
62 | expect(el).toMatchSnapshot()
63 | })
64 | })
65 | })
66 |
--------------------------------------------------------------------------------
/packages/animation/src/animation.test.ts:
--------------------------------------------------------------------------------
1 | import { SvgAnimation } from './animation'
2 | import type { FrameAnimation } from './types'
3 |
4 | const defaultTestData = ``
8 |
9 | describe('animation.ts', () => {
10 | describe('SvgAnimation', () => {
11 | const generateAnimation = (svgStr = defaultTestData) => {
12 | const anim = new SvgAnimation(document.createElement('div'))
13 | anim.svg.parseSVGString(svgStr)
14 | return anim
15 | }
16 |
17 | it('generateFrame', () => {
18 | const svg = generateAnimation()
19 | svg.setAnimation((paths) => {
20 | return [paths[0]]
21 | })
22 | expect(svg.generateFrame().length).toBe(1)
23 | })
24 |
25 | // TODO Improve test pattern
26 | it('toAnimationElement', () => {
27 | const svg = generateAnimation()
28 | const testAnimation: FrameAnimation = (paths, count: any) => {
29 | const update = []
30 | for (let i = 0; i < paths.length; i += 1) {
31 | // Test property
32 | if (count % 2 === 0) paths[i].attrs.stroke = '#0ff'
33 | // Test Attribute
34 | if (count % 3 === 0)
35 | Object.assign(paths[i].attrs, {
36 | strokeLinecap: 'mitter',
37 | })
38 | if (count < paths[i].commands.length) {
39 | paths[i].commands = paths[i].commands.slice(0, count)
40 | update.push(paths[i])
41 | break
42 | }
43 | count -= paths[i].commands.length
44 | update.push(paths[i])
45 | }
46 | return update
47 | }
48 | svg.setAnimation(testAnimation)
49 | expect(svg.toElement()).toMatchSnapshot()
50 | })
51 |
52 | it('setAnimation, start, stop', async () => {
53 | const svg = generateAnimation()
54 | let loop = 0
55 | svg.setAnimation(
56 | (_paths, fid) => {
57 | loop += 1
58 | return []
59 | },
60 | {
61 | ms: 300,
62 | frames: 3,
63 | }
64 | )
65 | svg.start()
66 | setTimeout(() => {
67 | svg.stop()
68 | expect(loop).toBe(3)
69 | }, 1000)
70 | })
71 | })
72 | })
73 |
--------------------------------------------------------------------------------
/packages/img-trace/README.md:
--------------------------------------------------------------------------------
1 | # `@svg-drawing/img-trace`
2 |
3 | [](https://www.npmjs.com/package/@svg-drawing/img-trace) [](https://www.npmjs.com/package/@svg-drawing/img-trace)
4 |
5 | ## Install
6 |
7 | ### npm
8 |
9 | ```shell
10 | yarn add @svg-drawing/img-trace
11 | # or
12 | # npm i @svg-drawing/img-trace
13 | ```
14 |
15 | ## How to use
16 |
17 | Example code is [here](/examples/docs/pages/demo/img-trace.tsx)
18 |
19 | Example of downloading the image converted to Svg
20 |
21 | ```ts
22 | import {
23 | ImgTrace
24 | ImgLoader,
25 | } from '@svg-drawing/img-trace'
26 | import { download } from '@svg-drawing/core'
27 |
28 | const svgDownload = async () => {
29 | new ImgLoader().fromUrl('./images/example.png', (imgd) => {
30 | const svg = new ImgTrace().load(imgd)
31 | download(svg)
32 | }
33 | }
34 |
35 | svgDownload()
36 | ```
37 |
38 | Example of rendering an image converted to Svg
39 |
40 | ```ts
41 | import { Renderer } from '@svg-drawing/core'
42 | import {
43 | ImgTrace
44 | ImgLoader,
45 | } from '@svg-drawing/img-trace'
46 |
47 | const handleImage = (imgd) => {
48 | const svg = new ImgTrace().load(imgd)
49 | const renderer = new Renderer(document.getElementById('render-area'))
50 | renderer.update(svg.toJson())
51 | }
52 |
53 | new ImgLoader().fromUrl('./images/example.png', handleImage)
54 | ```
55 |
56 | Example of get colors palettes.
57 |
58 | ```ts
59 | import {
60 | ImgTrace
61 | ImgLoader,
62 | Palette
63 | } from '@svg-drawing/img-trace'
64 | import { download } from '@svg-drawing/core'
65 |
66 | // imgd is new ImageData()
67 | const colorSvgDownload = () => {
68 | new ImgLoader().fromUrl('./images/example.png', (imgd) => {
69 | // extracting colors from an image.
70 | const palette = Palette.imageData(imgd, {
71 | numberOfColors: 8 // The default value. If it is 8 or less, the value is gray scale.
72 | })
73 | // const palette = Palette.number(8) // Extracts the color evenly by the number passed
74 | // const palette = Palette.grey(8) // Grey scale palettes.
75 |
76 | const svg = new ImgTrace({ palettes }).load(imgd)
77 | download(svg)
78 | })
79 | }
80 |
81 | colorSvgDownload()
82 |
83 | ```
84 |
85 | ## Thanks
86 |
87 | https://github.com/jankovicsandras/imagetracerjs
88 |
--------------------------------------------------------------------------------
/examples/react/pages/_document.tsx:
--------------------------------------------------------------------------------
1 | import Document, { Head, Html, Main, NextScript } from 'next/document'
2 | import { ServerStyleSheet } from 'styled-components'
3 | import { GA_TRACKING_ID } from '../lib/gtag'
4 | import type { DocumentContext, DocumentInitialProps } from 'next/document'
5 |
6 | export default class MyDocument extends Document {
7 | static async getInitialProps(
8 | ctx: DocumentContext
9 | ): Promise {
10 | const sheet = new ServerStyleSheet()
11 | const originalRenderPage = ctx.renderPage
12 |
13 | try {
14 | ctx.renderPage = () =>
15 | originalRenderPage({
16 | enhanceApp: (App) => (props) =>
17 | sheet.collectStyles(),
18 | })
19 |
20 | const initialProps = await Document.getInitialProps(ctx)
21 | return {
22 | html: initialProps.html,
23 | head: initialProps.head,
24 | // @ts-expect-error
25 | styles: (
26 | <>
27 | {initialProps.styles}
28 | {sheet.getStyleElement()}
29 | >
30 | ),
31 | }
32 | } catch {
33 | return {
34 | styles: undefined,
35 | html: '',
36 | head: undefined,
37 | }
38 | } finally {
39 | sheet.seal()
40 | }
41 | }
42 |
43 | render() {
44 | return (
45 |
46 |
47 |
48 |
53 | {/* Global Site Tag (gtag.js) - Google Analytics */}
54 |
58 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | )
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/docs/packages/classes/svg_drawing_core/Convert.md:
--------------------------------------------------------------------------------
1 | # Class: Convert
2 |
3 | [@svg-drawing/core](../../modules/svg_drawing_core.md).Convert
4 |
5 | ## Constructors
6 |
7 | ### constructor
8 |
9 | • **new Convert**(`__namedParameters?`)
10 |
11 | #### Parameters
12 |
13 | | Name | Type |
14 | | :------ | :------ |
15 | | `__namedParameters` | [`ConvertOption`](../../interfaces/svg_drawing_core/ConvertOption.md) |
16 |
17 | #### Defined in
18 |
19 | [core/src/convert.ts:6](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/convert.ts#L6)
20 |
21 | ## Properties
22 |
23 | ### ratio
24 |
25 | • **ratio**: `number`
26 |
27 | #### Defined in
28 |
29 | [core/src/convert.ts:5](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/convert.ts#L5)
30 |
31 | ## Methods
32 |
33 | ### bezierCurve
34 |
35 | ▸ **bezierCurve**(`p1`, `p2`, `p3`, `p4`): [`Command`](Command.md)
36 |
37 | #### Parameters
38 |
39 | | Name | Type |
40 | | :------ | :------ |
41 | | `p1` | [`PointObject`](../../modules/svg_drawing_core.md#pointobject) |
42 | | `p2` | [`PointObject`](../../modules/svg_drawing_core.md#pointobject) |
43 | | `p3` | [`PointObject`](../../modules/svg_drawing_core.md#pointobject) |
44 | | `p4` | [`PointObject`](../../modules/svg_drawing_core.md#pointobject) |
45 |
46 | #### Returns
47 |
48 | [`Command`](Command.md)
49 |
50 | #### Defined in
51 |
52 | [core/src/convert.ts:22](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/convert.ts#L22)
53 |
54 | ___
55 |
56 | ### bezierCurveCommands
57 |
58 | ▸ **bezierCurveCommands**(`p`): [`Command`](Command.md)[]
59 |
60 | #### Parameters
61 |
62 | | Name | Type |
63 | | :------ | :------ |
64 | | `p` | [`PointObject`](../../modules/svg_drawing_core.md#pointobject)[] |
65 |
66 | #### Returns
67 |
68 | [`Command`](Command.md)[]
69 |
70 | #### Defined in
71 |
72 | [core/src/convert.ts:44](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/convert.ts#L44)
73 |
74 | ___
75 |
76 | ### lineCommands
77 |
78 | ▸ **lineCommands**(`points`): [`Command`](Command.md)[]
79 |
80 | #### Parameters
81 |
82 | | Name | Type |
83 | | :------ | :------ |
84 | | `points` | [`PointObject`](../../modules/svg_drawing_core.md#pointobject)[] |
85 |
86 | #### Returns
87 |
88 | [`Command`](Command.md)[]
89 |
90 | #### Defined in
91 |
92 | [core/src/convert.ts:37](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/convert.ts#L37)
93 |
--------------------------------------------------------------------------------
/docs/packages/classes/svg_drawing_core/DrawHandler.md:
--------------------------------------------------------------------------------
1 | # Class: DrawHandler
2 |
3 | [@svg-drawing/core](../../modules/svg_drawing_core.md).DrawHandler
4 |
5 | ## Constructors
6 |
7 | ### constructor
8 |
9 | • **new DrawHandler**(`_el`, `__namedParameters`)
10 |
11 | #### Parameters
12 |
13 | | Name | Type |
14 | | :------ | :------ |
15 | | `_el` | `HTMLElement` |
16 | | `__namedParameters` | [`DrawHandlerCallback`](../../modules/svg_drawing_core.md#drawhandlercallback) |
17 |
18 | #### Defined in
19 |
20 | [core/src/handler.ts:54](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/handler.ts#L54)
21 |
22 | ## Properties
23 |
24 | ### end
25 |
26 | • **end**: () => `void`
27 |
28 | #### Type declaration
29 |
30 | ▸ (): `void`
31 |
32 | EventHandler
33 |
34 | ##### Returns
35 |
36 | `void`
37 |
38 | #### Defined in
39 |
40 | [core/src/handler.ts:51](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/handler.ts#L51)
41 |
42 | ___
43 |
44 | ### move
45 |
46 | • **move**: (`po`: [`PointObject`](../../modules/svg_drawing_core.md#pointobject)) => `void`
47 |
48 | #### Type declaration
49 |
50 | ▸ (`po`): `void`
51 |
52 | ##### Parameters
53 |
54 | | Name | Type |
55 | | :------ | :------ |
56 | | `po` | [`PointObject`](../../modules/svg_drawing_core.md#pointobject) |
57 |
58 | ##### Returns
59 |
60 | `void`
61 |
62 | #### Defined in
63 |
64 | [core/src/handler.ts:53](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/handler.ts#L53)
65 |
66 | ___
67 |
68 | ### start
69 |
70 | • **start**: () => `void`
71 |
72 | #### Type declaration
73 |
74 | ▸ (): `void`
75 |
76 | ##### Returns
77 |
78 | `void`
79 |
80 | #### Defined in
81 |
82 | [core/src/handler.ts:52](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/handler.ts#L52)
83 |
84 | ## Methods
85 |
86 | ### off
87 |
88 | ▸ **off**(): `void`
89 |
90 | Exec removeEventListener
91 |
92 | #### Returns
93 |
94 | `void`
95 |
96 | #### Defined in
97 |
98 | [core/src/handler.ts:76](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/handler.ts#L76)
99 |
100 | ___
101 |
102 | ### on
103 |
104 | ▸ **on**(): `void`
105 |
106 | Exec addEventListener
107 |
108 | #### Returns
109 |
110 | `void`
111 |
112 | #### Defined in
113 |
114 | [core/src/handler.ts:82](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/handler.ts#L82)
115 |
--------------------------------------------------------------------------------
/packages/core/src/renderer.ts:
--------------------------------------------------------------------------------
1 | import { camel2kebab } from './utils'
2 | import type { PathObject, RendererOption, SvgObject } from './types'
3 |
4 | const VERSION = '1.1'
5 | const SVG_NS = 'http://www.w3.org/2000/svg'
6 | const SVG_XLINK = 'http://www.w3.org/1999/xlink'
7 | interface Attrs {
8 | [key: string]: string
9 | }
10 | export const createSvgElement = (
11 | attrs: Attrs,
12 | childs: SVGElement[]
13 | ): SVGSVGElement => {
14 | const svg = document.createElementNS(SVG_NS, 'svg')
15 | svg.setAttributeNS(null, 'version', VERSION)
16 | svg.setAttribute('xmlns', SVG_NS)
17 | svg.setAttribute('xmlns:xlink', SVG_XLINK)
18 | Object.keys(attrs)
19 | .sort()
20 | .map((key: string) => {
21 | svg.setAttribute(key, attrs[key])
22 | })
23 | childs.map((el: SVGElement) => {
24 | svg.appendChild(el)
25 | })
26 | return svg
27 | }
28 |
29 | export const createSvgChildElement = (
30 | elname: string,
31 | attrs: Attrs
32 | ): SVGElement => {
33 | const path = document.createElementNS(SVG_NS, elname)
34 | Object.keys(attrs)
35 | .sort()
36 | .map((key: string) => {
37 | path.setAttribute(key, attrs[key])
38 | })
39 | return path
40 | }
41 |
42 | export const pathObjectToElement = (path: PathObject): SVGElement => {
43 | const kebabAttrs = Object.entries(path).reduce(
44 | (acc, [key, val], _i) =>
45 | val
46 | ? {
47 | ...acc,
48 | [camel2kebab(key)]: val,
49 | }
50 | : acc,
51 | {}
52 | )
53 | return createSvgChildElement('path', kebabAttrs)
54 | }
55 |
56 | export const svgObjectToElement = ({
57 | width,
58 | height,
59 | background,
60 | paths,
61 | }: SvgObject): SVGSVGElement => {
62 | const size = { width: String(width), height: String(height) }
63 | const bgEl = background
64 | ? [createSvgChildElement('rect', { ...size, fill: background })]
65 | : []
66 | const updateEl = createSvgElement(size, [
67 | ...bgEl,
68 | ...paths.map(pathObjectToElement),
69 | ])
70 | return updateEl
71 | }
72 |
73 | export class Renderer {
74 | constructor(public el: HTMLElement, { background }: RendererOption = {}) {
75 | /** Setup parameter */
76 | const { width, height } = el.getBoundingClientRect()
77 | el.appendChild(svgObjectToElement({ background, width, height, paths: [] }))
78 | }
79 |
80 | public update(svgObj: SvgObject): void {
81 | this.el.replaceChild(svgObjectToElement(svgObj), this.el.childNodes[0])
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/packages/core/src/types.ts:
--------------------------------------------------------------------------------
1 | /** Svg Path JSON */
2 | export type PathObject = {
3 | [camelCase: string]: string | undefined
4 | }
5 | /** Svg JSON */
6 | export type SvgObject = {
7 | width: number
8 | height: number
9 | background?: string
10 | paths: PathObject[]
11 | }
12 |
13 | /** Path Object */
14 | export type PointObject = {
15 | x: number
16 | y: number
17 | pressure?: number
18 | }
19 |
20 | /** Command Object */
21 | export type CommandType =
22 | | 'M'
23 | | 'm'
24 | | 'L'
25 | | 'l'
26 | | 'C'
27 | | 'c'
28 | | 'Z'
29 | | 'H'
30 | | 'h'
31 | | 'V'
32 | | 'v'
33 | | 'A'
34 | | 'a'
35 | | 'Q'
36 | | 'q'
37 | export type CommandObject = {
38 | type: CommandType
39 | value: number[]
40 | }
41 | /** Svg options */
42 | export type SvgOption = {
43 | width: number
44 | height: number
45 | background?: string
46 | }
47 | /** Convert options */
48 | export interface ConvertOption {
49 | ratio?: number
50 | }
51 | /** Renderer options */
52 | export type RendererOption = Pick
53 |
54 | /** SvgDrawing options */
55 | export type DrawingOption = RendererOption & {
56 | penColor?: string
57 | penWidth?: number
58 | curve?: boolean
59 | close?: boolean
60 | delay?: number
61 | fill?: string
62 | }
63 | /** Download options */
64 | export type DownloadOption = {
65 | extension: 'svg' | 'png' | 'jpg'
66 | filename?: string
67 | }
68 | /** DrawHandler callback */
69 | export type DrawHandlerCallback = {
70 | start: () => void
71 | end: () => void
72 | move: (po: PointObject) => void
73 | }
74 | /** ResizeHandler callback */
75 | export type ResizeHandlerCallback = {
76 | resize: (
77 | rect: DOMRect | { width: number; height: number; left: number; top: number }
78 | ) => void
79 | }
80 | export type DrawListenerType = 'pointer' | 'touch' | 'mouse'
81 |
82 | export type DrawEventName = Extract<
83 | keyof GlobalEventHandlersEventMap,
84 | | 'pointerdown'
85 | | 'pointermove'
86 | | 'pointerleave'
87 | | 'pointercancel'
88 | | 'pointerup'
89 | | 'touchstart'
90 | | 'touchmove'
91 | | 'touchend'
92 | | 'touchcancel'
93 | | 'mousedown'
94 | | 'mousemove'
95 | | 'mouseleave'
96 | | 'mouseout'
97 | | 'mouseup'
98 | >
99 | export type ListenerMaps = Record<
100 | DrawListenerType,
101 | {
102 | start: Array
103 | move: Array
104 | end: Array
105 | frameout: Array
106 | }
107 | >
108 |
--------------------------------------------------------------------------------
/docs/packages/classes/svg_drawing_img_trace/ImgTrace.md:
--------------------------------------------------------------------------------
1 | # Class: ImgTrace
2 |
3 | [@svg-drawing/img-trace](../../modules/svg_drawing_img_trace.md).ImgTrace
4 |
5 | ## Constructors
6 |
7 | ### constructor
8 |
9 | • **new ImgTrace**(`opts?`)
10 |
11 | #### Parameters
12 |
13 | | Name | Type |
14 | | :------ | :------ |
15 | | `opts` | [`ImgTraceOption`](../../interfaces/svg_drawing_img_trace/ImgTraceOption.md) |
16 |
17 | #### Defined in
18 |
19 | [img-trace/src/trace.ts:200](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L200)
20 |
21 | ## Properties
22 |
23 | ### commandOmit
24 |
25 | • **commandOmit**: `number`
26 |
27 | #### Defined in
28 |
29 | [img-trace/src/trace.ts:193](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L193)
30 |
31 | ___
32 |
33 | ### ltres
34 |
35 | • **ltres**: `number`
36 |
37 | #### Defined in
38 |
39 | [img-trace/src/trace.ts:188](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L188)
40 |
41 | ___
42 |
43 | ### palettes
44 |
45 | • **palettes**: [`Rgba`](../../interfaces/svg_drawing_img_trace/Rgba.md)[]
46 |
47 | #### Defined in
48 |
49 | [img-trace/src/trace.ts:197](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L197)
50 |
51 | ___
52 |
53 | ### pathAttrs
54 |
55 | • **pathAttrs**: `PathObject`
56 |
57 | #### Defined in
58 |
59 | [img-trace/src/trace.ts:195](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L195)
60 |
61 | ___
62 |
63 | ### pathOmit
64 |
65 | • **pathOmit**: `number`
66 |
67 | #### Defined in
68 |
69 | [img-trace/src/trace.ts:192](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L192)
70 |
71 | ___
72 |
73 | ### qtres
74 |
75 | • **qtres**: `number`
76 |
77 | #### Defined in
78 |
79 | [img-trace/src/trace.ts:189](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L189)
80 |
81 | ___
82 |
83 | ### rightangleenhance
84 |
85 | • **rightangleenhance**: `boolean`
86 |
87 | #### Defined in
88 |
89 | [img-trace/src/trace.ts:190](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L190)
90 |
91 | ## Methods
92 |
93 | ### load
94 |
95 | ▸ **load**(`argImgd`): `Svg`
96 |
97 | #### Parameters
98 |
99 | | Name | Type |
100 | | :------ | :------ |
101 | | `argImgd` | `ImageData` |
102 |
103 | #### Returns
104 |
105 | `Svg`
106 |
107 | #### Defined in
108 |
109 | [img-trace/src/trace.ts:217](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/img-trace/src/trace.ts#L217)
110 |
--------------------------------------------------------------------------------
/packages/react/src/useDrawing.ts:
--------------------------------------------------------------------------------
1 | import { SvgDrawing, svgObjectToElement } from '@svg-drawing/core'
2 | import { useRef, useEffect, useCallback } from 'react'
3 | import type { UseSvgDrawing } from './types'
4 | import type { DrawingOption } from '@svg-drawing/core'
5 | import type { MutableRefObject } from 'react'
6 |
7 | export const useSvgDrawing = (
8 | option?: Partial
9 | ): [MutableRefObject, UseSvgDrawing] => {
10 | const renderRef = useRef(null)
11 | const drawingRef = useRef(null)
12 | const getSvgXML = useCallback(() => {
13 | if (!drawingRef.current) return null
14 | return svgObjectToElement(drawingRef.current.svg.toJson()).outerHTML
15 | }, [])
16 | const download = useCallback((opt) => {
17 | if (!drawingRef.current) return
18 | drawingRef.current.download(opt)
19 | }, [])
20 | const changePenColor = useCallback((param: DrawingOption['penColor']) => {
21 | if (!drawingRef.current || !param) return
22 | drawingRef.current.penColor = param
23 | }, [])
24 | const changeFill = useCallback((param: DrawingOption['fill']) => {
25 | if (!drawingRef.current || !param) return
26 | drawingRef.current.fill = param
27 | }, [])
28 | const changeDelay = useCallback((param: DrawingOption['delay']) => {
29 | if (!drawingRef.current || !param) return
30 | drawingRef.current.changeDelay(param)
31 | }, [])
32 | const changePenWidth = useCallback((param: DrawingOption['penWidth']) => {
33 | if (!drawingRef.current) return
34 | drawingRef.current.penWidth = Number(param)
35 | }, [])
36 | const changeClose = useCallback((param: DrawingOption['close']) => {
37 | if (!drawingRef.current) return
38 | drawingRef.current.close = param ?? false
39 | }, [])
40 | const changeCurve = useCallback((param: DrawingOption['curve']) => {
41 | if (!drawingRef.current) return
42 | drawingRef.current.curve = param ?? true
43 | }, [])
44 | const clear = useCallback(() => {
45 | if (!drawingRef.current) return
46 | drawingRef.current.clear()
47 | }, [])
48 | const undo = useCallback(() => {
49 | if (!drawingRef.current) return
50 | drawingRef.current.undo()
51 | }, [])
52 | useEffect(() => {
53 | if (drawingRef.current) return
54 | if (!renderRef.current) return
55 | drawingRef.current = new SvgDrawing(renderRef.current, {
56 | ...option,
57 | })
58 | })
59 |
60 | return [
61 | renderRef,
62 | {
63 | ref: drawingRef,
64 | changePenWidth,
65 | changePenColor,
66 | changeFill,
67 | changeDelay,
68 | changeClose,
69 | changeCurve,
70 | clear,
71 | undo,
72 | getSvgXML,
73 | download,
74 | },
75 | ]
76 | }
77 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // TODO: Add eslint-import-plugin
2 | // TODO: Separate TypeScript config
3 | // TODO: Separate test config
4 | module.exports = {
5 | env: {
6 | node: true,
7 | browser: true,
8 | commonjs: true,
9 | es6: true,
10 | },
11 | extends: [
12 | 'eslint:recommended',
13 |
14 | // import
15 | 'plugin:import/recommended',
16 | 'plugin:import/typescript',
17 |
18 | // react
19 | 'plugin:react/recommended',
20 | 'plugin:react-hooks/recommended',
21 | 'plugin:jsx-a11y/recommended',
22 |
23 | // TypeScript
24 | 'plugin:@typescript-eslint/recommended',
25 |
26 | // Test
27 | 'plugin:jest/recommended',
28 |
29 | // prettier
30 | 'plugin:prettier/recommended',
31 | 'prettier',
32 | ],
33 | parser: '@typescript-eslint/parser',
34 | settings: {
35 | react: {
36 | version: 'detect',
37 | },
38 | },
39 | rules: {
40 | strict: 'error',
41 | 'one-var': ['error', 'never'],
42 | 'check-constructor': 'off',
43 | 'no-comma-dangle': 'off',
44 | 'no-empty-interface': 'off',
45 | 'no-unused-vars': 'off',
46 |
47 | // import
48 | 'import/order': [
49 | 'warn',
50 | {
51 | groups: [
52 | 'builtin',
53 | 'external',
54 | 'internal',
55 | 'index',
56 | 'sibling',
57 | 'parent',
58 | 'object',
59 | 'type',
60 | ],
61 | alphabetize: {
62 | order: 'asc',
63 | caseInsensitive: true,
64 | },
65 | },
66 | ],
67 |
68 | // React
69 | 'react/jsx-uses-react': 'error',
70 | 'react/jsx-uses-vars': 'error',
71 | 'react/no-deprecated': 'error',
72 | 'react/display-name': 'off',
73 | 'react/prop-types': 'off',
74 | 'react/react-in-jsx-scope': 'off', // For Next.js
75 |
76 | 'react-hooks/rules-of-hooks': 'error',
77 | 'react-hooks/exhaustive-deps': 'warn',
78 |
79 | 'jsx-a11y/click-events-have-key-events': 'off',
80 | 'jsx-a11y/no-static-element-interactions': 'off',
81 | 'jsx-a11y/anchor-is-valid': 'off', // For Next.js
82 |
83 | // TypeScript
84 | '@typescript-eslint/no-explicit-any': 'off',
85 | '@typescript-eslint/explicit-function-return-type': 'off',
86 | '@typescript-eslint/explicit-module-boundary-types': 'off',
87 | '@typescript-eslint/no-use-before-define': 'off',
88 | '@typescript-eslint/no-unused-vars': 'off',
89 | '@typescript-eslint/ban-ts-comment': 'off',
90 | '@typescript-eslint/consistent-type-imports': [
91 | 'error',
92 | {
93 | prefer: 'type-imports',
94 | },
95 | ],
96 |
97 | // Test
98 | 'jest/no-done-callback': 'warn',
99 | },
100 | }
101 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # svg-drawing
2 |
3 | [](https://www.npmjs.com/package/svg-drawing) [](https://www.npmjs.com/package/svg-drawing) [](https://codecov.io/gh/kmkzt/svg-drawing)
4 |
5 | 
6 |
7 | `svg-drawing` is svg based drawing library.
8 |
9 | This is a **[demo](https://svg-drawing.vercel.app)**.
10 | [Code](./examples/demo). [Documents](./docs/packages/modules.md)
11 |
12 |
13 | This project has moved to monorepo. If you want to use the previous version, please use [here](https://github.com/kmkzt/svg-drawing/tree/v3.0.0).
14 |
15 | ## Getting Started
16 |
17 | ### npm
18 |
19 | ```shell
20 | npm i @svg-drawing/core
21 | # or
22 | yarn add @svg-drawing/core
23 | ```
24 |
25 | ```javascript
26 | import { SvgDrawing } from '@svg-drawing/core'
27 |
28 | const el = document.createElement('div')
29 |
30 | // Drawing area will be resized to fit the rendering area
31 | el.setAttribute(
32 | 'style',
33 | `
34 | border: 1px solid #ddd;
35 | width: 500px;
36 | height: 500px;
37 | `
38 | )
39 | document.body.appendChid(el)
40 | new SvgDrawing(el)
41 | ```
42 |
43 | ### CDN
44 |
45 | ```html
46 |
47 |
48 |
49 |
52 | ```
53 |
54 | **[Here](./examples/html)** is an example for Html only.
55 |
56 | ## Packages
57 |
58 | | Packages | Description |
59 | | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
60 | | [@svg-drawing/core](./packages/core) | Core Module |
61 | | [@svg-drawing/animation](./packages/animation) | Animate the drawn Svg. Can be animations using `JavaScript` or `` |
62 | | [@svg-drawing/img-trace](./packages/img-trace) | Image(png/jpg) convert Svg. |
63 | | [@svg-drawing/react](./packages/react) | For React. |
64 |
--------------------------------------------------------------------------------
/packages/core/src/download.ts:
--------------------------------------------------------------------------------
1 | import { svgObjectToElement } from './renderer'
2 | import type { Svg } from './svg'
3 | import type { DownloadOption, SvgObject } from './types'
4 |
5 | export const toBase64 = (svgObj: SvgObject): string => {
6 | return svg2base64(svgObjectToElement(svgObj).outerHTML)
7 | }
8 |
9 | export const svg2base64 = (svg: string): string =>
10 | `data:image/svg+xml;base64,${btoa(svg)}`
11 |
12 | export const mimeTypeMap: { [key in DownloadOption['extension']]: string } = {
13 | png: 'image/png',
14 | jpg: 'image/jpeg',
15 | svg: 'image/svg+xml',
16 | } as const
17 |
18 | export const downloadBlob = ({
19 | data,
20 | extension,
21 | filename,
22 | }: {
23 | data: string
24 | extension: keyof typeof mimeTypeMap
25 | filename?: string
26 | }): void => {
27 | const bin = atob(data.replace(/^.*,/, ''))
28 | const buffer = new Uint8Array(bin.length)
29 | for (let i = 0; i < bin.length; i += 1) {
30 | buffer[i] = bin.charCodeAt(i)
31 | }
32 | const fname = filename || `${Date.now()}.${extension}`
33 | const blob = new Blob([buffer.buffer], {
34 | type: mimeTypeMap[extension],
35 | })
36 | if ((window.navigator as any).msSaveBlob) {
37 | // IE
38 | ;(window.navigator as any).msSaveBlob(blob, fname)
39 | } else if (window.URL && window.URL.createObjectURL) {
40 | // Firefox, Chrome, Safari
41 | const a = document.createElement('a')
42 | a.download = fname
43 | a.href = window.URL.createObjectURL(blob)
44 | document.body.appendChild(a)
45 | a.click()
46 | document.body.removeChild(a)
47 | } else {
48 | // Other
49 | window.open(data, '_blank')
50 | }
51 | }
52 |
53 | const defaultOpts: DownloadOption = {
54 | extension: 'svg',
55 | }
56 | // TODO: Add filename config
57 | export const download = (
58 | svg: Svg,
59 | opt: DownloadOption = defaultOpts,
60 | dlb: typeof downloadBlob = downloadBlob
61 | ): void => {
62 | const { filename, extension: ext } = { ...defaultOpts, ...opt }
63 | const base64 = toBase64(svg.toJson())
64 | if (ext === 'svg') {
65 | dlb({
66 | data: base64,
67 | extension: 'svg',
68 | filename,
69 | })
70 | return
71 | }
72 |
73 | const { width, height, background } = svg
74 | const img: any = new Image()
75 | const renderCanvas = () => {
76 | const canvas = document.createElement('canvas')
77 | canvas.setAttribute('width', String(width))
78 | canvas.setAttribute('height', String(height))
79 | const ctx = canvas.getContext('2d')
80 | if (!ctx) return
81 | if (background || ext === 'jpg') {
82 | ctx.fillStyle = background || '#fff'
83 | ctx.fillRect(0, 0, width, height)
84 | }
85 | ctx.drawImage(img, 0, 0)
86 | if (ext === 'png') {
87 | dlb({ data: canvas.toDataURL('image/png'), extension: 'png' })
88 | } else {
89 | dlb({ data: canvas.toDataURL('image/jpeg'), extension: 'jpg' })
90 | }
91 | }
92 | img.addEventListener('load', renderCanvas, false)
93 | img.src = base64
94 | }
95 |
--------------------------------------------------------------------------------
/examples/react/config/theme.ts:
--------------------------------------------------------------------------------
1 | // https://github.com/rebassjs/rebass/blob/master/packages/preset/src/index.js
2 | export default {
3 | colors: {
4 | text: '#000',
5 | background: '#fff',
6 | primary: '#07c',
7 | secondary: '#30c',
8 | muted: '#f6f6f9',
9 | gray: '#dddddf',
10 | highlight: 'hsla(205, 100%, 40%, 0.125)',
11 | },
12 | fonts: {
13 | body: 'system-ui, sans-serif',
14 | heading: 'inherit',
15 | monospace: 'Menlo, monospace',
16 | },
17 | fontSizes: [12, 14, 16, 20, 24, 32, 48, 64, 96],
18 | fontWeights: {
19 | body: 400,
20 | heading: 700,
21 | bold: 700,
22 | },
23 | lineHeights: {
24 | body: 1.5,
25 | heading: 1.25,
26 | },
27 | space: [0, 4, 8, 16, 32, 64, 128, 256, 512],
28 | sizes: {
29 | avatar: 48,
30 | },
31 | radii: {
32 | default: 4,
33 | circle: 99999,
34 | },
35 | shadows: {
36 | card: '0 0 4px rgba(0, 0, 0, .125)',
37 | },
38 | // rebass variants
39 | text: {
40 | heading: {
41 | fontFamily: 'heading',
42 | lineHeight: 'heading',
43 | fontWeight: 'heading',
44 | },
45 | display: {
46 | fontFamily: 'heading',
47 | fontWeight: 'heading',
48 | lineHeight: 'heading',
49 | fontSize: [5, 6, 7],
50 | },
51 | caps: {
52 | textTransform: 'uppercase',
53 | letterSpacing: '0.1em',
54 | },
55 | },
56 | variants: {
57 | avatar: {
58 | width: 'avatar',
59 | height: 'avatar',
60 | borderRadius: 'circle',
61 | },
62 | card: {
63 | p: 2,
64 | bg: 'background',
65 | boxShadow: 'card',
66 | },
67 | link: {
68 | color: 'primary',
69 | },
70 | nav: {
71 | fontSize: 1,
72 | fontWeight: 'bold',
73 | display: 'inline-block',
74 | p: 2,
75 | color: 'inherit',
76 | textDecoration: 'none',
77 | ':hover,:focus,.active': {
78 | color: 'primary',
79 | },
80 | },
81 | },
82 | buttons: {
83 | primary: {
84 | fontSize: 1,
85 | fontWeight: 'bold',
86 | color: 'background',
87 | bg: 'primary',
88 | borderRadius: 'default',
89 | },
90 | outline: {
91 | variant: 'buttons.default',
92 | color: 'primary',
93 | bg: 'transparent',
94 | boxShadow: 'inset 0 0 2px',
95 | },
96 | secondary: {
97 | variant: 'buttons.default',
98 | color: 'background',
99 | bg: 'secondary',
100 | },
101 | },
102 | styles: {
103 | root: {
104 | fontFamily: 'body',
105 | fontWeight: 'body',
106 | lineHeight: 'body',
107 | },
108 | },
109 | // https://rebassjs.org/forms/#theming
110 | forms: {
111 | input: {
112 | p: 1,
113 | },
114 | select: {
115 | borderRadius: 9999,
116 | },
117 | textarea: {},
118 | label: {
119 | width: 'auto',
120 | fontSize: 0,
121 | },
122 | radio: {},
123 | checkbox: {},
124 | },
125 | }
126 |
--------------------------------------------------------------------------------
/docs/packages/classes/svg_drawing_core/Point.md:
--------------------------------------------------------------------------------
1 | # Class: Point
2 |
3 | [@svg-drawing/core](../../modules/svg_drawing_core.md).Point
4 |
5 | ## Constructors
6 |
7 | ### constructor
8 |
9 | • **new Point**(`x`, `y`)
10 |
11 | #### Parameters
12 |
13 | | Name | Type |
14 | | :------ | :------ |
15 | | `x` | `number` |
16 | | `y` | `number` |
17 |
18 | #### Defined in
19 |
20 | [core/src/svg.ts:7](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/svg.ts#L7)
21 |
22 | ## Properties
23 |
24 | ### x
25 |
26 | • **x**: `number`
27 |
28 | #### Defined in
29 |
30 | [core/src/svg.ts:5](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/svg.ts#L5)
31 |
32 | ___
33 |
34 | ### y
35 |
36 | • **y**: `number`
37 |
38 | #### Defined in
39 |
40 | [core/src/svg.ts:6](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/svg.ts#L6)
41 |
42 | ## Methods
43 |
44 | ### add
45 |
46 | ▸ **add**(`p`): [`Point`](Point.md)
47 |
48 | #### Parameters
49 |
50 | | Name | Type |
51 | | :------ | :------ |
52 | | `p` | [`Point`](Point.md) |
53 |
54 | #### Returns
55 |
56 | [`Point`](Point.md)
57 |
58 | #### Defined in
59 |
60 | [core/src/svg.ts:22](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/svg.ts#L22)
61 |
62 | ___
63 |
64 | ### clone
65 |
66 | ▸ **clone**(): [`Point`](Point.md)
67 |
68 | #### Returns
69 |
70 | [`Point`](Point.md)
71 |
72 | #### Defined in
73 |
74 | [core/src/svg.ts:34](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/svg.ts#L34)
75 |
76 | ___
77 |
78 | ### eql
79 |
80 | ▸ **eql**(`p`): `boolean`
81 |
82 | #### Parameters
83 |
84 | | Name | Type |
85 | | :------ | :------ |
86 | | `p` | [`Point`](Point.md) |
87 |
88 | #### Returns
89 |
90 | `boolean`
91 |
92 | #### Defined in
93 |
94 | [core/src/svg.ts:30](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/svg.ts#L30)
95 |
96 | ___
97 |
98 | ### scale
99 |
100 | ▸ **scale**(`r`): [`Point`](Point.md)
101 |
102 | #### Parameters
103 |
104 | | Name | Type |
105 | | :------ | :------ |
106 | | `r` | `number` |
107 |
108 | #### Returns
109 |
110 | [`Point`](Point.md)
111 |
112 | #### Defined in
113 |
114 | [core/src/svg.ts:18](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/svg.ts#L18)
115 |
116 | ___
117 |
118 | ### sub
119 |
120 | ▸ **sub**(`p`): [`Point`](Point.md)
121 |
122 | #### Parameters
123 |
124 | | Name | Type |
125 | | :------ | :------ |
126 | | `p` | [`Point`](Point.md) |
127 |
128 | #### Returns
129 |
130 | [`Point`](Point.md)
131 |
132 | #### Defined in
133 |
134 | [core/src/svg.ts:26](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/svg.ts#L26)
135 |
136 | ___
137 |
138 | ### toVector
139 |
140 | ▸ **toVector**(): [`Vector`](Vector.md)
141 |
142 | #### Returns
143 |
144 | [`Vector`](Vector.md)
145 |
146 | #### Defined in
147 |
148 | [core/src/svg.ts:12](https://github.com/kmkzt/svg-drawing/blob/c168ec0/packages/core/src/svg.ts#L12)
149 |
--------------------------------------------------------------------------------
/packages/img-trace/src/imgloader.ts:
--------------------------------------------------------------------------------
1 | interface ImgLoaderOption {
2 | corsenabled: boolean
3 | }
4 |
5 | export class ImgLoader {
6 | public corsenabled: boolean
7 |
8 | constructor(options: Partial) {
9 | this.corsenabled = options.corsenabled ?? true
10 | }
11 |
12 | // TODO: improve types.
13 | // if exists callback, return void. if not existed callback, return Promise.
14 | public fromUrl(
15 | url: string,
16 | callback?: (imgd: ImageData) => void
17 | ): void | Promise {
18 | // TODO: cors improve
19 | // const xhr = new XMLHttpRequest()
20 | // xhr.responseType = 'blob'
21 | // xhr.open('GET', url, true)
22 | // xhr.onload = function() {
23 | // const img = new Image()
24 | // img.onload = function() {
25 | // this.loadImageElement(img, callback)
26 | // }
27 | // img.onerror = (err: any) => {
28 | // console.log(err)
29 | // }
30 | // console.log(this.response)
31 |
32 | // img.src = URL.createObjectURL(this.response)
33 | // }
34 | // xhr.onerror = (err: any) => console.log(err)
35 | // xhr.send(null)
36 | const load = (
37 | resolve: (imgd: ImageData) => void,
38 | reject?: (a: any) => void
39 | ) => {
40 | const img = new Image()
41 | if (this.corsenabled) {
42 | img.crossOrigin = 'Anonymous'
43 | }
44 | img.onload = () => {
45 | this.fromImageElement(img, resolve)
46 | }
47 | img.onerror = (err: any) => {
48 | if (reject) {
49 | reject(err)
50 | } else {
51 | console.error(err)
52 | }
53 | }
54 | img.src = url
55 | }
56 | if (callback) {
57 | load(callback)
58 | } else {
59 | return new Promise(load)
60 | }
61 | }
62 |
63 | // TODO: improve types.
64 | // if exists callback, return void. if not existed callback, return Promise.
65 | public fromImageElement(
66 | img: HTMLImageElement,
67 | callback?: (imgd: ImageData) => void
68 | ): Promise | void {
69 | const load = (
70 | resolve: (imgd: ImageData) => void,
71 | reject?: (a: any) => void
72 | ) => {
73 | const canvas = document.createElement('canvas')
74 | canvas.width = img.naturalWidth || img.width
75 | canvas.height = img.naturalHeight || img.height
76 | const context = canvas.getContext('2d')
77 | context?.drawImage(img, 0, 0)
78 | const imgd: ImageData | undefined = context?.getImageData(
79 | 0,
80 | 0,
81 | canvas.width,
82 | canvas.height
83 | )
84 | if (!imgd) {
85 | if (reject) {
86 | reject('error canvas context.')
87 | return
88 | } else {
89 | throw 'error canvas context.'
90 | }
91 | }
92 | resolve(imgd)
93 | }
94 | if (callback) {
95 | load(callback)
96 | } else {
97 | return new Promise(load)
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/packages/react/README.md:
--------------------------------------------------------------------------------
1 | # `@svg-drawing/react`
2 |
3 | [](https://www.npmjs.com/package/@svg-drawing/react) [](https://www.npmjs.com/package/@svg-drawing/react)
4 |
5 | ## Get started
6 |
7 | ```shell
8 | yarn add react @svg-drawing/react
9 | ```
10 |
11 | ## How to use
12 |
13 | Example code is [here](/examples/demo/pages/react.tsx)
14 |
15 | This is example.
16 |
17 | ```javascript
18 | import React from 'react'
19 | import { useSvgDrawing } from '@svg-drawing/react'
20 |
21 | const Drawing = () => {
22 | const [renderRef, draw] = useSvgDrawing()
23 | // Drawing area will be resized to fit the rendering area
24 | return
25 | }
26 | ```
27 |
28 | useSvgDrawing options.
29 |
30 | ```javascript
31 | const [renderRef, draw] = useSvgDrawing({
32 | penWidth: 10, // pen width
33 | penColor: '#e00', // pen color
34 | close: true, // Use close command for path. Default is false.
35 | curve: false, // Use curve command for path. Default is true.
36 | delay: 60, // Set how many ms to draw points every.
37 | fill: '', // Set fill attribute for path. default is `none`
38 | })
39 | ```
40 |
41 | Drawing methods.
42 |
43 | ```javascript
44 | // svg-drawing hooks
45 | const [renderRef, draw] = useSvgDrawing()
46 |
47 | // Call the SvgDrawing. Access the current settings of penWidth, penColor etc
48 | // Details are https://github.com/kmkzt/svg-drawing/tree/master/packages/core.
49 | const logger = useCallback(() => {
50 | if (!draw.ref.current) return
51 | console.log(draw.ref.current.penColor) // #333
52 | console.log(draw.ref.current.penWidth) // 1
53 | }, [])
54 |
55 | // Erase all drawing.
56 | return
57 | // Undo drawing.
58 | return
59 |
60 | // Download image.
61 | const handleDownload = useCallback(() => {
62 | draw.download() // default svg download
63 | draw.download({ extension: 'svg', filename: 'a.svg'})
64 | draw.download({ extension: 'png', filename: 'b.png'})
65 | draw.download({ extension: 'jpg', filename: 'c.jpg'})
66 | }, [draw.download])
67 |
68 | // Chage parameter
69 | const handleChangeParameter = useCallback(() => {
70 | // Change pen config
71 | draw.changePenColor('#00b')
72 | // Change pen width
73 | draw.changePenWidth(10)
74 | // Change fill attribure of svg path element.
75 | draw.changFill('#00b')
76 | // Change throttle delay of drawing
77 | draw.changeDelay(10)
78 | // Set whether to use curved comma for svg path element.
79 | draw.changCurve(false)
80 | // Set whether to use curved comma for svg path element.
81 | draw.changeClose(true)
82 | }, [draw])
83 |
84 | // get svgXML
85 | // return SVGElement
86 | const loggerXML = useCallback(() => {
87 | console.log(draw.getSvgXML()) //