# elice-canvas-plugin

> Neo smart pen app of Elice platform.

Latest version **0.231227.0** (published 2023-12-27) · UNLICENSED license · 0 weekly downloads

## Install

```sh
npm install elice-canvas-plugin
pnpm add elice-canvas-plugin
yarn add elice-canvas-plugin
bun add elice-canvas-plugin
```

## Health

**Score 25/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities.

Warnings: low downloads; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.231227.0 |
| Published | 2023-12-27 |
| First published | 2023-12-27 |
| Weekly downloads | 0 |
| License | UNLICENSED |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | ~20.5 |
| Dependencies | 7 |
| Unpacked size | 64.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Elice |
| Maintainers | vsnm25 |

## Links

- npm: https://www.npmjs.com/package/elice-canvas-plugin
- npm.io page: https://npm.io/package/elice-canvas-plugin

## Dependencies (7)

- [konva](https://npm.io/package/konva.md) ^9.2.3
- [tslib](https://npm.io/package/tslib.md) ^2.6.2
- [zustand](https://npm.io/package/zustand.md) ^4.4.7
- [lodash-es](https://npm.io/package/lodash-es.md) ^4.17.21
- [react-use](https://npm.io/package/react-use.md) ^17.4.2
- [web_pen_sdk](https://npm.io/package/web_pen_sdk.md) ^0.6.9
- [web_view_sdk_test](https://npm.io/package/web_view_sdk_test.md) ^2.5.8

## Recent versions

- 0.231227.0 (latest) — 2023-12-27

## README

# Elice-canvas-plugin

Elice-canvas-plugin is a canvas drawing library that makes it easier and faster to implement handwriting on the web.

Initially, we will use the [web_pen_sdk](https://github.com/neostudio-team/webPenSDK) to implement pen drawing, but we will enhance it to implement features with other handwriting tools.

## Getting Started
This example is how to use the libraries in your app. And you need to create instance.

<details>
  <summary><strong>Core</strong> basic usage</summary>

  ### HTML
  First create new html file and add elements which include container. Default id is set to `elice-smart-pen-container` and if you want to customize then set container option in `EliceSmartPen`.
  ```html
  <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Elice Smart Pen - Core</title>
</head>
<body>
    <header>
        <h3>Elice Smart Pen</h1>
        <button id="pen-connection" type="button">펜 연결하기</button>
    </header>
    <div id="elice-smart-pen-container"></div>
</body>
</html>
  ```

  ### Script
  Add script tag which import plugin module. After import module you can initialize plugin by `init` method in instance.
  ```html
  <script type="module">
      import { EliceSmartPen } from 'elice-canvas-plugin';

      const eliceSmartPen = new EliceSmartPen();
      eliceSmartPen.init();
  </script>
  ```

  ### Event & Subscribe
  This example codes are placed in script tag where you import plugin. So first you need to add pen connection handler at element. 
  ```typescript
const penConnectionButton = document.getElementById("pen-connection");
penConnectionButton?.addEventListener("click", () => {
  void eliceSmartPen.togglePenConnection(true);
});
  ```

  Then you need to subscribe instance store state to detect pen controller is created. If controller is created, you can create new drawing canvas by `createDrawingStage` method.
  ```typescript
  eliceSmartPen.store.subscribe((current, prev) => {
  if (current.penController !== prev.penController) {
    const isConnected = Boolean(current.penController);

    if (penConnectionButton) {
      penConnectionButton.innerText = isConnected
        ? "펜 연결중"
        : "펜 연결하기";
    }

    if (current.penController) {
      eliceSmartPen.createDrawingStage();
    }
  }
});
  ```

  You can simply add event listeners by `on` method.
  ```typescript
  eliceSmartPen.on(EliceSmartPenEvents.PenUp, () => {
    localStorage.setItem("saved-drawing", eliceSmartPen.extractDrawingStage('json'));
  });
  eliceSmartPen.on(EliceSmartPenEvents.NeoPUI, (_, payload) => {
    alert(`This is Neo pen PUI data\n${JSON.stringify(payload)}`);
  });
  ```
  
</details>

<details>
  <summary><strong>React</strong> basic usage</summary>

  ### Provider
  You need to pass instance as prop at `EliceSmartPenProvider`. It automatically call `init` method in instance. Finally you can use helpful hooks `useEliceSmartPen` and `useEliceSmartPenState` in Component.

  ```tsx
import { useState } from 'react';
import { EliceSmartPen, EliceSmartPenProvider } from "elice-canvas-plugin";

function App() {
  const [eliceSmartPen] = useState(() => new EliceSmartPen());

  return (
    <EliceSmartPenProvider eliceSmartPen={eliceSmartPen}>
      <Tool/>
      <Note/>
    </EliceSmartPenProvider>
  );
}

export default App;
```

  ### Hooks
  This plugin provide `useEliceSmartPen`, `useEliceSmartPenState` hooks. `useEliceSmartPen` returns instance that provide properties and method of canvas core logics. `useEliceSmartPenState` returns states in instance store. You can use this states to create on demand ui, effects, message events.

  ```tsx
import React from 'react';
import { useEliceSmartPen, useEliceSmartPenState, EliceSmartPenEvents } from "elice-canvas-plugin";

  function Tool() {
    const eliceSmartPen = useEliceSmartPen();
    const penController = useEliceSmartPenState((state => state.penController));

    const handlePenConnection = () => {
        eliceSmartPen.togglePenConnection(true);
    }

    // create drawing
    React.useEffect(() => {
        if(!penController){
            return;
        }

        eliceSmartPen.createDrawingStage();
    }, [penController]);

    React.useEffect(() => {
        // add listeners.
        eliceSmartPen.on(
        EliceSmartPenEvents.PenUp,
        (eliceSmartPen) => {
            console.log('Pen-up event is fired.');
        },
        );

        return () => {
            // remove listeners.
            eliceSmartPen.off(EliceSmartPenEvents.PenUp);
        }
    }, []);

    return (
        <div>
            <button onClick={handlePenConnection}>penController ? Connected : Connect</button>
        </div>
    )
}

  export default Tool;
  ```

  ### Container
  Basically, this plugin find container by [getElementById](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById). By default it set to `elice-smart-pen-container` and also you can customize it. If container is not found, document body is set to container of drawing canvas. Canvas is basically set to `absolute` position, so you have to set `relative` position at container.

  ```tsx
import { ELICE_SMART_PEN_CONTAINER } from "elice-canvas-plugin";

  function Note() {
    return (
      <div
        id={ELICE_SMART_PEN_CONTAINER}
        style={{ position: "relative", width: "30rem", aspectRatio: 1 }}
      />
    )
  }

  export default Note;
  ```
</details>


## Demos

All demos located in `./playground` folder. There you will find Core (HTML, JS), React versions.

To open demo, run:

### `yarn core`

Runs the playground which implement with `core`.
Open [http://localhost:3120](http://localhost:3120) to view it in your browser.

### `yarn react`

Runs the playground which implement with `core` and `react`.
Open [http://localhost:3121](http://localhost:3121) to view it in your browser.

## Core
All features are based on `EliceSmartPen`. You need to initialize it and optionally set configuration.

### Methods & Properties
After you initialize `EliceSmartPen`, you have initialized instance in variable with helpful methods and properties:

| properties |                  type                 |   |
|------------|-----------------------------------|---|
| store      |  StoreApi<EliceSmartPenState\>  |  State manager which used zustand.  |
| options    |  EliceSmartPenOptions  |  Initial configuration.  |

You can see `store` detail information in [here](https://git.elicer.io/elice/frontend/library/elice-canvas-plugin/-/blob/feat/IP-934_neo_pen/src/core/store/README.md).

| methods             |     type                                                                                                                                                 |     |
|---------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|---|
| init                |  () => void  |  Initialize configuration of pen, drawing, store.                                                                                                     |
| togglePenConnection |  (value) => Promise<void> | Connect or disconnect pen.                                                                                                                            |
| readDrawingStage    |  (drawing) => void  |Redraw passed drawing stage.                                                                                                                         |
| createDrawingStage  |  () => void  | Create new drawing stage.                                                                                                                            |
| extractDrawingStage |  () => string  |  Extract drawing stage result that formatted by json.                                                                                                 |
| clearDrawingStage   |  () => void   |  Clear drawing in current stage.                                                                                                                      |
| scanDrawingStage    |  () => Promise<void>   |Scan drawing stage to find overlapped drawings on inputs. Those drawings are converted to text which implement by ocr and set value of target input. |
| on               |  (event, callback) => void  | Add event at event stack.                                                                                                                        |
| off              |  (event) => void  |  Remove event which stored in event stack.                                                                                                        |

## React
If you use react, you can use those helpful hooks.
Before you use those hooks, you must wrap your app or page component with `EliceSmartPenProvider`.

| hooks                 |                                                 |
|-----------------------|-------------------------------------------------|
| useEliceSmartPen      | React hooks that return EliceSmartPen instance. |
| useEliceSmartPenStore | React hooks that return states in store.        |

## Event
We support extra helpful custom events. For performance, this listeners are bind with debounce. You can get event types from enum `EliceSmartPenEvents`.

| Event | type                             |                                                                  |
|-------|----------------------------------|------------------------------------------------------------------|
| PenUp  | (eliceSmartPen) => void | This event is fired when last of Pen_UP event callback is fired. |
| NeoPUI | (eliceSmartPen, payload) => void          | This event is fired when you point ncode data in note.     |

---
_Source: https://npm.io/package/elice-canvas-plugin · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
