diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..ce50cb6 --- /dev/null +++ b/.npmignore @@ -0,0 +1,3 @@ +* +# npmignore +!src/lib/**/* diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..63b4b68 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [year] [fullname] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index e5f733e..1e7fc8c 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,63 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). +# react-konva-to-svg -## Getting Started +**Extend Konva's functionality to export stages as SVG. Enhance the quality of exported images with SVG format.** -First, run the development server: +[![GitHub License](https://img.shields.io/github/license/dendrofen/react-konva-to-svg)](LICENSE) -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -``` +## Features + +- Export Konva stages to SVG format. +- Asynchronous export with progress tracking. +- Before and after export callbacks for custom processing. +- Flexible context with a function that handles Konva stage objects. +- Export results as text SVG or Blob SVG. + +## Table of Contents + +- [Installation](#installation) +- [Usage](#usage) +- [Example](#example) +- [Demo](#demo) +- [Contributing](#contributing) +- [License](#license) -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. +## Installation -You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. +You can install `react-konva-to-svg` using npm, yarn, or directly from GitHub. -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. +- **npm**: `npm install react-konva-to-svg` +- **yarn**: `yarn add react-konva-to-svg` +- **GitHub**: [GitHub Repository](https://github.com/dendrofen/react-konva-to-svg) -## Learn More +## Usage -To learn more about Next.js, take a look at the following resources: +To use `react-konva-to-svg`, import the library and utilize the `exportStageSVG` function with your Konva stage object. This function allows you to customize the export process. -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. +### `exportStageSVG(stage, blob, options)` -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! +- `stage`: The Konva stage object you want to export. +- `blob` (optional): Set to `true` to export as Blob SVG, or `false` (default) to export as text SVG. +- `options` (optional): An object containing the following callbacks: + - `onBefore`: A callback function called before export. Receives an array `[stage, layer]` as an argument. + - `onAfter`: A callback function called after export. Receives an array `[stage, layer]` as an argument. -## Deploy on Vercel +**Example usage:** + +```javascript +import { exportStageSVG } from 'react-konva-to-svg'; + +// Example usage +const stage = /* your Konva stage */; +const result = await exportStageSVG(stage, false, { + onBefore: ([stage, layer]) => { + // Perform actions before export + }, + onAfter: ([stage, layer]) => { + // Perform actions after export + }, +}); +``` -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. +## Demo -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. +Explore a live demo of react-konva-to-svg in action: [Demo](https://dendrofen.github.io/react-konva-to-svg/) \ No newline at end of file diff --git a/next.config.js b/next.config.js index 9c3cfe9..73e325b 100644 --- a/next.config.js +++ b/next.config.js @@ -2,7 +2,7 @@ const nextConfig = { output: 'export', - basePath: '/konva-react-to-svg', + basePath: '/react-konva-to-svg', images: { unoptimized: true, }, diff --git a/package.json b/package.json index 93e420c..e6b3179 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,27 @@ { "name": "react-konva-to-svg", - "version": "0.1.0", + "version": "1.0.0", "private": false, + "keywords": [ + "react-konva", + "react-konva-components", + "react-konva-utils", + "react-konva-export", + "canvas-api", + "svg-canvas", + "react-konva-to-svg", + "canvas", + "svg", + "konva" + ], + "description": "Extend Konva's functionality to export stages as SVG. Enhance the quality of exported images with SVG format.", + "author": "dendrofen", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/dendrofen/react-konva-to-svg.git" + }, + "homepage": "https://dendrofen.github.io/react-konva-to-svg/", "scripts": { "dev": "next dev", "build": "next build", @@ -9,13 +29,19 @@ "lint": "next lint" }, "dependencies": { + "react": "^18.2.0", + "konva": "^9.2.0", + "react-konva": "^18.2.10", + "svgcanvas": "^2.5.0" + }, + "devDependencies": { "eslint": "8.46.0", "eslint-config-next": "13.4.13", "konva": "^9.2.0", "next": "13.4.13", - "react": "18.2.0", + "react": "^18.2.0", "react-dom": "18.2.0", "react-konva": "^18.2.10", "svgcanvas": "^2.5.0" } -} +} \ No newline at end of file diff --git a/src/app/page.js b/src/app/page.js index c553b39..7344b43 100644 --- a/src/app/page.js +++ b/src/app/page.js @@ -21,7 +21,7 @@ export default function Home() { color="#fff" viewBox="0 0 250 250" style={{ position: "absolute", top: "0", border: "0", right: "0" }} - ariaHidden="true" + aria-hidden="true" > } A Promise that resolves after sleeping. + */ export const sleep = async (time) => new Promise(resolve => setTimeout(resolve, time)); +/** + * Exports the SVG representation of a Konva stage. + * @param {Stage} stage - The Konva stage to export. + * @param {boolean} [blob=false] - Whether to return a Blob object instead of a string. + * @param {Object} [options] - Additional options. + * @param {Function} [options.onBefore] - A callback function to execute before exporting. + * @param {Function} [options.onAfter] - A callback function to execute after exporting. + * @returns {string|Blob} The SVG data or a Blob object. + */ export async function exportStageSVG(stage, blob = false, { onBefore, onAfter } = {}) { + // Get the first layer of the stage const layer = stage.getLayers()[0]; + // Call the 'onBefore' callback function if provided, passing in the stage and layer onBefore && onBefore([stage, layer]); + // Asynchronously sleep for 200 milliseconds await sleep(200); + // Create a new context for rendering the SVG const oldContext = layer.canvas.context._context; const c2s = layer.canvas.context._context = new Context({ height: stage.height(), @@ -16,17 +34,27 @@ export async function exportStageSVG(stage, blob = false, { onBefore, onAfter } ctx: oldContext }); + // Draw the stage on the new context stage.draw(); + // Get the serialized SVG data let out = c2s.getSerializedSvg(); + + // If 'blob' is true, create a Blob object with the SVG data and specify the MIME type out = blob ? new Blob([out], { type: "image/svg+xml;charset=utf-8" }) : out; + // Restore the original context layer.canvas.context._context = oldContext; - onAfter && onAfter([stage, layer]) + // Call the 'onAfter' callback function if provided, passing in the stage and layer + onAfter && onAfter([stage, layer]); + + // Asynchronously sleep for 200 milliseconds await sleep(200); + // Redraw the stage stage.draw(); + // Return the SVG data or Blob object return out; -} \ No newline at end of file +}