一个让你跳过canvas,直接绘图的 2d 绘图库,上手简单,接口简洁,功能丰富.
NPM
npm i omg.js
CDN
https://unpkg.com/[email protected]/dist/omg.min.js (你可以修改 @version 来改变引用的版本)
下载
- ES6
import omg from 'omg.js';
const stage = omg({
...
});
// Init
stage.init();
- 浏览器
<script src="yourpath/omg.min.js"></script>
<script>
var stage = omg({
...
});
stage.init();
</script>
import omg from 'omg.js';
const stage = omg({
element: document.getElementById('canvas'),
width: 500,
height: 500,
enableGlobalTranslate: true,
enableGlobalScale: true,
position: 'absolute', // 改变canvas.style.position
images: [], // 预加载的图片列表,通常不用指定,因为使用接口绘制图片的时候,会自动预加载。
prepareImage: true, // 是否开启预加载图片
// 活着
prepareImage: () => {
// 如果prepareImage指定一个函数的话,也表示开启预加载图片,而且在加载完成后,会触发这个回调函数。
hideLoading();
}
});
// 在init之前,你可以通过`stage.extend(yourShape)`拓展自定义的图形。
stage.init();
const rect = stage.graphs.rectangle({
x: 120,
y: 120,
width: 200,
height: 200,
color: '#'+(~~(Math.random()*(1<<24))).toString(16)
}).on('mousedown', function() {
console.log('click rect2');
}).on('mouseenter', function() {
rect.color = '#'+(~~(Math.random()*(1<<24))).toString(16);
stage.redraw();
}).on('mouseleave', function() {
rect.color = '#'+(~~(Math.random()*(1<<24))).toString(16);
stage.redraw();
}).on('dragin', function() {
console.log('drag in rect2');
rect.color = '#ffffff';
stage.redraw();
}).on('dragout', function() {
console.log('drag out rect2');
rect.color = '#'+(~~(Math.random()*(1<<24))).toString(16);
stage.redraw();
}).on('drop', function() {
console.log('you drop on the rect2!');
rect.color = '#000';
stage.redraw();
}).config({
drag: true,
changeIndex: true
});
// 把图形添加到待绘制的列表中.
stage.addChild(rect);
// 绘制,并且绑定事件。
stage.show();
矩形
const rect = stage.graphs.rectangle({
x: 0,
y: 0,
width: 110,
height: 110,
rotate: 45, // 如果指定了radius的话,rotate会出现异常(待修复)
radius: {
tl: 6, // 左上
tr: 6, // 右上
bl: 6, // 左下
br: 6 // 右下
},
color: '#514022'
});
折线
const polyline = stage.graphs.line({
matrix: [
[10, 180],
[40, 50],
[80, 180],
[90, 80],
[110, 100],
[140, 50],
[260, 180]
]
});
不规则多边形
const polygon = stage.graphs.polygon({
matrix: [
[310, 120],
[360, 120],
[348, 230],
[250, 340],
[146, 200]
],
color: 'black',
style: 'stroke',
lineWidth: 4
});
图片
const image = stage.graphs.image({
x: 0,
y: 0,
width: 800,
height: 500,
src: './img/timg.jpg'
});
// 支持canvas绘制图片的所有接口.
const image3 = stage.graphs.image({
x: 200,
y: 200,
width: 97,
height: 110,
sliceX: 5,
sliceY: 0,
sliceWidth: 97,
sliceHeight: 110,
src: './img/action.png'
});
文字
const text = stage.graphs.text({
x: 300,
y: 40,
width: 150,
height: 40, // x, y, width, height指定了一个矩形, 文字就在其中
paddingTop: 8, // 用于调整文字在矩形中的位置
center: true, // 文字居中
background: {
color: 'blue', // 背景颜色
img: './img/text_bg.png' // 背景图片
}, // 给文字添加背景颜色(矩形)
font: 'italic bold 20px arial,sans-serif', // 文字样式
text: 'Hello stage', // 文字内容
color: '#fff', // 文字颜色
style: 'fill' // fill -- 填充, stroke -- 描边
});
圆形
const arc = stage.graphs.arc({
x: 400,
y: 400,
radius: 30,
color: 'rgba(255, 255, 255, 0.5)',
style: 'fill' // fill -- 填充, stroke -- 描边
});
扇形
const arcb = stage.graphs.arc({
x: 130,
y: 380,
radius: 100,
startAngle: 45,
endAngle: 165,
color: '#512854',
style: 'fill'
});
const arcb = stage.graphs.arc({
...,
hide: true
});
// 或者
arcb.hide = true;
如果omg提供的默认图形不够用, 你可以轻松拓展自定义图形.
在init
之前, 你可以通过 extend
方法来拓展自定义图形.
const stage = omg({
...
});
const yourShape = function(settings, _this) {
const draw = function() {
const canvas = _this.canvas;
const scale = _this.scale;
// 如果你想要自定义图形支持drag, scale, mousedown, mouseenter等事件,你必须添加这一行
stage.ext.DefineScale.call(this, scale, 'moveX', 'moveY', 'matrix');
const matrix = this.scaled_matrix;
canvas.save();
canvas.translate(this.scaled_moveX, this.scaled_moveY);
canvas.beginPath();
matrix.forEach((point, i) => {
i === 0 ? canvas.moveTo(point[0], point[1]) : canvas.lineTo(point[0], point[1]);
});
canvas.lineTo(matrix[0][0], matrix[0][1]);
canvas.fillStyle = this.color;
canvas.fill();
canvas.closePath();
canvas.restore();
};
return Object.assign({}, stage.ext.display(settings, _this), {
type: 'polygon',
draw: draw,
lineWidth: settings.lineWidth || 1,
matrix: settings.matrix
});
};
// 在init之前,拓展自定义图形.
stage.extend({
yourShape: yourShape
});
stage.init();
// 使用自定义图形
const shape = stage.graphs.yourShape({
...settings
});
stage.addChild(shape);
stage.show();
给全局canvas添加的 (mousedown, mousemove) 事件.
stage.mousedown(function(e) {
console.log(stage.utils.getPos(e));
});
stage.mousemove(function(e) {
console.log(stage.utils.getPos(e));
});
所有pc端支持的事件:
- mousedown
- mouseup
- mouseenter
- mouseleave
- mousemove'
- drag
- dragend
- dragin
- dragout
- drop
所有移动端支持的事件:
- touchstart
- touchmove
- touchend
- tap
支持链式调用.
/*
* @cur: 当前图形.
*/
shape.on('mousedown', function( cur ) {
console.log('you click rect');
}).on('mousemove', function( cur ) {
console.log('you move!');
}).on('mouseleave', function( cur ) {
console.log('you leave!');
}).drag(true).config(){...};
rect.config({
zindex: 10,
drag: true, // 图形开启拖拽
changeIndex: true, // 当拖拽的时候,改变图形的顺序
fixed: true, // 不受globalTranslate and globalScale 的影响。
});
你可以把一些图形添加到一个组里,这样你可以让这些图形表现的行为一致。
const group = stage.group({
x: 100,
y: 100,
width: 200,
height: 200,
title: {
title: {
text: 'Group Name',
fontSize: 14,
paddingTop: 12,
paddingLeft: 14
}
},
/**
* @param {Object} background - 给组添加背景颜色
*/
background: {
color: '#000'
},
/**
* @param {Object} border - 给组添加边框
*/
border: {
color: '#000',
},
zindex: 10
}).on('mousedown', function() {
console.log('you clicked group');
});
- 方法
group.add()
把图形添加到组里. 组内图形的坐标原点是组的 (x, y) 坐标。
- 方法
group.remove()
从组内删除图形.
- remove([Array]) - 删除多个图形
- remove([Function]) - 删除的图形支持用filter过滤.
- 方法
group.updateAllChildsPosition()
更新组内所有子图形的坐标位置。如果组的坐标发生了改变,需要调用这个函数来保证组内的图形跟随移动。
group和图形一样,都需要addChild
来添加到stage。
stage.addChild(rect);
stage.addChild(line);
stage.addChild(group);
// 或者
stage.addChild([rect, line, arc1, text1]);
stage.removeChild(rect);
stage.removeChild([rect, arc, line]);
stage.removeFirstChild();
stage.removeLastChild();
stage.removeAllChilds();
绘制并且绑定事件.
stage.show();
如果你通过addChild
或removeChild
新增了某些图形和事件或者移除了某些图形和事件,那么你需要通过以下方法重置事件。
stage.show()
or
stage.draw();
stage._events.triggerEvents();
stage.draw();
stage.redraw();
重置整个舞台,让所有图形的状态回归到初始值,会重置所有的拖拽位移和缩放.
stage.reset();
function go() {
rect.x++;
line.y = line.y + 2;
arc.radius++;
}
stage.animate(go);
/**
* @param: {keys | Object} -- 动画结束时的值,是个对象
* @param: {config | Object} -- 动画的一些配置项
*/
shape.animateTo({
x: 100,
y: 100,
width: 200,
height: 200
}, {
duration: 1000, // 动画持续事件,默认 500 毫秒
delay: 500, // 动画延迟的事件,默认 0 毫秒
easing: 'bounceOut', // 动画的补间类型,默认 'linear' (匀速)
onStart: function(keys) {
/**
* @param: keys
* keys是一个对象,存放着图形运动到当前的一些坐标和内部数据。
* same below
*/
console.log(keys.x, keys.y, keys.width, keys.height);
},
onUpdate: function(keys) {
console.log(keys.x, keys.y, keys.width, keys.height);
},
onFinish: function(keys) {
console.log(keys.x, keys.y, keys.width, keys.height);
},
});
- linear
- quadIn
- quadOut
- quadInOut
- cubicIn
- cubicOut
- cubicInOut
- quartIn
- quartOut
- quartInOut
- quintIn
- quintOut
- quintInOut
- sineIn
- sineOut
- sineInOut
- bounceOut
- bounceIn
- bounceInOut
stage.clearAnimation();
如果舞台上的所有动画都结束后,会调用这个方法。
stage.finishAnimation = () => {
console.log('所有动画都结束了!');
};
- opt.width {Function} -- 缩放后的宽度
- opt.height {Function} -- 缩放后的高度
- opt.resize {Function} -- 在缩放后触发的回调函数
world.resize({
width: () => document.body.clientWidth,
height: () => document.body.clientHeight,
// 如果你传了resize, 需要调用update这个函数来更新canvas的尺寸。
resize: (update) => {
update();
}
});
当舞台上有动画的时候,你可以通过调用fpsOn
来开启获取帧率。
stage.fpsOn(function(fps) {
// fps即是帧率,每秒刷新一次
console.log(fps);
});
stage.fpsOff();