From 4b3248035882369512148b2a920647cbe5b44f82 Mon Sep 17 00:00:00 2001 From: mkwiser Date: Sat, 20 Sep 2014 21:51:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8B=86=E5=88=86=E6=8E=A7=E5=88=B6=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/editor/Editor.js | 340 +--------------------------- src/editor/command/support.js | 2 + src/editor/controller/font.js | 117 ++++++++++ src/editor/controller/initAxis.js | 52 +++++ src/editor/controller/initBinder.js | 26 +++ src/editor/controller/initLayer.js | 46 ++++ src/editor/controller/initRender.js | 178 +++++++++++++++ src/render/render.js | 3 - 8 files changed, 427 insertions(+), 337 deletions(-) create mode 100644 src/editor/controller/font.js create mode 100644 src/editor/controller/initAxis.js create mode 100644 src/editor/controller/initBinder.js create mode 100644 src/editor/controller/initLayer.js create mode 100644 src/editor/controller/initRender.js diff --git a/src/editor/Editor.js b/src/editor/Editor.js index 593974b..e008a69 100644 --- a/src/editor/Editor.js +++ b/src/editor/Editor.js @@ -10,255 +10,15 @@ define( function(require) { var lang = require('common/lang'); - var computeBoundingBox = require('graphics/computeBoundingBox'); - var pathAdjust = require('graphics/pathAdjust'); var modeSupport = require('./mode/support'); - var commandList = require('./menu/commandList'); var ContextMenu = require('./menu/ContextMenu'); var commandSupport = require('./command/support'); var History = require('./util/History'); - /** - * 初始化渲染器 - */ - function initRender() { - var me = this; - var render = this.render; - - function setCamera(e) { - render.camera.x = e.x; - render.camera.y = e.y; - render.camera.event = e; - } - - render.capture.on('down', function(e) { - - if (me.contextMenu.visible()) { - return; - } - - render.camera.startX = e.x; - render.camera.startY = e.y; - setCamera(e); - - me.mode.down && me.mode.down.call(me, e); - }); - - render.capture.on('dragstart', function(e) { - - if (me.contextMenu.visible()) { - return; - } - setCamera(e); - me.mode.dragstart && me.mode.dragstart.call(me, e); - }); - - render.capture.on('drag', function(e) { - - if (me.contextMenu.visible()) { - return; - } - - render.camera.mx = e.x - render.camera.x; - render.camera.my = e.y - render.camera.y; - setCamera(e); - - me.mode.drag && me.mode.drag.call(me, e); - }); - - render.capture.on('dragend', function(e) { - - if (me.contextMenu.visible()) { - return; - } - setCamera(e); - - me.mode.dragend && me.mode.dragend.call(me, e); - }); - - render.capture.on('move', function(e) { - - if (me.contextMenu.visible()) { - return; - } - - me.mode.move && me.mode.move.call(me, e); - }); - - render.capture.on('up', function(e) { - - if (me.contextMenu.visible()) { - return; - } - - me.mode.up && me.mode.up.call(me, e); - }); - - render.capture.on('click', function(e) { - - if (me.contextMenu.visible()) { - return; - } - - me.mode.click && me.mode.click.call(me, e); - }); - - - render.capture.on('dblclick', function(e) { - - if (me.contextMenu.visible()) { - return; - } - - if(me.mode === modeSupport.bound) { - me.setMode('point'); - } - else if(me.mode === modeSupport.point){ - me.setMode(); - } - else { - me.setMode('point'); - } - }); - - render.capture.on('rightdown', function(e) { - - if (me.mode.rightdown) { - me.mode.rightdown.call(me, e); - } - else { - me.contextMenu.onClick = lang.bind(onContextMenu, me); - me.contextMenu.show(e, commandList.editor); - } - }); - - render.keyCapture.on('keyup', function(e) { - if (me.contextMenu.visible()) { - return; - } - - // 撤销 - if (e.keyCode == 90 && e.ctrlKey) { - me.execCommand('undo'); - } - // 恢复 - else if (e.keyCode == 89 && e.ctrlKey) { - me.execCommand('redo'); - } - // esc键,重置model - else if (e.key == 'esc' && !me.mode.keyup) { - me.setMode(); - } - else { - me.mode.keyup && me.mode.keyup.call(me, e); - } - }); - - render.keyCapture.on('keydown', function(e) { - if (me.contextMenu.visible()) { - return; - } - - me.mode.keydown && me.mode.keydown.call(me, e); - }); - } - - /** - * 初始化层 - */ - function initLayer() { - - this.coverLayer = this.render.addLayer('cover', { - level: 30, - fill: false, - strokeColor: 'green', - fillColor: 'white' - }); - - this.fontLayer = this.render.addLayer('font', { - level: 20, - lineWidth: 1, - strokeColor: 'red', - strokeSeparate: false - }); - - this.axisLayer = this.render.addLayer('axis', { - level: 10, - fill: false - }); - - this.render.addLayer('graduation', { - level: 40, - fill: false, - disabled: true - }); - } - - /** - * 初始化坐标系 - * - * @param {Object} origin 字体原点 - */ - function initAxis(origin) { - - // 绘制轴线 - this.axis = this.axisLayer.addShape('axis', { - id: 'axis', - x: origin.x, - y: origin.y, - gap: origin.axisGap, - unitsPerEm: this.options.unitsPerEm, - metrics: this.options.metrics, - // 刻度配置 - graduation: { - gap: origin.axisGap - }, - selectable: false - }); - - this.rightSideBearing = this.axisLayer.addShape('line', { - id: 'rightSideBearing', - p0: { - x: origin.rightSideBearing - }, - style: { - strokeColor: 'blue' - } - }); - - this.render.getLayer('graduation').addShape('graduation', { - config: this.axis - }); - - } - - /** - * 初始化绑定器 - */ - function initBinder() { - var me = this; - // 保存历史记录 - this.on('change', function(e) { - me.history.add(me.getShapes()); - }); - - } - - - /** - * 右键点击处理 - */ - function onContextMenu(e) { - this.contextMenu.hide(); - if (e.command == 'add_referenceline') { - var pos = e.pos; - this.execCommand('addreferenceline', pos.x, pos.y); - } - else { - this.execCommand(e.command, e); - } - } - + // editor 的控制器 + var initLayer = require('./controller/initLayer'); + var initRender = require('./controller/initRender'); + var initBinder = require('./controller/initBinder'); /** * Render控制器 @@ -293,95 +53,6 @@ define( return this; }; - /** - * 设置渲染器 - */ - Editor.prototype.setFont = function(font) { - - var contours = font.contours; - - 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 = contours.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 rightSideBearing = offsetX + font.advanceWidth + font.xMin; - initAxis.call(this, { - x: offsetX, - y: offsetY, - rightSideBearing: rightSideBearing, - axisGap: 100 - }); - - var fontLayer = this.render.painter.getLayer('font'); - - shapes.forEach(function(shape) { - fontLayer.addShape('path', shape); - }); - - this.render.refresh(); - - // 重置历史 - this.history.reset(); - this.history.add(this.getShapes()); - - this.setMode(); - - return this; - }; - - /** - * 获取编辑中的shapes - * - * @return {Array} 获取编辑中的shape - */ - Editor.prototype.getShapes = function() { - var origin = this.render.getLayer('axis').shapes[0]; - var shapes = lang.clone(this.fontLayer.shapes); - var scale = 1 / this.render.camera.scale; - // 调整坐标系 - shapes.forEach(function(shape) { - pathAdjust(shape.points, scale, -scale, -origin.x, -origin.y); - }); - return shapes; - }; - - /** - * 设置编辑中的shapes - * - * @return {this} - */ - Editor.prototype.setShapes = function(shapes) { - var origin = this.render.getLayer('axis').shapes[0]; - var scale = this.render.camera.scale; - // 调整坐标系 - shapes.forEach(function(shape) { - pathAdjust(shape.points, scale, -scale); - pathAdjust(shape.points, 1, 1, origin.x, origin.y); - }); - this.fontLayer.shapes = shapes; - this.fontLayer.refresh(); - return this; - }; - - /** * 切换编辑模式 * @@ -393,8 +64,8 @@ define( if (this.mode) { this.mode.end.call(this); } - this.mode = modeSupport[modeName] || modeSupport['default']; + this.mode = modeSupport[modeName] || modeSupport['default']; var args = Array.prototype.slice.call(arguments, 1); this.mode.begin.apply(this, args); }; @@ -473,6 +144,7 @@ define( this.history = null; }; + lang.extend(Editor.prototype, require('./controller/font')); require('common/observable').mixin(Editor.prototype); return Editor; diff --git a/src/editor/command/support.js b/src/editor/command/support.js index a2c7464..4c38b52 100644 --- a/src/editor/command/support.js +++ b/src/editor/command/support.js @@ -109,6 +109,7 @@ define( */ undo: function() { var shapes = this.history.back(); + this.fontLayer.shapes.length = 0; this.setShapes(shapes); this.setMode(); }, @@ -118,6 +119,7 @@ define( */ redo: function() { var shapes = this.history.forward(); + this.fontLayer.shapes.length = 0; this.setShapes(shapes); this.setMode(); }, diff --git a/src/editor/controller/font.js b/src/editor/controller/font.js new file mode 100644 index 0000000..4c83bee --- /dev/null +++ b/src/editor/controller/font.js @@ -0,0 +1,117 @@ +/** + * @file font.js + * @author mengke01 + * @date + * @description + * Editor 的font相关方法 + */ + + +define( + function(require) { + var initAxis = require('./initAxis'); + var lang = require('common/lang'); + var pathAdjust = require('graphics/pathAdjust'); + var computeBoundingBox = require('graphics/computeBoundingBox'); + + /** + * 初始化字体 + * + * @param {Object} font font结构 + */ + function setFont(font) { + + var contours = font.contours; + + 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 = contours.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 rightSideBearing = offsetX + font.advanceWidth + font.xMin; + initAxis.call(this, { + x: offsetX, + y: offsetY, + rightSideBearing: rightSideBearing, + axisGap: 100 + }); + + var fontLayer = this.render.painter.getLayer('font'); + + shapes.forEach(function(shape) { + fontLayer.addShape('path', shape); + }); + + this.render.refresh(); + + // 重置历史 + this.history.reset(); + this.history.add(this.getShapes()); + + this.setMode(); + + return this; + } + + + /** + * 设置编辑中的shapes + * + * @param {Array} shapes 轮廓数组 + * @return {this} + */ + function setShapes(shapes) { + var origin = this.render.getLayer('axis').shapes[0]; + var scale = this.render.camera.scale; + // 调整坐标系 + shapes.forEach(function(shape) { + pathAdjust(shape.points, scale, -scale); + pathAdjust(shape.points, 1, 1, origin.x, origin.y); + }); + Array.prototype.splice.apply(this.fontLayer.shapes, [-1, 0].concat(shapes)); + this.fontLayer.refresh(); + return this; + } + + /** + * 获取编辑中的shapes + * + * @param {Array} shapes 要获取的shapes + * @return {Array} 获取编辑中的shape + */ + function getShapes(shapes) { + var origin = this.render.getLayer('axis').shapes[0]; + shapes = shapes ? lang.clone(shapes) : lang.clone(this.fontLayer.shapes); + var scale = 1 / this.render.camera.scale; + // 调整坐标系 + shapes.forEach(function(shape) { + pathAdjust(shape.points, scale, -scale, -origin.x, -origin.y); + }); + + return shapes; + } + + return { + setFont: setFont, + setShapes: setShapes, + getShapes: getShapes + }; + } +); diff --git a/src/editor/controller/initAxis.js b/src/editor/controller/initAxis.js new file mode 100644 index 0000000..c8419c0 --- /dev/null +++ b/src/editor/controller/initAxis.js @@ -0,0 +1,52 @@ +/** + * @file initAxis.js + * @author mengke01 + * @date + * @description + * Editor 的坐标系初始化 + */ + + +define( + function(require) { + + /** + * 初始化坐标系 + * + * @param {Object} origin 字体原点 + */ + function initAxis(origin) { + + // 绘制轴线 + this.axis = this.axisLayer.addShape('axis', { + id: 'axis', + x: origin.x, + y: origin.y, + gap: origin.axisGap, + unitsPerEm: this.options.unitsPerEm, + metrics: this.options.metrics, + // 刻度配置 + graduation: { + gap: origin.axisGap + }, + selectable: false + }); + + this.rightSideBearing = this.axisLayer.addShape('line', { + id: 'rightSideBearing', + p0: { + x: origin.rightSideBearing + }, + style: { + strokeColor: 'blue' + } + }); + + this.render.getLayer('graduation').addShape('graduation', { + config: this.axis + }); + } + + return initAxis; + } +); diff --git a/src/editor/controller/initBinder.js b/src/editor/controller/initBinder.js new file mode 100644 index 0000000..4dedaef --- /dev/null +++ b/src/editor/controller/initBinder.js @@ -0,0 +1,26 @@ +/** + * @file initBinder.js + * @author mengke01 + * @date + * @description + * 初始化绑定器 + */ + + +define( + function(require) { + + /** + * 初始化绑定器 + */ + function initBinder() { + var me = this; + // 保存历史记录 + this.on('change', function(e) { + me.history.add(me.getShapes()); + }); + } + + return initBinder; + } +); diff --git a/src/editor/controller/initLayer.js b/src/editor/controller/initLayer.js new file mode 100644 index 0000000..c55e997 --- /dev/null +++ b/src/editor/controller/initLayer.js @@ -0,0 +1,46 @@ +/** + * @file initLayer.js + * @author mengke01 + * @date + * @description + * Editor的layer初始化 + */ + + +define( + function(require) { + + /** + * 初始化层 + */ + function initLayer() { + + this.coverLayer = this.render.addLayer('cover', { + level: 30, + fill: false, + strokeColor: 'green', + fillColor: 'white' + }); + + this.fontLayer = this.render.addLayer('font', { + level: 20, + lineWidth: 1, + strokeColor: 'red', + strokeSeparate: false + }); + + this.axisLayer = this.render.addLayer('axis', { + level: 10, + fill: false + }); + + this.render.addLayer('graduation', { + level: 40, + fill: false, + disabled: true + }); + } + + return initLayer; + } +); diff --git a/src/editor/controller/initRender.js b/src/editor/controller/initRender.js new file mode 100644 index 0000000..924563f --- /dev/null +++ b/src/editor/controller/initRender.js @@ -0,0 +1,178 @@ +/** + * @file initRender.js + * @author mengke01 + * @date + * @description + * Editor 的render初始化 + */ + + +define( + function(require) { + + var commandList = require('../menu/commandList'); + var lang = require('common/lang'); + + + /** + * 右键点击处理 + */ + function onContextMenu(e) { + this.contextMenu.hide(); + if (e.command == 'add_referenceline') { + var pos = e.pos; + this.execCommand('addreferenceline', pos.x, pos.y); + } + else { + this.execCommand(e.command, e); + } + } + + /** + * 初始化渲染器 + */ + function initRender() { + var me = this; + var render = this.render; + + function setCamera(e) { + render.camera.x = e.x; + render.camera.y = e.y; + render.camera.event = e; + } + + render.capture.on('down', function(e) { + + if (me.contextMenu.visible()) { + return; + } + + render.camera.startX = e.x; + render.camera.startY = e.y; + setCamera(e); + + me.mode.down && me.mode.down.call(me, e); + }); + + render.capture.on('dragstart', function(e) { + + if (me.contextMenu.visible()) { + return; + } + setCamera(e); + me.mode.dragstart && me.mode.dragstart.call(me, e); + }); + + render.capture.on('drag', function(e) { + + if (me.contextMenu.visible()) { + return; + } + + render.camera.mx = e.x - render.camera.x; + render.camera.my = e.y - render.camera.y; + setCamera(e); + + me.mode.drag && me.mode.drag.call(me, e); + }); + + render.capture.on('dragend', function(e) { + + if (me.contextMenu.visible()) { + return; + } + setCamera(e); + + me.mode.dragend && me.mode.dragend.call(me, e); + }); + + render.capture.on('move', function(e) { + + if (me.contextMenu.visible()) { + return; + } + + me.mode.move && me.mode.move.call(me, e); + }); + + render.capture.on('up', function(e) { + + if (me.contextMenu.visible()) { + return; + } + + me.mode.up && me.mode.up.call(me, e); + }); + + render.capture.on('click', function(e) { + + if (me.contextMenu.visible()) { + return; + } + + me.mode.click && me.mode.click.call(me, e); + }); + + + render.capture.on('dblclick', function(e) { + + if (me.contextMenu.visible()) { + return; + } + + if(me.mode === modeSupport.bound) { + me.setMode('point'); + } + else if(me.mode === modeSupport.point){ + me.setMode(); + } + else { + me.setMode('point'); + } + }); + + render.capture.on('rightdown', function(e) { + + if (me.mode.rightdown) { + me.mode.rightdown.call(me, e); + } + else { + me.contextMenu.onClick = lang.bind(onContextMenu, me); + me.contextMenu.show(e, commandList.editor); + } + }); + + render.keyCapture.on('keyup', function(e) { + if (me.contextMenu.visible()) { + return; + } + + // 撤销 + if (e.keyCode == 90 && e.ctrlKey) { + me.execCommand('undo'); + } + // 恢复 + else if (e.keyCode == 89 && e.ctrlKey) { + me.execCommand('redo'); + } + // esc键,重置model + else if (e.key == 'esc' && !me.mode.keyup) { + me.setMode(); + } + else { + me.mode.keyup && me.mode.keyup.call(me, e); + } + }); + + render.keyCapture.on('keydown', function(e) { + if (me.contextMenu.visible()) { + return; + } + + me.mode.keydown && me.mode.keydown.call(me, e); + }); + } + + return initRender; + } +); diff --git a/src/render/render.js b/src/render/render.js index bfb95d5..dd4ecc9 100644 --- a/src/render/render.js +++ b/src/render/render.js @@ -29,8 +29,6 @@ define( this.options.painter ); - - // 注册鼠标 this.capture = new MouseCapture( this.main, @@ -43,7 +41,6 @@ define( this.options.keyboard ); - this.camera = this.painter.camera; // 是否允许缩放