diff --git a/README.md b/README.md
index 481e2f6..da33080 100644
--- a/README.md
+++ b/README.md
@@ -17,3 +17,7 @@ fonteditor 在线ttf字体编辑器
5. 2014-11-10 ttf编辑器增加智能吸附,增加编辑器设置.
+6. 2014-12-7 ttf编辑器增加百度编辑器样式.
+
+7. 2014-12-13 ttf编辑器增加列表和查看器命令栏.
+
diff --git a/css/common/bootstrap.less b/css/common/bootstrap.less
index 1a2980c..c253a3e 100644
--- a/css/common/bootstrap.less
+++ b/css/common/bootstrap.less
@@ -133,6 +133,11 @@ hr {
background: #28B4A0;
}
+.btn-confirm {
+ color: #FFF;
+ background: #4A90E2;
+}
+
.btn-ico {
padding: 5px 10px;
font-size: 12px;
@@ -148,12 +153,14 @@ hr {
// 命令组
.command-groups {
height: 40px;
- line-height: 40px;
padding-left: 8px;
+ overflow: hidden;
background: rgba(112, 119, 128, 0.8);
>li {
+
float: left;
+ line-height: 40px;
padding: 0 8px;
color: #FFF;
cursor: pointer;
@@ -166,11 +173,20 @@ hr {
text-decoration: underline;
}
+ >.ico {
+ font-size: 20px;
+ text-decoration: none;
+ }
+
&:hover {
background: lighten(#707781, 10%);
}
}
+ >li[data-theme="ico"] {
+ padding: 0 12px;
+ }
+
>li[data-disabled] {
color: #B9BDC1;
}
@@ -178,4 +194,12 @@ hr {
>li[data-on] {
background: darken(#707781, 10%);
}
+
+ >[data-split] {
+ padding: 0;
+ width: 1px;
+ height: 40px;
+ background: lighten(#707781, 15%);
+ pointer-events: none;
+ }
}
\ No newline at end of file
diff --git a/css/common/common.less b/css/common/common.less
index 829ed4b..ab3ac51 100644
--- a/css/common/common.less
+++ b/css/common/common.less
@@ -127,11 +127,38 @@ body, html {
position: fixed;
width: 70%;
top: @top-height;
+ padding-top: @command-groups-height;
bottom: 0;
z-index: 1;
background: #FEFEFE;
border-right: 1px solid #DDD;
display: none;
+
+ .command-groups {
+ background: rgba(112, 119, 128, 1);
+ margin-top: -40px;
+ }
+
+ .close-editor {
+ position: absolute;
+ right: 0;
+ top: 0;
+ padding-right: 5px;
+ z-index: 100;
+ font-size: 20px;
+ line-height: 38px;
+ color: #FFF;
+ display: none;
+ &:hover {
+ cursor: pointer
+ }
+ }
+
+ &:hover {
+ .close-editor {
+ display: block;
+ }
+ }
}
.editor.editing {
diff --git a/css/common/editor.less b/css/common/editor.less
index 1aa1b82..e86d3a2 100644
--- a/css/common/editor.less
+++ b/css/common/editor.less
@@ -92,9 +92,3 @@
}
}
-.editor:hover {
- .close-editor {
- display: block;
- }
-}
-
diff --git a/css/common/ico.less b/css/common/ico.less
index a74175f..8deb738 100644
--- a/css/common/ico.less
+++ b/css/common/ico.less
@@ -33,8 +33,13 @@
.icon();
}
+.i-leave {
+ .i-ico('\e00c');
+}
+
.i-edit,
-.i-del {
+.i-del,
+.i-leave {
font-size: 12px;
&:hover {
cursor: pointer;
@@ -99,18 +104,62 @@
.i-ico('\e022');
}
-.close-editor {
- position: absolute;
- right: 0;
- top: 0;
- z-index: 100;
- padding: 0 3px;
- z-index: 100;
- font-size: 14px;
- background: #FFF;
- border-left: 1px solid #000;
- display: none;
- &:hover {
- cursor: pointer
- }
+
+
+// glyf编辑器
+
+.i-upshape {
+ .i-ico('\e014');
}
+
+.i-downshape {
+ .i-ico('\e00b');
+}
+
+.i-reversepoints {
+ .i-ico('\e00d');
+}
+
+.i-alignleft {
+ .i-ico('\e006');
+}
+
+.i-aligncenter {
+ .i-ico('\e004');
+}
+
+.i-alignright {
+ .i-ico('\e007');
+}
+
+.i-aligntop {
+ .i-ico('\e008');
+}
+
+.i-alignmiddle {
+ .i-ico('\e005');
+}
+
+.i-aligndescent {
+ .i-ico('\e009');
+}
+
+.i-alignbaseline {
+ .i-ico('\e009');
+}
+
+.i-rotateleft {
+ .i-ico('\e01c');
+}
+
+.i-rotateright {
+ .i-ico('\e01d');
+}
+
+.i-flip {
+ .i-ico('\e013');
+}
+
+.i-mirror {
+ .i-ico('\e012');
+}
\ No newline at end of file
diff --git a/demo/css/editor.css b/demo/css/editor.css
index 72b60ad..c7df596 100644
--- a/demo/css/editor.css
+++ b/demo/css/editor.css
@@ -29,12 +29,17 @@ a:hover {
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.1px;
}
+.i-leave:before {
+ content: '\e00c';
+}
.i-edit,
-.i-del {
+.i-del,
+.i-leave {
font-size: 12px;
}
.i-edit:hover,
-.i-del:hover {
+.i-del:hover,
+.i-leave:hover {
cursor: pointer;
color: #4A90E2;
}
@@ -80,19 +85,47 @@ a:hover {
.i-save:before {
content: '\e022';
}
-.close-editor {
- position: absolute;
- right: 0;
- top: 0;
- padding: 0 3px;
- z-index: 100;
- font-size: 14px;
- background: #FFF;
- border-left: 1px solid #000;
- display: none;
+.i-upshape:before {
+ content: '\e014';
}
-.close-editor:hover {
- cursor: pointer;
+.i-downshape:before {
+ content: '\e00b';
+}
+.i-reversepoints:before {
+ content: '\e00d';
+}
+.i-alignleft:before {
+ content: '\e006';
+}
+.i-aligncenter:before {
+ content: '\e004';
+}
+.i-alignright:before {
+ content: '\e007';
+}
+.i-aligntop:before {
+ content: '\e008';
+}
+.i-alignmiddle:before {
+ content: '\e005';
+}
+.i-aligndescent:before {
+ content: '\e009';
+}
+.i-alignbaseline:before {
+ content: '\e009';
+}
+.i-rotateleft:before {
+ content: '\e01c';
+}
+.i-rotateright:before {
+ content: '\e01d';
+}
+.i-flip:before {
+ content: '\e013';
+}
+.i-mirror:before {
+ content: '\e012';
}
.glyf-editor {
width: 100%;
@@ -182,9 +215,6 @@ a:hover {
.editor-contextmenu li:last-child {
border-bottom: none;
}
-.editor:hover .close-editor {
- display: block;
-}
body,
html {
height: 100%;
diff --git a/index.html b/index.html
index d862e9c..7a029b0 100644
--- a/index.html
+++ b/index.html
@@ -94,9 +94,10 @@
-
-
-
+
@@ -112,8 +113,8 @@
diff --git a/src/editor/Editor.js b/src/editor/Editor.js
index 7d9bf0c..9c51bde 100644
--- a/src/editor/Editor.js
+++ b/src/editor/Editor.js
@@ -95,6 +95,39 @@ define(
return this;
};
+ /**
+ * 设置选中的shapes
+ * @param {Array} shapes 选中的shapes
+ */
+ Editor.prototype.setSelected = function(shapes) {
+ this.setMode('shapes', shapes);
+ };
+
+ /**
+ * 刷新选中的shapes
+ * @param {Array} shapes 选中的shapes
+ */
+ Editor.prototype.refreshSelected = function(shapes) {
+ if (this.currentGroup) {
+ var lastShapes = this.currentGroup.shapes;
+ this.currentGroup.setShapes(shapes);
+ this.currentGroup.refresh();
+
+ if (shapes !== lastShapes) {
+ this.fire('selection:change', {
+ shapes: shapes
+ });
+ }
+ }
+ };
+
+ /**
+ * 获取选中的shapes
+ * @return {Array} 选中的shapes
+ */
+ Editor.prototype.getSelected = function() {
+ return this.currentGroup ? this.currentGroup.shapes : null;
+ };
/**
* 执行指定命令
@@ -109,15 +142,17 @@ define(
command: command,
args: args
};
- this.fire('command', event);
+ this.fire('beforecommand', event);
if(event.returnValue === false) {
return false;
}
if (commandSupport[command]) {
- commandSupport[command].apply(this, args);
- return true;
+ var ret = commandSupport[command].apply(this, args);
+ event.result = ret;
+ this.fire('command', event);
+ return ret;
}
return false;
@@ -148,17 +183,6 @@ define(
return true;
};
- /**
- * 添加到剪切板
- *
- * @param {Array} 形状集合
- * @return {this}
- */
- Editor.prototype.setClipBoard = function(shapes) {
- clipboard.set(shapes, 'editor-shape');
- return this;
- };
-
/**
* 是否改变过
*
@@ -184,6 +208,17 @@ define(
}
};
+ /**
+ * 添加到剪切板
+ *
+ * @param {Array} 形状集合
+ * @return {this}
+ */
+ Editor.prototype.setClipBoard = function(shapes) {
+ clipboard.set(shapes, 'editor-shape');
+ return this;
+ };
+
/**
* 从剪切板中获取
*
diff --git a/src/editor/command/align.js b/src/editor/command/align.js
index 85a8c6a..5b84010 100644
--- a/src/editor/command/align.js
+++ b/src/editor/command/align.js
@@ -21,10 +21,10 @@ define(
* @param {Array} shapes 形状集合
* @param {string} align 对齐方式
*/
- align: function(shapes, align) {
+ alignshapes: function(shapes, align) {
- if (!shapes.length) {
- return;
+ if (!shapes || !shapes.length) {
+ return false;
}
var contours = shapes.map(function(shape) {
@@ -67,6 +67,7 @@ define(
});
this.fontLayer.refresh();
+ this.refreshSelected(shapes);
},
/**
@@ -75,10 +76,10 @@ define(
* @param {Array} shapes 形状集合
* @param {string} align 对齐方式
*/
- verticalalign: function(shapes, align) {
+ verticalalignshapes: function(shapes, align) {
- if (!shapes.length) {
- return;
+ if (!shapes || !shapes.length) {
+ return false;
}
var contours = shapes.map(function(shape) {
@@ -113,7 +114,50 @@ define(
});
this.fontLayer.refresh();
+ this.refreshSelected(shapes);
+ },
+
+ /**
+ * 字体水平对齐
+ *
+ * @param {Array} shapes 形状集合
+ * @param {string} align 对齐方式
+ */
+ horizontalalignshapes: function(shapes, align) {
+
+ if (!shapes || !shapes.length) {
+ return false;
+ }
+
+ var contours = shapes.map(function(shape) {
+ return shape.points;
+ });
+
+ var xbaseline = this.axis.x; // 基线
+ var rightSideBearing = this.rightSideBearing.p0.x;
+
+ // 求边界线
+ var bound = computeBoundingBox.computePath.apply(null, contours);
+ var xOffset = 0;
+
+ if ('left' === align) {
+ xOffset = xbaseline - bound.x;
+ }
+ else if ('center' === align) {
+ xOffset = (xbaseline + rightSideBearing) / 2 - bound.x - bound.width / 2;
+ }
+ else if ('right' === align) {
+ xOffset = rightSideBearing - bound.x - bound.width;
+ }
+
+ contours.forEach(function(contour) {
+ pathAdjust(contour, 1, 1, xOffset, 0);
+ });
+
+ this.fontLayer.refresh();
+ this.refreshSelected(shapes);
}
+
};
return support;
diff --git a/src/editor/command/commandSupport.js b/src/editor/command/commandSupport.js
new file mode 100644
index 0000000..d5947a7
--- /dev/null
+++ b/src/editor/command/commandSupport.js
@@ -0,0 +1,42 @@
+/**
+ * @file supportHistory.js
+ * @author mengke01
+ * @date
+ * @description
+ * 命令相关配置
+ */
+
+
+define(
+ function(require) {
+
+ // 支持历史记录的命令列表
+ var supportHistory = {
+ alignshapes: true,
+ verticalalignshapes: true,
+ horizontalalignshapes: true,
+ joinshapes: true,
+ intersectshapes: true,
+ tangencyshapes: true,
+ splitshapes: true,
+ removeshapes: true,
+ reversepoints: true,
+ topshape: true,
+ bottomshape: true,
+ upshape: true,
+ downshape: true,
+ cutshapes: true,
+ pasteshapes: true,
+ addshapes: true,
+ rotateleft: true,
+ rotateright: true,
+ flipshapes: true,
+ mirrorshapes: true
+ };
+
+
+ return {
+ history: supportHistory
+ };
+ }
+);
diff --git a/src/editor/command/editor.js b/src/editor/command/editor.js
new file mode 100644
index 0000000..708ce74
--- /dev/null
+++ b/src/editor/command/editor.js
@@ -0,0 +1,135 @@
+/**
+ * @file editor.js
+ * @author mengke01
+ * @date
+ * @description
+ * 编辑器相关命令
+ */
+
+
+define(
+ function(require) {
+ var lang = require('common/lang');
+ var computeBoundingBox = require('graphics/computeBoundingBox');
+ var commandList = require('../menu/commandList');
+ var shapesSupport = require('../shapes/support');
+ var menuUtil = require('../menu/util');
+
+ return {
+
+ /**
+ * 重置缩放
+ */
+ rescale: function() {
+ this.coverLayer.clearShapes();
+ var size = this.render.getSize();
+ var scale = 512 / this.options.unitsPerEm;
+ this.render.scaleTo(scale, {
+ x: size.width / 2,
+ y: size.height / 2
+ });
+ this.setMode();
+ },
+
+
+ /**
+ * 撤销
+ */
+ undo: function() {
+ var shapes = this.history.back();
+ this.fontLayer.shapes.length = 0;
+ this.setShapes(shapes);
+ this.setMode();
+ },
+
+ /**
+ * 恢复
+ */
+ redo: function() {
+ var shapes = this.history.forward();
+ this.fontLayer.shapes.length = 0;
+ this.setShapes(shapes);
+ this.setMode();
+ },
+
+ /**
+ * 是否打开网格吸附
+ */
+ gridsorption: function(enabled) {
+ menuUtil.setSelected(commandList.editor, 'setting.gridsorption', !!enabled);
+ this.options.sorption.enableGrid = this.sorption.enableGrid = !!enabled;
+ },
+
+ /**
+ * 是否打开轮廓吸附
+ */
+ shapesorption: function(enabled) {
+ menuUtil.setSelected(commandList.editor, 'setting.shapesorption', !!enabled);
+ this.options.sorption.enableShape = this.sorption.enableShape = !!enabled;
+ },
+
+ /**
+ * 是否打开轮廓吸附
+ */
+ showgrid: function(enabled) {
+ menuUtil.setSelected(commandList.editor, 'setting.showgrid', !!enabled);
+ this.options.axis.showGrid = this.axis.showGrid = !!enabled;
+ this.axisLayer.refresh();
+ },
+
+ /**
+ * 更多设置
+ */
+ moresetting: function(enabled) {
+ this.fire('setting:editor', {
+ setting: this.options
+ });
+ },
+
+ /**
+ * 添加path
+ */
+ addpath: function() {
+ this.setMode('addpath');
+ },
+
+ /**
+ * 添加自选图形
+ */
+ addsupportshapes: function(type) {
+ if (shapesSupport[type]) {
+ this.setMode('addshapes', lang.clone(shapesSupport[type]));
+ }
+ },
+
+ /**
+ * 设置字体信息
+ */
+ fontsetting: function() {
+
+ // 计算边界
+ var box = computeBoundingBox.computePathBox.apply(null, this.fontLayer.shapes.map(function(shape) {
+ return shape.points;
+ }));
+
+ var leftSideBearing = 0;
+ var rightSideBearing = 0;
+
+ if (box) {
+ var scale = this.render.camera.scale;
+ var leftSideBearing = (box.x - this.axis.x) / scale;
+ var rightSideBearing = (this.rightSideBearing.p0.x - box.x - box.width) / scale;
+ }
+
+ this.fire('setting:font', {
+ setting: {
+ leftSideBearing: Math.round(leftSideBearing),
+ rightSideBearing: Math.round(rightSideBearing || 0),
+ unicode: this.font.unicode,
+ name: this.font.name
+ }
+ });
+ }
+ };
+ }
+);
diff --git a/src/editor/command/shapes.js b/src/editor/command/join.js
similarity index 91%
rename from src/editor/command/shapes.js
rename to src/editor/command/join.js
index 8ced399..e8c0763 100644
--- a/src/editor/command/shapes.js
+++ b/src/editor/command/join.js
@@ -1,5 +1,5 @@
/**
- * @file shapes.js
+ * @file join.js
* @author mengke01
* @date
* @description
@@ -74,7 +74,6 @@ define(
return shapes;
}
-
var support = {
/**
@@ -82,6 +81,7 @@ define(
*/
joinshapes: function(shapes) {
combineShape.call(this, shapes, pathJoin.Relation.join);
+ this.refreshSelected(shapes);
},
/**
@@ -89,6 +89,7 @@ define(
*/
intersectshapes: function(shapes) {
combineShape.call(this, shapes, pathJoin.Relation.intersect);
+ this.refreshSelected(shapes);
},
/**
@@ -96,13 +97,15 @@ define(
*/
tangencyshapes: function(shapes) {
combineShape.call(this, shapes, pathJoin.Relation.tangency);
+ this.refreshSelected(shapes);
},
/**
* 切割路径
*/
- splitshapes: function(p0, p1, outShapes) {
+ splitshapes: function(p0, p1) {
var shapes = this.fontLayer.shapes;
+ var outShapes = [];
for(var i = shapes.length - 1; i >=0; i--) {
var result = pathSplitBySegment(shapes[i].points, p0, p1);
if (result) {
@@ -122,6 +125,10 @@ define(
if (outShapes.length) {
this.fontLayer.refresh();
+ this.setMode('shapes', outShapes);
+ }
+ else {
+ return false;
}
}
};
diff --git a/src/editor/command/referenceline.js b/src/editor/command/referenceline.js
new file mode 100644
index 0000000..a2cd0d0
--- /dev/null
+++ b/src/editor/command/referenceline.js
@@ -0,0 +1,86 @@
+/**
+ * @file referenceline.js
+ * @author mengke01
+ * @date
+ * @description
+ * 参考线相关命令
+ */
+
+
+define(
+ function(require) {
+
+
+ return {
+ /**
+ * 添加参考线
+ */
+ addreferenceline: function(x, y) {
+ if(x > 20) {
+ this.axisLayer.addShape('line', {
+ p0: {
+ x: x
+ },
+ style: this.options.referenceline.style
+ });
+ }
+
+ if(y > 20) {
+ this.axisLayer.addShape('line', {
+ p0: {
+ y: y
+ },
+ style: this.options.referenceline.style
+ });
+ }
+ this.axisLayer.refresh();
+ },
+
+ /**
+ * 移除参考线
+ */
+ removereferenceline: function(x, y) {
+ var lines = [];
+ // 如果传入的是shape对象
+ if(typeof(x) === 'object') {
+ lines.push(x);
+ }
+
+ var axisLayer = this.axisLayer;
+ var rightSideBearing = this.rightSideBearing;
+
+ // 获取选中的参考线
+ if(x > 20 || y > 20) {
+ var result = this.axisLayer.getShapeIn(x, y);
+ lines = lines.concat(result);
+ }
+
+ // rightside bearing 线不可移除
+ lines = lines.filter(function(line) {
+ return line !== rightSideBearing;
+ });
+
+ lines.forEach(function(l) {
+ axisLayer.removeShape(l);
+ });
+ axisLayer.refresh();
+ },
+
+ /**
+ * 清除参考线
+ */
+ clearreferenceline: function() {
+ var axisLayer = this.axisLayer;
+ var rightSideBearing = this.rightSideBearing;
+ var lines = axisLayer.shapes.filter(function(line) {
+ return line.type === 'line' && line !== rightSideBearing;
+ });
+
+ lines.forEach(function(l) {
+ axisLayer.removeShape(l);
+ });
+ axisLayer.refresh();
+ }
+ };
+ }
+);
diff --git a/src/editor/command/shape.js b/src/editor/command/shape.js
new file mode 100644
index 0000000..f703891
--- /dev/null
+++ b/src/editor/command/shape.js
@@ -0,0 +1,151 @@
+/**
+ * @file shape.js
+ * @author mengke01
+ * @date
+ * @description
+ * 形状相关命令
+ */
+
+
+define(
+ function(require) {
+
+ var computeBoundingBox = require('graphics/computeBoundingBox');
+ var pathAdjust = require('graphics/pathAdjust');
+
+
+
+ return {
+
+ /**
+ * 移除shape
+ */
+ removeshapes: function(shapes) {
+
+ var fontLayer = this.fontLayer;
+ shapes.forEach(function(shape) {
+ fontLayer.removeShape(shape);
+ });
+ fontLayer.refresh();
+ this.refreshSelected([]);
+ this.setMode();
+ },
+
+ /**
+ * 反转shape
+ */
+ reversepoints: function(shapes) {
+ shapes.forEach(function(shape) {
+ shape.points = shape.points.reverse();
+ });
+
+ this.fontLayer.refresh();
+ },
+
+ /**
+ * 设置shape到顶层
+ */
+ topshape: function(shape) {
+ var index = this.fontLayer.shapes.indexOf(shape);
+ this.fontLayer.shapes.splice(index, 1);
+ this.fontLayer.shapes.push(shape);
+ },
+
+ /**
+ * 设置shape到底层
+ */
+ bottomshape: function(shape) {
+ var index = this.fontLayer.shapes.indexOf(shape);
+ this.fontLayer.shapes.splice(index, 1);
+ this.fontLayer.shapes.unshift(shape);
+ },
+
+ /**
+ * 提升shape层级
+ */
+ upshape: function(shape) {
+ var index = this.fontLayer.shapes.indexOf(shape);
+ this.fontLayer.shapes.splice(index, 1);
+ this.fontLayer.shapes.splice(index + 1, 0, shape);
+ },
+
+ /**
+ * 降低shape层级
+ */
+ downshape: function(shape) {
+ var index = this.fontLayer.shapes.indexOf(shape);
+ this.fontLayer.shapes.splice(index, 1);
+ this.fontLayer.shapes.splice(index - 1, 0, shape);
+ },
+
+ /**
+ * 剪切shapes
+ *
+ * @param {Array} shapes 形状集合
+ */
+ cutshapes: function(shapes) {
+ var cutedShapes = this.getShapes(shapes);
+ this.setClipBoard(cutedShapes);
+ var fontLayer = this.fontLayer;
+ shapes.forEach(function(shape) {
+ fontLayer.removeShape(shape);
+ });
+ fontLayer.refresh();
+ this.refreshSelected([]);
+ },
+
+ /**
+ * 复制shapes
+ *
+ * @param {Array} shapes 形状集合
+ */
+ copyshapes: function(shapes) {
+ shapes = this.getShapes(shapes);
+ this.setClipBoard(shapes);
+ },
+
+ /**
+ * 粘贴shapes
+ *
+ * @param {Array} shapes 形状集合
+ */
+ pasteshapes: function(shapes, pos) {
+
+ if (!shapes || !shapes.length) {
+ return false;
+ }
+
+ if (pos) {
+ var bound = computeBoundingBox.computePath.apply(null,
+ shapes.map(function(shape){
+ return shape.points;
+ })
+ );
+ // 需要根据坐标原点以及缩放换算成鼠标位置移动
+ var origin = this.axis;
+ var scale = this.render.camera.scale;
+ var x = (pos.x - origin.x) / scale;
+ var y = (origin.y - pos.y) / scale;
+
+ shapes.forEach(function(shape) {
+ pathAdjust(shape.points, 1, 1, x - bound.x, y - bound.y - bound.height);
+ });
+ }
+
+
+ this.setShapes(shapes);
+ this.setMode('shapes', shapes);
+ },
+
+ /**
+ * 增加shapes
+ *
+ * @param {Array} shapes 形状集合
+ */
+ addshapes: function(shapes) {
+ this.setShapes(shapes);
+ this.fontLayer.refresh();
+ }
+ };
+ }
+);
diff --git a/src/editor/command/support.js b/src/editor/command/support.js
index f3145ae..487e814 100644
--- a/src/editor/command/support.js
+++ b/src/editor/command/support.js
@@ -9,296 +9,14 @@
define(
function(require) {
-
var lang = require('common/lang');
- var computeBoundingBox = require('graphics/computeBoundingBox');
- var shapesSupport = require('../shapes/support');
- var menuUtil = require('../menu/util');
- var commandList = require('../menu/commandList');
-
- var support = {
-
- /**
- * 重置缩放
- */
- rescale: function() {
- this.coverLayer.clearShapes();
- var size = this.render.getSize();
- var scale = 512 / this.options.unitsPerEm;
- this.render.scaleTo(scale, {
- x: size.width / 2,
- y: size.height / 2
- });
- this.setMode();
- },
-
-
- /**
- * 添加path
- */
- addpath: function() {
- this.setMode('addpath');
- },
-
- /**
- * 添加自选图形
- */
- addsupportshapes: function(type) {
- if (shapesSupport[type]) {
- this.setMode('addshapes', lang.clone(shapesSupport[type]));
- }
- },
-
- /**
- * 移除shape
- */
- removeshapes: function(shapes) {
- var fontLayer = this.fontLayer;
- shapes.forEach(function(shape) {
- fontLayer.removeShape(shape);
- });
- fontLayer.refresh();
- },
-
- /**
- * 反转shape
- */
- reversepoint: function(shapes) {
- shapes.forEach(function(shape) {
- shape.points = shape.points.reverse();
- });
-
- this.fontLayer.refresh();
- },
-
- /**
- * 设置shape到顶层
- */
- topshape: function(shape) {
- var index = this.fontLayer.shapes.indexOf(shape);
- this.fontLayer.shapes.splice(index, 1);
- this.fontLayer.shapes.push(shape);
- },
-
- /**
- * 设置shape到底层
- */
- bottomshape: function(shape) {
- var index = this.fontLayer.shapes.indexOf(shape);
- this.fontLayer.shapes.splice(index, 1);
- this.fontLayer.shapes.unshift(shape);
- },
-
- /**
- * 提升shape层级
- */
- upshape: function(shape) {
- var index = this.fontLayer.shapes.indexOf(shape);
- this.fontLayer.shapes.splice(index, 1);
- this.fontLayer.shapes.splice(index + 1, 0, shape);
- },
-
- /**
- * 降低shape层级
- */
- downshape: function(shape) {
- var index = this.fontLayer.shapes.indexOf(shape);
- this.fontLayer.shapes.splice(index, 1);
- this.fontLayer.shapes.splice(index - 1, 0, shape);
- },
-
- /**
- * 撤销
- */
- undo: function() {
- var shapes = this.history.back();
- this.fontLayer.shapes.length = 0;
- this.setShapes(shapes);
- this.setMode();
- },
-
- /**
- * 恢复
- */
- redo: function() {
- var shapes = this.history.forward();
- this.fontLayer.shapes.length = 0;
- this.setShapes(shapes);
- this.setMode();
- },
-
- /**
- * 添加参考线
- */
- addreferenceline: function(x, y) {
- if(x > 20) {
- this.axisLayer.addShape('line', {
- p0: {
- x: x
- },
- style: this.options.referenceline.style
- });
- }
-
- if(y > 20) {
- this.axisLayer.addShape('line', {
- p0: {
- y: y
- },
- style: this.options.referenceline.style
- });
- }
- this.axisLayer.refresh();
- },
-
- /**
- * 移除参考线
- */
- removereferenceline: function(x, y) {
- var lines = [];
- // 如果传入的是shape对象
- if(typeof(x) === 'object') {
- lines.push(x);
- }
-
- var axisLayer = this.axisLayer;
- var rightSideBearing = this.rightSideBearing;
-
- // 获取选中的参考线
- if(x > 20 || y > 20) {
- var result = this.axisLayer.getShapeIn(x, y);
- lines = lines.concat(result);
- }
-
- // rightside bearing 线不可移除
- lines = lines.filter(function(line) {
- return line !== rightSideBearing;
- });
-
- lines.forEach(function(l) {
- axisLayer.removeShape(l);
- });
- axisLayer.refresh();
- },
-
- /**
- * 清除参考线
- */
- clearreferenceline: function() {
- var axisLayer = this.axisLayer;
- var rightSideBearing = this.rightSideBearing;
- var lines = axisLayer.shapes.filter(function(line) {
- return line.type === 'line' && line !== rightSideBearing;
- });
-
- lines.forEach(function(l) {
- axisLayer.removeShape(l);
- });
- axisLayer.refresh();
- },
-
- /**
- * 剪切shapes
- *
- * @param {Array} shapes 形状集合
- */
- cutshapes: function(shapes) {
- var cutedShapes = this.getShapes(shapes);
- this.setClipBoard(cutedShapes);
- var fontLayer = this.fontLayer;
- shapes.forEach(function(shape) {
- fontLayer.removeShape(shape);
- });
- fontLayer.refresh();
- },
-
- /**
- * 复制shapes
- *
- * @param {Array} shapes 形状集合
- */
- copyshapes: function(shapes) {
- shapes = this.getShapes(shapes);
- this.setClipBoard(shapes);
- },
-
- /**
- * 增加shapes
- *
- * @param {Array} shapes 形状集合
- */
- addshapes: function(shapes) {
- this.setShapes(shapes);
- },
-
- /**
- * 是否打开网格吸附
- */
- gridsorption: function(enabled) {
- menuUtil.setSelected(commandList.editor, 'setting.gridsorption', !!enabled);
- this.options.sorption.enableGrid = this.sorption.enableGrid = !!enabled;
- },
-
- /**
- * 是否打开轮廓吸附
- */
- shapesorption: function(enabled) {
- menuUtil.setSelected(commandList.editor, 'setting.shapesorption', !!enabled);
- this.options.sorption.enableShape = this.sorption.enableShape = !!enabled;
- },
-
- /**
- * 是否打开轮廓吸附
- */
- showgrid: function(enabled) {
- menuUtil.setSelected(commandList.editor, 'setting.showgrid', !!enabled);
- this.options.axis.showGrid = this.axis.showGrid = !!enabled;
- this.axisLayer.refresh();
- },
-
- /**
- * 设置字体信息
- */
- setfont: function() {
-
- // 计算边界
- var box = computeBoundingBox.computePathBox.apply(null, this.fontLayer.shapes.map(function(shape) {
- return shape.points;
- }));
-
- var leftSideBearing = 0;
- var rightSideBearing = 0;
-
- if (box) {
- var scale = this.render.camera.scale;
- var leftSideBearing = (box.x - this.axis.x) / scale;
- var rightSideBearing = (this.rightSideBearing.p0.x - box.x - box.width) / scale;
- }
-
- this.fire('setting:font', {
- setting: {
- leftSideBearing: Math.round(leftSideBearing),
- rightSideBearing: Math.round(rightSideBearing || 0),
- unicode: this.font.unicode,
- name: this.font.name
- }
- });
- },
-
- /**
- * 更多设置
- */
- moresetting: function(enabled) {
- this.fire('setting:editor', {
- setting: this.options
- });
- }
- };
-
+ var support = {};
+ lang.extend(support, require('./shape'));
lang.extend(support, require('./transform'));
- lang.extend(support, require('./shapes'));
lang.extend(support, require('./align'));
-
+ lang.extend(support, require('./join'));
+ lang.extend(support, require('./referenceline'));
+ lang.extend(support, require('./editor'));
return support;
}
);
diff --git a/src/editor/command/transform.js b/src/editor/command/transform.js
index 797d11d..3448b00 100644
--- a/src/editor/command/transform.js
+++ b/src/editor/command/transform.js
@@ -18,9 +18,12 @@ define(
* 旋转图形
*
* @param {Array} shapes 图形集合
- * @param {number} angle 角度
+ * @param {number} angle 弧度
*/
function rotate(shapes, angle) {
+ if (!angle) {
+ return false;
+ }
var points = shapes.map(function(shape) {return shape.points;});
var bound = computeBoundingBox.computePath.apply(null, points);
@@ -68,36 +71,69 @@ define(
var support = {
+ /**
+ * 旋转指定角度
+ * @param {Array} shapes 图形集合
+ * @param {number} angle 弧度
+ */
+ rotate: function(shapes, angle) {
+
+ if (!shapes || !shapes.length) {
+ return false;
+ }
+
+ var ret = rotate(shapes, angle);
+ if (false !== ret) {
+ this.fontLayer.refresh();
+ this.refreshSelected(shapes);
+ }
+ return ret;
+ },
+
/**
* 向左旋转
+ * @param {Array} shapes 图形集合
*/
rotateleft: function(shapes) {
- rotate(shapes, - Math.PI / 2);
- this.fontLayer.refresh();
+ return support.rotate.call(this, shapes, - Math.PI / 2);
},
/**
* 向右旋转
+ * @param {Array} shapes 图形集合
*/
rotateright: function(shapes) {
- rotate(shapes, Math.PI / 2);
- this.fontLayer.refresh();
+ return support.rotate.call(this, shapes, Math.PI / 2);
},
/**
* 翻转
+ * @param {Array} shapes 图形集合
*/
- reverseshapes: function(shapes) {
+ flipshapes: function(shapes) {
+
+ if (!shapes || !shapes.length) {
+ return false;
+ }
+
mirror(shapes, 1, -1);
this.fontLayer.refresh();
+ this.refreshSelected(shapes);
},
/**
* 镜像
+ * @param {Array} shapes 图形集合
*/
mirrorshapes: function(shapes) {
+
+ if (!shapes || !shapes.length) {
+ return false;
+ }
+
mirror(shapes, -1, 1);
this.fontLayer.refresh();
+ this.refreshSelected(shapes);
}
};
diff --git a/src/editor/controller/initBinder.js b/src/editor/controller/initBinder.js
index 4dedaef..0bf3c2a 100644
--- a/src/editor/controller/initBinder.js
+++ b/src/editor/controller/initBinder.js
@@ -9,16 +9,29 @@
define(
function(require) {
-
+
+ var commandSupport = require('../command/commandSupport');
+
/**
* 初始化绑定器
*/
function initBinder() {
var me = this;
+
// 保存历史记录
- this.on('change', function(e) {
+ me.on('change', function(e) {
me.history.add(me.getShapes());
});
+
+ // me.on('beforecommand', function(e) {
+ // console.log(e.command);
+ // });
+
+ me.on('command', function(e) {
+ if (false !== e.result && commandSupport.history[e.command]) {
+ me.fire('change');
+ }
+ });
}
return initBinder;
diff --git a/src/editor/controller/initRender.js b/src/editor/controller/initRender.js
index 1fc62d9..afe3e88 100644
--- a/src/editor/controller/initRender.js
+++ b/src/editor/controller/initRender.js
@@ -13,8 +13,6 @@ define(
var commandList = require('../menu/commandList');
var lang = require('common/lang');
var modeSupport = require('../mode/support');
- var pathAdjust = require('graphics/pathAdjust');
- var computeBoundingBox = require('graphics/computeBoundingBox');
var selectShape = require('render/util/selectShape');
/**
@@ -22,9 +20,9 @@ define(
*/
function onContextMenu(e) {
this.contextMenu.hide();
- if (e.command == 'add_referenceline') {
- var pos = e.pos;
- this.execCommand('addreferenceline', pos.x, pos.y);
+
+ if (e.command == 'addreferenceline') {
+ this.execCommand('addreferenceline', e.pos.x, e.pos.y);
}
else if (e.command == 'split') {
this.setMode('split');
@@ -32,27 +30,10 @@ define(
else if (e.command == 'paste') {
var shapes = this.getClipBoard();
if(shapes) {
- var bound = computeBoundingBox.computePath.apply(null,
- shapes.map(function(shape){
- return shape.points;
- })
- );
- // 需要根据坐标原点以及缩放换算成鼠标位置移动
- var origin = this.axis;
- var pos = e.pos;
- var scale = this.render.camera.scale;
- var x = (pos.x - origin.x) / scale;
- var y = (origin.y - pos.y) / scale;
-
- shapes.forEach(function(shape) {
- pathAdjust(shape.points, 1, 1, x - bound.x, y - bound.y - bound.height);
- });
- this.setShapes(shapes);
- this.setMode('shapes', shapes);
- this.fire('change');
+ this.execCommand('pasteshapes', shapes, e.pos);
}
}
- else if (e.command == 'add_supportshapes') {
+ else if (e.command == 'addsupportshapes') {
var type = e.args.type;
this.execCommand('addsupportshapes', type);
}
@@ -214,9 +195,7 @@ define(
else if (e.keyCode == 86 && e.ctrlKey) {
var shapes = me.getClipBoard();
if(shapes) {
- me.setShapes(shapes);
- me.setMode('shapes', shapes);
- me.fire('change');
+ me.execCommand('pasteshapes', shapes);
}
}
// 放大
diff --git a/src/editor/menu/editor.js b/src/editor/menu/editor.js
index e6a6a8c..84f4180 100644
--- a/src/editor/menu/editor.js
+++ b/src/editor/menu/editor.js
@@ -19,27 +19,27 @@ define(
title: '添加形状',
items: [
{
- name: 'add_supportshapes',
+ name: 'addsupportshapes',
type: 'circle',
title: '添加圆'
},
{
- name: 'add_supportshapes',
+ name: 'addsupportshapes',
type: 'rect',
title: '添加矩形'
},
{
- name: 'add_supportshapes',
+ name: 'addsupportshapes',
type: 'roundrect',
title: '添加圆角矩形'
},
{
- name: 'add_supportshapes',
+ name: 'addsupportshapes',
type: 'star',
title: '添加五角星'
},
{
- name: 'add_supportshapes',
+ name: 'addsupportshapes',
type: 'arrow',
title: '添加箭头'
}
@@ -84,7 +84,7 @@ define(
]
},
{
- name: 'add_referenceline',
+ name: 'addreferenceline',
title: '添加参考线'
},
{
@@ -96,7 +96,7 @@ define(
title: '重置缩放'
},
{
- name: 'setfont',
+ name: 'fontsetting',
title: '字形信息'
}
];
diff --git a/src/editor/menu/shape.js b/src/editor/menu/shape.js
index d9c82423..ae17bea 100644
--- a/src/editor/menu/shape.js
+++ b/src/editor/menu/shape.js
@@ -11,19 +11,19 @@ define(
function(require) {
return [
{
- name: 'remove',
+ name: 'removeshapes',
title: '删除轮廓'
},
{
- name: 'reverse_point',
+ name: 'reversepoints',
title: '改变方向'
},
{
- name: 'cut',
+ name: 'cutshapes',
title: '剪切'
},
{
- name: 'copy',
+ name: 'copyshapes',
title: '复制'
},
{
@@ -31,19 +31,19 @@ define(
title: '顺序',
items: [
{
- name: 'top',
+ name: 'topshape',
title: '置前'
},
{
- name: 'bottom',
+ name: 'bottomshape',
title: '置后'
},
{
- name: 'up',
+ name: 'upshape',
title: '上移一层'
},
{
- name: 'down',
+ name: 'downshape',
title: '下移一层'
}
]
@@ -53,51 +53,72 @@ define(
title: '变换',
items: [
{
- name: 'rotate_left',
+ name: 'rotateleft',
title: '向左旋转'
},
{
- name: 'rotate_right',
+ name: 'rotateright',
title: '向右旋转'
},
{
- name: 'reverse_shapes',
+ name: 'flipshapes',
title: '翻转'
},
{
- name: 'mirror_shapes',
+ name: 'mirrorshapes',
title: '镜像'
}
]
},
{
- name: 'shapes_verticalalign',
- title: '垂直方向',
+ name: 'horizontalalignshapes_',
+ title: '水平方向',
items: [
{
- name: 'shapes_verticalalign',
- type: 'ascent',
- title: '顶端对齐'
+ name: 'horizontalalignshapes',
+ align: 'left',
+ title: '左对齐'
},
{
- name: 'shapes_verticalalign',
- type: 'middle',
+ name: 'horizontalalignshapes',
+ align: 'center',
title: '居中对齐'
},
{
- name: 'shapes_verticalalign',
- type: 'descent',
+ name: 'horizontalalignshapes',
+ align: 'right',
+ title: '右对齐'
+ }
+ ]
+ },
+ {
+ name: 'verticalalignshapes_',
+ title: '垂直方向',
+ items: [
+ {
+ name: 'verticalalignshapes',
+ align: 'ascent',
+ title: '顶端对齐'
+ },
+ {
+ name: 'verticalalignshapes',
+ align: 'middle',
+ title: '居中对齐'
+ },
+ {
+ name: 'verticalalignshapes',
+ align: 'descent',
title: '底端对齐'
},
{
- name: 'shapes_verticalalign',
- type: 'baseline',
+ name: 'verticalalignshapes',
+ align: 'baseline',
title: '基线对齐'
}
]
},
{
- name: 'add_referenceline',
+ name: 'addreferenceline',
title: '添加边界参考线'
}
];
diff --git a/src/editor/menu/shapes.js b/src/editor/menu/shapes.js
index cc9abd6..69efa88 100644
--- a/src/editor/menu/shapes.js
+++ b/src/editor/menu/shapes.js
@@ -11,19 +11,19 @@ define(
function(require) {
return [
{
- name: 'reverse_point',
+ name: 'reversepoints',
title: '改变方向'
},
{
- name: 'remove',
+ name: 'removeshapes',
title: '删除轮廓'
},
{
- name: 'cut',
+ name: 'cutshapes',
title: '剪切'
},
{
- name: 'copy',
+ name: 'copyshapes',
title: '复制'
},
{
@@ -31,15 +31,15 @@ define(
title: '连接轮廓',
items: [
{
- name: 'join_shapes',
+ name: 'joinshapes',
title: '结合'
},
{
- name: 'intersect_shapes',
+ name: 'intersectshapes',
title: '相交'
},
{
- name: 'tangency_shapes',
+ name: 'tangencyshapes',
title: '相切'
}
]
@@ -49,88 +49,109 @@ define(
title: '变换',
items: [
{
- name: 'rotate_left',
+ name: 'rotateleft',
title: '向左旋转'
},
{
- name: 'rotate_right',
+ name: 'rotateright',
title: '向右旋转'
},
{
- name: 'reverse_shapes',
+ name: 'flipshapes',
title: '翻转'
},
{
- name: 'mirror_shapes',
+ name: 'mirrorshapes',
title: '镜像'
}
]
},
{
- name: 'shapes_align',
+ name: 'alignshapes_',
title: '对齐形状',
items: [
{
- name: 'shapes_align',
- type: 'left',
+ name: 'alignshapes',
+ align: 'left',
title: '左对齐'
},
{
- name: 'shapes_align',
- type: 'center',
+ name: 'alignshapes',
+ align: 'center',
title: '居中对齐'
},
{
- name: 'shapes_align',
- type: 'right',
+ name: 'alignshapes',
+ align: 'right',
title: '右对齐'
},
{
- name: 'shapes_align',
- type: 'top',
+ name: 'alignshapes',
+ align: 'top',
title: '顶部对齐'
},
{
- name: 'shapes_align',
- type: 'middle',
+ name: 'alignshapes',
+ align: 'middle',
title: '中间对齐'
},
{
- name: 'shapes_align',
- type: 'bottom',
+ name: 'alignshapes',
+ align: 'bottom',
title: '底部对齐'
}
]
},
{
- name: 'shapes_verticalalign',
- title: '垂直方向',
+ name: 'horizontalalignshapes_',
+ title: '水平方向',
items: [
{
- name: 'shapes_verticalalign',
- type: 'ascent',
- title: '顶端对齐'
+ name: 'horizontalalignshapes',
+ align: 'left',
+ title: '左对齐'
},
{
- name: 'shapes_verticalalign',
- type: 'middle',
+ name: 'horizontalalignshapes',
+ align: 'center',
title: '居中对齐'
},
{
- name: 'shapes_verticalalign',
- type: 'descent',
+ name: 'horizontalalignshapes',
+ align: 'right',
+ title: '右对齐'
+ }
+ ]
+ },
+ {
+ name: 'verticalalignshapes_',
+ title: '垂直方向',
+ items: [
+ {
+ name: 'verticalalignshapes',
+ align: 'ascent',
+ title: '顶端对齐'
+ },
+ {
+ name: 'verticalalignshapes',
+ align: 'middle',
+ title: '居中对齐'
+ },
+ {
+ name: 'verticalalignshapes',
+ align: 'descent',
title: '底端对齐'
},
{
- name: 'shapes_verticalalign',
- type: 'baseline',
+ name: 'verticalalignshapes',
+ align: 'baseline',
title: '基线对齐'
}
]
},
{
- name: 'add_referenceline',
+ name: 'addreferenceline',
title: '添加边界参考线'
}
];
diff --git a/src/editor/mode/shapes.js b/src/editor/mode/shapes.js
index 73c01f3..23a8dbf 100644
--- a/src/editor/mode/shapes.js
+++ b/src/editor/mode/shapes.js
@@ -31,114 +31,55 @@ define(
* @param {string} command 命令
*/
function onContextMenu(e) {
- if(this.currentGroup.shapes.length === 0) {
- return;
- }
- this.fire('command', e);
- if(e.returnValue === false) {
+ if(!this.currentGroup.shapes.length) {
return;
}
this.contextMenu.hide();
var command = e.command;
-
- // 是否编辑器支持
- if(this.supportCommand(command)) {
- this.execCommand(command, e);
- return;
- }
-
+ var args = e.args;
var shapes = this.currentGroup.shapes;
- var shape = shapes[0];
- if (command == 'remove') {
- this.execCommand('removeshapes', shapes);
- this.setMode();
+ switch (command) {
+ case 'topshape':
+ case 'bottomshape':
+ case 'upshape':
+ case 'downshape':
+ this.execCommand(command, shapes[0]);
+ break;
+ case 'joinshapes':
+ case 'intersectshapes':
+ case 'tangencyshapes':
+ case 'rotateleft':
+ case 'rotateright':
+ case 'flipshapes':
+ case 'mirrorshapes':
+ case 'cutshapes':
+ case 'copyshapes':
+ case 'removeshapes':
+ case 'reversepoints':
+ this.execCommand(command, shapes);
+ break;
+ case 'alignshapes':
+ case 'verticalalignshapes':
+ case 'horizontalalignshapes':
+ this.execCommand(command, shapes, args.align);
+ break;
+ case 'addreferenceline':
+ var bound = this.currentGroup.getBound();
+ if(bound) {
+ this.execCommand(command, bound.x, bound.y);
+ this.execCommand(command, bound.x + bound.width, bound.y + bound.height);
+ }
+ break;
+ default:
+ // 是否编辑器支持
+ if(this.supportCommand(command)) {
+ this.execCommand(command, e);
+ }
}
- else if (command == 'reverse_point') {
- this.execCommand('reversepoint', shapes);
- }
- else if (command == 'top') {
- this.execCommand('topshape', shape);
- }
- else if (command == 'bottom') {
- this.execCommand('bottomshape', shape);
- }
- else if (command == 'up') {
- this.execCommand('upshape', shape);
- }
- else if (command == 'down') {
- this.execCommand('downshape', shape);
- }
-
- // 相交,结合和相切
- else if (command == 'join_shapes') {
- this.execCommand('joinshapes', shapes);
- this.currentGroup.setShapes(shapes);
- this.currentGroup.refresh();
- }
- else if (command == 'intersect_shapes') {
- this.execCommand('intersectshapes', shapes);
- this.currentGroup.setShapes(shapes);
- this.currentGroup.refresh();
- }
- else if (command == 'tangency_shapes') {
- this.execCommand('tangencyshapes', shapes);
- this.currentGroup.setShapes(shapes);
- this.currentGroup.refresh();
- }
-
- else if (command == 'rotate_left') {
- this.execCommand('rotateleft', shapes);
- this.currentGroup.setShapes(shapes);
- this.currentGroup.refresh();
- }
- else if (command == 'rotate_right') {
- this.execCommand('rotateright', shapes);
- this.currentGroup.setShapes(shapes);
- this.currentGroup.refresh();
- }
- else if (command == 'reverse_shapes') {
- this.execCommand('reverseshapes', shapes);
- this.currentGroup.setShapes(shapes);
- this.currentGroup.refresh();
- }
- else if (command == 'mirror_shapes') {
- this.execCommand('mirrorshapes', shapes);
- this.currentGroup.setShapes(shapes);
- this.currentGroup.refresh();
- }
- else if (command == 'add_referenceline') {
- var bound = this.currentGroup.getBound();
- if(bound) {
- this.execCommand('addreferenceline', bound.x, bound.y);
- this.execCommand(
- 'addreferenceline',
- bound.x + bound.width, bound.y + bound.height
- );
- }
- }
- else if (command == 'cut') {
- this.execCommand('cutshapes', shapes);
- this.setMode();
- this.fire('change');
- }
- else if (command == 'copy') {
- this.execCommand('copyshapes', shapes);
- }
- else if (command == 'shapes_align') {
- this.execCommand('align', shapes, e.args.type);
- this.currentGroup.setShapes(shapes);
- this.currentGroup.refresh();
- }
- else if (command == 'shapes_verticalalign') {
- this.execCommand('verticalalign', shapes, e.args.type);
- this.currentGroup.setShapes(shapes);
- this.currentGroup.refresh();
- }
- this.fire('change');
}
@@ -169,23 +110,25 @@ define(
var shapeIndex = this.currentGroup.shapes.indexOf(shape);
if(shapeIndex >= 0) {
+ // ctl多选,点选2次, !altKey 防止复制冲突
if (e.ctrlKey && !e.altKey) {
this.currentGroup.shapes.splice(shapeIndex, 1);
- this.currentGroup.setShapes(this.currentGroup.shapes);
- this.currentGroup.refresh();
+ this.refreshSelected(this.currentGroup.shapes.slice(0));
this.clicked = false;
}
return;
}
else {
+
var shapes = [shape];
+ // 多选
if (e.ctrlKey) {
shapes = shapes.concat(this.currentGroup.shapes);;
}
- this.currentGroup.setShapes(shapes);
+
this.currentGroup.setMode('scale');
- this.currentGroup.refresh();
+ this.refreshSelected(shapes);
this.clicked = false;
return;
}
@@ -298,7 +241,6 @@ define(
if (e.key == 'delete') {
this.execCommand('removeshapes', this.currentGroup.shapes);
this.setMode();
- this.fire('change');
}
// 全选
else if(e.keyCode == 65 && e.ctrlKey) {
@@ -322,10 +264,6 @@ define(
if (e.keyCode == 88 && e.ctrlKey) {
if (this.currentGroup.shapes.length) {
this.execCommand('cutshapes', this.currentGroup.shapes);
- this.currentGroup.shapes.length = 0;
- this.coverLayer.clearShapes();
- this.coverLayer.refresh();
- this.fire('change');
}
}
// 复制
@@ -344,15 +282,21 @@ define(
* 开始模式
*/
begin: function(shapes, prevMode) {
+
this.currentGroup = new ShapesGroup(shapes, this);
this.currentGroup.refresh();
this.currentGroup.setMode('scale');
+
if (prevMode == 'bound') {
this.clicked = false;
}
else {
this.clicked = true;
}
+
+ this.fire('selection:change', {
+ shapes: shapes
+ });
},
@@ -364,8 +308,8 @@ define(
this.currentPoint = null;
this.currentGroup.dispose();
this.currentGroup = null;
-
this.render.setCursor('default');
+ this.fire('selection:change');
}
};
diff --git a/src/editor/mode/split.js b/src/editor/mode/split.js
index 261c74b..b5e715d 100644
--- a/src/editor/mode/split.js
+++ b/src/editor/mode/split.js
@@ -56,12 +56,8 @@ define(
var p1 = this.splitLine.p1;
// 对shape进行多选
if (Math.abs(p0.x - p1.x) >= 20 || Math.abs(p0.y - p1.y) >= 20) {
- var shapes = [];
- this.execCommand('splitshapes', p0, p1, shapes);
- if (shapes.length) {
- this.setMode('shapes', shapes);
- this.fire('change');
- return;
+ if (false !== this.execCommand('splitshapes', p0, p1)) {
+ return;
}
}
}
diff --git a/src/fonteditor/main.js b/src/fonteditor/main.js
index 385cc2a..581e512 100644
--- a/src/fonteditor/main.js
+++ b/src/fonteditor/main.js
@@ -86,6 +86,7 @@ define(
init: function () {
bindEvent();
+ // glyf查看器命令组
program.viewerCommandMenu = new CommandMenu($('#glyf-list-commandmenu'), {
commands: require('./widget/menu/viewer')
});
@@ -95,8 +96,15 @@ define(
commandMenu: program.viewerCommandMenu
});
+ // 字体查看器命令组
+ program.editorCommandMenu = new CommandMenu($('#editor-commandmenu'), {
+ commands: require('./widget/menu/editor')
+ });
+
// 字体查看器
- program.editor = new GLYFEditor($('#glyf-editor'));
+ program.editor = new GLYFEditor($('#glyf-editor'), {
+ commandMenu: program.editorCommandMenu
+ });
// 项目管理
program.project = require('./widget/project');
diff --git a/src/fonteditor/widget/actions.js b/src/fonteditor/widget/actions.js
index aadd763..8aec796 100644
--- a/src/fonteditor/widget/actions.js
+++ b/src/fonteditor/widget/actions.js
@@ -47,11 +47,28 @@ define(
var actions = {
'undo': function() {
- program.ttfManager.undo();
+ if (program.editor.isEditing()) {
+ program.editor.undo();
+ setTimeout(function(){
+ program.editor.focus();
+ }, 20);
+
+ }
+ else {
+ program.ttfManager.undo();
+ }
},
'redo': function() {
- program.ttfManager.redo();
+ if (program.editor.isEditing()) {
+ program.editor.redo();
+ setTimeout(function(){
+ program.editor.focus();
+ }, 20);
+ }
+ else {
+ program.ttfManager.redo();
+ }
},
// 新建
diff --git a/src/fonteditor/widget/commandmenu.js b/src/fonteditor/widget/commandmenu.js
index c5657e2..7c0e1f3 100644
--- a/src/fonteditor/widget/commandmenu.js
+++ b/src/fonteditor/widget/commandmenu.js
@@ -41,7 +41,7 @@ define(
command.on = false;
me.fire('command:un', {
command: name,
-
+ args: command
});
return;
}
@@ -86,13 +86,28 @@ define(
commands = commands || this.commands;
var str = '';
commands.forEach(function(item, i) {
- str += ''
- + item.title
- + (item.quickKey ? '('+ item.quickKey +')' : '')
- +'';
+
+ if (item.type === 'split') {
+ str += '';
+ }
+ else {
+
+ str += '';
+
+ if (item.ico) {
+ str += '';
+ }
+ else {
+ str += item.title
+ + (item.quickKey ? '('+ item.quickKey +')' : '');
+ }
+
+ str +='';
+ }
});
this.main.html(str);
this.commands = commands;
diff --git a/src/fonteditor/widget/glyfeditor.js b/src/fonteditor/widget/glyfeditor.js
index f1cefea..5fb8ab8 100644
--- a/src/fonteditor/widget/glyfeditor.js
+++ b/src/fonteditor/widget/glyfeditor.js
@@ -14,6 +14,21 @@ define(
var editorOptions = require('editor/options');
var setting = require('./setting');
var program = require('./program');
+ var lang = require('common/lang');
+
+
+ // 支持的命令列表
+ var COMMAND_SUPPORT = {
+ // 形状组
+ shapes: [
+ 'copyshapes', 'removeshapes',
+ 'horizontalalignshapes', 'verticalalignshapes',
+ 'rotateleft', 'rotateright', 'flipshapes', 'mirrorshapes'
+ ],
+ // 单个形状
+ shape: ['upshape', 'downshape', 'reversepoints']
+ };
+
/**
* 绑定editor编辑器
@@ -49,6 +64,87 @@ define(
editor: e.setting
});
});
+
+ var commandMenu = this.options.commandMenu;
+ if (commandMenu) {
+
+ editor.on('selection:change', lang.debounce(function(e) {
+ var length = e.shapes ? e.shapes.length : 0;
+ if (!length) {
+ commandMenu.disableCommands(COMMAND_SUPPORT.shapes);
+ commandMenu.disableCommands(COMMAND_SUPPORT.shape);
+ }
+ else {
+ commandMenu.enableCommands(COMMAND_SUPPORT.shapes);
+ commandMenu[length === 1 ? 'enableCommands' : 'disableCommands'](COMMAND_SUPPORT.shape);
+ }
+ }), 100);
+
+ commandMenu.on('command', function(e) {
+
+ var command = e.command;
+ var args = e.args;
+ var shapes;
+
+ if (command === 'pasteshapes') {
+ shapes = editor.getClipBoard();
+ }
+ else {
+ shapes = editor.getSelected();
+ }
+
+ if (shapes && shapes.length) {
+ switch (command) {
+ case 'topshape':
+ case 'bottomshape':
+ case 'upshape':
+ case 'downshape':
+ editor.execCommand(command, shapes[0]);
+ break;
+
+ case 'copyshapes':
+ case 'pasteshapes':
+ case 'removeshapes':
+ case 'joinshapes':
+ case 'intersectshapes':
+ case 'tangencyshapes':
+ case 'rotateleft':
+ case 'rotateright':
+ case 'flipshapes':
+ case 'mirrorshapes':
+ case 'cutshapes':
+ case 'copyshapes':
+ case 'removeshapes':
+ case 'reversepoints':
+ editor.execCommand(command, shapes);
+ break;
+
+ case 'alignshapes':
+ case 'verticalalignshapes':
+ case 'horizontalalignshapes':
+ editor.execCommand(command, shapes, args.align);
+ break;
+ }
+ }
+
+ // 这里延时进行focus
+ setTimeout(function() {
+ me.focus();
+ }, 20);
+ });
+ }
+
+ }
+
+ /**
+ * 执行指定命令
+ *
+ * @param {string} command 命令名
+ */
+ function execCommand(command) {
+ if (this.editor) {
+ this.editor.execCommand.apply(this.editor, arguments);
+ }
}
/**
@@ -122,6 +218,20 @@ define(
this.editor && this.editor.blur();
};
+ /**
+ * 撤销
+ */
+ GLYFEditor.prototype.undo = function() {
+ execCommand.call(this, 'undo');
+ };
+
+ /**
+ * 重做
+ */
+ GLYFEditor.prototype.redo = function() {
+ execCommand.call(this, 'redo');
+ };
+
/**
* 设置项目
* @param {Object} options 参数集合
diff --git a/src/fonteditor/widget/glyfviewer.js b/src/fonteditor/widget/glyfviewer.js
index 5dfd97d..356af2f 100644
--- a/src/fonteditor/widget/glyfviewer.js
+++ b/src/fonteditor/widget/glyfviewer.js
@@ -293,13 +293,13 @@ define(
var selected = me.getSelected();
if (selected.length) {
commandMenu.enableCommands(['copy', 'cut', 'del']);
- commandMenu[selected.length === 1 ? 'enableCommands' : 'disableCommands'](['info']);
+ commandMenu[selected.length === 1 ? 'enableCommands' : 'disableCommands'](['fontsetting']);
}
else {
- commandMenu.disableCommands(['copy', 'cut', 'del', 'info']);
+ commandMenu.disableCommands(['copy', 'cut', 'del', 'fontsetting']);
}
- }, 20));
+ }, 100));
commandMenu.on('command', function(e) {
var command = e.command;
diff --git a/src/fonteditor/widget/menu/editor.js b/src/fonteditor/widget/menu/editor.js
new file mode 100644
index 0000000..cdc185c
--- /dev/null
+++ b/src/fonteditor/widget/menu/editor.js
@@ -0,0 +1,132 @@
+/**
+ * @file viewer.js
+ * @author mengke01
+ * @date
+ * @description
+ * glyf编辑器相关命令
+ */
+
+
+define(
+ function(require) {
+ return [
+ {
+ name: 'copyshapes',
+ title: '复制',
+ quickKey: 'C',
+ disabled: true
+ },
+ {
+ name: 'pasteshapes',
+ title: '粘贴',
+ quickKey: 'V'
+ },
+ {
+ name: 'removeshapes',
+ title: '删除',
+ quickKey: 'D',
+ disabled: true
+ },
+ {
+ type: 'split'
+ },
+ {
+ name: 'upshape',
+ title: '上移一层',
+ ico: 'upshape',
+ disabled: true
+ },
+ {
+ name: 'downshape',
+ title: '下移一层',
+ ico: 'downshape',
+ disabled: true
+ },
+ {
+ name: 'reversepoints',
+ title: '改变方向',
+ ico: 'reversepoints',
+ disabled: true
+ },
+ {
+ type: 'split'
+ },
+ {
+ name: 'horizontalalignshapes',
+ title: '左对齐',
+ ico: 'alignleft',
+ align: 'left',
+ disabled: true
+ },
+ {
+ name: 'horizontalalignshapes',
+ title: '居中对齐',
+ ico: 'aligncenter',
+ align: 'center',
+ disabled: true
+ },
+ {
+ name: 'horizontalalignshapes',
+ title: '右对齐',
+ ico: 'alignright',
+ align: 'right',
+ disabled: true
+ },
+ {
+ name: 'verticalalignshapes',
+ title: '顶端对齐',
+ ico: 'aligntop',
+ align: 'ascent',
+ disabled: true
+ },
+ {
+ name: 'verticalalignshapes',
+ title: '居中对齐',
+ ico: 'alignmiddle',
+ align: 'middle',
+ disabled: true
+ },
+ {
+ name: 'verticalalignshapes',
+ title: '底端对齐',
+ ico: 'aligndescent',
+ align: 'descent',
+ disabled: true
+ },
+ {
+ name: 'verticalalignshapes',
+ title: '基线对齐',
+ ico: 'alignbaseline',
+ align: 'baseline',
+ disabled: true
+ },
+ {
+ type: 'split'
+ },
+ {
+ name: 'rotateleft',
+ title: '向左旋转',
+ ico: 'rotateleft',
+ disabled: true
+ },
+ {
+ name: 'rotateright',
+ title: '向右旋转',
+ ico: 'rotateright',
+ disabled: true
+ },
+ {
+ name: 'flipshapes',
+ title: '翻转',
+ ico: 'flip',
+ disabled: true
+ },
+ {
+ name: 'mirrorshapes',
+ title: '镜像',
+ ico: 'mirror',
+ disabled: true
+ }
+ ];
+ }
+);
diff --git a/src/fonteditor/widget/menu/viewer.js b/src/fonteditor/widget/menu/viewer.js
index c7d8fcd..b4628a4 100644
--- a/src/fonteditor/widget/menu/viewer.js
+++ b/src/fonteditor/widget/menu/viewer.js
@@ -9,40 +9,44 @@
define(
function(require) {
+
return [
{
- name: "copy",
- title: "复制",
+ name: 'copy',
+ title: '复制',
quickKey: 'C',
disabled: true
},
{
- name: "cut",
- title: "剪切",
+ name: 'cut',
+ title: '剪切',
quickKey: 'X'
},
{
- name: "paste",
- title: "粘贴",
+ name: 'paste',
+ title: '粘贴',
quickKey: 'V'
},
{
- name: "del",
- title: "删除",
+ name: 'del',
+ title: '删除',
quickKey: 'D',
disabled: true
},
{
- name: "adjust-pos",
- title: "调整位置"
+ type: 'split'
},
{
- name: "adjust-glyf",
- title: "调整字形"
+ name: 'adjust-pos',
+ title: '调整位置'
},
{
- name: "info",
- title: "字形信息",
+ name: 'adjust-glyf',
+ title: '调整字形'
+ },
+ {
+ name: 'fontsetting',
+ title: '字形信息',
disabled: true
}
];