├── .gitignore
├── .nvmrc
├── .prettierrc
├── LICENSE
├── README.md
├── babel.config.js
├── example
├── README.md
├── package-lock.json
├── package.json
├── public
│ ├── _redirects
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src
│ ├── App.js
│ ├── demo1
│ ├── demo.js
│ ├── demo.svg
│ └── demoProps.js
│ ├── demo2
│ ├── demo.js
│ ├── demo.svg
│ └── params.js
│ ├── demo3
│ ├── demo.js
│ ├── demo.svg
│ └── utils.js
│ ├── index.css
│ ├── index.js
│ └── links.js
├── netlify.toml
├── package-lock.json
├── package.json
├── src
├── index.js
└── shapes.js
└── test
├── __snapshots__
└── point.test.js.snap
└── point.test.js
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # See https://help.github.com/ignore-files/ for more about ignoring files.
3 |
4 | # dependencies
5 | node_modules
6 |
7 | # builds
8 | build
9 | dist
10 | .rpt2_cache
11 |
12 | # misc
13 | .DS_Store
14 | .env
15 | .env.local
16 | .env.development.local
17 | .env.test.local
18 | .env.production.local
19 |
20 | npm-debug.log*
21 | yarn-debug.log*
22 | yarn-error.log*
23 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v12.18.0
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "jsxSingleQuote": true,
4 | "semi": false,
5 | "tabWidth": 2,
6 | "bracketSpacing": true,
7 | "jsxBracketSameLine": false,
8 | "arrowParens": "always",
9 | "trailingComma": "none"
10 | }
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Mithi Sevilla
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # A Bare Minimum 2D Plotter
2 |
3 | > An extremely lightweight React component to declaratively (and elegantly) plot shapes on an inline SVG
4 |
5 | [](https://www.npmjs.com/package/bare-minimum-2d)
6 | [](https://bundlephobia.com/result?p=bare-minimum-2d@0.2.0)
7 | [](https://bundlephobia.com/result?p=bare-minimum-2d@0.2.0)
8 |
9 | ## Update: External Plugins 🥳
10 | You can now use your own shape implementation by passing it as a plugin (see [plugin section](./README.md#plugins) below for more information).
11 | Below are a couple of plugins by [@fuddl](https://github.com/fuddl).
12 |
13 | * [`text-marker`](https://www.npmjs.com/package/bare-minimum-text-marker) ([Demo](https://fuddl.github.io/bare-minimum-text-marker/))
14 | * [`quadratic-bezier`](https://www.npmjs.com/package/bare-minimum-quadratic-bezier) ([Demo](https://fuddl.github.io/bare-minimum-quadratic-bezier/))
15 |
16 | ## Demo Applications
17 |
18 | | Responsive Illustrations | On-The-Fly Animations | Interactive Applications |
19 | | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
20 | | [][demo_link1] | [][demo_link2] | [][demo_link3] |
21 | | [demo][demo_link1] | [demo][demo_link2] | [demo][demo_link3] |
22 | | [source code][source_link1] | [source code][source_link2] | [source code][source_link3] |
23 |
24 | [demo_link1]: https://bare-minimum-2d.netlify.app/demo1
25 | [demo_link2]: https://bare-minimum-2d.netlify.app/demo2
26 | [demo_link3]: https://bare-minimum-2d.netlify.app/demo3
27 | [source_link1]: https://github.com/mithi/bare-minimum-2d/blob/master/example/src/demo1/demo.js
28 | [source_link2]: https://github.com/mithi/bare-minimum-2d/blob/master/example/src/demo2/demo.js
29 | [source_link3]: https://github.com/mithi/bare-minimum-2d/blob/master/example/src/demo3/demo.js
30 |
31 | ## Install
32 |
33 | ```bash
34 | npm install --save bare-minimum-2d
35 | ```
36 |
37 | ## Usage
38 |
39 | This is [an example](./example/src/demo1/demoProps.js) of what you can pass to a `BareMinimum2d` component.
40 |
41 | You pass it like so:
42 |
43 | ```jsx
44 | import BareMinimum2d from 'bare-minimum-2d'
45 |
46 |
47 |
48 |
49 | ```
50 |
51 | The component takes the dimensions of its parent and is always centered
52 |
53 | ## Everything you need to know explained in two minutes
54 |
55 | A `BareMinimum2d` component only has two props: `container` and `data`. `container` is a small object with exactly four elements. `data` is an array containing objects.
56 |
57 | Example:
58 |
59 | ```jsx
60 | import BareMinimum2d from 'bare-minimum-2d'
61 |
62 | const container = {
63 | color: '#0000FF',
64 | opacity: 0.2,
65 | xRange: 300,
66 | yRange: 500
67 | }
68 |
69 | const data = [{
70 | x: [0],
71 | y: [0],
72 | color: "#FFFFFF",
73 | opacity: 1.0,
74 | size: 10,
75 | type: 'points',
76 | id: 'center'
77 | }]
78 |
79 |
80 |
81 |
82 | ```
83 |
84 | `container.color` and `container.opacity` specifies the canvas color of `BareMinimum2d`.
85 |
86 | The cartesian coordinate system of `BareMinimum` will follow the diagram below given `container.xRange` and `container.yRange`. Position (0, 0) will always be at the center of the rendered component.
87 |
88 | ```js
89 | yRange/2
90 | |
91 | |
92 | -xRange/2 -------(0,0)--------- xRange/2
93 | |
94 | |
95 | -yRange/2
96 | ```
97 |
98 | Please take a look at more [complex example data prop](./example/src/demo1/demoProps.js) to get the idea.
99 | each element of the array `data` should be a hash-like objectwith a `type` key which should have a value that is one of
100 | the following:
101 |
102 | | points | ellipse | lines | polygon |
103 | | ------ | -------- | ------ | -------- |
104 | | plural | singular | plural | singular |
105 |
106 | Elements of the `data` array will be stacked based on the order they are declared.
107 | The first element will be at the most bottom layer while the last element of the array will be at the top.
108 |
109 | All attributes are ALWAYS required, nothing is optional because there are no default values. The `id` attribute must be unique for each element of the `data` array.
110 |
111 | #### Create your own
112 |
113 | You can add your own shapes as a plugin for example, here's an example plugin written by [@fuddl](https://github.com/fuddl)
114 |
115 | ```jsx
116 |
117 | const Triangle = ({ x, y, transforms, size, color, opacity, id, i }) => {
118 | const cx = transforms.tx(x)
119 | const cy = transforms.ty(y)
120 | const ySize = size * 0.8626
121 | return (
122 |
134 | )
135 | }
136 |
137 | const trianglesPlugin = {
138 | triangle: (element, transforms) => {
139 | const { size, color, opacity, id } = element
140 | return element.x.map((x, i) => (
141 |
154 | ))
155 | }
156 | }
157 | ```
158 |
159 | And you can use it like so:
160 |
161 | ```jsx
162 | const triangle = {
163 | "x": [-163.72675374383329],
164 | "y": [-154.33259574213795],
165 | "opacity": 1,
166 | "size": 60,
167 | "color": "#2196F3",
168 | "type": "triangles",
169 | "id":"points0"
170 | }
171 |
172 |
35 | BareMinimum2d is a low-level and lightweight React component you can use
36 |
37 | to render points, lines, ellipses, and polygons on the screen.
38 |
39 |
40 |
41 | Go check out the three demos linked above. If you're interested in it,
42 |
43 | you can checkout the repository (also linked above).
44 |
74 |
75 | )
76 | }
77 |
78 | export default App
79 |
--------------------------------------------------------------------------------
/example/src/demo1/demo.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import BareMinimum2d from 'bare-minimum-2d'
3 | import DEMO_PROPS from './demoProps'
4 | import { URL_SOURCE_CODE_DEMO1, URL_SOURCE_PROPS_DEMO1 } from '../links'
5 | import { useEffect, useState } from 'react'
6 |
7 | // Adapted from: https://usehooks.com/useWindowSize/
8 | function useWindowSize() {
9 | // Initialize state with undefined width/height so server and client renders match
10 | const [windowSize, setWindowSize] = useState({
11 | width: undefined,
12 | height: undefined
13 | })
14 |
15 | useEffect(() => {
16 | const handleResize = () =>
17 | setWindowSize({
18 | width: window.innerWidth,
19 | height: window.innerHeight
20 | })
21 |
22 | window.addEventListener('resize', handleResize)
23 | handleResize() // call it right away!
24 |
25 | return () => window.removeEventListener('resize', handleResize)
26 | }, [])
27 |
28 | return windowSize
29 | }
30 |
31 | /*****
32 | DEMO #1
33 |
34 | In this demo, simple points, lines, ellipses and polygons are drawn.
35 |
36 | This demo shows that the BareMinimum2d component
37 | takes the dimensions of its parent component
38 | and will always scale and be centered.
39 |
40 | Check out the data structure of the props passed
41 | to BareMinimum2d and the resulting svg
42 | which are located at this same directory.
43 | They're named demoProps.js and demo.svg respectively.
44 |
45 | This component which wraps < BareMinimum2d /> uses ResizeObserver
46 | to listen for changes in dimensions of its width
47 | (to display it to the user) when changed, whenever this occurs
48 | we take this opportunity to get the document window's height
49 | and sync it to the height of this component.
50 |
51 | *****/
52 |
53 | const DemoSticky = ({ height, width }) => (
54 |
55 |
56 | Resize the window.
57 |
58 | {height} x {width}
59 |
60 |
61 |
62 | BareMinimum2d takes the dimensions of
63 |
64 | its parent and it will always be centered.
65 |
66 |
67 |
68 | Use BareMinimum2d to specify as many polygons,
69 |
70 | lines, ellipses and points as you like.
71 |
71 | Move your cursor to spin the pinwheel.
72 |
73 | BareMinimum2d can be used for interactive applications.
74 |
75 | You can also add your pass your own shape implementation as a plugin.
76 |