Cax
Canvas 渲染引擎,支持 SVG,兼容了小程序、小游戏和 Web
* Simple API, Lightweight and High performance * Support PC and Mobile Canvas 2D Rendering and Mouse and Touch Event * Support event of element and element management like DOM * Turing complete group nesting system * Support clip and clip transformation * Built-in Text, Bitmap, Sprite, Graphics and Shape * Support [SVG Path](https://github.com/dntzhang/cax/blob/master/packages/cax/src/render/display/shape/path.js) rendering * Support [CSS filter](https://github.com/dntzhang/cax/tree/master/packa... The project is written primarily in JavaScript, first published in 2012. It has gained significant community traction with 2,126 stars and 321 forks on GitHub. Key topics include: 2d, canvas, minigame, miniprogram, render.
English | 简体中文
Cax 
Canvas 2D Rendering Engine
Features
- Simple API, Lightweight and High performance
- Support PC and Mobile Canvas 2D Rendering and Mouse and Touch Event
- Support event of element and element management like DOM
- Turing complete group nesting system
- Support clip and clip transformation
- Built-in Text, Bitmap, Sprite, Graphics and Shape
- Support SVG Path rendering
- Support CSS filter
- Built-in images loader
- Built-in cross platform motion library → to2to
Demo
- Wechart by Cax

- Simple
- Animation
- Clip
- Clip Transform
- Clip Transition
- To2To Animate
- Swing
- Cax + Matter
- Pie Chart
- To + Shape
- Vision
- Cache
- Filter
- SVG
- Graphics
- Composite Operation
- Cax + Dragonbones
Docs
- Getting Started
- Built-in Object
- Property
- Method
- Event
- Motion
- Clip
- Custom Object
- Who is using cax?
- License
Getting Started
Get cax through npm or cdn:
bashnpm i cax
Usage:
jsimport cax from 'cax' const stage = new cax.Stage(200, 200, 'body') cax.loadImgs({ imgs: ['./test.jpg'], complete: (imgs) => { const img = imgs[0] const bitmap = new cax.Bitmap(img) bitmap.x = stage.width / 2 bitmap.y = stage.height / 2 bitmap.rotation = -10 bitmap.originX = img.width / 2 bitmap.originY = img.height / 2 bitmap.filter('blur(10px)') stage.add(bitmap) stage.update() } })
Built-in Object
Group
For grouping, group can also nested group, and the parent container's properties will be superimposed on child properties, such as:
- the x of group is 100, the x of bitmap in group is 200, and the x of the bitmap rendered to stage is 300.
- the alpha of group is 0.7, the alpha of bitmap in group is 0.6, and the alpha of the bitmap rendered to stage is 0.42.
jsconst group = new cax.Group() const rect = new cax.Rect(100, 100, { fillStyle: 'black' }) group.add(rect) stage.add(group) stage.update()
Group has commonly used add and remove methods to add and delete elements. The first add will be drawn first, and all subsequent add will be covered above the top add.
Group Method
add
add child to group
jsgroupObj.add(child)
remove
remove child from group
jsgroupObj.remove(child)
empty
remove all the children from group
jsgroupObj.empty()
replace
replace child by another obj
jsgroupObj.replace(current, prev)
Stage
Stage is the largest top container inherited from Group, so have all the methods and props of Group.
Stage Method
update
Any element can't be seen on the stage. You must execute the update method.
jsstage.update()
Any element property is modified. Please perform stage.update() to update the stage, or put it in the timer.
jscax.tick(stage.update.bind(stage))
scaleEventPoint
When the height of the canvas and the pixels of the canvas are not one-to-one, the event triggering position is inaccurate, and you can use the scaleEventPoint method to make the event correct.
js//The width of the canvas is half the canvas pixel stage.scaleEventPoint(0.5, 0.5)
Example: https://github.com/dntzhang/cax/blob/master/packages/cax/examples/pie/main.js#L218-L220
Stage Prop
disableMoveDetection
Disable event detection for mouse or touch mobile. Default value in the web is false. You can change it:
jsstage.disableMoveDetection = true
moveDetectionInterval
Set the touchmove and mousemove detection interval by moveDetectionInterval.
js//check twice in one second stage.moveDetectionInterval = 500
Bitmap
jsconst bitmap = new cax.Bitmap(img) stage.add(bitmap) stage.update()
If you only transmit URL instead of the instance of the Image object, you need to do this:
jsconst bitmap = new cax.Bitmap('./wepay.png', ()=>{ stage.update() }) stage.add(bitmap)
bitmap-prop
rect
You can set the picture clipping display area, and other transform attributes:
jsbitmap.rect = [0, 0, 170, 140] bitmap.x = 200 bitmap.rotation = 30
Sprite
The sequence frame animation component can combine any region of any picture into a series of animations.
jsconst sprite = new cax.Sprite({ framerate: 7, imgs: ['./mario-sheet.png'], frames: [ // x, y, width, height, originX, originY ,imageIndex [0, 0, 32, 32], [32 * 1, 0, 32, 32], [32 * 2, 0, 32, 32], [32 * 3, 0, 32, 32], [32 * 4, 0, 32, 32], [32 * 5, 0, 32, 32], [32 * 6, 0, 32, 32], [32 * 7, 0, 32, 32], [32 * 8, 0, 32, 32], [32 * 9, 0, 32, 32], [32 * 10, 0, 32, 32], [32 * 11, 0, 32, 32], [32 * 12, 0, 32, 32], [32 * 13, 0, 32, 32], [32 * 14, 0, 32, 32] ], animations: { walk: { frames: [0, 1] }, happy: { frames: [5, 6, 7, 8, 9] }, win: { frames: [12] } }, playOnce: false, currentAnimation: "walk", animationEnd: function () { } });
Sprite Method
gotoAndPlay
Jump to the current animationName and start playing
jsspriteObj.gotoAndPlay(animationName)
gotoAndStop
Jump to the current animationName and stop
jsspriteObj.gotoAndStop(animationName)
gotoAndPlayOnce
Jump to the current animationName and start playing, then destroy yourself after animation. Often used in explosions
jsspriteObj.gotoAndPlayOnce(animationName)
Text
Text object
jsconst text = new cax.Text('Hello World', { font: '20px Arial', color: '#ff7700', baseline: 'top' })
Method
getWidth
Get text width
jstextObj.getWidth()
Graphics
The drawing object is used to draw graphics with Canvas instructions in the basic way of linking.
jsconst graphics = new cax.Graphics() graphics .beginPath() .arc(0, 0, 10, 0, Math.PI * 2) .closePath() .fillStyle('#f4862c') .fill() .strokeStyle('black') .stroke() graphics.x = 100 graphics.y = 200 stage.add(graphics)
In particular, if you perform a graphics connection rendering operation in a loop, be sure to add the clear () method, or the path will be overloaded to your browser:
jscax.setInterval(function(){ graphics .clear() .beginPath() .arc(0, 0, 10, 0, Math.PI * 2) .stroke() }, 16)
Shape
Unlike Graphics, Shape usually has limited width height, so it can be buffered with off screen Canvas. The following are Shape.
Rect
jsconst rect = new cax.Rect(200, 100, { fillStyle: 'black' })
Circle
jsconst circle = new cax.Circle(10)
Ellipse
jsconst ellipse = new cax.Ellipse(120, 20)
Element
Element is a combination of multiple elements, such as Bitmap, Group, Text, Shape and other mixed images.
Button
jsconst button = new cax.Button({ width: 100, height: 40, text: "Click Me!" })
Property
Transform
| name | Describe |
|---|---|
| x | Horizontal offset |
| y | Vertical offset |
| scaleX | Horizontal scaling |
| scaleY | Vertical scaling |
| scale | Horizontal and Vertical scaling |
| rotation | rotation |
| skewX | skewX |
| skewY | skewY |
| originX | Rotation base point X |
| originY | Rotation base point Y |
Alpha
| Name | Describe |
|---|---|
| alpha | The transparency of the element |
Notice that the father and son have set up alpha to do multiplicative stacking.
compositeOperation
| Name | Describe |
|---|---|
| compositeOperation | The superposition pattern drawn from the source image to the target image |
Notice that if you don't have a definition of compositeOperation to look up, find the nearest compositeOperation's parent container as its own compositeOperation.
Cursor
| Name | Describe |
|---|---|
| cursor | The shape of the mouse |
Fixed
| Name | Describe |
|---|---|
| fixed | Whether to fixed or not, the default is false, and set to true will not overlay the transform of ancestors. |
Shadow
| Name | Describe |
|---|---|
| shadow | shadow |
Usage:
jsobj.shadow = { color: '#42B035', offsetX: -5, offsetY: 5, blur: 10 }
Stage
| Name | Describe |
|---|---|
| stage | get the root stage |
Usage:
jsobj.stage
Method
destroy
Destroy self
jsobj.destroy()
Event
| Name | Describe |
|---|---|
| click | Click time trigger on the element |
| mousedown | Triggers when the mouse button is pressed on the element |
| mousemove | Trigger when the mouse pointer moves to the element |
| mouseup | Trigger when the mouse button is released on the element |
| mouseover | Trigger when the mouse pointer moves to the element |
| mouseout | Trigger when the mouse pointer moves out of the element |
| tap | Leave the finger and leave immediately |
| touchstart | The start of finger touch action |
| touchmove | Move the finger after touch |
| touchend | End of finger touch action |
| drag | Drag and drop |
jsconst handler = () => {} obj.on('click', handler) //unbind obj.off('click', handler)
Motion
Cax has built-in to capability to write motion effects in a continuous way.
jsconst easing = cax.To.easing.elasticInOut cax.To.get(bitmap) .to({ y: 340, rotation: 240 }, 2000, easing) .begin(() => { console.log("Task one has began!") }) .progress(() => { console.log("Task one is progressing!") }) .end(() => { console.log("Task one has completed!") }) .wait(500) .to() .rotation(0, 1400, easing) .begin(() => { console.log("Task two has began!") }) .progress(() => { console.log("Task two is progressing!") }) .end(() => { console.log("Task two has completed!") }) .start();
toandtoare paralleltoandwaitare serial- The serial between
toandtois serial with the nexttoandto
If you want circular motion, you can use the cycle method:
jscax.To.get(bitmap) .to() .y(340, 2000, cax.easing.elasticInOut) .to .y(0, 2000, cax.easing.elasticInOut) .cycle() .start()
It's important to note that, unlike tween.js, Cax uses the camelcase. For example, Cubic.In becomes cubicIn.
Clip
jsconst stage = new cax.Stage(600, 400, 'body') const bitmap = new cax.Bitmap('./wepay-diy.jpg', () => { stage.update() }) const clipPath = new cax.Graphics() clipPath.arc(40, 40, 25, 0, Math.PI * 2) bitmap.clip(clipPath) stage.add(bitmap)
You can get the same effect with blow code:
jsconst clipPath = new cax.Graphics() clipPath.x = 40 clipPath.y = 40 clipPath.arc(0, 0, 25, 0, Math.PI * 2)
So you can find that clip graphics supports all the transformation props(x,y,scaleX,scaleY,rotation,skewX,skewY,originX,originY).
Custom Object
Custom Shape
Custom Shape inherits from cax.Shape:
jsclass Sector extends cax.Shape { constructor (r, from, to, option) { super() this.option = option || {} this.r = r this.from = from this.to = to } draw () { this.beginPath() .moveTo(0, 0) .arc(0, 0, this.r, this.from, this.to) .closePath() .fillStyle(this.option.fillStyle) .fill() .strokeStyle(this.option.strokeStyle) .lineWidth(this.option.lineWidth) .stroke() } }
Use the Shape:
jsconst sector = new Sector(10, 0, Math.PI/6, { fillStyle: 'red' lineWidth: 2 }) stage.add(sector) stage.update()
Custom Element
Custom Element inherits from cax.Group:
jsclass Button extends cax.Group { constructor (option) { super() this.width = option.width this.roundedRect = new cax.RoundedRect(option.width, option.height, option.r) this.text = new cax.Text(option.text, { font: option.font, color: option.color }) this.text.x = option.width / 2 - this.text.getWidth() / 2 * this.text.scaleX this.text.y = option.height / 2 - 10 + 5 * this.text.scaleY this.add(this.roundedRect, this.text) } } export default Button
Use the Button:
jsconst button = new cax.Button({ width: 100, height: 40, text: "Click Me!" })
In general, it is suggested that inherit Group from a slightly complex combination, which is conducive to expansion and management of internal components.
Wechat Game Demo


License
MIT
Contributors
Showing top 10 contributors by commit count.
