commit
ff45cfdca3
@ -1,5 +1,7 @@
|
||||
# editor
|
||||
|
||||
[重构](refactoring.md)
|
||||
|
||||
>! 以下均是v2.0时的说明, 未及时改动
|
||||
|
||||
本目录下所有文件,以及`../editor.html`和`../启动服务.exe`([源码](http://github.com/ckcz123/mota-js-server/))是地图编辑器的所有组件.
|
||||
@ -31,7 +33,7 @@
|
||||
``` js
|
||||
editor.mapInit();//清空地图
|
||||
editor.changeFloor('MT2')//切换地图
|
||||
editor.guid()//产生一个可以作为id的长随机字符串
|
||||
editor.util.guid()//产生一个可以作为id的长随机字符串
|
||||
```
|
||||
|
||||
`editor.updateMap`中画未定义快的报错
|
||||
|
||||
@ -41,31 +41,9 @@ editor.info
|
||||
/////////// 数据相关 ///////////
|
||||
|
||||
editor.prototype.init = function (callback) {
|
||||
var afterCoreReset = function () {
|
||||
|
||||
editor.idsInit(core.maps, core.icons.icons); // 初始化图片素材信息
|
||||
editor.drawInitData(core.icons.icons); // 初始化绘图
|
||||
|
||||
editor.fetchMapFromCore();
|
||||
editor.updateMap();
|
||||
editor.buildMark();
|
||||
editor.drawEventBlock();
|
||||
|
||||
editor.pos = {x: 0, y: 0};
|
||||
editor.mode.loc();
|
||||
editor.info = editor.ids[editor.indexs[201]];
|
||||
editor.mode.enemyitem();
|
||||
editor.mode.floor();
|
||||
editor.mode.tower();
|
||||
editor.mode.functions();
|
||||
editor.mode.commonevent();
|
||||
editor.mode.showMode('tower');
|
||||
|
||||
editor_multi = editor_multi();
|
||||
editor_blockly = editor_blockly();
|
||||
if (Boolean(callback)) callback();
|
||||
|
||||
}
|
||||
editor_util_wrapper(editor);
|
||||
editor_table_wrapper(editor);
|
||||
|
||||
var afterMainInit = function () {
|
||||
core.floors = JSON.parse(JSON.stringify(core.floors, function (k, v) {
|
||||
@ -97,6 +75,33 @@ editor.prototype.init = function (callback) {
|
||||
core.events.setInitData(null);
|
||||
});
|
||||
}
|
||||
|
||||
var afterCoreReset = function () {
|
||||
|
||||
editor.idsInit(core.maps, core.icons.icons); // 初始化图片素材信息
|
||||
editor.drawInitData(core.icons.icons); // 初始化绘图
|
||||
|
||||
editor.fetchMapFromCore();
|
||||
editor.updateMap();
|
||||
editor.buildMark();
|
||||
editor.drawEventBlock();
|
||||
|
||||
editor.pos = {x: 0, y: 0};
|
||||
editor.mode.loc();
|
||||
editor.info = editor.ids[editor.indexs[201]];
|
||||
editor.mode.enemyitem();
|
||||
editor.mode.floor();
|
||||
editor.mode.tower();
|
||||
editor.mode.functions();
|
||||
editor.mode.commonevent();
|
||||
editor.mode.showMode('tower');
|
||||
|
||||
editor_multi = editor_multi();
|
||||
editor_blockly = editor_blockly();
|
||||
if (Boolean(callback)) callback();
|
||||
|
||||
}
|
||||
|
||||
afterMainInit();
|
||||
}
|
||||
|
||||
@ -354,21 +359,6 @@ editor.prototype.moveViewport=function(x,y){
|
||||
editor.drawPosSelection();
|
||||
}
|
||||
|
||||
/////////// 通用 ///////////
|
||||
|
||||
editor.prototype.guid = function () {
|
||||
return 'id_' + 'xxxxxxxx_xxxx_4xxx_yxxx_xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
editor.prototype.HTMLescape = function (str_) {
|
||||
return String(str_).split('').map(function (v) {
|
||||
return '&#' + v.charCodeAt(0) + ';'
|
||||
}).join('');
|
||||
}
|
||||
|
||||
/////////// 界面交互相关 ///////////
|
||||
|
||||
editor.prototype.drawInitData = function (icons) {
|
||||
|
||||
@ -94,7 +94,7 @@ editor_file = function (editor, callback) {
|
||||
}
|
||||
// format 更改实现方式以支持undefined删除
|
||||
var tempJsonObj=Object.assign({},editor.currentFloorData);
|
||||
var tempMap=[['map',editor.guid()],['bgmap',editor.guid()],['fgmap',editor.guid()]];
|
||||
var tempMap=[['map',editor.util.guid()],['bgmap',editor.util.guid()],['fgmap',editor.util.guid()]];
|
||||
tempMap.forEach(function(v){
|
||||
v[2]=tempJsonObj[v[0]];
|
||||
tempJsonObj[v[0]]=v[1];
|
||||
@ -764,7 +764,7 @@ editor_file = function (editor, callback) {
|
||||
var fmap = {};
|
||||
var fjson = JSON.stringify(functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a, function (k, v) {
|
||||
if (v instanceof Function) {
|
||||
var id_ = editor.guid();
|
||||
var id_ = editor.util.guid();
|
||||
fmap[id_] = v.toString();
|
||||
return id_;
|
||||
} else return v
|
||||
@ -853,11 +853,11 @@ editor_file = function (editor, callback) {
|
||||
var plmap = {};
|
||||
var pljson = JSON.stringify(plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1, function (k, v) {
|
||||
if (v instanceof Function) {
|
||||
var id_ = editor.guid();
|
||||
var id_ = editor.util.guid();
|
||||
plmap[id_] = v.toString();
|
||||
return id_;
|
||||
} else if(v===null){
|
||||
var id_ = editor.guid();
|
||||
var id_ = editor.util.guid();
|
||||
plmap[id_] = 'null';
|
||||
return id_;
|
||||
} return v
|
||||
@ -980,7 +980,7 @@ editor_file = function (editor, callback) {
|
||||
var emap = {};
|
||||
var estr = JSON.stringify(maps_90f36752_8815_4be8_b32b_d7fad1d0542e, function (k, v) {
|
||||
if (v.id != null) {
|
||||
var id_ = editor.guid();
|
||||
var id_ = editor.util.guid();
|
||||
emap[id_] = JSON.stringify(v);
|
||||
return id_;
|
||||
} else return v
|
||||
@ -1014,7 +1014,7 @@ editor_file = function (editor, callback) {
|
||||
var emap = {};
|
||||
var estr = JSON.stringify(enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80, function (k, v) {
|
||||
if (v.hp != null) {
|
||||
var id_ = editor.guid();
|
||||
var id_ = editor.util.guid();
|
||||
emap[id_] = JSON.stringify(v);
|
||||
return id_;
|
||||
} else return v
|
||||
|
||||
@ -38,305 +38,6 @@ editor_mode = function (editor) {
|
||||
if (Boolean(callback)) callback();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* 把来自数据文件的obj和来自*comment.js的commentObj组装成表格
|
||||
* commentObj在无视['_data']的意义下与obj同形
|
||||
* 即: commentObj['_data']['a']['_data']['b'] 与 obj['a']['b'] 是对应的
|
||||
* 在此意义下, 两者的结构是一致的
|
||||
* 在commentObj没有被定义的obj的分支, 会取defaultcobj作为默认值
|
||||
* 因此在深度优先遍历时,维护
|
||||
* field="['a']['b']"
|
||||
* cfield="['_data']['a']['_data']['b']"
|
||||
* vobj=obj['a']['b']
|
||||
* cobj=commentObj['_data']['a']['_data']['b']
|
||||
* cobj
|
||||
* cobj = Object.assign({}, defaultcobj, pcobj['_data'][ii])
|
||||
* 每一项若未定义,就从defaultcobj中取
|
||||
* 当其是函数不是具体值时,把args = {field: field, cfield: cfield, vobj: vobj, cobj: cobj}代入算出该值
|
||||
* 得到的叶节点的<tr>结构如下
|
||||
* tr>td[title=field]
|
||||
* >td[title=comment,cobj=cobj:json]
|
||||
* >td>div>input[value=thiseval]
|
||||
* 返回结果
|
||||
* 返回一个对象, 假设被命名为tableinfo
|
||||
* 在把一个 table 的 innerHTML 赋值为 tableinfo.HTML 后
|
||||
* 再调 tableinfo.listen(tableinfo.guids) 进行绑定事件
|
||||
* @param {Object} obj
|
||||
* @param {Object} commentObj
|
||||
* @returns {{"HTML":String,"guids":String[],"listen":Function}}
|
||||
*/
|
||||
editor_mode.prototype.objToTable_ = function (obj, commentObj) {
|
||||
// 表格抬头
|
||||
var outstr = ["\n<tr><td>条目</td><td>注释</td><td>值</td></tr>\n"];
|
||||
var guids = [];
|
||||
var defaultcobj = {
|
||||
// 默认是文本域
|
||||
_type: 'textarea',
|
||||
_data: '',
|
||||
_string: function (args) {//object~[field,cfield,vobj,cobj]
|
||||
var thiseval = args.vobj;
|
||||
return (typeof(thiseval) === typeof('')) && thiseval[0] === '"';
|
||||
},
|
||||
// 默认情况下 非对象和数组的视为叶节点
|
||||
_leaf: function (args) {//object~[field,cfield,vobj,cobj]
|
||||
var thiseval = args.vobj;
|
||||
if (thiseval == null || thiseval == undefined) return true;//null,undefined
|
||||
if (typeof(thiseval) === typeof('')) return true;//字符串
|
||||
if (Object.keys(thiseval).length === 0) return true;//数字,true,false,空数组,空对象
|
||||
return false;
|
||||
},
|
||||
}
|
||||
/**
|
||||
* 深度优先遍历, p*即为父节点的四个属性
|
||||
* @param {String} pfield
|
||||
* @param {String} pcfield
|
||||
* @param {Object} pvobj
|
||||
* @param {Object} pcobj
|
||||
*/
|
||||
var recursionParse = function (pfield, pcfield, pvobj, pcobj) {
|
||||
var keysForTableOrder={};
|
||||
var voidMark={};
|
||||
// 1. 按照pcobj排序生成
|
||||
if (pcobj && pcobj['_data']){
|
||||
for (var ii in pcobj['_data']) keysForTableOrder[ii]=voidMark;
|
||||
}
|
||||
// 2. 对每个pvobj且不在pcobj的,再添加到最后
|
||||
keysForTableOrder=Object.assign(keysForTableOrder,pvobj)
|
||||
for (var ii in keysForTableOrder) {
|
||||
// 3. 对于pcobj有但是pvobj中没有的, 弹出提示, (正常情况下editor_file会补全成null)
|
||||
// 事实上能执行到这一步工程没崩掉打不开,就继续吧..
|
||||
if(keysForTableOrder[ii]===voidMark){
|
||||
if(typeof id_815975ad_ee6f_4684_aac7_397b7e392702==="undefined"){
|
||||
alert('comment和data不匹配,请在群 HTML5造塔技术交流群 959329661 内反馈')
|
||||
console.error('comment和data不匹配,请在群 HTML5造塔技术交流群 959329661 内反馈')
|
||||
id_815975ad_ee6f_4684_aac7_397b7e392702=1;
|
||||
}
|
||||
pvobj[ii]=null;
|
||||
}
|
||||
var field = pfield + "['" + ii + "']";
|
||||
var cfield = pcfield + "['_data']['" + ii + "']";
|
||||
var vobj = pvobj[ii];
|
||||
var cobj = null;
|
||||
if (pcobj && pcobj['_data'] && pcobj['_data'][ii]) {
|
||||
// cobj存在时直接取
|
||||
cobj = Object.assign({}, defaultcobj, pcobj['_data'][ii]);
|
||||
} else {
|
||||
// 当其函数时代入参数算出cobj, 不存在时只取defaultcobj
|
||||
if (pcobj && (pcobj['_data'] instanceof Function)) cobj = Object.assign({}, defaultcobj, pcobj['_data'](ii));
|
||||
else cobj = Object.assign({}, defaultcobj);
|
||||
}
|
||||
var args = {field: field, cfield: cfield, vobj: vobj, cobj: cobj}
|
||||
// 当cobj的参数为函数时,代入args算出值
|
||||
for (var key in cobj) {
|
||||
if (key === '_data') continue;
|
||||
if (cobj[key] instanceof Function) cobj[key] = cobj[key](args);
|
||||
}
|
||||
// 标记为_hide的属性不展示
|
||||
if (cobj._hide)continue;
|
||||
if (!cobj._leaf) {
|
||||
// 不是叶节点时, 插入展开的标记并继续遍历, 此处可以改成按钮用来添加新项或折叠等
|
||||
outstr.push(["<tr><td>----</td><td>----</td><td>", field, "</td></tr>\n"].join(''));
|
||||
recursionParse(field, cfield, vobj, cobj);
|
||||
} else {
|
||||
// 是叶节点时, 调objToTr_渲染<tr>
|
||||
var leafnode = editor_mode.objToTr_(obj, commentObj, field, cfield, vobj, cobj);
|
||||
outstr.push(leafnode[0]);
|
||||
guids.push(leafnode[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 开始遍历
|
||||
recursionParse("", "", obj, commentObj);
|
||||
var checkRange = function (cobj, thiseval) {
|
||||
if (cobj._range) {
|
||||
return eval(cobj._range);
|
||||
}
|
||||
if (cobj._select) {
|
||||
return cobj._select.values.indexOf(thiseval)!==-1;
|
||||
}
|
||||
if (cobj._bool) {
|
||||
return [true,false].indexOf(thiseval)!==-1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
var listen = function (guids) {
|
||||
// 每个叶节点的事件绑定
|
||||
guids.forEach(function (guid) {
|
||||
// tr>td[title=field]
|
||||
// >td[title=comment,cobj=cobj:json]
|
||||
// >td>div>input[value=thiseval]
|
||||
var thisTr = document.getElementById(guid);
|
||||
var input = thisTr.children[2].children[0].children[0];
|
||||
var field = thisTr.children[0].getAttribute('title');
|
||||
var cobj = JSON.parse(thisTr.children[1].getAttribute('cobj'));
|
||||
var modeNode = thisTr.parentNode;
|
||||
while (!editor_mode._ids.hasOwnProperty(modeNode.getAttribute('id'))) {
|
||||
modeNode = modeNode.parentNode;
|
||||
}
|
||||
input.onchange = function () {
|
||||
editor_mode.onmode(editor_mode._ids[modeNode.getAttribute('id')]);
|
||||
var thiseval = null;
|
||||
if (input.checked != null) input.value = input.checked;
|
||||
try {
|
||||
thiseval = JSON.parse(input.value);
|
||||
} catch (ee) {
|
||||
printe(field + ' : ' + ee);
|
||||
throw ee;
|
||||
}
|
||||
if (checkRange(cobj, thiseval)) {
|
||||
editor_mode.addAction(['change', field, thiseval]);
|
||||
editor_mode.onmode('save');//自动保存 删掉此行的话点保存按钮才会保存
|
||||
} else {
|
||||
printe(field + ' : 输入的值不合要求,请鼠标放置在注释上查看说明');
|
||||
}
|
||||
}
|
||||
// 双击表格时
|
||||
// 正常编辑: 尝试用事件编辑器或多行文本编辑器打开
|
||||
// 添加: 在该项的同一级创建一个内容为null新的项, 刷新后生效并可以继续编辑
|
||||
// 删除: 删除该项, 刷新后生效
|
||||
// 在点击按钮 添加/删除 后,下一次双击将被视为 添加/删除
|
||||
var dblclickfunc=function () {
|
||||
if(editor_mode.doubleClickMode==='change'){
|
||||
if (cobj._type === 'event') editor_blockly.import(guid, {type: cobj._event});
|
||||
if (cobj._type === 'textarea') editor_multi.import(guid, {lint: cobj._lint, string: cobj._string});
|
||||
}
|
||||
if(editor_mode.doubleClickMode==='add'){
|
||||
editor_mode.doubleClickMode='change';
|
||||
addfunc()
|
||||
}
|
||||
if(editor_mode.doubleClickMode==='delete'){
|
||||
editor_mode.doubleClickMode='change';
|
||||
deletefunc()
|
||||
}
|
||||
}
|
||||
input.ondblclick = dblclickfunc
|
||||
var doubleClickCheck=[0];
|
||||
thisTr.onclick = function(){
|
||||
var newClick = new Date().getTime();
|
||||
var lastClick = doubleClickCheck.shift();
|
||||
doubleClickCheck.push(newClick);
|
||||
if(newClick-lastClick<500){
|
||||
dblclickfunc()
|
||||
}
|
||||
}
|
||||
var deletefunc=function(){
|
||||
editor_mode.onmode(editor_mode._ids[modeNode.getAttribute('id')]);
|
||||
if (checkRange(cobj, null)) {
|
||||
editor_mode.addAction(['delete', field, undefined]);
|
||||
editor_mode.onmode('save');//自动保存 删掉此行的话点保存按钮才会保存
|
||||
} else {
|
||||
printe(field + ' : 该值不允许为null,无法删除');
|
||||
}
|
||||
}
|
||||
var addfunc=function(){
|
||||
editor_mode.onmode(editor_mode._ids[modeNode.getAttribute('id')]);
|
||||
|
||||
var mode = document.getElementById('editModeSelect').value;
|
||||
|
||||
// 1.输入id
|
||||
var newid=prompt('请输入新项的ID(仅公共事件支持中文ID)');
|
||||
if (newid == null || newid.length==0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查commentEvents
|
||||
if (mode !== 'commonevent') {
|
||||
// 2.检查id是否符合规范或与已有id重复
|
||||
if (!/^[a-zA-Z0-9_]+$/.test(newid)){
|
||||
printe('id不符合规范, 请使用大小写字母数字下划线来构成');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var conflict=true;
|
||||
var basefield=field.replace(/\[[^\[]*\]$/,'');
|
||||
if (basefield==="['main']"){
|
||||
printe("全塔属性 ~ ['main'] 不允许添加新值");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var baseobj=eval('obj'+basefield);
|
||||
conflict=newid in baseobj;
|
||||
} catch (ee) {
|
||||
// 理论上这里不会发生错误
|
||||
printe(ee);
|
||||
throw ee;
|
||||
}
|
||||
if (conflict){
|
||||
printe('id已存在, 请直接修改该项的值');
|
||||
return;
|
||||
}
|
||||
// 3.添加
|
||||
editor_mode.addAction(['add',basefield+"['"+newid+"']",null]);
|
||||
editor_mode.onmode('save');//自动保存 删掉此行的话点保存按钮才会保存
|
||||
}
|
||||
});
|
||||
}
|
||||
return {"HTML": outstr.join(''), "guids": guids, "listen": listen};
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回叶节点<tr>形如
|
||||
* tr>td[title=field]
|
||||
* >td[title=comment,cobj=cobj:json]
|
||||
* >td>div>input[value=thiseval]
|
||||
* 参数意义在 objToTable_ 中已解释
|
||||
* @param {Object} obj
|
||||
* @param {Object} commentObj
|
||||
* @param {String} field
|
||||
* @param {String} cfield
|
||||
* @param {Object} vobj
|
||||
* @param {Object} cobj
|
||||
*/
|
||||
editor_mode.prototype.objToTr_ = function (obj, commentObj, field, cfield, vobj, cobj) {
|
||||
var guid = editor.guid();
|
||||
var thiseval = vobj;
|
||||
var comment = String(cobj._data);
|
||||
|
||||
var charlength = 10;
|
||||
// "['a']['b']" => "b"
|
||||
var shortField = field.split("']").slice(-2)[0].split("['").slice(-1)[0];
|
||||
// 把长度超过 charlength 的字符改成 固定长度+...的形式
|
||||
shortField = (shortField.length < charlength ? shortField : shortField.slice(0, charlength) + '...');
|
||||
|
||||
// 完整的内容转义后供悬停查看
|
||||
var commentHTMLescape = editor.HTMLescape(comment);
|
||||
// 把长度超过 charlength 的字符改成 固定长度+...的形式
|
||||
var shortCommentHTMLescape = (comment.length < charlength ? commentHTMLescape : editor.HTMLescape(comment.slice(0, charlength)) + '...');
|
||||
|
||||
var cobjstr = Object.assign({}, cobj);
|
||||
delete cobjstr._data;
|
||||
// 把cobj塞到第二个td的[cobj]中, 方便绑定事件时取
|
||||
cobjstr = editor.HTMLescape(JSON.stringify(cobjstr));
|
||||
|
||||
var outstr = ['<tr id="', guid, '"><td title="', field, '">', shortField, '</td>',
|
||||
'<td title="', commentHTMLescape, '" cobj="', cobjstr, '">', shortCommentHTMLescape, '</td>',
|
||||
'<td><div class="etableInputDiv">', editor_mode.objToTd_(obj, commentObj, field, cfield, vobj, cobj), '</div></td></tr>\n',
|
||||
];
|
||||
return [outstr.join(''), guid];
|
||||
}
|
||||
|
||||
editor_mode.prototype.objToTd_ = function (obj, commentObj, field, cfield, vobj, cobj) {
|
||||
var thiseval = vobj;
|
||||
if (cobj._select) {
|
||||
var values = cobj._select.values;
|
||||
var outstr = ['<select>\n', "<option value='", JSON.stringify(thiseval), "'>", JSON.stringify(thiseval), '</option>\n'];
|
||||
values.forEach(function (v) {
|
||||
outstr.push(["<option value='", JSON.stringify(v), "'>", JSON.stringify(v), '</option>\n'].join(''))
|
||||
});
|
||||
outstr.push('</select>');
|
||||
return outstr.join('');
|
||||
} else if (cobj._input) {
|
||||
return ["<input type='text' spellcheck='false' value='", JSON.stringify(thiseval), "'/>\n"].join('');
|
||||
} else if (cobj._bool) {
|
||||
return ["<input type='checkbox' ", (thiseval ? 'checked ' : ''), "/>\n"].join('');
|
||||
} else {
|
||||
var num = 0;//editor_mode.indent(field);
|
||||
return ["<textarea spellcheck='false' >", JSON.stringify(thiseval, null, num), '</textarea>\n'].join('');
|
||||
}
|
||||
}
|
||||
|
||||
editor_mode.prototype.indent = function (field) {
|
||||
var num = '\t';
|
||||
if (field.indexOf("['main']") === 0) return 0;
|
||||
@ -429,7 +130,7 @@ editor_mode = function (editor) {
|
||||
//console.log(objs_)
|
||||
});
|
||||
//只查询不修改时,内部实现不是异步的,所以可以这么写
|
||||
var tableinfo = editor_mode.objToTable_(objs[0], objs[1]);
|
||||
var tableinfo = editor.table.objToTable(objs[0], objs[1]);
|
||||
document.getElementById('table_3d846fc4_7644_44d1_aa04_433d266a73df').innerHTML = tableinfo.HTML;
|
||||
tableinfo.listen(tableinfo.guids);
|
||||
editor.drawPosSelection();
|
||||
@ -472,7 +173,7 @@ editor_mode = function (editor) {
|
||||
});
|
||||
}
|
||||
//只查询不修改时,内部实现不是异步的,所以可以这么写
|
||||
var tableinfo = editor_mode.objToTable_(objs[0], objs[1]);
|
||||
var tableinfo = editor.table.objToTable(objs[0], objs[1]);
|
||||
document.getElementById('table_a3f03d4c_55b8_4ef6_b362_b345783acd72').innerHTML = tableinfo.HTML;
|
||||
tableinfo.listen(tableinfo.guids);
|
||||
|
||||
@ -486,7 +187,7 @@ editor_mode = function (editor) {
|
||||
//console.log(objs_)
|
||||
});
|
||||
//只查询不修改时,内部实现不是异步的,所以可以这么写
|
||||
var tableinfo = editor_mode.objToTable_(objs[0], objs[1]);
|
||||
var tableinfo = editor.table.objToTable(objs[0], objs[1]);
|
||||
document.getElementById('table_4a3b1b09_b2fb_4bdf_b9ab_9f4cdac14c74').innerHTML = tableinfo.HTML;
|
||||
tableinfo.listen(tableinfo.guids);
|
||||
if (Boolean(callback)) callback();
|
||||
@ -499,7 +200,7 @@ editor_mode = function (editor) {
|
||||
//console.log(objs_)
|
||||
});
|
||||
//只查询不修改时,内部实现不是异步的,所以可以这么写
|
||||
var tableinfo = editor_mode.objToTable_(objs[0], objs[1]);
|
||||
var tableinfo = editor.table.objToTable(objs[0], objs[1]);
|
||||
document.getElementById('table_b6a03e4c_5968_4633_ac40_0dfdd2c9cde5').innerHTML = tableinfo.HTML;
|
||||
tableinfo.listen(tableinfo.guids);
|
||||
if (Boolean(callback)) callback();
|
||||
@ -512,7 +213,7 @@ editor_mode = function (editor) {
|
||||
//console.log(objs_)
|
||||
});
|
||||
//只查询不修改时,内部实现不是异步的,所以可以这么写
|
||||
var tableinfo = editor_mode.objToTable_(objs[0], objs[1]);
|
||||
var tableinfo = editor.table.objToTable(objs[0], objs[1]);
|
||||
document.getElementById('table_e260a2be_5690_476a_b04e_dacddede78b3').innerHTML = tableinfo.HTML;
|
||||
tableinfo.listen(tableinfo.guids);
|
||||
if (Boolean(callback)) callback();
|
||||
@ -525,7 +226,7 @@ editor_mode = function (editor) {
|
||||
//console.log(objs_)
|
||||
});
|
||||
//只查询不修改时,内部实现不是异步的,所以可以这么写
|
||||
var tableinfo = editor_mode.objToTable_(objs[0], objs[1]);
|
||||
var tableinfo = editor.table.objToTable(objs[0], objs[1]);
|
||||
document.getElementById('table_b7bf0124_99fd_4af8_ae2f_0017f04a7c7d').innerHTML = tableinfo.HTML;
|
||||
tableinfo.listen(tableinfo.guids);
|
||||
if (Boolean(callback)) callback();
|
||||
@ -538,7 +239,7 @@ editor_mode = function (editor) {
|
||||
//console.log(objs_)
|
||||
});
|
||||
//只查询不修改时,内部实现不是异步的,所以可以这么写
|
||||
var tableinfo = editor_mode.objToTable_(objs[0], objs[1]);
|
||||
var tableinfo = editor.table.objToTable(objs[0], objs[1]);
|
||||
document.getElementById('table_e2c034ec_47c6_48ae_8db8_4f8f32fea2d6').innerHTML = tableinfo.HTML;
|
||||
tableinfo.listen(tableinfo.guids);
|
||||
if (Boolean(callback)) callback();
|
||||
@ -773,21 +474,8 @@ editor_mode = function (editor) {
|
||||
}
|
||||
selectAppend.onchange();
|
||||
|
||||
var getPixel=function(imgData, x, y) {
|
||||
var offset = (x + y * imgData.width) * 4;
|
||||
var r = imgData.data[offset+0];
|
||||
var g = imgData.data[offset+1];
|
||||
var b = imgData.data[offset+2];
|
||||
var a = imgData.data[offset+3];
|
||||
return [r,g,b,a];
|
||||
}
|
||||
var setPixel=function(imgData, x, y, rgba) {
|
||||
var offset = (x + y * imgData.width) * 4;
|
||||
imgData.data[offset+0]=rgba[0];
|
||||
imgData.data[offset+1]=rgba[1];
|
||||
imgData.data[offset+2]=rgba[2];
|
||||
imgData.data[offset+3]=rgba[3];
|
||||
}
|
||||
var getPixel=editor.util.getPixel
|
||||
var setPixel=editor.util.setPixel
|
||||
|
||||
var autoAdjust = function (image, callback) {
|
||||
var changed = false;
|
||||
@ -946,113 +634,9 @@ editor_mode = function (editor) {
|
||||
var nimgData=new ImageData(imgData.width,imgData.height);
|
||||
// ImageData .data 形如一维数组,依次排着每个点的 R(0~255) G(0~255) B(0~255) A(0~255)
|
||||
var convert=function(rgba,delta){
|
||||
var round=Math.round;
|
||||
// rgbToHsl hue2rgb hslToRgb from https://github.com/carloscabo/colz.git
|
||||
//--------------------------------------------
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2014 Carlos Cabo
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//--------------------------------------------
|
||||
// https://github.com/carloscabo/colz/blob/master/public/js/colz.class.js
|
||||
var rgbToHsl = function (rgba) {
|
||||
var arg, r, g, b, h, s, l, d, max, min;
|
||||
|
||||
arg = rgba;
|
||||
|
||||
if (typeof arg[0] === 'number') {
|
||||
r = arg[0];
|
||||
g = arg[1];
|
||||
b = arg[2];
|
||||
} else {
|
||||
r = arg[0][0];
|
||||
g = arg[0][1];
|
||||
b = arg[0][2];
|
||||
}
|
||||
|
||||
r /= 255;
|
||||
g /= 255;
|
||||
b /= 255;
|
||||
|
||||
max = Math.max(r, g, b);
|
||||
min = Math.min(r, g, b);
|
||||
l = (max + min) / 2;
|
||||
|
||||
if (max === min) {
|
||||
h = s = 0; // achromatic
|
||||
} else {
|
||||
d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
|
||||
switch (max) {
|
||||
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
||||
case g: h = (b - r) / d + 2; break;
|
||||
case b: h = (r - g) / d + 4; break;
|
||||
}
|
||||
|
||||
h /= 6;
|
||||
}
|
||||
|
||||
//CARLOS
|
||||
h = round(h * 360);
|
||||
s = round(s * 100);
|
||||
l = round(l * 100);
|
||||
|
||||
return [h, s, l];
|
||||
}
|
||||
//
|
||||
var hue2rgb = function (p, q, t) {
|
||||
if (t < 0) { t += 1; }
|
||||
if (t > 1) { t -= 1; }
|
||||
if (t < 1 / 6) { return p + (q - p) * 6 * t; }
|
||||
if (t < 1 / 2) { return q; }
|
||||
if (t < 2 / 3) { return p + (q - p) * (2 / 3 - t) * 6; }
|
||||
return p;
|
||||
}
|
||||
var hslToRgb = function (hsl) {
|
||||
var arg, r, g, b, h, s, l, q, p;
|
||||
|
||||
arg = hsl;
|
||||
|
||||
if (typeof arg[0] === 'number') {
|
||||
h = arg[0] / 360;
|
||||
s = arg[1] / 100;
|
||||
l = arg[2] / 100;
|
||||
} else {
|
||||
h = arg[0][0] / 360;
|
||||
s = arg[0][1] / 100;
|
||||
l = arg[0][2] / 100;
|
||||
}
|
||||
|
||||
if (s === 0) {
|
||||
r = g = b = l; // achromatic
|
||||
} else {
|
||||
|
||||
q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
p = 2 * l - q;
|
||||
r = hue2rgb(p, q, h + 1 / 3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1 / 3);
|
||||
}
|
||||
return [round(r * 255), round(g * 255), round(b * 255)];
|
||||
}
|
||||
var rgbToHsl = editor.util.rgbToHsl
|
||||
var hue2rgb = editor.util.hue2rgb
|
||||
var hslToRgb = editor.util.hslToRgb
|
||||
//
|
||||
var hsl=rgbToHsl(rgba)
|
||||
hsl[0]=(hsl[0]+delta)%360
|
||||
|
||||
@ -103,7 +103,7 @@ editor_multi = function () {
|
||||
var tmap = {};
|
||||
var tstr = JSON.stringify(tobj, function (k, v) {
|
||||
if (typeof(v) === typeof('') && v.slice(0, 8) === 'function') {
|
||||
var id_ = editor.guid();
|
||||
var id_ = editor.util.guid();
|
||||
tmap[id_] = v.toString();
|
||||
return id_;
|
||||
} else return v
|
||||
@ -146,7 +146,7 @@ editor_multi = function () {
|
||||
var tmap = {};
|
||||
var tstr = JSON.stringify(tobj, function (k, v) {
|
||||
if (v instanceof Function) {
|
||||
var id_ = editor.guid();
|
||||
var id_ = editor.util.guid();
|
||||
tmap[id_] = v.toString();
|
||||
return id_;
|
||||
} else return v
|
||||
|
||||
382
_server/editor_table.js
Normal file
382
_server/editor_table.js
Normal file
@ -0,0 +1,382 @@
|
||||
editor_table_wrapper = function (editor) {
|
||||
|
||||
editor_table = function () {
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// HTML模板
|
||||
|
||||
editor_table.prototype.select = function (value, values) {
|
||||
return `<select>\n${
|
||||
editor.table.option(value) +
|
||||
values.map(function (v) {
|
||||
return editor.table.option(v)
|
||||
}).join('')
|
||||
}</select>\n`
|
||||
}
|
||||
editor_table.prototype.option = function (value) {
|
||||
return `<option value='${JSON.stringify(value)}'>${JSON.stringify(value)}</option>\n`
|
||||
}
|
||||
editor_table.prototype.text = function (value) {
|
||||
return `<input type='text' spellcheck='false' value='${JSON.stringify(value)}'/>\n`
|
||||
}
|
||||
editor_table.prototype.checkbox = function (value) {
|
||||
return `<input type='checkbox' ${(value ? 'checked ' : '')}/>\n`
|
||||
}
|
||||
editor_table.prototype.textarea = function (value, indent) {
|
||||
return `<textarea spellcheck='false'>${JSON.stringify(value, null, indent || 0)}</textarea>\n`
|
||||
}
|
||||
|
||||
editor_table.prototype.title = function () {
|
||||
return `\n<tr><td>条目</td><td>注释</td><td>值</td></tr>\n`
|
||||
}
|
||||
|
||||
editor_table.prototype.gap = function (field) {
|
||||
return `<tr><td>----</td><td>----</td><td>${field}</td></tr>\n`
|
||||
}
|
||||
|
||||
editor_table.prototype.tr = function (guid, field, shortField, commentHTMLescape, cobjstr, shortCommentHTMLescape, tdstr) {
|
||||
return `<tr id="${guid}">
|
||||
<td title="${field}">${shortField}</td>
|
||||
<td title="${commentHTMLescape}" cobj="${cobjstr}">${shortCommentHTMLescape}</td>
|
||||
<td><div class="etableInputDiv">${tdstr}</div></td>
|
||||
</tr>\n`
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 表格生成的控制
|
||||
|
||||
/**
|
||||
* 注释对象的默认值
|
||||
*/
|
||||
editor_table.prototype.defaultcobj = {
|
||||
// 默认是文本域
|
||||
_type: 'textarea',
|
||||
_data: '',
|
||||
_string: function (args) {//object~[field,cfield,vobj,cobj]
|
||||
var thiseval = args.vobj;
|
||||
return (typeof (thiseval) === typeof ('')) && thiseval[0] === '"';
|
||||
},
|
||||
// 默认情况下 非对象和数组的视为叶节点
|
||||
_leaf: function (args) {//object~[field,cfield,vobj,cobj]
|
||||
var thiseval = args.vobj;
|
||||
if (thiseval == null || thiseval == undefined) return true;//null,undefined
|
||||
if (typeof (thiseval) === typeof ('')) return true;//字符串
|
||||
if (Object.keys(thiseval).length === 0) return true;//数字,true,false,空数组,空对象
|
||||
return false;
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* 把来自数据文件的obj和来自*comment.js的commentObj组装成表格
|
||||
* commentObj在无视['_data']的意义下与obj同形
|
||||
* 即: commentObj['_data']['a']['_data']['b'] 与 obj['a']['b'] 是对应的
|
||||
* 在此意义下, 两者的结构是一致的
|
||||
* 在commentObj没有被定义的obj的分支, 会取defaultcobj作为默认值
|
||||
* 因此在深度优先遍历时,维护
|
||||
* field="['a']['b']"
|
||||
* cfield="['_data']['a']['_data']['b']"
|
||||
* vobj=obj['a']['b']
|
||||
* cobj=commentObj['_data']['a']['_data']['b']
|
||||
* cobj
|
||||
* cobj = Object.assign({}, defaultcobj, pcobj['_data'][ii])
|
||||
* 每一项若未定义,就从defaultcobj中取
|
||||
* 当其是函数不是具体值时,把args = {field: field, cfield: cfield, vobj: vobj, cobj: cobj}代入算出该值
|
||||
* 得到的叶节点的<tr>结构如下
|
||||
* tr>td[title=field]
|
||||
* >td[title=comment,cobj=cobj:json]
|
||||
* >td>div>input[value=thiseval]
|
||||
* 返回结果
|
||||
* 返回一个对象, 假设被命名为tableinfo
|
||||
* 在把一个 table 的 innerHTML 赋值为 tableinfo.HTML 后
|
||||
* 再调 tableinfo.listen(tableinfo.guids) 进行绑定事件
|
||||
* @param {Object} obj
|
||||
* @param {Object} commentObj
|
||||
* @returns {{"HTML":String,"guids":String[],"listen":Function}}
|
||||
*/
|
||||
editor_table.prototype.objToTable = function (obj, commentObj) {
|
||||
// 表格抬头
|
||||
var outstr = [editor.table.title()];
|
||||
var guids = [];
|
||||
var defaultcobj = this.defaultcobj
|
||||
/**
|
||||
* 深度优先遍历, p*即为父节点的四个属性
|
||||
* @param {String} pfield
|
||||
* @param {String} pcfield
|
||||
* @param {Object} pvobj
|
||||
* @param {Object} pcobj
|
||||
*/
|
||||
var recursionParse = function (pfield, pcfield, pvobj, pcobj) {
|
||||
var keysForTableOrder = {};
|
||||
var voidMark = {};
|
||||
// 1. 按照pcobj排序生成
|
||||
if (pcobj && pcobj['_data']) {
|
||||
for (var ii in pcobj['_data']) keysForTableOrder[ii] = voidMark;
|
||||
}
|
||||
// 2. 对每个pvobj且不在pcobj的,再添加到最后
|
||||
keysForTableOrder = Object.assign(keysForTableOrder, pvobj)
|
||||
for (var ii in keysForTableOrder) {
|
||||
// 3. 对于pcobj有但是pvobj中没有的, 弹出提示, (正常情况下editor_file会补全成null)
|
||||
// 事实上能执行到这一步工程没崩掉打不开,就继续吧..
|
||||
if (keysForTableOrder[ii] === voidMark) {
|
||||
if (typeof id_815975ad_ee6f_4684_aac7_397b7e392702 === "undefined") {
|
||||
alert('comment和data不匹配,请在群 HTML5造塔技术交流群 959329661 内反馈')
|
||||
console.error('comment和data不匹配,请在群 HTML5造塔技术交流群 959329661 内反馈')
|
||||
id_815975ad_ee6f_4684_aac7_397b7e392702 = 1;
|
||||
}
|
||||
pvobj[ii] = null;
|
||||
}
|
||||
var field = pfield + "['" + ii + "']";
|
||||
var cfield = pcfield + "['_data']['" + ii + "']";
|
||||
var vobj = pvobj[ii];
|
||||
var cobj = null;
|
||||
if (pcobj && pcobj['_data'] && pcobj['_data'][ii]) {
|
||||
// cobj存在时直接取
|
||||
cobj = Object.assign({}, defaultcobj, pcobj['_data'][ii]);
|
||||
} else {
|
||||
// 当其函数时代入参数算出cobj, 不存在时只取defaultcobj
|
||||
if (pcobj && (pcobj['_data'] instanceof Function)) cobj = Object.assign({}, defaultcobj, pcobj['_data'](ii));
|
||||
else cobj = Object.assign({}, defaultcobj);
|
||||
}
|
||||
var args = { field: field, cfield: cfield, vobj: vobj, cobj: cobj }
|
||||
// 当cobj的参数为函数时,代入args算出值
|
||||
for (var key in cobj) {
|
||||
if (key === '_data') continue;
|
||||
if (cobj[key] instanceof Function) cobj[key] = cobj[key](args);
|
||||
}
|
||||
// 标记为_hide的属性不展示
|
||||
if (cobj._hide) continue;
|
||||
if (!cobj._leaf) {
|
||||
// 不是叶节点时, 插入展开的标记并继续遍历, 此处可以改成按钮用来添加新项或折叠等
|
||||
outstr.push(editor.table.gap(field));
|
||||
recursionParse(field, cfield, vobj, cobj);
|
||||
} else {
|
||||
// 是叶节点时, 调objToTr_渲染<tr>
|
||||
var leafnode = editor.table.objToTr(obj, commentObj, field, cfield, vobj, cobj);
|
||||
outstr.push(leafnode[0]);
|
||||
guids.push(leafnode[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 开始遍历
|
||||
recursionParse("", "", obj, commentObj);
|
||||
|
||||
var listen = function (guids) {
|
||||
// 每个叶节点的事件绑定
|
||||
guids.forEach(editor.table.guidListen);
|
||||
}
|
||||
return { "HTML": outstr.join(''), "guids": guids, "listen": listen };
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回叶节点<tr>形如
|
||||
* tr>td[title=field]
|
||||
* >td[title=comment,cobj=cobj:json]
|
||||
* >td>div>input[value=thiseval]
|
||||
* 参数意义在 objToTable 中已解释
|
||||
* @param {Object} obj
|
||||
* @param {Object} commentObj
|
||||
* @param {String} field
|
||||
* @param {String} cfield
|
||||
* @param {Object} vobj
|
||||
* @param {Object} cobj
|
||||
*/
|
||||
editor_table.prototype.objToTr = function (obj, commentObj, field, cfield, vobj, cobj) {
|
||||
var guid = editor.util.guid();
|
||||
var thiseval = vobj;
|
||||
var comment = String(cobj._data);
|
||||
|
||||
var charlength = 10;
|
||||
// "['a']['b']" => "b"
|
||||
var shortField = field.split("']").slice(-2)[0].split("['").slice(-1)[0];
|
||||
// 把长度超过 charlength 的字符改成 固定长度+...的形式
|
||||
shortField = (shortField.length < charlength ? shortField : shortField.slice(0, charlength) + '...');
|
||||
|
||||
// 完整的内容转义后供悬停查看
|
||||
var commentHTMLescape = editor.util.HTMLescape(comment);
|
||||
// 把长度超过 charlength 的字符改成 固定长度+...的形式
|
||||
var shortCommentHTMLescape = (comment.length < charlength ? commentHTMLescape : editor.util.HTMLescape(comment.slice(0, charlength)) + '...');
|
||||
|
||||
var cobjstr = Object.assign({}, cobj);
|
||||
delete cobjstr._data;
|
||||
// 把cobj塞到第二个td的[cobj]中, 方便绑定事件时取
|
||||
cobjstr = editor.util.HTMLescape(JSON.stringify(cobjstr));
|
||||
|
||||
var tdstr = editor.table.objToTd(obj, commentObj, field, cfield, vobj, cobj)
|
||||
var outstr = editor.table.tr(guid, field, shortField, commentHTMLescape, cobjstr, shortCommentHTMLescape, tdstr)
|
||||
return [outstr, guid];
|
||||
}
|
||||
|
||||
editor_table.prototype.objToTd = function (obj, commentObj, field, cfield, vobj, cobj) {
|
||||
var thiseval = vobj;
|
||||
if (cobj._select) {
|
||||
var values = cobj._select.values;
|
||||
return editor.table.select(thiseval, values);
|
||||
} else if (cobj._input) {
|
||||
return editor.table.text(thiseval);
|
||||
} else if (cobj._bool) {
|
||||
return editor.table.checkbox(thiseval);
|
||||
} else {
|
||||
var indent = 0;
|
||||
return editor.table.textarea(thiseval, indent);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 表格的用户交互
|
||||
|
||||
/**
|
||||
* 检查一个值是否允许被设置为当前输入
|
||||
* @param {Object} cobj
|
||||
* @param {*} thiseval
|
||||
*/
|
||||
editor_table.prototype.checkRange = function (cobj, thiseval) {
|
||||
if (cobj._range) {
|
||||
return eval(cobj._range);
|
||||
}
|
||||
if (cobj._select) {
|
||||
return cobj._select.values.indexOf(thiseval) !== -1;
|
||||
}
|
||||
if (cobj._bool) {
|
||||
return [true, false].indexOf(thiseval) !== -1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听一个guid对应的表格项
|
||||
* @param {String} guid
|
||||
*/
|
||||
editor_table.prototype.guidListen = function (guid) {
|
||||
// tr>td[title=field]
|
||||
// >td[title=comment,cobj=cobj:json]
|
||||
// >td>div>input[value=thiseval]
|
||||
var thisTr = document.getElementById(guid);
|
||||
var input = thisTr.children[2].children[0].children[0];
|
||||
var field = thisTr.children[0].getAttribute('title');
|
||||
var cobj = JSON.parse(thisTr.children[1].getAttribute('cobj'));
|
||||
var modeNode = thisTr.parentNode;
|
||||
while (!editor_mode._ids.hasOwnProperty(modeNode.getAttribute('id'))) {
|
||||
modeNode = modeNode.parentNode;
|
||||
}
|
||||
input.onchange = function () {
|
||||
editor.table.onchange(guid, thisTr, input, field, cobj, modeNode)
|
||||
}
|
||||
// 用检测两次单击的方式来实现双击(以支持手机端的双击)
|
||||
var doubleClickCheck = [0];
|
||||
thisTr.onclick = function () {
|
||||
var newClick = new Date().getTime();
|
||||
var lastClick = doubleClickCheck.shift();
|
||||
doubleClickCheck.push(newClick);
|
||||
if (newClick - lastClick < 500) {
|
||||
editor.table.dblclickfunc(guid, thisTr, input, field, cobj, modeNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 表格的值变化时
|
||||
*/
|
||||
editor_table.prototype.onchange = function (guid, thisTr, input, field, cobj, modeNode) {
|
||||
editor_mode.onmode(editor_mode._ids[modeNode.getAttribute('id')]);
|
||||
var thiseval = null;
|
||||
if (input.checked != null) input.value = input.checked;
|
||||
try {
|
||||
thiseval = JSON.parse(input.value);
|
||||
} catch (ee) {
|
||||
printe(field + ' : ' + ee);
|
||||
throw ee;
|
||||
}
|
||||
if (editor.table.checkRange(cobj, thiseval)) {
|
||||
editor_mode.addAction(['change', field, thiseval]);
|
||||
editor_mode.onmode('save');//自动保存 删掉此行的话点保存按钮才会保存
|
||||
} else {
|
||||
printe(field + ' : 输入的值不合要求,请鼠标放置在注释上查看说明');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 双击表格时
|
||||
* 正常编辑: 尝试用事件编辑器或多行文本编辑器打开
|
||||
* 添加: 在该项的同一级创建一个内容为null新的项, 刷新后生效并可以继续编辑
|
||||
* 删除: 删除该项, 刷新后生效
|
||||
* 在点击按钮 添加/删除 后,下一次双击将被视为 添加/删除
|
||||
*/
|
||||
editor_table.prototype.dblclickfunc = function (guid, thisTr, input, field, cobj, modeNode) {
|
||||
if (editor_mode.doubleClickMode === 'change') {
|
||||
if (cobj._type === 'event') editor_blockly.import(guid, { type: cobj._event });
|
||||
if (cobj._type === 'textarea') editor_multi.import(guid, { lint: cobj._lint, string: cobj._string });
|
||||
} else if (editor_mode.doubleClickMode === 'add') {
|
||||
editor_mode.doubleClickMode = 'change';
|
||||
editor.table.addfunc(guid, thisTr, input, field, cobj, modeNode)
|
||||
} else if (editor_mode.doubleClickMode === 'delete') {
|
||||
editor_mode.doubleClickMode = 'change';
|
||||
editor.table.deletefunc(guid, thisTr, input, field, cobj, modeNode)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除表格项
|
||||
*/
|
||||
editor_table.prototype.deletefunc = function (guid, thisTr, input, field, cobj, modeNode) {
|
||||
editor_mode.onmode(editor_mode._ids[modeNode.getAttribute('id')]);
|
||||
if (editor.table.checkRange(cobj, null)) {
|
||||
editor_mode.addAction(['delete', field, undefined]);
|
||||
editor_mode.onmode('save');//自动保存 删掉此行的话点保存按钮才会保存
|
||||
} else {
|
||||
printe(field + ' : 该值不允许为null,无法删除');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加表格项
|
||||
*/
|
||||
editor_table.prototype.addfunc = function (guid, thisTr, input, field, cobj, modeNode) {
|
||||
editor_mode.onmode(editor_mode._ids[modeNode.getAttribute('id')]);
|
||||
|
||||
var mode = document.getElementById('editModeSelect').value;
|
||||
|
||||
// 1.输入id
|
||||
var newid = prompt('请输入新项的ID(仅公共事件支持中文ID)');
|
||||
if (newid == null || newid.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查commentEvents
|
||||
if (mode !== 'commonevent') {
|
||||
// 2.检查id是否符合规范或与已有id重复
|
||||
if (!/^[a-zA-Z0-9_]+$/.test(newid)) {
|
||||
printe('id不符合规范, 请使用大小写字母数字下划线来构成');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var conflict = true;
|
||||
var basefield = field.replace(/\[[^\[]*\]$/, '');
|
||||
if (basefield === "['main']") {
|
||||
printe("全塔属性 ~ ['main'] 不允许添加新值");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var baseobj = eval('obj' + basefield);
|
||||
conflict = newid in baseobj;
|
||||
} catch (ee) {
|
||||
// 理论上这里不会发生错误
|
||||
printe(ee);
|
||||
throw ee;
|
||||
}
|
||||
if (conflict) {
|
||||
printe('id已存在, 请直接修改该项的值');
|
||||
return;
|
||||
}
|
||||
// 3.添加
|
||||
editor_mode.addAction(['add', basefield + "['" + newid + "']", null]);
|
||||
editor_mode.onmode('save');//自动保存 删掉此行的话点保存按钮才会保存
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
editor.constructor.prototype.table = new editor_table();
|
||||
}
|
||||
//editor_table_wrapper(editor);
|
||||
150
_server/editor_util.js
Normal file
150
_server/editor_util.js
Normal file
@ -0,0 +1,150 @@
|
||||
editor_util_wrapper = function (editor) {
|
||||
|
||||
editor_util = function () {
|
||||
|
||||
}
|
||||
|
||||
editor_util.prototype.guid = function () {
|
||||
return 'id_' + 'xxxxxxxx_xxxx_4xxx_yxxx_xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
editor_util.prototype.HTMLescape = function (str_) {
|
||||
return String(str_).split('').map(function (v) {
|
||||
return '&#' + v.charCodeAt(0) + ';'
|
||||
}).join('');
|
||||
}
|
||||
|
||||
editor_util.prototype.getPixel = function (imgData, x, y) {
|
||||
var offset = (x + y * imgData.width) * 4;
|
||||
var r = imgData.data[offset + 0];
|
||||
var g = imgData.data[offset + 1];
|
||||
var b = imgData.data[offset + 2];
|
||||
var a = imgData.data[offset + 3];
|
||||
return [r, g, b, a];
|
||||
}
|
||||
|
||||
editor_util.prototype.setPixel = function (imgData, x, y, rgba) {
|
||||
var offset = (x + y * imgData.width) * 4;
|
||||
imgData.data[offset + 0] = rgba[0];
|
||||
imgData.data[offset + 1] = rgba[1];
|
||||
imgData.data[offset + 2] = rgba[2];
|
||||
imgData.data[offset + 3] = rgba[3];
|
||||
}
|
||||
|
||||
// rgbToHsl hue2rgb hslToRgb from https://github.com/carloscabo/colz.git
|
||||
//--------------------------------------------
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2014 Carlos Cabo
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//--------------------------------------------
|
||||
// https://github.com/carloscabo/colz/blob/master/public/js/colz.class.js
|
||||
var round=Math.round;
|
||||
var rgbToHsl = function (rgba) {
|
||||
var arg, r, g, b, h, s, l, d, max, min;
|
||||
|
||||
arg = rgba;
|
||||
|
||||
if (typeof arg[0] === 'number') {
|
||||
r = arg[0];
|
||||
g = arg[1];
|
||||
b = arg[2];
|
||||
} else {
|
||||
r = arg[0][0];
|
||||
g = arg[0][1];
|
||||
b = arg[0][2];
|
||||
}
|
||||
|
||||
r /= 255;
|
||||
g /= 255;
|
||||
b /= 255;
|
||||
|
||||
max = Math.max(r, g, b);
|
||||
min = Math.min(r, g, b);
|
||||
l = (max + min) / 2;
|
||||
|
||||
if (max === min) {
|
||||
h = s = 0; // achromatic
|
||||
} else {
|
||||
d = max - min;
|
||||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
|
||||
switch (max) {
|
||||
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
||||
case g: h = (b - r) / d + 2; break;
|
||||
case b: h = (r - g) / d + 4; break;
|
||||
}
|
||||
|
||||
h /= 6;
|
||||
}
|
||||
|
||||
//CARLOS
|
||||
h = round(h * 360);
|
||||
s = round(s * 100);
|
||||
l = round(l * 100);
|
||||
|
||||
return [h, s, l];
|
||||
}
|
||||
//
|
||||
var hue2rgb = function (p, q, t) {
|
||||
if (t < 0) { t += 1; }
|
||||
if (t > 1) { t -= 1; }
|
||||
if (t < 1 / 6) { return p + (q - p) * 6 * t; }
|
||||
if (t < 1 / 2) { return q; }
|
||||
if (t < 2 / 3) { return p + (q - p) * (2 / 3 - t) * 6; }
|
||||
return p;
|
||||
}
|
||||
var hslToRgb = function (hsl) {
|
||||
var arg, r, g, b, h, s, l, q, p;
|
||||
|
||||
arg = hsl;
|
||||
|
||||
if (typeof arg[0] === 'number') {
|
||||
h = arg[0] / 360;
|
||||
s = arg[1] / 100;
|
||||
l = arg[2] / 100;
|
||||
} else {
|
||||
h = arg[0][0] / 360;
|
||||
s = arg[0][1] / 100;
|
||||
l = arg[0][2] / 100;
|
||||
}
|
||||
|
||||
if (s === 0) {
|
||||
r = g = b = l; // achromatic
|
||||
} else {
|
||||
|
||||
q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
p = 2 * l - q;
|
||||
r = hue2rgb(p, q, h + 1 / 3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1 / 3);
|
||||
}
|
||||
return [round(r * 255), round(g * 255), round(b * 255)];
|
||||
}
|
||||
editor_util.prototype.rgbToHsl=rgbToHsl
|
||||
editor_util.prototype.hue2rgb=hue2rgb
|
||||
editor_util.prototype.hslToRgb=hslToRgb
|
||||
|
||||
editor.constructor.prototype.util = new editor_util();
|
||||
}
|
||||
//editor_util_wrapper(editor);
|
||||
89
_server/refactoring.md
Normal file
89
_server/refactoring.md
Normal file
@ -0,0 +1,89 @@
|
||||
# 重构
|
||||
|
||||
+ [ ] 按功能拆分文件
|
||||
+ [ ] 左侧页面模块化, 方便添加
|
||||
+ [ ] 不同的模式的文件操作尽可能模块化
|
||||
|
||||
---
|
||||
|
||||
文件结构
|
||||
|
||||
+ [x] editor_blockly 图块化事件编辑器, 基本不改动
|
||||
+ [x] editor_multi 多行文本编辑器, 基本不改动
|
||||
+ [ ] editor_table 处理表格的生成, 及其响应的事件, 从原editor\_mode中分离
|
||||
+ [ ] editor_file 调用fs.js编辑文件, 把原editor\_file模块化
|
||||
+ [ ] editor_game 处理来自core的数据, 导入为editor的数据, 从原editor中分离
|
||||
+ [ ] editor_util 生成guid等函数, 从editor分离
|
||||
+ [ ] editor 执行初始化流程加组合各组件
|
||||
|
||||
+ [ ] 原editor_mode 移除
|
||||
+ [ ] 原vm 移除
|
||||
|
||||
---
|
||||
|
||||
对象结构
|
||||
|
||||
```
|
||||
editor: {
|
||||
__proto__: {
|
||||
blockly: 组件
|
||||
multi: 组件
|
||||
file: 组件
|
||||
table: 组件
|
||||
util: 组件
|
||||
}
|
||||
game: 来自游戏的数据
|
||||
config: 编辑器配置
|
||||
mode: 当前的模式(左侧的选择)
|
||||
map: 当前编辑层的地图
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
某些注意到的点
|
||||
|
||||
+ 地图的编辑与其他(如全塔属性和楼层属性), 现在的文件操作的模式是完全不同的
|
||||
楼层文件的储存与其他不同
|
||||
|
||||
+ functions和plugins的借助JSON.stringify的replacer特殊处理
|
||||
|
||||
+ 目前editor.map中储存的是info\<object\>, 准备改为和core一致只储存数字
|
||||
|
||||
## 功能改进
|
||||
|
||||
+ [ ] 大地图
|
||||
在切换时, 每次都回到最左上->每个楼层记录一个位置
|
||||
四个箭头目前不能长按
|
||||
|
||||
+ [ ] ? 表格折叠
|
||||
变为四栏, 可以折叠展开
|
||||
|
||||
+ [ ] blockly对于无法识别的图块原样返回
|
||||
|
||||
+ [ ] ? 简洁的事件方块注册
|
||||
`editor.registerEvent('log',[['test','Int','测试',0],['floorId','Idstring','楼层','MT0']])`
|
||||
|
||||
+ [ ] 一个显示所有快捷键的文本
|
||||
|
||||
+ [ ] 更多快捷键
|
||||
【全塔属性】、【楼层属性】等常用的编辑栏切换
|
||||
|
||||
+ [ ] ? 地图编辑优化
|
||||
常用的地图编辑快捷键/命令:复制ctrl+c、粘贴ctrl+v、(复制可绑定为现在的“选中xx位置事件” 粘贴为复制xx事件到此处),撤回ctrl+z、取消撤回ctrl+y
|
||||
可以按住拖动图块与事件。
|
||||
|
||||
+ [ ] ? 自由建立快捷键到命令的注册表。
|
||||
|
||||
+ [ ] 画地图也自动保存
|
||||
|
||||
|
||||
|
||||
## 左侧页面模式
|
||||
|
||||
标题? 保存按钮? 添加按钮? 删除按钮?
|
||||
|
||||
自定义内容?
|
||||
|
||||
表格?
|
||||
@ -525,7 +525,9 @@ if (location.protocol.indexOf("http")!=0) {
|
||||
<!-- <script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script> -->
|
||||
<script src='_server/vendor/polyfill.min.js'></script>
|
||||
<script src='_server/fs.js'></script>
|
||||
<script src='_server/editor_util.js'></script>
|
||||
<script src='_server/editor_file.js'></script>
|
||||
<script src='_server/editor_table.js'></script>
|
||||
<script src='_server/editor_mode.js'></script>
|
||||
<script src='_server/vm.js'></script>
|
||||
<script src='libs/thirdparty/lz-string.min.js'></script>
|
||||
|
||||
@ -508,7 +508,9 @@ if (location.protocol.indexOf("http")!=0) {
|
||||
<!-- <script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script> -->
|
||||
<script src='_server/vendor/polyfill.min.js'></script>
|
||||
<script src='_server/fs.js'></script>
|
||||
<script src='_server/editor_util.js'></script>
|
||||
<script src='_server/editor_file.js'></script>
|
||||
<script src='_server/editor_table.js'></script>
|
||||
<script src='_server/editor_mode.js'></script>
|
||||
<script src='_server/vm.js'></script>
|
||||
<script src='libs/thirdparty/lz-string.min.js'></script>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user