236 lines
6.4 KiB
JavaScript
236 lines
6.4 KiB
JavaScript
/**
|
|
* @file Editor.js
|
|
* @author mengke01
|
|
* @date
|
|
* @description
|
|
* 字体编辑控制器
|
|
*/
|
|
|
|
|
|
define(
|
|
function(require) {
|
|
var lang = require('common/lang');
|
|
var computeBoundingBox = require('graphics/computeBoundingBox');
|
|
var pathAdjust = require('render/util/pathAdjust');
|
|
var glyf2path = require('ttf/util/glyf2path');
|
|
var editorMode = require('./mode/editorMode');
|
|
|
|
/**
|
|
* 初始化
|
|
*/
|
|
function initRender() {
|
|
var me = this;
|
|
var render = this.render;
|
|
|
|
render.capture.on('wheel', function(e) {
|
|
|
|
var defaultRatio = render.options.defaultRatio || 1.2;
|
|
var ratio = e.delta > 0 ? defaultRatio : 1 / defaultRatio;
|
|
|
|
if (render.camera.scale * ratio < 0.1) {
|
|
return;
|
|
}
|
|
|
|
render.camera.ratio = ratio;
|
|
render.camera.center.x = e.x;
|
|
render.camera.center.y = e.y;
|
|
render.camera.scale *= ratio;
|
|
render.painter.refresh();
|
|
render.camera.ratio = 1;
|
|
|
|
});
|
|
|
|
render.capture.on('down', function(e) {
|
|
render.camera.startx = e.x;
|
|
render.camera.starty = e.y;
|
|
render.camera.x = e.x;
|
|
render.camera.y = e.y;
|
|
render.camera.event = e;
|
|
|
|
me.mode.down && me.mode.down.call(me, e);
|
|
});
|
|
|
|
render.capture.on('dragstart', function(e) {
|
|
render.camera.x = e.x;
|
|
render.camera.y = e.y;
|
|
render.camera.event = e;
|
|
|
|
me.mode.dragstart && me.mode.dragstart.call(me, e);
|
|
});
|
|
|
|
render.capture.on('drag', function(e) {
|
|
render.camera.mx = e.x - render.camera.x;
|
|
render.camera.my = e.y - render.camera.y;
|
|
render.camera.x = e.x;
|
|
render.camera.y = e.y;
|
|
render.camera.event = e;
|
|
|
|
me.mode.drag && me.mode.drag.call(me, e);
|
|
});
|
|
|
|
render.capture.on('dragend', function(e) {
|
|
render.camera.x = e.x;
|
|
render.camera.y = e.y;
|
|
render.camera.event = e;
|
|
|
|
me.mode.dragend && me.mode.dragend.call(me, e);
|
|
});
|
|
|
|
render.capture.on('dblclick', function(e) {
|
|
me.mode.end.call(me, e);
|
|
if(me.mode === editorMode.bound) {
|
|
me.mode = editorMode.point;
|
|
|
|
}
|
|
else if(me.mode === editorMode.point){
|
|
me.mode = editorMode.bound;
|
|
}
|
|
me.mode.begin.call(me, e);
|
|
});
|
|
|
|
}
|
|
|
|
function initLayer() {
|
|
|
|
this.render.addLayer('cover', {
|
|
level: 30,
|
|
stroke: true,
|
|
fill: false,
|
|
strokeColor: 'green',
|
|
fillColor: 'white',
|
|
});
|
|
|
|
this.render.addLayer('font', {
|
|
level: 20,
|
|
strokeColor: 'red'
|
|
});
|
|
|
|
this.render.addLayer('axis', {
|
|
level: 10,
|
|
stroke: true,
|
|
fill: false,
|
|
strokeColor: '#A6A6FF'
|
|
});
|
|
}
|
|
|
|
function initAxis() {
|
|
// 将坐标原点翻转
|
|
var center = this.render.camera.center;
|
|
|
|
// 绘制轴线
|
|
this.axis = {
|
|
type: 'axis',
|
|
x: center.x,
|
|
y: center.y,
|
|
width: 100,
|
|
unitsPerEm: this.options.unitsPerEm,
|
|
metrics: this.options.metrics,
|
|
selectable: false
|
|
};
|
|
this.render.getLayer('axis').addShape(this.axis);
|
|
}
|
|
|
|
/**
|
|
* Render控制器
|
|
* @param {Object} options 参数
|
|
* @constructor
|
|
*/
|
|
function Editor(options) {
|
|
this.options = lang.extend({
|
|
unitsPerEm: 512,
|
|
// 字体测量规格
|
|
metrics: {
|
|
WinAscent: 480,
|
|
WinDecent: -33,
|
|
'x-Height': 256,
|
|
'CapHeight': 358
|
|
}
|
|
}, options);
|
|
}
|
|
|
|
/**
|
|
* 设置渲染器
|
|
*/
|
|
Editor.prototype.setRender = function(render) {
|
|
this.render = render;
|
|
initRender.call(this);
|
|
initLayer.call(this);
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* 设置渲染器
|
|
*/
|
|
Editor.prototype.setFont = function(font) {
|
|
|
|
var paths = glyf2path(font);
|
|
|
|
var width = this.render.painter.width;
|
|
var height = this.render.painter.height;
|
|
var options = this.options;
|
|
|
|
// 坐标原点位置,基线原点
|
|
var offsetX = (width - options.unitsPerEm) / 2;
|
|
var offsetY = (height + (options.unitsPerEm + options.metrics.WinDecent)) / 2;
|
|
|
|
// 构造形状集合
|
|
var shapes = paths.map(function(path) {
|
|
var shape = {};
|
|
var bound = computeBoundingBox.computePath(path);
|
|
|
|
path = pathAdjust(path, 1, -1);
|
|
shape.points = pathAdjust(path, 1, 1, offsetX, offsetY);
|
|
|
|
return shape;
|
|
});
|
|
|
|
this.font = font;
|
|
|
|
// 渲染形状
|
|
this.render.reset();
|
|
|
|
// 设置坐标原点
|
|
var camera = this.render.camera;
|
|
camera.center.x = offsetX;
|
|
camera.center.y = offsetY;
|
|
|
|
initAxis.call(this);
|
|
|
|
var fontLayer = this.render.painter.getLayer('font');
|
|
|
|
shapes.forEach(function(shape) {
|
|
fontLayer.addShape('path', shape);
|
|
});
|
|
|
|
this.render.refresh();
|
|
|
|
if (this.mode) {
|
|
this.mode.end.call(this);
|
|
}
|
|
|
|
this.mode = editorMode.bound;
|
|
this.mode.begin.call(this);
|
|
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* 刷新编辑器组件
|
|
*/
|
|
Editor.prototype.refresh = function() {
|
|
this.render.refresh();
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* 注销
|
|
*/
|
|
Editor.prototype.dispose = function() {
|
|
this.render && this.render.dispose();
|
|
this.options = this.render = null;
|
|
};
|
|
|
|
return Editor;
|
|
}
|
|
);
|