Socket
Socket
Sign inDemoInstall

@jiaminghi/c-render

Package Overview
Dependencies
5
Maintainers
2
Versions
34
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.4.3 to 1.0.0-alpha.2

.babelrc.js

21

CHANGELOG.md

@@ -0,1 +1,19 @@

# 1.0.0-alpha.2 (2020-09-04)
### Types
- **types:** Type optimization
# 1.0.1-alpha.1 (2020-07-30)
### Types
- **types:** Type optimization
# 1.0.1-alpha (2020-07-24)
### Typescript
- **Typescript** Refactor using typescript.
# 0.4.3-alpha (2019-08-29)

@@ -82,3 +100,2 @@

# 0.2.11-alpha (2019-05-29)

@@ -177,2 +194,2 @@

- **graphs:** Add new graphs ([polyline](https://github.com/jiaming743/CRender#polyline),[smoothline](https://github.com/jiaming743/CRender#smoothline))
- **prototype:** Add methos to delete graphs (`deleteAllElements`,`deleteElement`)
- **prototype:** Add methos to delete graphs (`deleteAllElements`,`deleteElement`)

97

package.json
{
"name": "@jiaminghi/c-render",
"version": "0.4.3",
"version": "1.0.0-alpha.2",
"author": "JiaMing <743192023@qq.com>",
"description": "Canvas-based vector graphics rendering plugin",
"main": "lib/index.js",
"unpkg": "dist/index.js",
"module": "es/index.js",
"types": "es/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/jiaming743/CRender.git"
"url": "https://github.com/DataV-Team/CRender.git"
},
"scripts": {
"build": "node build/index.js",
"prepublish": "npm run build",
"deploy": "node deploy/index.js",
"test": "mocha"
"dev": "ts-node scripts/dev.ts",
"clean": "rimraf lib dist es",
"type:check": "tsc --noEmit",
"lint": "eslint --ext js,ts src test",
"format:check": "prettier --check .",
"format": "prettier --write .",
"build:rollup": "rollup -c",
"build:es": "babel src --out-dir es --extensions \".ts\"",
"build": "npm run build:rollup && npm run build:es && npm run format",
"prepare": "npm run clean && npm run check && npm run build",
"test": "mocha",
"test:fun": "ts-node scripts/test.ts",
"check": "npm run type:check && npm run lint && npm run format:check && npm run test",
"docs": "vuepress dev docs",
"build:docs": "vuepress build docs",
"deploy": "ts-node scripts/deploy.ts"
},
"husky": {
"hooks": {
"pre-commit": "npm run check",
"pre-push": "npm run check"
}
},
"license": "MIT",
"bugs": {
"url": "https://github.com/jiaming743/CRender/issues"
"url": "https://github.com/DataV-Team/CRender/issues"
},

@@ -27,22 +48,58 @@ "keywords": [

],
"homepage": "https://github.com/jiaming743/CRender#readme",
"homepage": "https://github.com/DataV-Team/CRender#readme",
"dependencies": {
"@babel/runtime": "^7.5.5",
"@jiaminghi/bezier-curve": "*",
"@jiaminghi/color": "*",
"@jiaminghi/transition": "*"
"@jiaminghi/bezier-curve": "^1.0.1",
"@jiaminghi/color": "^1.1.1",
"@jiaminghi/transition": "2.0.1"
},
"devDependencies": {
"@babel/cli": "^7.4.4",
"@babel/core": "^7.4.5",
"@babel/preset-env": "^7.5.5",
"@babel/plugin-transform-runtime": "^7.5.5",
"@babel/register": "^7.4.4",
"@jiaminghi/fs": "0.0.2",
"@babel/cli": "^7.8.4",
"@babel/core": "^7.8.6",
"@babel/plugin-transform-runtime": "^7.10.5",
"@babel/preset-env": "^7.8.6",
"@babel/preset-typescript": "^7.10.4",
"@babel/register": "^7.9.0",
"@jiaminghi/fs": "^0.1.1",
"@jiaminghi/ftp": "^0.0.2",
"@jiaminghi/print": "^0.2.0",
"@jiaminghi/utils-node": "^0.1.0",
"@rollup/plugin-babel": "^5.0.3",
"@rollup/plugin-commonjs": "^12.0.0",
"@rollup/plugin-node-resolve": "^8.0.1",
"@rollup/plugin-replace": "^2.3.3",
"@types/chai": "^4.2.11",
"@types/ftp": "^0.3.31",
"@types/lodash": "^4.14.157",
"@types/mocha": "^7.0.2",
"@types/node": "^13.11.0",
"@types/react": "^16.9.35",
"@types/react-dom": "^16.9.8",
"@types/rimraf": "^3.0.0",
"@typescript-eslint/eslint-plugin": "^2.27.0",
"@typescript-eslint/parser": "^2.27.0",
"babel-plugin-transform-runtime": "^6.23.0",
"chai": "^4.2.0",
"eslint": "^6.8.0",
"ftp": "^0.3.10",
"mocha": "^6.1.4",
"browserify": "^16.5.0",
"uglifyjs": "^2.4.11"
"husky": "^4.2.5",
"less": "^3.11.3",
"less-loader": "^6.1.0",
"lite-server": "^2.5.4",
"lodash": "^4.17.19",
"mocha": "^6.2.3",
"npm-run-all": "^4.1.5",
"open": "^7.1.0",
"prettier": "^2.0.4",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"rimraf": "^3.0.2",
"rollup": "^2.15.0",
"rollup-plugin-postcss": "^3.1.2",
"rollup-plugin-terser": "^5.3.0",
"rollup-plugin-typescript2": "^0.27.0",
"ts-node": "^8.8.2",
"typescript": "^3.8.3",
"vuepress": "^1.5.0"
}
}

@@ -6,4 +6,4 @@ [中文](./README.md)

<p align="center">
<a href="https://travis-ci.com/jiaming743/CRender"><img src="https://img.shields.io/travis/com/jiaming743/CRender.svg" alt="Travis CI"></a>
<a href="https://github.com/jiaming743/CRender/blob/master/LICENSE"><img src="https://img.shields.io/github/license/jiaming743/CRender.svg" alt="LICENSE" /> </a>
<a href="https://travis-ci.com/DataV-Team/CRender"><img src="https://img.shields.io/travis/com/DataV-Team/CRender" alt="Travis CI"></a>
<a href="https://github.com/DataV-Team/CRender/blob/master/LICENSE"><img src="https://img.shields.io/github/license/DataV-Team/CRender.svg" alt="LICENSE" /> </a>
<a href="https://www.npmjs.com/package/@jiaminghi/c-render"><img src="https://img.shields.io/npm/v/@jiaminghi/c-render.svg" alt="LICENSE" /> </a>

@@ -26,7 +26,6 @@ </p>

```html
<!--Resources are located on personal servers for experience and testing only, do not use in production environments-->
<!--Debug version-->
<script src="http://lib.jiaminghi.com/crender/crender.map.js"></script>
<script src="https://unpkg.com/@jiaminghi/c-render/dist/index.js"></script>
<!--Compression version-->
<script src="http://lib.jiaminghi.com/crender/crender.min.js"></script>
<script src="https://unpkg.com/@jiaminghi/c-render/dist/index.min.js"></script>
<script>

@@ -39,1950 +38,1 @@ const { CRender, extendNewGraph } = window.CRender

Detailed documents and examples can be viewed on the [HomePage](http://crender.jiaminghi.com/EN/).
- [Use](#Use)
- [Class CRender](#class-crender)
- [Class Graph](#class-graph)
- [Class Style](#class-style)
- [Examples](#examples)
- [Extend New Graph](#Extend-New-Graph)
- [Related support](#Related-support)
------
<h3 align="center">Use</h3>
```javascript
import CRender from '@jiaminghi/c-redner'
const canvas = document.getElementById('canvas')
// Instantiate CRender
const render = new CRender(canvas)
// Add graph to render
const circle = render.add({ name: 'circle', ... })
```
<h3 align="center">Class CRender</h3>
### Class
```javascript
/**
* @description Class of CRender
* @param {Object} canvas Canvas DOM
* @return {CRender} Instance of CRender
*/
class CRender {
// ...
}
```
### properties
- [ctx](#ctx)
- [area](#area)
- [animationStatus](#animationStatus)
- [graphs](#graphs)
- [color](#color)
- [bezierCurve](#bezierCurve)
#### ctx
```javascript
/**
* @description Context of the canvas
* @type {Object}
* @example ctx = canvas.getContext('2d')
*/
```
#### area
```javascript
/**
* @description Width and height of the canvas
* @type {Array<Number>}
* @example area = [300,100]
*/
```
#### animationStatus
```javascript
/**
* @description Whether render is in animation rendering
* @type {Boolean}
* @example animationStatus = true|false
*/
```
#### graphs
```javascript
/**
* @description Added graph
* @type {Array<Graph>}
* @example graphs = [Graph, Graph, ...]
*/
```
#### [color](https://github.com/jiaming743/color/blob/master/README_EN.md)
```javascript
/**
* @description Color plugin
* @type {Object}
*/
```
#### [bezierCurve](https://github.com/jiaming743/BezierCurve/blob/master/README_EN.md)
```javascript
/**
* @description Bezier Curve plugin
* @type {Object}
*/
```
### prototype
- [add](#add)
Add graph to render.
- [clone](#clone)
Clone Graph.
- [delGraph](#delGraph)
Delete graph in render.
- [delAllGraph](#delAllGraph)
Delete all graph in render.
- [drawAllGraph](#drawAllGraph)
Draw all the graphs in the render.
- [clearArea](#clearArea)
Clear canvas drawing area.
- [launchAnimation](#launchAnimation)
Animate the graph whose animation queue is not empty and the animationPause is equal to false.
#### add
```javascript
/**
* @description Add graph to render
* @param {Object} config Graph configuration
* @return {Graph} Graph instance
*/
CRender.prototype.add = function (config = {}) {
// ...
}
```
#### Clone
```javascript
/**
* @description Clone Graph
* @param {Graph} graph The target to be cloned
* @return {Graph} Cloned graph
*/
CRender.prototype.clone = function (graph) {
}
```
#### delGraph
```javascript
/**
* @description Delete graph in render
* @param {Graph} graph The graph to be deleted
* @return {Undefined} Void
*/
CRender.prototype.delGraph = function (graph) {
// ...
}
```
#### delAllGraph
```javascript
/**
* @description Delete all graph in render
* @return {Undefined} Void
*/
CRender.prototype.delAllGraph = function () {
// ...
}
```
#### drawAllGraph
```javascript
/**
* @description Draw all the graphs in the render
* @return {Undefined} Void
*/
CRender.prototype.drawAllGraph = function () {
// ...
}
```
#### clearArea
```javascript
/**
* @description Clear canvas drawing area
* @return {Undefined} Void
*/
CRender.prototype.clearArea = function () {
// ...
}
```
#### launchAnimation
```javascript
/**
* @description Animate the graph whose animation queue is not empty
* and the animationPause is equal to false
* @return {Promise} Animation Promise
*/
CRender.prototype.launchAnimation = function () {
// ...
}
```
<h3 align="center">Class Graph</h3>
### properties
**When adding a graph, you can configure them.**
- [visible](#visible)
- [shape](#shape)
- [style](#style)
- [drag](#drag)
- [hover](#hover)
- [index](#index)
- [animationDelay](#animationDelay)
- [animationFrame](#animationFrame)
- [animationCurve](#animationCurve)
- [animationPause](#animationPause)
- [hoverRect](#hoverRect)
- [mouseEnter](#mouseEnter)
- [mouseOuter](#mouseOuter)
- [click](#click)
#### visible
```javascript
/**
* @description Weather to render graph
* @type {Boolean}
* @default visible = true
*/
```
#### shape
```javascript
/**
* @description Graph shape data
* @type {Object}
*/
```
#### [style](#Class-Style)
```javascript
/**
* @description Graph style data (Instance of Style)
* @type {Style}
*/
```
#### drag
```javascript
/**
* @description Whether to enable drag
* @type {Boolean}
* @default drag = false
*/
```
#### hover
```javascript
/**
* @description Whether to enable hover
* @type {Boolean}
* @default hover = false
*/
```
#### index
```javascript
/**
* @description Graph rendering index
* Give priority to index high graph in rendering
* @type {Number}
* @default index = 1
*/
```
#### animationDelay
```javascript
/**
* @description Animation delay time(ms)
* @type {Number}
* @default animationDelay = 0
*/
```
#### animationFrame
```javascript
/**
* @description Number of animation frames
* @type {Number}
* @default animationFrame = 30
*/
```
#### [animationCurve](https://github.com/jiaming743/transition/blob/master/README_EN.md)
```javascript
/**
* @description Animation easing curve
* @type {String}
* @default animationCurve = 'linear'
*/
```
#### animationPause
```javascript
/**
* @description Weather to pause graph animation
* @type {Boolean}
* @default animationPause = false
*/
```
#### hoverRect
```javascript
/**
* @description Rectangular hover detection zone
* Use this method for hover detection first
* @type {Null|Array<Number>}
* @default hoverRect = null
* @example hoverRect = [0, 0, 100, 100] // [Rect start x, y, Rect width, height]
*/
```
#### mouseEnter
```javascript
/**
* @description Mouse enter event handler
* @type {Null|Function}
* @default mouseEnter = null
*/
```
#### mouseOuter
```javascript
/**
* @description Mouse outer event handler
* @type {Null|Function}
* @default mouseOuter = null
*/
```
#### click
```javascript
/**
* @description Mouse click event handler
* @type {Null|Function}
* @default click = null
*/
```
#### Tip
Enable **mouseEnter**, **mouseOuter**, **click** event support requires configuring the `hover` property of the graph to `true`. Extended new graph require the **hoverCheck** method to be configured to provide event support.
### prototype
- [attr](#attr)
Update graph state.
- [animation](#animation)
Update graphics state (with animation).
- [animationEnd](#animationEnd)
Skip to the last frame of animation.
- [pauseAnimation](#pauseAnimation)
Pause animation behavior.
- [playAnimation](#playAnimation)
Try animation behavior.
#### attr
```javascript
/**
* @description Update graph state
* @param {String} attrName Updated attribute name
* @param {Any} change Updated value
* @return {Undefined} Void
*/
Graph.prototype.attr = function (attrName, change = undefined) {
// ...
}
```
#### animation
```javascript
/**
* @description Update graphics state (with animation)
* Only shape and style attributes are supported
* @param {String} attrName Updated attribute name
* @param {Any} change Updated value
* @param {Boolean} wait Whether to store the animation waiting
* for the next animation request
* @return {Promise} Animation Promise
*/
Graph.prototype.animation = async function (attrName, change, wait = false) {
// ...
}
```
#### animationEnd
```javascript
/**
* @description Skip to the last frame of animation
* @return {Undefined} Void
*/
Graph.prototype.animationEnd = function () {
// ...
}
```
#### pauseAnimation
```javascript
/**
* @description Pause animation behavior
* @return {Undefined} Void
*/
Graph.prototype.pauseAnimation = function () {
// ...
}
```
#### playAnimation
```javascript
/**
* @description Try animation behavior
* @return {Undefined} Void
*/
Graph.prototype.playAnimation = function () {
// ...
}
```
### Life Cycle
When you add graph to the render, you can configure the following functions in the configuration, they will be called at a specific time.
- [added](#added)
Called after the graphics are added.
- [beforeDraw](#beforeDraw)
Called before the drawing is drawn.
- [drawed](#drawed)
Called after the drawing is completed
- [beforeMove](#beforeMove)
Called before moving the graphic.
- [moved](#moved)
Called after moving the graphic.
- [beforeDelete](#beforeDelete)
Called before deleting the graphic.
- [deleted](#deleted)
Called after the graphic is deleted.
#### added
```javascript
/**
* @description Called after the graphics are added
* @param {Graph} Graph instance
*/
config = {
//...,
added ({ shape, style }) {
// do something...
}
}
```
#### beforeDraw
```javascript
/**
* @description Called before the drawing is drawn,
* the graphic style has been initialized.
* You can modify the ctx property before drawing.
* @param {Graph} Graph instance
* @param {CRender} CRender instance
*/
config = {
//...,
beforeDraw ({ shape, style }, { ctx }) {
// do something...
ctx.stroke = 'transparent'
}
}
```
#### drawed
```javascript
/**
* @description Called after the drawing is completed
* @param {Graph} Graph instance
* @param {CRender} CRender instance
*/
config = {
//...,
drawed ({ shape, style }, { ctx }) {
// do something...
}
}
```
#### beforeMove
```javascript
/**
* @description Called before moving the graphic,
* before the drag behavior occurs
* @param {Event} Mouse event
* @param {Graph} Graph instance
*/
config = {
//...,
beforeMove ({ offsetX, offsetY }, { shape, style }) {
// do something...
}
}
```
#### moved
```javascript
/**
* @description Called after moving the graphic,
* after the drag behavior occurs
* @param {Event} Mouse event
* @param {Graph} Graph instance
*/
config = {
//...,
moved ({ offsetX, offsetY }, { shape, style }) {
// do something...
}
}
```
#### beforeDelete
```javascript
/**
* @description Called before deleting the graphic
* @param {Graph} Graph instance
*/
config = {
//...,
beforeDelete ({ shape, style }) {
// do something...
}
}
```
#### deleted
```javascript
/**
* @description Called after the graphic is deleted
* @param {Graph} Graph instance
*/
config = {
//...,
deleted ({ shape, style }) {
// do something...
}
}
```
<h3 align="center">Class Style</h3>
### properties
- [fill](#fill)
- [stroke](#stroke)
- [opacity](#opacity)
- [lineCap](#lineCap)
- [lineJoin](#)
- [lineDash](#lineDash)
- [lineDashOffset](#lineDashOffset)
- [shadowBlur](#shadowBlur)
- [shadowColor](#shadowColor)
- [shadowOffsetX](#shadowOffsetX)
- [shadowOffsetY](#shadowOffsetY)
- [lineWidth](#lineWidth)
- [graphCenter](#graphCenter)
- [scale](#scale)
- [rotate](#rotate)
- [translate](#translate)
- [hoverCursor](#hoverCursor)
- [fontStyle](#fontStyle)
- [fontVarient](#fontVarient)
- [fontWeight](#fontWeight)
- [fontSize](#fontSize)
- [fontFamily](#fontFamily)
- [textAlign](#textAlign)
- [textBaseline](#textBaseline)
- [gradientColor](#gradientColor)
- [gradientType](#gradientType)
- [gradientParams](#gradientParams)
- [gradientWith](#gradientWith)
- [gradientStops](#gradientStops)
- [colors](#colors)
#### fill
```javascript
/**
* @description Rgba value of graph fill color
* @type {Array<Number>}
* @default fill = [0, 0, 0, 1]
*/
```
#### stroke
```javascript
/**
* @description Rgba value of graph stroke color
* @type {Array<Number>}
* @default stroke = [0, 0, 0, 1]
*/
```
#### opacity
```javascript
/**
* @description Opacity of graph
* @type {Number}
* @default opacity = 1
*/
```
#### lineCap
```javascript
/**
* @description LineCap of Ctx
* @type {Null|String}
* @default lineCap = null
* @example lineCap = 'butt'|'round'|'square'
*/
```
#### lineJoin
```javascript
/**
* @description Linejoin of Ctx
* @type {Null|String}
* @default lineJoin = null
* @example lineJoin = 'round'|'bevel'|'miter'
*/
```
#### lineDash
```javascript
/**
* @description LineDash of Ctx
* @type {Null|Array<Number>}
* @default lineDash = null
* @example lineDash = [10, 10]
*/
```
#### lineDashOffset
```javascript
/**
* @description LineDashOffset of Ctx
* @type {Null|Number}
* @default lineDashOffset = null
* @example lineDashOffset = 10
*/
```
#### shadowBlur
```javascript
/**
* @description ShadowBlur of Ctx
* @type {Number}
* @default shadowBlur = 0
*/
```
#### shadowColor
```javascript
/**
* @description Rgba value of graph shadow color
* @type {Array<Number>}
* @default shadowColor = [0, 0, 0, 0]
*/
```
#### shadowOffsetX
```javascript
/**
* @description ShadowOffsetX of Ctx
* @type {Number}
* @default shadowOffsetX = 0
*/
```
#### shadowOffsetY
```javascript
/**
* @description ShadowOffsetY of Ctx
* @type {Number}
* @default shadowOffsetY = 0
*/
```
#### lineWidth
```javascript
/**
* @description LineWidth of Ctx
* @type {Number}
* @default lineWidth = 0
*/
```
#### graphCenter
```javascript
/**
* @description Center point of the graph
* @type {Null|Array<Number>}
* @default graphCenter = null
* @example graphCenter = [10, 10]
*/
```
#### scale
```javascript
/**
* @description Graph scale
* @type {Null|Array<Number>}
* @default scale = null
* @example scale = [1.5, 1.5]
*/
```
#### rotate
```javascript
/**
* @description Graph rotation degree
* @type {Null|Number}
* @default rotate = null
* @example rotate = 10
*/
```
#### translate
```javascript
/**
* @description Graph translate distance
* @type {Null|Array<Number>}
* @default translate = null
* @example translate = [10, 10]
*/
```
#### hoverCursor
```javascript
/**
* @description Cursor status when hover
* @type {String}
* @default hoverCursor = 'pointer'
* @example hoverCursor = 'default'|'pointer'|'auto'|'crosshair'|'move'|'wait'|...
*/
```
#### fontStyle
```javascript
/**
* @description Font style of Ctx
* @type {String}
* @default fontStyle = 'normal'
* @example fontStyle = 'normal'|'italic'|'oblique'
*/
```
#### fontVarient
```javascript
/**
* @description Font varient of Ctx
* @type {String}
* @default fontVarient = 'normal'
* @example fontVarient = 'normal'|'small-caps'
*/
```
#### fontWeight
```javascript
/**
* @description Font weight of Ctx
* @type {String|Number}
* @default fontWeight = 'normal'
* @example fontWeight = 'normal'|'bold'|'bolder'|'lighter'|Number
*/
```
#### fontSize
```javascript
/**
* @description Font size of Ctx
* @type {Number}
* @default fontSize = 10
*/
```
#### fontFamily
```javascript
/**
* @description Font family of Ctx
* @type {String}
* @default fontFamily = 'Arial'
*/
```
#### textAlign
```javascript
/**
* @description TextAlign of Ctx
* @type {String}
* @default textAlign = 'center'
* @example textAlign = 'start'|'end'|'left'|'right'|'center'
*/
```
#### textBaseline
```javascript
/**
* @description TextBaseline of Ctx
* @type {String}
* @default textBaseline = 'middle'
* @example textBaseline = 'top'|'bottom'|'middle'|'alphabetic'|'hanging'
*/
```
#### gradientColor
```javascript
/**
* @description The color used to create the gradient
* @type {Null|Array<String>}
* @default gradientColor = null
* @example gradientColor = ['#000', '#111', '#222']
*/
```
#### gradientType
```javascript
/**
* @description Gradient type
* @type {String}
* @default gradientType = 'linear'
* @example gradientType = 'linear' | 'radial'
*/
```
#### gradientParams
```javascript
/**
* @description Gradient params
* @type {Array<Number>}
* @default gradientParams = null
* @example gradientParams = [x0, y0, x1, y1] (Linear Gradient)
* @example gradientParams = [x0, y0, r0, x1, y1, r1] (Radial Gradient)
*/
```
#### gradientWith
```javascript
/**
* @description When to use gradients
* @type {String}
* @default gradientWith = 'stroke'
* @example gradientWith = 'stroke' | 'fill'
*/
```
#### gradientStops
```javascript
/**
* @description Gradient color stops
* @type {String|Array<Number>}
* @default gradientStops = 'auto'
* @example gradientStops = 'auto' | [0, .2, .3, 1]
*/
```
#### colors
```javascript
/**
* @description Extended color that supports animation transition
* @type {Array<String>|Object}
* @default colors = null
* @example colors = ['#000', '#111', '#222']
* @example colors = { a: '#000', b: '#111' }
*/
```
#### Tip
**Gradient** is automatically enabled when `gradientColor` and `gradientParams` are configured.
### prototype
- [getStyle](#getStyle)
Get the current style configuration.
#### getStyle
```javascript
/**
* @description Get the current style configuration
* @return {Object} Style configuration
*/
Style.prototype.getStyle = function () {
}
```
<h3 align="center">Examples</h3>
CRender provides some basic vector graph, examples are as follows.
- [circle](#circle)
- [ellipse](#ellipse)
- [rect](#rect)
- [ring](#ring)
- [arc](#arc)
- [sector](#sector)
- [regPolygon](#regPolygon)
- [polyline](#polyline)
- [polyline (closed)](#polyline-closed)
- [smoothline](#smoothline)
- [smoothline (closed)](#smoothline-closed)
- [bezierCurve](#bezierCurve)
- [bezierCurve (closed)](#bezierCurve-closed)
- [text](#text)
#### circle
##### shape attribute
| Attribute name | Type | Default | Annotation |
| :------------: | :------: | :-----: | :-----------------------: |
| rx | `Number` | `0` | Center x-axis coordinate. |
| ry | `Number` | `0` | Center r-axis coordinate. |
| r | `Number` | `0` | Circle radius. |
```javascript
const { area: [w, h] } = render
const circleConfig = {
name: 'circle',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
rx: w / 2,
ry: h / 2,
r: 50
},
style: {
fill: '#9ce5f4',
shadowBlur: 0,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('shape', { r: 70 }, true)
this.animation('style', { shadowBlur: 20 })
},
mouseOuter (e) {
this.animation('shape', { r: 50 }, true)
this.animation('style', { shadowBlur: 0 })
}
}
const circle = render.add(circleConfig)
```
#### ellipse
##### shape attribute
| Attribute name | Type | Default | Annotation |
| :------------: | :------: | :-----: | :-----------------------: |
| rx | `Number` | `0` | Center x-axis coordinate. |
| ry | `Number` | `0` | Center y-axis coordinate. |
| hr | `Number` | `0` | Horizontal axis radius. |
| vr | `Number` | `0` | Vertical axis radius. |
```javascript
const { area: [w, h] } = render
const ellipseConfig = {
name: 'ellipse',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
rx: w / 2,
ry: h / 2,
hr: 80,
vr: 30
},
style: {
fill: '#9ce5f4',
shadowBlur: 0,
shadowColor: '#66eece',
scale: [1, 1],
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('style', { scale: [1.5, 1.5], shadowBlur: 20 })
},
mouseOuter (e) {
this.animation('style', { scale: [1, 1], shadowBlur: 0 })
}
}
const ellipse = render.add(ellipseConfig)
```
#### rect
##### shape attribute
| Attribute name | Type | Default | Annotation |
| :------------: | :------: | :-----: | :-------------------------------------------------------: |
| x | `Number` | `0` | The x coordinate of the top left corner of the rectangle. |
| y | `Number` | `0` | The y coordinate of the top left corner of the rectangle. |
| w | `Number` | `0` | Rectangle width. |
| h | `Number` | `0` | Rectangle height. |
```javascript
const { area: [w, h] } = render
const rectConfig = {
name: 'rect',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
x: w / 2 - rectWidth / 2,
y: h / 2 - rectHeight / 2,
w: rectWidth,
h: rectHeight
},
style: {
fill: '#9ce5f4',
shadowBlur: 0,
shadowColor: '#66eece',
hoverCursor: 'pointer',
translate: [0, 0]
},
mouseEnter (e) {
this.animation('shape', { w: 400 }, true)
this.animation('style', { shadowBlur: 20, translate: [-100, 0] })
},
mouseOuter (e) {
this.animation('shape', { w: 200 }, true)
this.animation('style', { shadowBlur: 0, translate: [0, 0] })
}
}
const rect = render.add(rectConfig)
```
#### ring
##### shape attribute
| Attribute name | Type | Default | Annotation |
| :------------: | :------: | :-----: | :-----------------------: |
| rx | `Number` | `0` | Center x-axis coordinate. |
| ry | `Number` | `0` | Center y-axis coordinate. |
| r | `Number` | `0` | Ring radius. |
```javascript
const { area: [w, h] } = render
const ringConfig = {
name: 'ring',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
rx: w / 2,
ry: h / 2,
r: 50
},
style: {
stroke: '#9ce5f4',
lineWidth: 20,
hoverCursor: 'pointer',
shadowBlur: 0,
shadowColor: '#66eece'
},
mouseEnter (e) {
this.animation('style', { shadowBlur: 20, lineWidth: 30 })
},
mouseOuter (e) {
this.animation('style', { shadowBlur: 0, lineWidth: 20 })
}
}
const ring = render.add(ringConfig)
```
#### arc
##### shape attribute
| Attribute name | Type | Default | Annotation |
| :------------: | :-------: | :-----: | :-----------------------: |
| rx | `Number` | `0` | Center x-axis coordinate. |
| ry | `Number` | `0` | Center y-axis coordinate. |
| r | `Number` | `0` | Arc radius. |
| startAngle | `Number` | `0` | Arc start angle. |
| endAngle | `Number` | `0` | Arc end angle. |
| clockWise | `Boolean` | `true` | Clockwise |
```javascript
const { area: [w, h] } = render
const arcConfig = {
name: 'arc',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
rx: w / 2,
ry: h / 2,
r: 60,
startAngle: 0,
endAngle: Math.PI / 3
},
style: {
stroke: '#9ce5f4',
lineWidth: 20,
shadowBlur: 0,
rotate: 0,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('shape', { endAngle: Math.PI }, true)
this.animation('style', { shadowBlur: 20, rotate: -30, lineWidth: 30 })
},
mouseOuter (e) {
this.animation('shape', { endAngle: Math.PI / 3 }, true)
this.animation('style', { shadowBlur: 0, rotate: 0, lineWidth: 20 })
}
}
const arc = render.add(arcConfig)
```
#### sector
##### shape attribute
| Attribute name | Type | Default | Annotation |
| :------------: | :-------: | :-----: | :-----------------------: |
| rx | `Number` | `0` | Center x-axis coordinate. |
| ry | `Number` | `0` | Center y-axis coordinate. |
| r | `Number` | `0` | Sector radius. |
| startAngle | `Number` | `0` | Sector start angle. |
| endAngle | `Number` | `0` | Sector end angle. |
| clockWise | `Boolean` | `true` | Clockwise |
```javascript
const { area: [w, h] } = render
const sectorConfig = {
name: 'sector',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
rx: w / 2,
ry: h / 2,
r: 60,
startAngle: 0,
endAngle: Math.PI / 3
},
style: {
fill: '#9ce5f4',
shadowBlur: 0,
rotate: 0,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('shape', { endAngle: Math.PI, r: 70 }, true)
this.animation('style', { shadowBlur: 20, rotate: -30, lineWidth: 30 })
},
mouseOuter (e) {
this.animation('shape', { endAngle: Math.PI / 3, r: 60 }, true)
this.animation('style', { shadowBlur: 0, rotate: 0, lineWidth: 20 })
}
}
const sector = render.add(sectorConfig)
```
#### regPolygon
##### shape attribute
| Attribute name | Type | Default | Annotation |
| :------------: | :------: | :-----: | :-----------------------: |
| rx | `Number` | `0` | Center x-axis coordinate. |
| ry | `Number` | `0` | Center y-axis coordinate. |
| r | `Number` | `0` | Circumradius. |
| side | `Number` | `0` | Edge number. |
```javascript
const { area: [w, h] } = render
const regPolygonConfig = {
name: 'regPolygon',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
rx: w / 2,
ry: h / 2,
r: 60,
side: 6
},
style: {
fill: '#9ce5f4',
hoverCursor: 'pointer',
shadowBlur: 0,
rotate: 0,
shadowColor: '#66eece'
},
mouseEnter (e) {
this.animation('shape', { endAngle: Math.PI, r: 100 }, true)
this.animation('style', { shadowBlur: 20, rotate: 180 })
},
mouseOuter (e) {
this.animation('shape', { endAngle: Math.PI / 3, r: 60 }, true)
this.animation('style', { shadowBlur: 0, rotate: 0 })
}
}
const regPolygon = render.add(regPolygonConfig)
```
#### polyline
##### shape attribute
| Attribute name | Type | Default | Annotation |
| :------------: | :-------: | :-----: | :------------------------------------: |
| points | `Array` | `[]` | The points that makes up the polyline. |
| close | `Boolean` | `false` | Whether to close the polyline. |
```javascript
const { area: [w, h] } = render
const top = h / 3
const bottom = h / 3 * 2
const gap = w / 10
const beginX = w / 2 - gap * 2
const points = new Array(5).fill('').map((t, i) =>
[beginX + gap * i, i % 2 === 0 ? top : bottom])
const polylineConfig = {
name: 'polyline',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
points
},
style: {
stroke: '#9ce5f4',
shadowBlur: 0,
lineWidth: 10,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('style', { lineWidth: 20, shadowBlur: 20 })
},
mouseOuter (e) {
this.animation('style', { lineWidth: 10, shadowBlur: 0 })
}
}
const polyline = render.add(polylineConfig)
```
#### polyline (closed)
```javascript
const { area: [w, h] } = render
const top = h / 3
const bottom = h / 3 * 2
const gap = w / 10
const beginX = w / 2 - gap * 2
const points = new Array(5).fill('').map((t, i) =>
[beginX + gap * i, i % 2 === 0 ? top : bottom])
points[2][1] += top * 1.3
const polylineClosedConfig = {
name: 'polyline',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
points,
close: true
},
style: {
fill: '#9ce5f4',
shadowBlur: 0,
lineWidth: 10,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('style', { shadowBlur: 20 }, true)
const pointsCloned = deepClone(this.shape.points)
pointsCloned[2][1] += top * 0.3
this.animation('shape', { points: pointsCloned })
},
mouseOuter (e) {
this.animation('style', { shadowBlur: 0 }, true)
const pointsCloned = deepClone(this.shape.points)
pointsCloned[2][1] -= top * 0.3
this.animation('shape', { points: pointsCloned })
}
}
const polylineClosed = render.add(polylineClosedConfig)
```
#### smoothline
##### shape attribute
| Attribute name | Type | Default | Annotation |
| :------------: | :-------: | :-----: | :--------------------------------------: |
| points | `Array` | `[]` | The points that makes up the smoothline. |
| close | `Boolean` | `false` | Whether to close the smoothline. |
```javascript
const { area: [w, h] } = render
const top = h / 3
const bottom = h / 3 * 2
const gap = w / 10
const beginX = w / 2 - gap * 2
const points = new Array(5).fill('').map((t, i) =>
[beginX + gap * i, i % 2 === 0 ? top : bottom])
const smoothlineConfig = {
name: 'smoothline',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
points
},
style: {
stroke: '#9ce5f4',
shadowBlur: 0,
lineWidth: 10,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('style', { lineWidth: 20, shadowBlur: 20 })
},
mouseOuter (e) {
this.animation('style', { lineWidth: 10, shadowBlur: 0 })
}
}
const smoothline = render.add(smoothlineConfig)
```
#### smoothline (closed)
```javascript
import { getCircleRadianPoint } from '../../CRender/lib/util'
function getPoints (radius, centerPoint, pointNum) {
const PIDived = Math.PI * 2 / pointNum
const points = new Array(pointNum).fill('')
.map((foo, i) =>
getCircleRadianPoint(...centerPoint, radius, PIDived * i)
)
return points
}
const { area: [w, h] } = render
const radius = h / 3
const centerPoint = [w / 2, h / 2]
const smoothlineClosedConfig = {
name: 'smoothline',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
points: getPoints(radius, centerPoint, 3),
close: true
},
style: {
fill: '#9ce5f4',
shadowBlur: 0,
lineWidth: 10,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('style', { lineWidth: 20, shadowBlur: 20, rotate: 120 })
},
mouseOuter (e) {
this.animation('style', { lineWidth: 10, shadowBlur: 0, rotate: 0 })
},
setGraphCenter (e, { style }) {
if (e) {
const { movementX, movementY } = e
const [cx, cy] = style.graphCenter
style.graphCenter = [cx + movementX, cy + movementY]
} else {
style.graphCenter = [...centerPoint]
}
}
}
const smoothlineClosed = render.add(smoothlineClosedConfig)
```
#### bezierCurve
##### shape attribute
| Attribute name | Type | Default | Annotation |
| :------------: | :-------: | :-----: | :---------------------------------------: |
| points | `Array` | `[]` | The points that makes up the bezierCurve. |
| close | `Boolean` | `false` | Whether to close the bezierCurve. |
```javascript
const { area: [w, h] } = render
const offsetX = w / 2
const offsetY = h / 2
const points = [
// Start point
[-100 + offsetX, -50 + offsetY],
// Multiple sets of bezier curve
[
// controlPoint1,controlPoint2,endPoint
[0 + offsetX, -50 + offsetY],
[0 + offsetX, 50 + offsetY],
[100 + offsetX, 50 + offsetY]
],
// [...],[...]
]
const bezierCurveConfig = {
name: 'bezierCurve',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
points
},
style: {
lineWidth: 10,
stroke: '#9ce5f4',
shadowBlur: 0,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('style', { lineWidth: 20, shadowBlur: 20 })
},
mouseOuter (e) {
this.animation('style', { lineWidth: 10, shadowBlur: 0 })
}
}
const bezierCurve = render.add(bezierCurveConfig)
```
#### bezierCurve (closed)
```javascript
import { getCircleRadianPoint } from '../../CRender/lib/util'
function getPetalPoints (insideRadius, outsideRadius, petalNum, petalCenter) {
const PI2Dived = Math.PI * 2 / (petalNum * 3)
let points = new Array(petalNum * 3).fill('')
.map((foo, i) =>
getCircleRadianPoint(...petalCenter,
i % 3 === 0 ? insideRadius : outsideRadius,
PI2Dived * i)
)
const startPoint = points.shift()
points.push(startPoint)
points = new Array(petalNum).fill('')
.map(foo => points.splice(0, 3))
points.unshift(startPoint)
return points
}
const { area: [w, h] } = render
const petalCenter = [w / 2, h / 2]
const [raidus1, raidus2, raidus3, raidus4] = [h / 6, h / 2.5, h / 3, h / 2]
const bezierCurveClosedConfig = {
name: 'bezierCurve',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
points: getPetalPoints(raidus1, raidus2, 6, petalCenter),
close: true
},
style: {
fill: '#9ce5f4',
shadowBlur: 0,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e, { style: { graphCenter } }) {
this.animation('style', { lineWidth: 20, shadowBlur: 20 }, true)
this.animation('shape', { points: getPetalPoints(raidus3, raidus4, 6, graphCenter) })
},
mouseOuter (e, { style: { graphCenter } }) {
this.animation('style', { lineWidth: 10, shadowBlur: 0 }, true)
this.animation('shape', { points: getPetalPoints(raidus1, raidus2, 6, graphCenter) })
},
setGraphCenter (e, { style }) {
if (e) {
const { movementX, movementY } = e
const [cx, cy] = style.graphCenter
style.graphCenter = [cx + movementX, cy + movementY]
} else {
style.graphCenter = [...petalCenter]
}
}
}
const bezierCurveClosed = render.add(bezierCurveClosedConfig)
```
#### text
##### shape attribute
| Attribute name | Type | Default | Annotation |
| :------------: | :------: | :---------: | :------------------------: |
| content | `String` | `''` | Text content. |
| position | `Array` | `[0, 0]` | Text start position. |
| maxWidth | `Number` | `Undefined` | Maximum width of the text. |
| rowGap | `Number` | `0` | Gap between row and row. |
```javascript
const { area: [w, h] } = render
const centerPoint = [w / 2, h / 2]
const hoverRect = [w / 2 - 100, h / 2 - 30 ,200, 60]
const textConfig = {
name: 'text',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
hoverRect,
shape: {
content: 'CRender',
position: centerPoint,
maxWidth: 200
},
style: {
fill: '#9ce5f4',
fontSize: 50,
shadowBlur: 0,
rotate: 0,
shadowColor: '#66eece',
hoverCursor: 'pointer',
scale: [1, 1],
rotate: 0
},
mouseEnter (e) {
this.animation('style', { shadowBlur: 20, scale: [1.5, 1.5], rotate: 30 })
},
mouseOuter (e) {
this.animation('style', { shadowBlur: 0, scale: [1, 1], rotate: 0 })
},
moved (e, { hoverRect }) {
const { movementX, movementY } = e
hoverRect[0] += movementX
hoverRect[1] += movementY
}
}
const text = render.add(textConfig)
```
##### Tip
* Graph of **text** should be configured with `hoverRect` to support mouse events.
* You can use `\n` to implement multiple lines of text.
<h3 align="center">Extend New Graph</h3>
CRender provides a Function to extend new graph,you can **customize** the graphics you want.
```javascript
import { extendNewGraph } from '@jiaminghi/c-render'
const graphName = 'newGraph'
const graphConfig = {
shape: { ... },
// ...
}
extendNewGraph(graphName, graphConfig)
```
#### extendNewGraph
```javascript
/**
* @description Extend new graph
* @param {String} name Name of Graph
* @param {Object} config Configuration of Graph
* @return {Undefined} Void
*/
function extendNewGraph (name, config) {
// ...
}
```
#### Graph Configuration Properties
- [shape](#shape-required)
- [validator](#validator-required)
- [draw](#draw-required)
- [hoverCheck](#hoverCheck)
- [setGraphCenter](#setGraphCenter)
- [move](#move)
- [example of extend new graph](#example-of-extend-new-graph)
#### shape (Required)
```javascript
/**
* @type {Object}
* @description Graph shape data
*/
config = {
// ...,
shape: {
// some property...
}
}
```
#### validator (Required)
```javascript
/**
* @type {Function}
* @description Graph configuration check
* Automatically invoked when the graph is added,
* and when the return value is false,
* the add behavior is terminated.
* @param {Graph} Current graph instance
* @return {Boolean} Whether the configuration is legal
*/
config = {
// ...,
validator ({ shape }) {
// check configuration...
// return true | false
}
}
```
#### draw (Required)
```javascript
/**
* @type {Function}
* @description Graph plotter
* @param {CRender} Current CRender instance
* @param {Graph} Current graph instance
* @return {Undefined} Void
*/
config = {
// ...,
draw ({ ctx }, { shape }) {
// drawing...
}
}
```
#### hoverCheck (Optional)
```javascript
/**
* @type {Function}
* @description According to the mouse event to detect
* whether the current graphics are in the hover state,
* support for mouseEnter, mouseOuter, drag, click.
* @param {Array<Number>} Position of mouse
* @param {Graph} Current graph instance
* @return {Boolean} Whether it is in hover
*/
config = {
// ...,
validator ([offsetX, offsetY], { shape }) {
// Check if it is in hover state...
// return true | false
}
}
```
#### setGraphCenter (Optional)
```javascript
/**
* @type {Function}
* @description Set the center point of the graph to
* support rotate, scale and translate.
* Add graph and drag behavior will be called.
* @param {Event} Mouse move Event (Called when adding a graphic, the value is null)
* @param {Graph} Current graph instance
* @return {Undefined} Void
*/
config = {
// ...,
setGraphCenter ([offsetX, offsetY], { style }) {
// style.graphCenter = [offsetX, offsetY]
}
}
```
#### move (Optional)
```javascript
/**
* @type {Function}
* @description Moving graph,support for drag
* @param {Event} Mouse move Event
* @param {Graph} Current graph instance
* @return {Undefined} Void
*/
config = {
// ...,
move ([offsetX, offsetY], { shape }) {
// do something...
}
}
```
#### example of extend new graph
```javascript
import { extendNewGraph } from '@jiaminghi/c-render'
const circle = {
shape: {
rx: 0,
ry: 0,
r: 0
},
validator ({ shape }) {
const { rx, ry, r } = shape
if (typeof rx !== 'number' || typeof ry !== 'number' || typeof r !== 'number') {
console.error('Shape configuration is abnormal!')
return false
}
return true
},
draw ({ ctx }, { shape }) {
ctx.beginPath()
const { rx, ry, r } = shape
ctx.arc(rx, ry, r, 0, Math.PI * 2)
ctx.fill()
ctx.stroke()
ctx.closePath()
},
hoverCheck (position, { shape }) {
const { rx, ry, r } = shape
return checkPointIsInCircle(rx, ry, r, position)
},
setGraphCenter (e, { shape, style }) {
const { rx, ry } = shape
style.graphCenter = [rx, ry]
},
move ({ movementX, movementY }, { shape }) {
this.attr('shape', {
rx: shape.rx + movementX,
ry: shape.ry + movementY
})
}
}
extendNewGraph('circle', circle)
```
<h3 align="center">Related support</h3>
- [Transition](https://github.com/jiaming743/transition/blob/master/README_EN.md)
Provide animation transition data (animationCurve).
If you want to expand the new easing curve, please move [Extend New Easing Curve](https://github.com/jiaming743/Transition/blob/master/README_EN.md#Extend-New-Easing-Curve).
- [BezierCurve](https://github.com/jiaming743/bezierCurve/blob/master/README_EN.md)
Provides support for bezierCurve, such as curve length calculation, conversion between curve and polyline.
- [Color](https://github.com/jiaming743/Color/blob/master/README_EN.md)
Color calculations are provided, such as obtaining the rgba value of the color to facilitate the calculation of the color animation state.

@@ -6,8 +6,8 @@ [ENGLISH](./README_EN.md)

<p align="center">
<a href="https://travis-ci.com/jiaming743/CRender"><img src="https://img.shields.io/travis/com/jiaming743/CRender.svg" alt="Travis CI"></a>
<a href="https://github.com/jiaming743/CRender/blob/master/LICENSE"><img src="https://img.shields.io/github/license/jiaming743/CRender.svg" alt="LICENSE" /></a>
<a href="https://travis-ci.com/DataV-Team/CRender"><img src="https://img.shields.io/travis/com/DataV-Team/CRender.svg" alt="Travis CI"></a>
<a href="https://github.com/DataV-Team/CRender/blob/master/LICENSE"><img src="https://img.shields.io/github/license/DataV-Team/CRender.svg" alt="LICENSE" /></a>
<a href="https://www.npmjs.com/package/@jiaminghi/c-render"><img src="https://img.shields.io/npm/v/@jiaminghi/c-render.svg" alt="version" /></a>
</p>
### CRender是干什么的?
### CRender 是干什么的?

@@ -17,3 +17,3 @@ - 它是一个基于**canvas**的**矢量**图形渲染插件。

### npm安装
### npm 安装

@@ -27,9 +27,8 @@ ```shell

