https://github.com/wang1212/reactive-zrender
A zrender-based declarative design drawing library.
https://github.com/wang1212/reactive-zrender
reactjs zrender
Last synced: 7 days ago
JSON representation
A zrender-based declarative design drawing library.
- Host: GitHub
- URL: https://github.com/wang1212/reactive-zrender
- Owner: wang1212
- License: mit
- Created: 2024-04-21T11:49:19.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-04-21T14:25:42.000Z (almost 2 years ago)
- Last Synced: 2025-04-06T10:18:45.150Z (10 months ago)
- Topics: reactjs, zrender
- Language: TypeScript
- Homepage:
- Size: 496 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# ReactiveZRender


[](https://www.codacy.com/gh/wang1212/reactive-zrender/dashboard?utm_source=github.com&utm_medium=referral&utm_content=wang1212/reactive-zrender&utm_campaign=Badge_Grade)
[](http://commitizen.github.io/cz-cli/)
English | [简体中文](./README.zh-CN.md)
> Note: This is an experimental project!
A [zrender](http://ecomfe.github.io/zrender/)-based declarative design drawing library.
The build tool is based on [rollup](http://rollupjs.org/) and [typescript](https://www.typescriptlang.org/), among other tools.
## About
The goal of this project is to wrap a **declarative**, **component-based** drawing library based on [zrender](http://ecomfe.github.io/zrender/), borrowing design patterns from React and Vue.
Supports 2 component declaration modes:
- JSON
```typescript
const Group = RZRender.defineComponent({
type: 'Group',
render: function ({ x = 0, y = 0 } = {}, children) {
const offset = (index) => 50 * index;
return {
type: 'group',
props: {
opts: {
x,
y,
},
},
children,
};
},
});
```
- Class
```typescript
class Rect extends RZRender.Component {
static type = 'Rect';
type = Rect.type;
triggerTooltip = true;
handleClick() {
alert('click rect');
}
handleMouseEnter() {
this.state.backgroundColor = 'red';
this.update();
}
handleMouseLeave(backgroundColor) {
this.state.backgroundColor = backgroundColor;
this.update();
}
render(
{
width = 10,
height = 10,
backgroundColor = 'black',
animation,
...rest
} = {},
children,
) {
console.log('render', this.state.backgroundColor);
return {
type: 'rect',
props: {
ref: this.state.ref,
opts: {
...rest,
shape: {
width,
height,
},
style: {
text: '11',
fill: this.state.backgroundColor,
},
onclick: () => this.handleClick(),
onmouseover: () => this.handleMouseEnter(),
onmouseout: () => this.handleMouseLeave(backgroundColor),
},
animation,
},
children,
};
}
onBeforeMount(props) {
// console.log('onBeforeMount', props);
this.state = {
ref: RZRender.createRef(),
backgroundColor: props.backgroundColor || 'black',
};
}
onMounted(props) {
// console.log('onMounted', props);
// console.log('state', this, this.state);
// console.log(
// 'metadata',
// dynamicRelationGraphs.relationGraphs.getElementMetadata(this.state.ref.value)
// );
}
onBeforeUpdate(props, prevProps) {
// console.log('onBeforeUpdate', props, prevProps);
}
onUpdated(props) {
// console.log('onUpdated', props);
}
onBeforeUnMount() {
// console.log('onBeforeUnMount', this.props);
}
}
```
The declared component should be known to the rendering engine, so the registration API needs to be called.
```typescript
const Group = RZRender.registerComponent(Group);
const Rect = RZRender.registerComponent(Rect);
```
Then, you can render declaratively by calling the `render()` api.
```typescript
const canvas = new RZRender.ReactiveZRender($dom.id);
canvas.render(
RZRender.Root(
{
opts: {
x: 10,
y: 100,
scaleX: 2,
},
},
[
{
type: 'text',
props: {
opts: {
style: {
text: 'Hello',
},
},
},
},
Rect({
backgroundColor: 'red',
animation: {
when: [
{
time: 300,
value: {
x: 25,
},
},
{
time: 1e3,
value: {
x: 75,
},
},
],
},
}),
Group(
{
x: 40,
y: 40,
},
[
{
type: 'rect',
props: {
opts: {
shape: {
width: 10,
height: 10,
},
style: {
fill: 'pink',
},
x: 100,
},
},
},
Rect({
width: 30,
height: 10,
backgroundColor: 'orange',
}),
],
),
Rect({
width: 30,
height: 10,
x: 100,
y: 0,
scaleX: 3,
}),
],
)
);
```
Yes, the code is ugly, and that's because there's no [JSX](https://legacy.reactjs.org/docs/introducing-jsx.html), because JSX requires compiler support.
`render()` can be called multiple times, implementing a **React-like Diff mechanism**.
## Bundle
Run `npm run build`, the following bundles will eventually be generated.
```plain
types/
build/
├── bundle.esm.js
├── bundle.esm.min.js
├── bundle.umd.js
└── bundle.umd.min.js
```
Will also generate the corresponding **sourcemap** file.
## Development Guidelines
### Scripts
- Development mode
```bash
npm run dev # or $ npm run esbuild-dev
```
- Development mode (web server)
```bash
npm run dev-serve # or $ npm run esbuild-dev-serve
```
- Run test
```bash
npm run test
```
- Build bundle
```bash
npm run build
```
- Build Html documents from Markdown documents
```bash
npm run build:docs-html
```
_See the `scripts` field in **package.json** for more commands._
### Git Commit Message Format
Adopt [community commit format best practices](https://www.conventionalcommits.org/):
```bash
# Before
git commit
# Now
npm run commit
```
_This constraint relies on tools [commitizen](http://commitizen.github.io/cz-cli/) and [commitlint](https://commitlint.js.org/) provided by the community._
### npm publish
The version management of this module adopts the specifications recommended by the community [Semantic Versioning](https://semver.org/). Follow version changes and maintain a **CHANGELOG.md**([Learn why](https://keepachangelog.com/)).
```bash
# Update version and generate changelog before publishing to npm repository
npm run release
# Or, preview
npm run release -- --dry-run
# Then publish to npm, if yes is not selected when auto-publishing to npm
npm publish # npm publish --access public
```
_These jobs are done with the help of [release-it](https://github.com/release-it/release-it) tool provided by the community._
## License
[MIT](./LICENSE).