vesh-vj
Version:
VESH's JavaScript Framework
958 lines (957 loc) • 79.9 kB
JavaScript
(function(V, $, W, M) {
W.Box = function(path, vm) {
var _ = this,
__ = {}; {
V.inherit.apply(_, [W.Control2, [W.Control2.merge({
template: '<div class="c_box"></div>',
vm: { border: 1 },
render: {
border: function(v) { _.node.css({ border: 'solid ' + v + 'px;' }); },
key: function(v) { _.node.css({ 'text-align': 'center', 'line-height': _.node.height() + 'px', 'vertical-align': 'middle', margin: '0 auto', 'minwidth': '40px', 'minheight': '20px' }).html(v); }
}
}, typeof(path) == 'string' ? { template: path } : (path || {}))]]);
}
};
W.FillControl = function(path, vm) {
var _ = this,
__ = {}; {
V.inherit.apply(_, [W.Control2, [W.Control2.merge({
template: '<div class="c_fillControl"></div>',
vm: vm,
onLoad: {
click: function(node) {
_.node.on('click', 'input', function(e) {
var _this = $(this);
_.call('click', { e: e, vid: _this.val(), name: _this.attr('name') });
V.stopProp(e);
return false;
});
_.node.on('click', 'a,.click', function(e) {
var _this = $(this);
if (_this.attr('href') && (_this.attr('href').indexOf('http://') >= 0 || _this.attr('href').indexOf('https://') >= 0)) {
return true;
} else {
_.call('click', { e: e, vid: _this.attr('vid') || _this.attr('href'), name: _this.attr('name') });
V.stopProp(e);
return false;
}
});
}
},
render: {
value: function(v) {
_.node.html(V.format(__.content, v));
}
}
}, typeof(path) == 'string' ? { template: path } : (path || {}))]]);
__.replaceNode = _.replaceNode
}
_.replaceNode = function() {
//必须覆盖这个方法否则_.node就是替换后的了
__.content = _.node.html();
__.replaceNode.apply(_, arguments);
};
};
W.History = function(path, vm) {
var _ = this,
__ = {}; {
V.inherit.apply(_, [W.Control2, [W.Control2.merge({
template: '<span class="c_history" style="display:none;"></span>',
onLoad: {
change: function(node, k, v) {
$(window).bind('hashchange', function(e) {
if (_.lastAction != window.location.hash.replace(/#/g, '')) {
_.call('change', { lastAction: _.lastAction });
_.lastAction = _.get().history.pop();
}
});
}
},
fill: function() {
return { hash: window.location.hash.replace(/#/g, '') };
},
render: {
//todo 如何取消父类操作 使用override操作 默认为false
visible: {
override: true,
Method: false
},
invisible: {
override: true,
Method: false
},
add: function(v) {
_.get().history = _.get().history || [];
(window.location.hash) && (function() {
var his = _.get().history;
(!(his.length > 0 && his[his.length - 1] == window.location.hash.replace(/#/g, ''))) && his.push(window.location.hash.replace(/#/g, ''));
})();
v = v.replace(/#/g, '');
(_.lastAction != v) && (function() {
window.location.hash = v;
_.lastAction = v;
})();
},
remove: function(v) {
_.get().history.pop();
},
back: function(v) {
(_.get().history && _.get().history.length > 0 && v) &&
(window.location.hash = _.get().history.pop());
}
}
}, typeof(path) == 'string' ? { template: path } : (path || {}))]]);
}
};
W.TextBox = function(path, vm) {
var _ = this,
__ = {}; {
V.inherit.apply(_, [W.Control2, [W.Control2.merge({
template: '<span class="c_textBox"><span style="display:none;"></span><input type="text"/></span>',
vm: vm || {},
onLoad: {
init: function(node) {
_.txt = node.find('span:first');
_.input = node.find('input:first');
},
hover: function(node, k, v) {
_.node.hover(function() {
if (_.node.parents("[disabled]").length > 0) return;
_.call('Hover', { hover: true });
}, function() {
if (_.node.parents("[disabled]").length > 0) return;
_.call('Hover', { hover: false });
});
},
blur: function(node, k, v) {
_.input && _.input.blur(function() {
_.call('blur');
});
}
},
fill: function() {
var value = $.trim(_.input.val());
value = (value == _.vm.data.title || value == _.vm.data.error) ? "" : value;
return { text: value, value: value };
},
render: {
'enable': function(v, data) {
v ? _.input.removeAttr('disabled') : _.input.attr('disabled', 'disabled');
},
'title': function(v, data) {
_.input.attr('placeholder', v || '');
},
'value': {
override: true,
as: ['text'],
Method: function(v, data) {
(typeof(v) != 'boolean' && 'false' != ('' + v).toLowerCase() && 'undefined' != ('' + v).toLowerCase()) ? (function() {
_.input.val(v);
(_.vm.data.title && !V.isValid(v)) ? _.input.val(_.vm.data.title): false;
})() : (function() {
_.input.val('');
})();
}
},
'name': {
override: true,
Method: function(v, data) {
_.input.attr('name', v);
}
},
'key': {
override: true,
Method: function(v, data) {
_.txt.text(v).show();
}
},
'size': {
override: true,
Method: function(v, data) {
_.input.attr('size', v)
}
},
'kind': {
override: true,
Method: function(v, data) {
_.input.attr('type', v)
}
},
'maxlength': {
override: true,
Method: function(v, data) {
_.input.attr('maxlength', v)
}
}
}
}, typeof(path) == 'string' ? { template: path } : (path || {}))]]);
}
_.animate = function(name, func) {
_._animate(name, _.input, func);
};
};
W.RadioBox = function(path, vm) {
var _ = this;
V.inherit.apply(_, [W.TextBox, [W.Control2.merge({
template: '<span class="c_radioBox"><span style="display:none;"></span><input type="radio"/></span>',
vm: vm,
fill: {
override: true,
Method: function() {
var ret = { checked: _.input.attr('checked') ? true : false };
ret.value = ret.checked;
return ret;
}
},
render: {
value: {
override: true,
as: ['checked'],
Method: function(v) {
V.setChecked(_.input, !!v);
}
}
}
}, typeof(path) == 'string' ? { template: path } : (path || {}))]]);
};
W.CheckBox = function(path, vm) {
var _ = this;
V.inherit.apply(_, [W.RadioBox, [path || '<span class="c_checkBox"><span style="display:none;"></span><input type="checkbox"/></span>', vm]]);
};
W.Select = function(path, vm) {
var _ = this,
__ = {
setValue: function(value) {
_.vm.data.preValue = _.input.find(':selected').val();
_.input.find(':selected').attr('selected', false);
_.input.find('option[value="' + value + '"]').attr('selected', true);
}
};
V.inherit.apply(_, [W.TextBox, [W.Control2.merge({
template: '<span class="c_select"><span style="display:none;"></span><select></select></span>',
vm: vm,
onLoad: {
init: function(node, k, v) {
_.txt = node.find('span:first');
_.input = node.find('select:first');
(_.events.error && _.get().validate) &&
_.validate(_, _.input);
}
},
fill: {
override: true,
Method: function() {
return { value: _.input.find("option:selected").val() };
}
},
render: {
values: function(v) {
v = (V.getType(v) == 'string') ? eval('(' + v + ')') : v;
(V.userAgent.ie7 || V.userAgent.ie8) ?
V.forC(v, function(k2, v2) {
var opn = document.createElement("OPTION");
_.input.get(0).appendChild(opn); //先追加
if (_.vm.data.value && _.vm.data.value == v2) {
opn.selected = true;
}
opn.innerText = k2;
opn.v = v2;
}, function() {
//神奇的Bug select重新填写需要改样式
V.once(function() { _.input.css('display', 'none').css('display', 'block') });
}, true):
(function() {
var sb = V.sb();
V.forC(v, function(k2, v2) {
sb.appendFormat('<option value="{value}">{key}</option>', { key: k2, value: v2 });
}, function() {
_.input.empty().html(sb.clear());
sb = null;
if (_.vm.data.value) { __.setValue(_.vm.data.value); }
}, true);
})();
},
'value': __.setValue,
}
}, typeof(path) == 'string' ? { template: path } : (path || {}))]]);
_.animate = function(name, func) {
_._animate(name, _.input, func);
};
};
W.RadioList = function(path, content, vm) {
var _ = this,
__ = {
content: content || '<li><span class="c_RadioList_li"><input name="{name}" type="radio" value="{value}"/><span>{key}</span></span></li>'
}; {
_.paths = ':radio';
V.inherit.apply(_, [W.Control2, [W.Control2.merge({
template: '<span class="c_RadioList"><span></span><ul></ul></span>',
vm: vm,
fill: function() {
return { value: _.ul.find(_.paths + ':checked').val() };
},
onLoad: {
init: function(node) {
_.title = node.find('span:first');
_.ul = node.find('ul');
_.vm.data.name = V.getValue(_.vm.data.name, _.paths.trim(':') + V.random());
}
},
render: {
'key': function(v) {
_.title.html(v);
},
'values': function(v) {
var sb = V.sb();
V.forC(v, function(k, v2) {
sb.appendFormat(__.content, { key: k, value: v2, name: _.vm.data.name });
}, function() {
_.ul.empty().append(sb.toString());
sb.clear();
sb = null;
if (_.vm.data.value) {
_.setValue(_.vm.data.value);
}
});
},
'value': function(v) {
_.setValue(v);
},
'name': function(v) {
_.node.find(_.paths).attr('name', v);
},
'enable': function(v) {
v ? _.node.find(_.paths).removeAttr('disabled') : _.node.find(_.paths).attr('disabled', 'disabled');
}
}
}, typeof(path) == 'string' ? { template: path } : (path || {}))]]);
}
_.setValue = function(v) {
V.setChecked(_.ul.find(_.paths + ":checked"), false);
V.setChecked(_.ul.find(_.paths + '[value="' + v + '"]'), true);
}
_.animate = function(name, func) {
_._animate(name, _.ul, func);
};
};
W.CheckList = function(path, content, vm) {
var _ = this,
__ = {}; {
V.inherit.apply(_, [W.RadioList, [W.Control2.merge({
template: '<div class="c_CheckList"><span></span><ul></ul></div>',
vm: vm,
fill: {
override: true,
Method: function() {
//需要兼容没有数据未创建时的错误
return _.ul.children().length > 0 ? {
value: (function() {
var ret = [];
_.ul.find(':checkbox:checked').each(function(i, v) {
ret.push($(v).val());
});
return ret.join(',');
})()
} : {};
}
}
}, typeof(path) == 'string' ? { template: path } : (path || {})), V.getValue(content, '<li><span class="c_CheckList_li"><input name="{name}" type="checkbox" value="{value}"/><span>{key}</span></span></li>')]]);
_.paths = ":checkbox";
}
_.setValue = function(value) {
value = V.getValue(value + '', '');
V.setChecked(_.ul.find(":checkbox:checked"), false);
V.each(value.split(','), function(v) {
V.setChecked(_.ul.find(':checkbox[value="' + v + '"]'), true);
});
};
_.animate = function(name, func) {
_._animate(name, _.sel, func);
};
};
W.Hidden = function(path, vm) {
var _ = this; {
V.inherit.apply(_, [W.Control2, [W.Control2.merge({
template: '<input class="c_hidden" type="hidden"/>',
vm: vm,
fill: function() {
return { val: _.node.val() };
},
render: {
value: function(v) { _.node.val(v) },
name: function(v) { _.node.attr('name', value) }
}
}, typeof(path) == 'string' ? { template: path } : (path || {}))]]);
}
};
W.PasswordBox = function(path, vm) {
var _ = this; {
V.inherit.apply(_, [W.TextBox, [W.Control2.merge({
template: '<span class="c_passwordBox"><span style="display:none;"></span><input type="password"/></span>',
vm: vm,
render: {
passchar: { as: ['alt'], Method: function(v, data, key) { _.input.attr(key, v); } }
}
}, typeof(path) == 'string' ? { template: path } : (path || {}))]]);
}
};
W.Button = function(path, vm) {
var _ = this; {
V.inherit.apply(_, [W.TextBox, [W.Control2.merge({
template: '<span class="c_button"><span style="display:none;"></span><input type="button"/></span>',
vm: vm,
fill: {
override: true,
Method: function() {
return {};
}
}
}, typeof(path) == 'string' ? { template: path } : (path || {}))]]);
}
};
W.Submit = function(path, vm) {
var _ = this; {
V.inherit.apply(_, [W.Button, [path || '<span class="c_submit"><span style="display:none;"></span><input type="submit"/></span>', vm]]);
}
};
W.Reset = function(path, vm) {
var _ = this; {
V.inherit.apply(_, [W.Button, [path || '<span class="c_reset"><span style="display:none;"></span><input type="reset"/></span>', vm]]);
}
};
W.Form = function(path, vm) {
var _ = this,
__ = {}; {
V.inherit.apply(_, [W.Control2, [W.Control2.merge({
template: '<form method="get" action="" class="c_form"></form>',
vm: { data: { enctype: 'multipart/form-data' } },
onLoad: {
init: function(node) {
_.cons = [];
node.find('[_]').each(function(i, v) {
_.cons[_.cons.length] = ($(v).attr('id'));
});
}
},
fill: function() {
var value = {};
_.vm.data.value = {};
if (_.cons) {
_.cons = _.cons && _.controls && !_.cons.length && !!_.controls.length ? _.controls.map(function(v) { return v.vm.id; }) : _.cons;
(_.cons.length) &&
_.cons.forEach(function(v) {
var vm = (_.vms ? _.vms[v] : null) || _.parent.vms[v] || _.page.vms[v];
//处理控件异步初始化 导致执行事件时内部控件未初始化完成。比较特殊 因为其包含其它控件 但是其它控件内部尚未初始化 使用Control2下的preonload和onload分离方式实现 对控件事件初始化和onLoad时间的分离
(vm && vm.nodeName != 'fill') && (value[v] = vm.update().value);
});
}
return { value: value };
},
render: {
method: function(v) { _.node.attr('method', v) },
action: function(v) { _.node.attr('action', v) },
target: function(v) { _.node.attr('target', v) },
name: function(v) { _.node.attr('name', v) },
enctype: function(v) { _.node.attr('enctype', v) },
valid: function(value) {
value && (function() {
var cons = _.cons.length ? Array.prototype.slice.apply(_.cons) : _.controls.map(function(v) { return v.vm.id });
V.whileC2(function() { return cons.shift(); }, function(v, next) {
var vm = (_.vms ? _.vms[v] : null) || _.parent.vms[v] || _.page.vms[v];
(vm) && vm.update({ valid: next });
}, function() {
value(_.fill().value);
});
})();
},
enable: function(v) {
_.cons = _.cons.length ? _.cons : _.controls.map(function(v) { return v.vm.id });
V.each(_.cons, function(v2) {
var vm = (_.vms ? _.vms[v2] : null) || _.parent.vms[v2] || _.page.vms[v2];
(vm) && vm.update({ enable: v });
})
},
value: function(v) {
_.node[0].reset();
_.vm.data.value = v || {};
_.cons = _.cons.length ? _.cons : _.controls.map(function(v) { return v.vm.id });
V.each(_.cons, function(v2) {
var vm = (_.vms ? _.vms[v2] : null) || _.parent.vms[v2] || _.page.vms[v2];
(vm) && (
(vm.nodeName == 'fill') ? vm.update({ value: v || {} }) :
vm.update({ value: v[v2] || false })
);
});
},
clear: function() {
_.cons = [];
_.clearControl();
}
}
}, typeof(path) == 'string' ? { template: path, vm: vm } : (path || {}))]]);
}
};
//识别 上下左右滑动及其动画,同时支持滑入滑出,支持点击或者tap,支持加载动画
//支持onUp向上滑动/onUpOut向上滑出/onDown向下滑动/onDownOut向下滑出/onLeft向左滑动/onLeftOut向左滑出/onRight向右滑动/onRightOut向右滑出/onDblClick双击/onScale(data(scale),self)双指改变大小/onRotate(data(angle),self)双指旋转 show('animatename')显示动画/hide('animatename')动画隐藏 limit动画事件响应阀值达到阀值后才触发事件,limitBack触发事件后是否立即回复正常
W.Panel = function(path, vm, limit, limitBack, lock) {
var _ = this,
__ = {
hasRender: false,
status: {
panelid: 'p' + V.random(),
transform: {
tx: 0,
ty: 0,
scale: 1,
angle: 0,
rx: 0,
ry: 0,
rz: 0
},
callevent: { value: false },
limit: V.getValue(limit, 0),
limitBack: V.getValue(limitBack, true),
lock: lock ? lock : false,
startX: 0,
startY: 0,
moving: false,
panelaction: {}
}
}; {
V.inherit.apply(_, [W.Control2, [W.Control2.merge({
template: '<div class="c_panel"></div>',
vm: V.merge(vm || {}, { data: { '_': true } }),
onLoad: {
init: function(node) {
node.attr('panelid', __.status.panelid);
},
finally: function(node) {
var ret = [];
V.forC(__.status.panelaction, function(k, v) {
v && (ret[ret.length] = k);
}, function() {
_.node.attr('panelaction', ret.join(','));
}, true);
},
'up': function(node) {
V.merge(__.status.panelaction, {
vol: true,
down: true
}, true);
},
'down': function() {
V.merge(__.status.panelaction, {
vol: true,
down: true
}, true);
},
'upout': function() {
V.merge(__.status.panelaction, {
vol: true,
upout: true
}, true);
},
'downout': function() {
V.merge(__.status.panelaction, {
vol: true,
downout: true
}, true);
},
'left': function() {
V.merge(__.status.panelaction, {
hor: true,
left: true
}, true);
},
'right': function() {
V.merge(__.status.panelaction, {
hor: true,
right: true
}, true);
},
'leftout': function() {
V.merge(__.status.panelaction, {
hor: true,
leftout: true
}, true);
},
'rightout': function() {
V.merge(__.status.panelaction, {
hor: true,
rightout: true
}, true);
},
'scale': function() {
__.status.panelaction.pinch = true;
},
'rotate': function() {
__.status.panelaction.rotate = true;
},
'dblclick': function() {
__.status.panelaction.dblclick = true;
}
},
render: {
width: function(v) {
_.node.width(v);
},
height: function(v) {
_.node.height(v);
},
'_': {
finally: true,
Method: function(v) {
!__.hasRender && (function() {
__.document = $(document);
__.hasRender = true;
//当物理控件的相关事务返回真时,启动提前终止的动画操作
__.finalMove = false;
__.mc = new Hammer.Manager(_.node[0]);
//最终动画方法和事件应该以便后面的控件自己控制移动和回滚的动画
//应该允许后面的继承控件自己控制
//事件的触发应该有阀值,在超出阀值时触发事件 并引发或者不引发回滚
__.mc.add(new Hammer.Pan({ threshold: 0, pointers: 0 }));
//__.mc.add(new Hammer.Swipe({velocity:0.6})).recognizeWith(__.mc.get('pan'));
if (__.status.panelaction.rotate || __.status.panelaction.pinch) {
__.mc.add(new Hammer.Rotate({ threshold: 0 })).recognizeWith(__.mc.get('pan'));
}
if (__.status.panelaction.pinch) {
__.mc.add(new Hammer.Pinch({ threshold: 0 })).recognizeWith([__.mc.get('pan'), __.mc.get('rotate')]);
}
if (__.status.panelaction.dblclick) {
__.mc.add(new Hammer.Tap({ event: 'doubletap', taps: 2 }));
}
//__.mc.add(new Hammer.Tap());swipeleft swiperight swipeup swipedown
__.mc.on(V.format("panleft panright panup pandown {pinorrot} {doubleclick}", {
//hor:(__.status.hor?'panleft panright':''),
//vol:(__.status.vol?'panup pandown':''),
pinorrot: __.status.panelaction.rotate ? 'rotatestart rotatemove rotateend rotate' : (__.status.panelaction.pinch ? 'pinchstart pinchmove pinchend' : ''),
doubleclick: __.status.panelaction.dblclick ? 'doubletap' : ''
}),
function(ev) {
//开始就有一个panelid 判断发生的target是否有panelid 如果有panelid且不是自己则不处理这个事情,否则处理这个事情(解决同向的滚动问题)
//修改为只要其定义的事件集合不包含我们的事件集合就可以处理
//需要过滤掉panelid相等但是不是本身的
var parent = ev.target.hasAttribute('panelid') ? $(ev.target) : $(ev.target).parents('[panelid]:first');
parent = parent.length > 0 ? parent : null;
(parent && parent.attr('panelid') == __.status.panelid) && (function() {
switch (ev.type) {
case 'panright':
case 'panleft':
case 'swiperight':
case 'swipeleft':
!__.status.panelaction['hor'] && (function() {
parent = $(parent).parents('[panelid]:first');
parent = parent.length > 0 ? parent : null;
})();
break;
case 'panup':
case 'pandown':
case 'swipeup':
case 'swipedown':
!__.status.panelaction['vol'] && (function() {
parent = $(parent).parents('[panelid]:first');
parent = parent.length > 0 ? parent : null;
})();
break;
case 'pinchstart':
case 'pinchmove':
case 'pinchin':
case 'pinchout':
case 'pinchend':
!__.status.panelaction['pinch'] && (function() {
parent = $(parent).parents('[panelid]:first');
parent = parent.length > 0 ? parent : null;
})();
break;
case 'rotate':
case 'rotatestart':
case 'rotatemove':
case 'rotateend':
!__.status.panelaction['rotate'] && (function() {
parent = $(parent).parents('[panelid]:first');
parent = parent.length > 0 ? parent : null;
})();
break;
case 'doubletap':
!__.status.panelaction['dblclick'] && (function() {
parent = $(parent).parents('[panelid]:first');
parent = parent.length > 0 ? parent : null;
})();
break;
}
})();
(parent && parent.attr('panelid') != __.status.panelid && parent.attr('panelaction') != '') && (function() {
var action = parent.attr('panelaction').split(',');
switch (ev.type) {
case 'panright':
case 'panleft':
case 'swiperight':
case 'swipeleft':
if ($.inArray('hor', action) >= 0) return;
break;
case 'panup':
case 'pandown':
case 'swipeup':
case 'swipedown':
if ($.inArray('vol', action) >= 0) return;
break;
case 'pinchstart':
case 'pinchmove':
case 'pinchin':
case 'pinchout':
case 'pinchend':
if ($.inArray('pinch', action) >= 0) return;
break;
case 'rotate':
case 'rotatestart':
case 'rotatemove':
case 'rotateend':
if ($.inArray('rotate', action) >= 0) return;
break;
case 'doubletap':
if ($.inArray('dblclick', action) >= 0) return;
break;
}
})()
if (!__.finalMove) {
//这里会出现闪烁,除非立即设定现在的位置 按理说finalMove应保护最终动画的完成
_.node.removeClass('animate').find('.animate').removeClass('animate');
switch (ev.type) {
case 'panright':
case 'swiperight':
if (__.status.hor && !__.rotating && !__.finalMove && Math.abs(ev.deltaX) > Math.abs(ev.deltaY)) {
__.status.lastAction = 'right';
__.finalMove = false || _.onRight(ev, __.status);
} else if (!__.status.hor && document.body.clientWidth < document.body.scrollWidth) {
//改为以一个固定的起始点+位移为处理方法 这样可以避免移动加倍的问题。
if (__.status.startX == 0) __.status.startX = __.document.scrollLeft();
__.document.scrollLeft(Math.max(__.status.startX - ev.deltaX, 0));
}
break;
case 'panleft':
case 'swipeleft':
if (__.status.hor && !__.rotating && !__.finalMove && Math.abs(ev.deltaX) > Math.abs(ev.deltaY)) {
__.status.lastAction = 'left';
__.finalMove = false || _.onLeft(ev, __.status);
} else if (!__.status.hor && document.body.clientWidth < document.body.scrollWidth) {
if (__.status.startX == 0) __.status.startX = __.document.scrollLeft();
__.document.scrollLeft(Math.min(__.status.startX - ev.deltaX, document.body.scrollWidth - document.body.clientWidth));
}
break;
case 'panup':
case 'swipeup':
if (__.status.vol && !__.rotating && !__.finalMove && Math.abs(ev.deltaX) < Math.abs(ev.deltaY)) {
__.status.lastAction = 'up';
__.finalMove = false || _.onUp(ev, __.status);
} else if (!__.status.vol && window.screen.availHeight < document.body.scrollHeight) {
if (__.status.startY == 0) __.status.startY = __.document.scrollTop();
__.document.scrollTop(Math.max(__.status.startY - ev.deltaY, document.body.scrollHeight - document.body.clientHeight));
}
break;
case 'pandown':
case 'swipedown':
if (__.status.vol && !__.rotating && !__.finalMove && Math.abs(ev.deltaX) < Math.abs(ev.deltaY)) {
__.status.lastAction = 'down';
__.finalMove = false || _.onDown(ev, __.status);
} else if (!__.status.vol && window.screen.availHeight < document.body.scrollHeight) {
if (__.status.startY == 0) __.status.startY = __.document.scrollTop();
__.document.scrollTop(Math.min(__.status.startY - ev.deltaY, document.body.scrollHeight));
}
break;
case 'pinchstart':
__.rotating = true;
case 'pinchmove':
__.finalMove = false || _.onScale(ev, __.status);
break;
case 'pinchin':
case 'pinchout':
__.status.lastAction = 'scale';
__.scale = ev.scale;
break;
case 'pinchend':
__.rotating = false;
break;
case 'rotate':
case 'rotatestart':
__.rotating = true;
case 'rotatemove':
//完成一个panel基础版本 其事件类应该可以由子类触发 完成一个hswiperpanel版本 完成一个上下移动的SPA初级模块
__.status.lastAction = 'rotate';
__.status.angle = ev.angle;
__.finalMove = false || _.onRotate(ev, __.status);
if (__.pinch) { __.status.scale = ev.scale };
break;
case 'rotateend':
__.rotating = false;
break;
}
//仅处理还原
if (__.finalMove) {
V.once(function() {
if (__.status.callevent.value) _.onFinal(__.status);
_.onBackAnimate(_.node, __.status);
__.status.callevent.value = false;
V.once(function() { __.finalMove = false; }, 300);
}, 100);
}
};
});
__.mc.on("hammer.input", function(ev) {
(ev.isFinal && !__.finalMove) && (function() {
V.once(function() {
if (__.status.callevent.value) _.onFinal(__.status);
_.onBackAnimate(_.node, __.status);
__.status.callevent.value = false;
V.once(function() { __.finalMove = false; }, 300);
}, 100);
})();
});
/*
__.mc.on("swipe", onSwipe);
__.mc.on("tap", onTap);
*/
})();
}
}
}
}, typeof(path) == 'string' ? { template: path } : (path || {}))]]);
_.status = __.status;
}
_.am = function(node, data, timeout) {
if (!__.status.lock && !__.moving) {
V.once(function() {
__.status.transform = V.merge(__.status.transform, data);
var value = V.format('translate3d({tx}px,{ty}px,0px) scale({scale},{scale}) rotate3d(0,0,0,{angle}deg)', __.status.transform);
node.css('webkitTransform', value).css('mozTransform', value).css('transform', value);
__.moving = false;
}, timeout || (1000 / 60));
__.moving = true;
}
};
//以方便继承类覆盖并执行动画
_.onLeft = function(ev, e) {
//使用速度计算距离不是太合理 Math.max(Math.abs(ev.velocity*ev.deltaTime),ev.distance)
if (Math.abs(ev.deltaX) < Math.max(30, _.node.width() * e.limit)) { _.am(_.node, { tx: (e.left || e.leftout) ? ev.deltaX : Math.max(0, ev.deltaX), ty: 0 }); } else { e.callevent.value = true; return e.limitBack; }
};
_.onRight = function(ev, e) {
if (Math.abs(ev.deltaX) < Math.max(30, _.node.width() * e.limit)) _.am(_.node, { tx: (e.right || e.rightout) ? ev.deltaX : Math.max(0, ev.deltaX), ty: 0 });
else { e.callevent.value = true; return e.limitBack; }
};
_.onUp = function(ev, e) {
if (Math.abs(ev.deltaY) < Math.max(30, _.node.height() * e.limit)) _.am(_.node, { ty: (e.up || e.upout) ? ev.deltaY : Math.max(0, ev.deltaY), tx: 0 });
else { e.callevent.value = true; return e.limitBack; }
};
_.onDown = function(ev, e) {
if (Math.abs(ev.deltaY) < Math.max(30, _.node.height() * e.limit)) _.am(_.node, { ty: (e.down || e.downout) ? ev.deltaY : Math.min(0, ev.deltaY), tx: 0 });
else { e.callevent.value = true; return e.limitBack; }
};
_.onScale = function(ev, e) {
if (Math.abs(ev.scale - 1) < e.limit) _.am(_.node, { scale: ev.scale });
else { e.callevent.value = true; }
};
_.onRotate = function(ev, e) {
_.am(_.node, { angle: ev.rotation, scale: e.pinch ? ev.scale : 1 });
e.callevent.value = true;
};
//最终执行动画并触发事件缓冲100毫秒发生
_.onBackAnimate = function(node, e) {
V.merge(e.transform, { tx: 0, ty: 0, scale: 1, angle: 0, rx: 0, ry: 0, rz: 0, startX: 0, startY: 0 }, true);
switch (e.lastAction) {
case 'left':
if (e.leftout) {
e.transform.tx = screen.width * -1;
}
break;
case 'right':
if (e.rightout) {
e.transform.tx = screen.width;
}
break;
case 'up':
if (e.upout) {
e.transform.ty = screen.height * -1;
}
break;
case 'down':
if (e.downout) {
e.transform.ty = screen.height;
}
break;
}
var value = V.format('translate3d({tx}px,{ty}px,0px) scale({scale},{scale}) rotate3d({rx},{ry},{rz},{angle}deg)', e.transform);
node.addClass('animate').css('webkitTransform', value).css('mozTransform', value).css('transform', value);
switch (e.lastAction) {
case 'left':
if (e.leftout) {
node.hide();
}
break;
case 'right':
if (e.rightout) {
node.hide();
}
break;
case 'up':
if (e.upout) {
node.hide();
}
break;
case 'down':
if (e.downout) {
node.hide();
}
break;
}
};
//最后触发的事件
_.onFinal = function(e) {
switch (e.lastAction) {
case 'left':
if (e.leftout) {
_.call('leftout');
} else
_.call('left');
break;
case 'right':
if (e.rightout) {
_.call('rightout');
} else
_.call('right');
break;
case 'up':
if (e.upout) {
_.call('upout');
} else
_.call('up');
break;
case 'down':
if (e.downout) {
_.call('downout');
} else
_.call('down');
break;
case 'scale':
_.call('scale', { scale: e.scale });
break;
case 'rotate':
if (e.pinch) {
if (e.scale != 1) { _.call('scale', { scale: e.scale }); }
}
_.call('rotate', { angle: e.angle });
break;
}
};
};
W.PagePanel = function(middler, path, vm, limit, limitBack) {
var _ = this,
__ = {}; {
V.inherit.apply(_, [middler.getTypeByAppName('VESH.view', 'panel'), [W.Control2.merge({
template: '<div style="overflow:hidden;" class="c_pagePanel"><div style="display:none;"></div></div>',
vm: V.merge(V.getValue(vm, {}), {
data: { direction: 'hor', value: 0 },
onLeft: function(data, self) { _.change(true); },
onRight: function(data, self) { _.change(false); },
onUp: function(data, self) { _.change(true); },
onDown: function(data, self) { _.change(false); }
}, true),