```html
<!--资源位于个人服务器仅供体验和测试,请勿在生产环境使用-->
<!--调试版-->
<script src="http://lib.jiaminghi.com/crender/crender.map.js"></script>
<script src="https://unpkg.com/@jiaminghi/c-render/dist/index.js"></script>
<!--压缩版-->
<script src="http://lib.jiaminghi.com/crender/crender.min.js"></script>
<script src="https://unpkg.com/@jiaminghi/c-render/dist/index.min.js"></script>
<script>
const { CRender, extendNewGraph } = window.CRender
const { CRender, GRAPHS } = window.CRender
// do something

@@ -40,1939 +39,1 @@ </script>

详细文档及示例请移步[HomePage](http://crender.jiaminghi.com).
- [使用](#使用)
- [Class CRender](#class-crender)
- [Class Graph](#class-graph)
- [Class Style](#class-style)
- [示例](#示例)
- [扩展新图形](#扩展新图形)
- [相关支持](#相关支持)
------
<h3 align="center">使用</h3>
```javascript
import CRender from '@jiaminghi/c-redner'
const canvas = document.getElementById('canvas')
// 实例化 CRender
const render = new CRender(canvas)
// 向render中添加图形
const circle = render.add({ name: 'circle', ... })
```
<h3 align="center">Class CRender</h3>
### 类
```javascript
/**
* @description Class of CRender
* @param {Object} canvas Canvas 节点
* @return {CRender} CRender实例
*/
class CRender {
// ...
}
```
### 实例属性
- [ctx](#ctx)
- [area](#area)
- [animationStatus](#animationStatus)
- [graphs](#graphs)
- [color](#color)
- [bezierCurve](#bezierCurve)
#### ctx
```javascript
/**
* @description canvas context
* @type {Object}
* @example ctx = canvas.getContext('2d')
*/
```
#### area
```javascript
/**
* @description canvas宽高
* @type {Array<Number>}
* @example area = [300,100]
*/
```
#### animationStatus
```javascript
/**
* @description render是否处于动画渲染中
* @type {Boolean}
* @example animationStatus = true|false
*/
```
#### graphs
```javascript
/**
* @description 已添加的图形
* @type {Array<Graph>}
* @example graphs = [Graph, Graph, ...]
*/
```
#### [color](https://github.com/jiaming743/color)
```javascript
/**
* @description 颜色插件
* @type {Object}
*/
```
#### [bezierCurve](https://github.com/jiaming743/BezierCurve)
```javascript
/**
* @description 贝塞尔曲线插件
* @type {Object}
*/
```
### 原型方法
- [add](#add)
向render中添加图形
- [clone](#clone)
克隆一个图形
- [delGraph](#delGraph)
删除render中的一个图形
- [delAllGraph](#delAllGraph)
删除render中所有的图形
- [drawAllGraph](#drawAllGraph)
渲染render中所有的图形
- [clearArea](#clearArea)
擦除canvas绘制区域
- [launchAnimation](#launchAnimation)
使动画队列不为空且animationPause不为false的图形进行动画
#### add
```javascript
/**
* @description 向render中添加图形
* @param {Object} config 图形配置
* @return {Graph} 图形实例
*/
CRender.prototype.add = function (config = {}) {
// ...
}
```
#### Clone
```javascript
/**
* @description 克隆一个图形
* @param {Graph} graph 将要被克隆的图形
* @return {Graph} 克隆的图形
*/
CRender.prototype.clone = function (graph) {
}
```
#### delGraph
```javascript
/**
* @description 删除render中的一个图形
* @param {Graph} graph 将要删除的图形实例
* @return {Undefined} 无返回值
*/
CRender.prototype.delGraph = function (graph) {
// ...
}
```
#### delAllGraph
```javascript
/**
* @description 删除render中所有的图形
* @return {Undefined} 无返回值
*/
CRender.prototype.delAllGraph = function () {
// ...
}
```
#### drawAllGraph
```javascript
/**
* @description 渲染render中所有的图形
* @return {Undefined} 无返回值
*/
CRender.prototype.drawAllGraph = function () {
// ...
}
```
#### clearArea
```javascript
/**
* @description 擦除canvas绘制区域
* @return {Undefined} 无返回值
*/
CRender.prototype.clearArea = function () {
// ...
}
```
#### launchAnimation
```javascript
/**
* @description 使动画队列不为空且animationPause不为false的图形进行动画
* @return {Promise} Animation Promise
*/
CRender.prototype.launchAnimation = function () {
// ...
}
```
<h3 align="center">Class Graph</h3>
### 实例属性
**当添加一个图形时,你可以配置这些属性。**
- [visible](#visible)
- [shape](#shape)
- [style](#style)
- [drag](#drag)
- [hover](#hover)
- [index](#index)
- [animationDelay](#animationDelay)
- [animationFrame](#animationFrame)
- [animationCurve](#animationCurve)
- [animationPause](#animationPause)
- [hoverRect](#hoverRect)
- [mouseEnter](#mouseEnter)
- [mouseOuter](#mouseOuter)
- [click](#click)
#### visible
```javascript
/**
* @description 该图形是否可被渲染
* @type {Boolean}
* @default visible = true
*/
```
#### shape
```javascript
/**
* @description 图形形状数据
* @type {Object}
*/
```
#### [style](#Class-Style)
```javascript
/**
* @description 图形样式数据 (Style实例)
* @type {Style}
*/
```
#### drag
```javascript
/**
* @description 是否启用拖拽功能
* @type {Boolean}
* @default drag = false
*/
```
#### hover
```javascript
/**
* @description 是否启用悬浮检测
* @type {Boolean}
* @default hover = false
*/
```
#### index
```javascript
/**
* @description 图形渲染层级,层级高者优先渲染
* @type {Number}
* @default index = 1
*/
```
#### animationDelay
```javascript
/**
* @description 动画延迟时间(ms)
* @type {Number}
* @default animationDelay = 0
*/
```
#### animationFrame
```javascript
/**
* @description 动画帧数
* @type {Number}
* @default animationFrame = 30
*/
```
#### [animationCurve](https://github.com/jiaming743/transition)
```javascript
/**
* @description 动画缓动曲线
* @type {String}
* @default animationCurve = 'linear'
*/
```
#### animationPause
```javascript
/**
* @description 是否暂停图形动画
* @type {Boolean}
* @default animationPause = false
*/
```
#### hoverRect
```javascript
/**
* @description 矩形悬浮检测盒,配置该项则优先使用其进行鼠标悬浮检测
* @type {Null|Array<Number>}
* @default hoverRect = null
* @example hoverRect = [0, 0, 100, 100] // [矩形起始点 x, y 坐标, 矩形宽, 高]
*/
```
#### mouseEnter
```javascript
/**
* @description 鼠标进入图形事件处理器
* @type {Null|Function}
* @default mouseEnter = null
*/
```
#### mouseOuter
```javascript
/**
* @description 鼠标移出图形事件处理器
* @type {Null|Function}
* @default mouseOuter = null
*/
```
#### click
```javascript
/**
* @description 鼠标点击图形事件处理器
* @type {Null|Function}
* @default click = null
*/
```
#### Tip
启用图形的**mouseEnter**,**mouseOuter**,**click**等事件支持需要将`hover`属性配置为`true`。扩展的新图形需要配置**hoverCheck**方法以提供事件支持。
### 原型方法
- [attr](#attr)
更新图形状态
- [animation](#animation)
更新图形状态(伴随动画)
- [animationEnd](#animationEnd)
跳至最后一帧动画
- [pauseAnimation](#pauseAnimation)
暂停动画行为
- [playAnimation](#playAnimation)
尝试动画行为
#### attr
```javascript
/**
* @description 更新图形状态
* @param {String} attrName 要更新的属性名
* @param {Any} change 更新的值
* @return {Undefined} 无返回值
*/
Graph.prototype.attr = function (attrName, change = undefined) {
// ...
}
```
#### animation
```javascript
/**
* @description 更新图形状态(伴随动画),仅支持shape和style属性
* @param {String} attrName 要更新的属性名
* @param {Any} change 更新的值
* @param {Boolean} wait 是否存储动画队列,等待下次动画请求
* @return {Promise} Animation Promise
*/
Graph.prototype.animation = async function (attrName, change, wait = false) {
// ...
}
```
#### animationEnd
```javascript
/**
* @description 跳至最后一帧动画
* @return {Undefined} 无返回值
*/
Graph.prototype.animationEnd = function () {
// ...
}
```
#### pauseAnimation
```javascript
/**
* @description 暂停动画行为
* @return {Undefined} 无返回值
*/
Graph.prototype.pauseAnimation = function () {
// ...
}
```
#### playAnimation
```javascript
/**
* @description 尝试动画行为
* @return {Undefined} 无返回值
*/
Graph.prototype.playAnimation = function () {
// ...
}
```
### 生命周期
当向**render**中添加图形时,你可以配置如下几个方法,它们将在特定时刻被调用。
- [added](#added)
图形添加时被调用
- [beforeDraw](#beforeDraw)
图形绘制前被调用
- [drawed](#drawed)
图形绘制后被调用
- [beforeMove](#beforeMove)
图形移动前被调用
- [moved](#moved)
图形移动后被调用
- [beforeDelete](#beforeDelete)
图形删除前被调用
- [deleted](#deleted)
图形删除后被调用
#### added
```javascript
/**
* @description 图形添加时被调用
* @param {Graph} 图形实例
*/
config = {
//...,
added ({ shape, style }) {
// 一些操作...
}
}
```
#### beforeDraw
```javascript
/**
* @description 图形绘制前被调用,图形样式已经初始化完毕
* 你可以在此时修改ctx属性
* @param {Graph} 图形实例
* @param {CRender} CRender实例
*/
config = {
//...,
beforeDraw ({ shape, style }, { ctx }) {
// 一些操作...
ctx.stroke = 'transparent'
}
}
```
#### drawed
```javascript
/**
* @description 图形绘制后被调用
* @param {Graph} 图形实例
* @param {CRender} CRender实例
*/
config = {
//...,
drawed ({ shape, style }, { ctx }) {
// 一些操作...
}
}
```
#### beforeMove
```javascript
/**
* @description 图形移动前被调用,移动行为发生前
* @param {Event} 鼠标事件
* @param {Graph} 图形实例
*/
config = {
//...,
beforeMove ({ offsetX, offsetY }, { shape, style }) {
// 一些操作...
}
}
```
#### moved
```javascript
/**
* @description 图形移动后被调用,移动行为发生后
* @param {Event} 鼠标事件
* @param {Graph} 图形实例
*/
config = {
//...,
moved ({ offsetX, offsetY }, { shape, style }) {
// 一些操作...
}
}
```
#### beforeDelete
```javascript
/**
* @description 图形删除前被调用
* @param {Graph} 图形实例
*/
config = {
//...,
beforeDelete ({ shape, style }) {
// 一些操作...
}
}
```
#### deleted
```javascript
/**
* @description 图形删除后被调用
* @param {Graph} 图形实例
*/
config = {
//...,
deleted ({ shape, style }) {
// 一些操作...
}
}
```
<h3 align="center">Class Style</h3>
### 实例属性
- [fill](#fill)
- [stroke](#stroke)
- [opacity](#opacity)
- [lineCap](#lineCap)
- [lineJoin](#)
- [lineDash](#lineDash)
- [lineDashOffset](#lineDashOffset)
- [shadowBlur](#shadowBlur)
- [shadowColor](#shadowColor)
- [shadowOffsetX](#shadowOffsetX)
- [shadowOffsetY](#shadowOffsetY)
- [lineWidth](#lineWidth)
- [graphCenter](#graphCenter)
- [scale](#scale)
- [rotate](#rotate)
- [translate](#translate)
- [hoverCursor](#hoverCursor)
- [fontStyle](#fontStyle)
- [fontVarient](#fontVarient)
- [fontWeight](#fontWeight)
- [fontSize](#fontSize)
- [fontFamily](#fontFamily)
- [textAlign](#textAlign)
- [textBaseline](#textBaseline)
- [gradientColor](#gradientColor)
- [gradientType](#gradientType)
- [gradientParams](#gradientParams)
- [gradientWith](#gradientWith)
- [gradientStops](#gradientStops)
- [colors](#colors)
#### fill
```javascript
/**
* @description 图形填充颜色的Rgba值
* @type {Array<Number>}
* @default fill = [0, 0, 0, 1]
*/
```
#### stroke
```javascript
/**
* @description 图形描边颜色的Rgba值
* @type {Array<Number>}
* @default stroke = [0, 0, 0, 1]
*/
```
#### opacity
```javascript
/**
* @description 图形透明度
* @type {Number}
* @default opacity = 1
*/
```
#### lineCap
```javascript
/**
* @description Ctx的lineCap属性值
* @type {Null|String}
* @default lineCap = null
* @example lineCap = 'butt'|'round'|'square'
*/
```
#### lineJoin
```javascript
/**
* @description Ctx的lineJoin属性值
* @type {Null|String}
* @default lineJoin = null
* @example lineJoin = 'round'|'bevel'|'miter'
*/
```
#### lineDash
```javascript
/**
* @description Ctx的lineDash属性值
* @type {Null|Array<Number>}
* @default lineDash = null
* @example lineDash = [10, 10]
*/
```
#### lineDashOffset
```javascript
/**
* @description Ctx的lineDashOffset属性值
* @type {Null|Number}
* @default lineDashOffset = null
* @example lineDashOffset = 10
*/
```
#### shadowBlur
```javascript
/**
* @description Ctx的shadowBlur属性值
* @type {Number}
* @default shadowBlur = 0
*/
```
#### shadowColor
```javascript
/**
* @description 图形阴影颜色的Rgba值
* @type {Array<Number>}
* @default shadowColor = [0, 0, 0, 0]
*/
```
#### shadowOffsetX
```javascript
/**
* @description Ctx的shadowOffsetX属性值
* @type {Number}
* @default shadowOffsetX = 0
*/
```
#### shadowOffsetY
```javascript
/**
* @description Ctx的shadowOffsetY属性值
* @type {Number}
* @default shadowOffsetY = 0
*/
```
#### lineWidth
```javascript
/**
* @description Ctx的lineWidth属性值
* @type {Number}
* @default lineWidth = 0
*/
```
#### graphCenter
```javascript
/**
* @description 图形中心点
* @type {Null|Array<Number>}
* @default graphCenter = null
* @example graphCenter = [10, 10]
*/
```
#### scale
```javascript
/**
* @description 图形缩放倍数
* @type {Null|Array<Number>}
* @default scale = null
* @example scale = [1.5, 1.5]
*/
```
#### rotate
```javascript
/**
* @description 图形旋转角度
* @type {Null|Number}
* @default rotate = null
* @example rotate = 10
*/
```
#### translate
```javascript
/**
* @description 图形位移距离
* @type {Null|Array<Number>}
* @default translate = null
* @example translate = [10, 10]
*/
```
#### hoverCursor
```javascript
/**
* @description 鼠标悬浮在图形上时cursor的值
* @type {String}
* @default hoverCursor = 'pointer'
* @example hoverCursor = 'default'|'pointer'|'auto'|'crosshair'|'move'|'wait'|...
*/
```
#### fontStyle
```javascript
/**
* @description Ctx的fontStyle属性值
* @type {String}
* @default fontStyle = 'normal'
* @example fontStyle = 'normal'|'italic'|'oblique'
*/
```
#### fontVarient
```javascript
/**
* @description Ctx的fontVarient属性值
* @type {String}
* @default fontVarient = 'normal'
* @example fontVarient = 'normal'|'small-caps'
*/
```
#### fontWeight
```javascript
/**
* @description Ctx的fontWeight属性值
* @type {String|Number}
* @default fontWeight = 'normal'
* @example fontWeight = 'normal'|'bold'|'bolder'|'lighter'|Number
*/
```
#### fontSize
```javascript
/**
* @description Ctx的fontSize属性值
* @type {Number}
* @default fontSize = 10
*/
```
#### fontFamily
```javascript
/**
* @description Ctx的fontFamily属性值
* @type {String}
* @default fontFamily = 'Arial'
*/
```
#### textAlign
```javascript
/**
* @description Ctx的textAlign属性值
* @type {String}
* @default textAlign = 'center'
* @example textAlign = 'start'|'end'|'left'|'right'|'center'
*/
```
#### textBaseline
```javascript
/**
* @description Ctx的textBaseline属性值
* @type {String}
* @default textBaseline = 'middle'
* @example textBaseline = 'top'|'bottom'|'middle'|'alphabetic'|'hanging'
*/
```
#### gradientColor
```javascript
/**
* @description 用于创建渐变色的颜色
* @type {Null|Array<String>}
* @default gradientColor = null
* @example gradientColor = ['#000', '#111', '#222']
*/
```
#### gradientType
```javascript
/**
* @description 渐变类型
* @type {String}
* @default gradientType = 'linear'
* @example gradientType = 'linear' | 'radial'
*/
```
#### gradientParams
```javascript
/**
* @description 渐变参数
* @type {Array<Number>}
* @default gradientParams = null
* @example gradientParams = [x0, y0, x1, y1] (线性渐变)
* @example gradientParams = [x0, y0, r0, x1, y1, r1] (径向渐变)
*/
```
#### gradientWith
```javascript
/**
* @description 使用渐变色的属性
* @type {String}
* @default gradientWith = 'stroke'
* @example gradientWith = 'stroke' | 'fill'
*/
```
#### gradientStops
```javascript
/**
* @description 渐变色位置
* @type {String|Array<Number>}
* @default gradientStops = 'auto'
* @example gradientStops = 'auto' | [0, .2, .3, 1]
*/
```
#### colors
```javascript
/**
* @description 支持动画过渡的颜色容器
* @type {Array<String>|Object}
* @default colors = null
* @example colors = ['#000', '#111', '#222']
* @example colors = { a: '#000', b: '#111' }
*/
```
#### Tip
`gradientColor`和`gradientParams`被配置后将自动启用**渐变**。
### 原型方法
- [getStyle](#getStyle)
获取图形当前样式配置
#### getStyle
```javascript
/**
* @description 获取图形当前样式配置
* @return {Object} 样式配置
*/
Style.prototype.getStyle = function () {
}
```
<h3 align="center">示例</h3>
CRender提供如下基础矢量图形。
- [圆形](#圆形)
- [椭圆形](#椭圆形)
- [矩形](#矩形)
- [环形](#环形)
- [弧形](#弧形)
- [扇形](#扇形)
- [正多边形](#正多边形)
- [折线](#折线)
- [折线(闭合)](#折线(闭合))
- [光滑曲线](#光滑曲线)
- [光滑曲线(闭合)](#光滑曲线(闭合))
- [贝塞尔曲线](#贝塞尔曲线)
- [贝塞尔曲线(闭合)](#贝塞尔曲线(闭合))
- [文本](#文本)
#### 圆形
##### shape属性
| 属性名 | 类型 | 默认值 | 注解 |
| :---: | :---: | :---: | :---: |
| rx | `Number` | `0` | 圆心x轴坐标 |
| ry | `Number` | `0` | 圆心y轴坐标 |
| r | `Number` | `0` | 圆半径 |
```javascript
const { area: [w, h] } = render
const circleConfig = {
name: 'circle',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
rx: w / 2,
ry: h / 2,
r: 50
},
style: {
fill: '#9ce5f4',
shadowBlur: 0,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('shape', { r: 70 }, true)
this.animation('style', { shadowBlur: 20 })
},
mouseOuter (e) {
this.animation('shape', { r: 50 }, true)
this.animation('style', { shadowBlur: 0 })
}
}
const circle = render.add(circleConfig)
```
#### 椭圆形
##### shape属性
| 属性名 | 类型 | 默认值 | 注解 |
| :---: | :---: | :---: | :---: |
| rx | `Number` | `0` | 圆心x轴坐标 |
| ry | `Number` | `0` | 圆心y轴坐标 |
| hr | `Number` | `0` | 横轴半径 |
| vr | `Number` | `0` | 竖轴半径 |
```javascript
const { area: [w, h] } = render
const ellipseConfig = {
name: 'ellipse',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
rx: w / 2,
ry: h / 2,
hr: 80,
vr: 30
},
style: {
fill: '#9ce5f4',
shadowBlur: 0,
shadowColor: '#66eece',
scale: [1, 1],
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('style', { scale: [1.5, 1.5], shadowBlur: 20 })
},
mouseOuter (e) {
this.animation('style', { scale: [1, 1], shadowBlur: 0 })
}
}
const ellipse = render.add(ellipseConfig)
```
#### 矩形
##### shape属性
| 属性名 | 类型 | 默认值 | 注解 |
| :---: | :---: | :---: | :---: |
| x | `Number` | `0` | 矩形左上角x轴坐标 |
| y | `Number` | `0` | 矩形左上角y轴坐标 |
| w | `Number` | `0` | 矩形宽度 |
| h | `Number` | `0` | 矩形高度 |
```javascript
const { area: [w, h] } = render
const rectConfig = {
name: 'rect',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
x: w / 2 - rectWidth / 2,
y: h / 2 - rectHeight / 2,
w: rectWidth,
h: rectHeight
},
style: {
fill: '#9ce5f4',
shadowBlur: 0,
shadowColor: '#66eece',
hoverCursor: 'pointer',
translate: [0, 0]
},
mouseEnter (e) {
this.animation('shape', { w: 400 }, true)
this.animation('style', { shadowBlur: 20, translate: [-100, 0] })
},
mouseOuter (e) {
this.animation('shape', { w: 200 }, true)
this.animation('style', { shadowBlur: 0, translate: [0, 0] })
}
}
const rect = render.add(rectConfig)
```
#### 环形
##### shape属性
| 属性名 | 类型 | 默认值 | 注解 |
| :---: | :---: | :---: | :---: |
| rx | `Number` | `0` | 中心点x轴坐标 |
| ry | `Number` | `0` | 中心点y轴坐标 |
| r | `Number` | `0` | 环半径 |
```javascript
const { area: [w, h] } = render
const ringConfig = {
name: 'ring',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
rx: w / 2,
ry: h / 2,
r: 50
},
style: {
stroke: '#9ce5f4',
lineWidth: 20,
hoverCursor: 'pointer',
shadowBlur: 0,
shadowColor: '#66eece'
},
mouseEnter (e) {
this.animation('style', { shadowBlur: 20, lineWidth: 30 })
},
mouseOuter (e) {
this.animation('style', { shadowBlur: 0, lineWidth: 20 })
}
}
const ring = render.add(ringConfig)
```
#### 弧形
##### shape属性
| 属性名 | 类型 | 默认值 | 注解 |
| :---: | :---: | :---: | :---: |
| rx | `Number` | `0` | 中心点x轴坐标 |
| ry | `Number` | `0` | 中心点y轴坐标 |
| r | `Number` | `0` | 弧半径 |
| startAngle | `Number` | `0` | 弧起始弧度值 |
| endAngle | `Number` | `0` | 弧结束弧度值 |
| clockWise | `Boolean` | `true` | 是否顺时针 |
```javascript
const { area: [w, h] } = render
const arcConfig = {
name: 'arc',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
rx: w / 2,
ry: h / 2,
r: 60,
startAngle: 0,
endAngle: Math.PI / 3
},
style: {
stroke: '#9ce5f4',
lineWidth: 20,
shadowBlur: 0,
rotate: 0,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('shape', { endAngle: Math.PI }, true)
this.animation('style', { shadowBlur: 20, rotate: -30, lineWidth: 30 })
},
mouseOuter (e) {
this.animation('shape', { endAngle: Math.PI / 3 }, true)
this.animation('style', { shadowBlur: 0, rotate: 0, lineWidth: 20 })
}
}
const arc = render.add(arcConfig)
```
#### 扇形
##### shape属性
| 属性名 | 类型 | 默认值 | 注解 |
| :---: | :---: | :---: | :---: |
| rx | `Number` | `0` | 中心点x轴坐标 |
| ry | `Number` | `0` | 中心点y轴坐标 |
| r | `Number` | `0` | 扇形半径 |
| startAngle | `Number` | `0` | 扇形起始弧度值 |
| endAngle | `Number` | `0` | 扇形结束弧度值 |
| clockWise | `Boolean` | `true` | 是否顺时针 |
```javascript
const { area: [w, h] } = render
const sectorConfig = {
name: 'sector',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
rx: w / 2,
ry: h / 2,
r: 60,
startAngle: 0,
endAngle: Math.PI / 3
},
style: {
fill: '#9ce5f4',
shadowBlur: 0,
rotate: 0,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('shape', { endAngle: Math.PI, r: 70 }, true)
this.animation('style', { shadowBlur: 20, rotate: -30, lineWidth: 30 })
},
mouseOuter (e) {
this.animation('shape', { endAngle: Math.PI / 3, r: 60 }, true)
this.animation('style', { shadowBlur: 0, rotate: 0, lineWidth: 20 })
}
}
const sector = render.add(sectorConfig)
```
#### 正多边形
##### shape属性
| 属性名 | 类型 | 默认值 | 注解 |
| :---: | :---: | :---: | :---: |
| rx | `Number` | `0` | 中心点x轴坐标 |
| ry | `Number` | `0` | 中心点y轴坐标 |
| r | `Number` | `0` | 外接圆半径 |
| side | `Number` | `0` | 边数 |
```javascript
const { area: [w, h] } = render
const regPolygonConfig = {
name: 'regPolygon',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
rx: w / 2,
ry: h / 2,
r: 60,
side: 6
},
style: {
fill: '#9ce5f4',
hoverCursor: 'pointer',
shadowBlur: 0,
rotate: 0,
shadowColor: '#66eece'
},
mouseEnter (e) {
this.animation('shape', { endAngle: Math.PI, r: 100 }, true)
this.animation('style', { shadowBlur: 20, rotate: 180 })
},
mouseOuter (e) {
this.animation('shape', { endAngle: Math.PI / 3, r: 60 }, true)
this.animation('style', { shadowBlur: 0, rotate: 0 })
}
}
const regPolygon = render.add(regPolygonConfig)
```
#### 折线
##### shape属性
| 属性名 | 类型 | 默认值 | 注解 |
| :---: | :---: | :---: | :---: |
| points | `Array` | `[]` | 构成折线的点 |
| close | `Boolean` | `false` | 是否闭合折线 |
```javascript
const { area: [w, h] } = render
const top = h / 3
const bottom = h / 3 * 2
const gap = w / 10
const beginX = w / 2 - gap * 2
const points = new Array(5).fill('').map((t, i) =>
[beginX + gap * i, i % 2 === 0 ? top : bottom])
const polylineConfig = {
name: 'polyline',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
points
},
style: {
stroke: '#9ce5f4',
shadowBlur: 0,
lineWidth: 10,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('style', { lineWidth: 20, shadowBlur: 20 })
},
mouseOuter (e) {
this.animation('style', { lineWidth: 10, shadowBlur: 0 })
}
}
const polyline = render.add(polylineConfig)
```
#### 折线(闭合)
```javascript
const { area: [w, h] } = render
const top = h / 3
const bottom = h / 3 * 2
const gap = w / 10
const beginX = w / 2 - gap * 2
const points = new Array(5).fill('').map((t, i) =>
[beginX + gap * i, i % 2 === 0 ? top : bottom])
points[2][1] += top * 1.3
const polylineClosedConfig = {
name: 'polyline',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
points,
close: true
},
style: {
fill: '#9ce5f4',
shadowBlur: 0,
lineWidth: 10,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('style', { shadowBlur: 20 }, true)
const pointsCloned = deepClone(this.shape.points)
pointsCloned[2][1] += top * 0.3
this.animation('shape', { points: pointsCloned })
},
mouseOuter (e) {
this.animation('style', { shadowBlur: 0 }, true)
const pointsCloned = deepClone(this.shape.points)
pointsCloned[2][1] -= top * 0.3
this.animation('shape', { points: pointsCloned })
}
}
const polylineClosed = render.add(polylineClosedConfig)
```
#### 光滑曲线
##### shape属性
| 属性名 | 类型 | 默认值 | 注解 |
| :---: | :---: | :---: | :---: |
| points | `Array` | `[]` | 构成光滑曲线的点 |
| close | `Boolean` | `false` | 是否闭合光滑曲线 |
```javascript
const { area: [w, h] } = render
const top = h / 3
const bottom = h / 3 * 2
const gap = w / 10
const beginX = w / 2 - gap * 2
const points = new Array(5).fill('').map((t, i) =>
[beginX + gap * i, i % 2 === 0 ? top : bottom])
const smoothlineConfig = {
name: 'smoothline',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
points
},
style: {
stroke: '#9ce5f4',
shadowBlur: 0,
lineWidth: 10,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('style', { lineWidth: 20, shadowBlur: 20 })
},
mouseOuter (e) {
this.animation('style', { lineWidth: 10, shadowBlur: 0 })
}
}
const smoothline = render.add(smoothlineConfig)
```
#### 光滑曲线(闭合)
```javascript
import { getCircleRadianPoint } from '../../CRender/lib/util'
function getPoints (radius, centerPoint, pointNum) {
const PIDived = Math.PI * 2 / pointNum
const points = new Array(pointNum).fill('')
.map((foo, i) =>
getCircleRadianPoint(...centerPoint, radius, PIDived * i)
)
return points
}
const { area: [w, h] } = render
const radius = h / 3
const centerPoint = [w / 2, h / 2]
const smoothlineClosedConfig = {
name: 'smoothline',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
points: getPoints(radius, centerPoint, 3),
close: true
},
style: {
fill: '#9ce5f4',
shadowBlur: 0,
lineWidth: 10,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('style', { lineWidth: 20, shadowBlur: 20, rotate: 120 })
},
mouseOuter (e) {
this.animation('style', { lineWidth: 10, shadowBlur: 0, rotate: 0 })
},
setGraphCenter (e, { style }) {
if (e) {
const { movementX, movementY } = e
const [cx, cy] = style.graphCenter
style.graphCenter = [cx + movementX, cy + movementY]
} else {
style.graphCenter = [...centerPoint]
}
}
}
const smoothlineClosed = render.add(smoothlineClosedConfig)
```
#### 贝塞尔曲线
##### shape属性
| 属性名 | 类型 | 默认值 | 注解 |
| :---: | :---: | :---: | :---: |
| points | `Array` | `[]` | 构成贝塞尔曲线的点 |
| close | `Boolean` | `false` | 是否闭合贝塞尔曲线 |
```javascript
const { area: [w, h] } = render
const offsetX = w / 2
const offsetY = h / 2
const points = [
// 起始点
[-100 + offsetX, -50 + offsetY],
// 多段贝塞尔曲线
[
// 控制点1,控制点2,结束点
[0 + offsetX, -50 + offsetY],
[0 + offsetX, 50 + offsetY],
[100 + offsetX, 50 + offsetY]
],
// [...],[...]
]
const bezierCurveConfig = {
name: 'bezierCurve',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
points
},
style: {
lineWidth: 10,
stroke: '#9ce5f4',
shadowBlur: 0,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e) {
this.animation('style', { lineWidth: 20, shadowBlur: 20 })
},
mouseOuter (e) {
this.animation('style', { lineWidth: 10, shadowBlur: 0 })
}
}
const bezierCurve = render.add(bezierCurveConfig)
```
#### 贝塞尔曲线(闭合)
```javascript
import { getCircleRadianPoint } from '../../CRender/lib/util'
function getPetalPoints (insideRadius, outsideRadius, petalNum, petalCenter) {
const PI2Dived = Math.PI * 2 / (petalNum * 3)
let points = new Array(petalNum * 3).fill('')
.map((foo, i) =>
getCircleRadianPoint(...petalCenter,
i % 3 === 0 ? insideRadius : outsideRadius,
PI2Dived * i)
)
const startPoint = points.shift()
points.push(startPoint)
points = new Array(petalNum).fill('')
.map(foo => points.splice(0, 3))
points.unshift(startPoint)
return points
}
const { area: [w, h] } = render
const petalCenter = [w / 2, h / 2]
const [raidus1, raidus2, raidus3, raidus4] = [h / 6, h / 2.5, h / 3, h / 2]
const bezierCurveClosedConfig = {
name: 'bezierCurve',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
shape: {
points: getPetalPoints(raidus1, raidus2, 6, petalCenter),
close: true
},
style: {
fill: '#9ce5f4',
shadowBlur: 0,
shadowColor: '#66eece',
hoverCursor: 'pointer'
},
mouseEnter (e, { style: { graphCenter } }) {
this.animation('style', { lineWidth: 20, shadowBlur: 20 }, true)
this.animation('shape', { points: getPetalPoints(raidus3, raidus4, 6, graphCenter) })
},
mouseOuter (e, { style: { graphCenter } }) {
this.animation('style', { lineWidth: 10, shadowBlur: 0 }, true)
this.animation('shape', { points: getPetalPoints(raidus1, raidus2, 6, graphCenter) })
},
setGraphCenter (e, { style }) {
if (e) {
const { movementX, movementY } = e
const [cx, cy] = style.graphCenter
style.graphCenter = [cx + movementX, cy + movementY]
} else {
style.graphCenter = [...petalCenter]
}
}
}
const bezierCurveClosed = render.add(bezierCurveClosedConfig)
```
#### 文本
##### shape属性
| 属性名 | 类型 | 默认值 | 注解 |
| :---: | :---: | :---: | :---: |
| content | `String` | `''` | 文本内容 |
| position | `Array` | `[0, 0]` | 文本起始位置 |
| maxWidth | `Number` | `Undefined` | 文本最大宽度 |
| rowGap | `Number` | `0` | 行间距 |
```javascript
const { area: [w, h] } = render
const centerPoint = [w / 2, h / 2]
const hoverRect = [w / 2 - 100, h / 2 - 30 ,200, 60]
const textConfig = {
name: 'text',
animationCurve: 'easeOutBack',
hover: true,
drag: true,
hoverRect,
shape: {
content: 'CRender',
position: centerPoint,
maxWidth: 200
},
style: {
fill: '#9ce5f4',
fontSize: 50,
shadowBlur: 0,
rotate: 0,
shadowColor: '#66eece',
hoverCursor: 'pointer',
scale: [1, 1],
rotate: 0
},
mouseEnter (e) {
this.animation('style', { shadowBlur: 20, scale: [1.5, 1.5], rotate: 30 })
},
mouseOuter (e) {
this.animation('style', { shadowBlur: 0, scale: [1, 1], rotate: 0 })
},
moved (e, { hoverRect }) {
const { movementX, movementY } = e
hoverRect[0] += movementX
hoverRect[1] += movementY
}
}
const text = render.add(textConfig)
```
##### Tip
* 图形**text**的鼠标事件依赖`hoverRect`属性,如需鼠标事件生效请对其配置
* 文本中插入`\n`可以进行换行。
<h3 align="center">扩展新图形</h3>
CRender提供了一个方法去扩展新的图形,你可以**自定义**想要的图形。
```javascript
import { extendNewGraph } from '@jiaminghi/c-render'
const graphName = 'newGraph'
const graphConfig = {
shape: { ... },
// ...
}
extendNewGraph(graphName, graphConfig)
```
#### extendNewGraph
```javascript
/**
* @description 扩展新图形
* @param {String} name 图形名称
* @param {Object} config 图形配置
* @return {Undefined} 无返回值
*/
function extendNewGraph (name, config) {
// ...
}
```
#### 图形配置属性
- [shape](#shape-required)
- [validator](#validator-required)
- [draw](#draw-required)
- [hoverCheck](#hoverCheck)
- [setGraphCenter](#setGraphCenter)
- [move](#move)
- [扩展示例](#扩展示例)
#### shape (必须)
```javascript
/**
* @type {Object}
* @description 图形形状数据
*/
config = {
// ...,
shape: {
// 一些属性...
}
}
```
#### validator (必须)
```javascript
/**
* @type {Function}
* @description 图形添加时将被调用,用于检测图形配置是否合法,
* 若返回值为false则终止添加行为
* @param {Graph} 当前图形实例
* @return {Boolean} 配置是否合法
*/
config = {
// ...,
validator ({ shape }) {
// 检查图形配置...
// return true | false
}
}
```
#### draw (必须)
```javascript
/**
* @type {Function}
* @description 图形绘制器
* @param {CRender} 当前CRender实例
* @param {Graph} 当前图形实例
* @return {Undefined} 无返回值
*/
config = {
// ...,
draw ({ ctx }, { shape }) {
// 绘制...
}
}
```
#### hoverCheck (可选)
```javascript
/**
* @type {Function}
* @description 通过鼠标位置去判断当前图形是否处于鼠标悬浮状态,
* 用于给mouseEnter, mouseOuter, drag, click事件提供支持。
* @param {Array<Number>} 鼠标位置
* @param {Graph} 当前图形实例
* @return {Boolean} 是否处于鼠标悬浮状态
*/
config = {
// ...,
validator ([offsetX, offsetY], { shape }) {
// 检测是否处于鼠标悬浮状态...
// return true | false
}
}
```
#### setGraphCenter (可选)
```javascript
/**
* @type {Function}
* @description 设置图形中心点
* 提供rotate, scale and translate支持
* 添加图形及图形被拖动后将被调用
* @param {Event} 鼠标事件 (图形被添加时调用,该参数为null)
* @param {Graph} 当前图形实例
* @return {Undefined} 无返回值
*/
config = {
// ...,
setGraphCenter ([offsetX, offsetY], { style }) {
// style.graphCenter = [offsetX, offsetY]
}
}
```
#### move (Optional)
```javascript
/**
* @type {Function}
* @description Moving graph,support for drag
* @param {Event} Mouse move Event
* @param {Graph} Current graph instance
* @return {Undefined} Void
*/
config = {
// ...,
move ([offsetX, offsetY], { shape }) {
// 一些操作...
}
}
```
#### 扩展示例
```javascript
import { extendNewGraph } from '@jiaminghi/c-render'
const circle = {
shape: {
rx: 0,
ry: 0,
r: 0
},
validator ({ shape }) {
const { rx, ry, r } = shape
if (typeof rx !== 'number' || typeof ry !== 'number' || typeof r !== 'number') {
console.error('Shape configuration is abnormal!')
return false
}
return true
},
draw ({ ctx }, { shape }) {
ctx.beginPath()
const { rx, ry, r } = shape
ctx.arc(rx, ry, r, 0, Math.PI * 2)
ctx.fill()
ctx.stroke()
ctx.closePath()
},
hoverCheck (position, { shape }) {
const { rx, ry, r } = shape
return checkPointIsInCircle(rx, ry, r, position)
},
setGraphCenter (e, { shape, style }) {
const { rx, ry } = shape
style.graphCenter = [rx, ry]
},
move ({ movementX, movementY }, { shape }) {
this.attr('shape', {
rx: shape.rx + movementX,
ry: shape.ry + movementY
})
}
}
extendNewGraph('circle', circle)
```
<h3 align="center">相关支持</h3>
- [Transition](https://github.com/jiaming743/transition)
提供动画过渡数据 (animationCurve)。
如果你想扩展新的缓动曲线,请移步 [扩展新曲线](http://transition.jiaminghi.com/guide/#扩展缓动曲线).
- [BezierCurve](https://github.com/jiaming743/bezierCurve)
提供贝塞尔曲线支持,例如计算曲线长度,曲线折线互转。
- [Color](https://github.com/jiaming743/Color)
提供了颜色计算,例如获取颜色的rgba值,以便于颜色动画状态的计算。

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc