Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

a-touch

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

a-touch - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

.eslintrc.js

425

lib/BetterM.js

@@ -0,1 +1,20 @@

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Transform = exports.M = void 0;
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/**

@@ -9,231 +28,238 @@ * 矩阵变换计算

*/
var M = {
// 矩阵 相乘计算
mm: function mm(M1, M2) {
var LEN = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4;
var m = [];
export const M = {
// 矩阵 相乘计算
mm(M1, M2, LEN = 4) {
const m = [];
for (let i = 0; i < LEN; i++) {
for (let j = 0; j < LEN; j++) {
let ele = 0;
for (let z = 0; z < LEN; z++) {
ele += M1[i * LEN + z] * M2[j + LEN * z];
}
m.push(ele);
}
for (var i = 0; i < LEN; i++) {
for (var j = 0; j < LEN; j++) {
var ele = 0;
for (var z = 0; z < LEN; z++) {
ele += M1[i * LEN + z] * M2[j + LEN * z];
}
return m.map((i) => +i.toFixed(4));
},
mms(...args) {
return args.reduce((prev, current) => M.mm(current, prev));
},
// 旋转
rotate(R, m) {
// x轴旋转
// const RM = [
// 1, 0, 0, 0,
// 0, Math.cos(R), Math.sin(R), 0,
// 0, -Math.sin(R), Math.cos(R), 0,
// 0, 0, 0, 1,
// ]
// y轴旋转
// const RM = [
// Math.cos(R), 0, -Math.sin(R), 0,
// Math.sin(R), 0, Math.cos(R), 0,
// 0, 0, 1, 0,
// 0, 0, 0, 1,
// ]
m.push(ele);
}
}
// z轴旋转
// prettier-ignore
const RM = [
Math.cos(R), -Math.sin(R), 0, 0,
Math.sin(R), Math.cos(R), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
];
return m.map(function (i) {
return +i.toFixed(4);
});
},
mms: function mms() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return M.mm(RM, m);
},
// 缩放
scale(S, m) {
// prettier-ignore
const RM = [
S, 0, 0, 0,
0, S, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
];
return args.reduce(function (prev, current) {
return M.mm(current, prev);
});
},
// 旋转
rotate: function rotate(R, m) {
// x轴旋转
// const RM = [
// 1, 0, 0, 0,
// 0, Math.cos(R), Math.sin(R), 0,
// 0, -Math.sin(R), Math.cos(R), 0,
// 0, 0, 0, 1,
// ]
// y轴旋转
// const RM = [
// Math.cos(R), 0, -Math.sin(R), 0,
// Math.sin(R), 0, Math.cos(R), 0,
// 0, 0, 1, 0,
// 0, 0, 0, 1,
// ]
// z轴旋转
// prettier-ignore
var RM = [Math.cos(R), -Math.sin(R), 0, 0, Math.sin(R), Math.cos(R), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
return M.mm(RM, m);
},
// 缩放
scale: function scale(S, m) {
// prettier-ignore
var RM = [S, 0, 0, 0, 0, S, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
return M.mm(RM, m);
},
// 位移
translate: function translate(x, y, m) {
// const newM = [...m]
// newM[12] += x
// newM[13] += y
// return newM
// prettier-ignore
var RM = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, 0, 1];
return M.mm(RM, m);
},
// 缩放位移矫正
trans: function trans(SCALE, current, origin, m) {
// 在这里,我们设置transform-origin: 0 0;然后所有的计算以图片的左上角为基准,这样方便计算位置变换后的位移
// 1. 计算出current中点相对于左上角的坐标
// 2. 根据缩放比例,计算出中点坐标的相对位移
// 3. 矩阵 -> 缩放后矩阵 -> 位移矫正
var p = {
x: (current.x + current.x1) / 2 - (origin.left + m[12]),
y: (current.y + current.y1) / 2 - (origin.top + m[13])
}; // 计算位移
return M.mm(RM, m);
},
// 位移
translate(x, y, m) {
// const newM = [...m]
// newM[12] += x
// newM[13] += y
// return newM
// prettier-ignore
const RM = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
x, y, 0, 1
];
return M.mm(RM, m);
},
// 缩放位移矫正
trans(SCALE, current, origin, m) {
// 在这里,我们设置transform-origin: 0 0;然后所有的计算以图片的左上角为基准,这样方便计算位置变换后的位移
// 1. 计算出current中点相对于左上角的坐标
// 2. 根据缩放比例,计算出中点坐标的相对位移
// 3. 矩阵 -> 缩放后矩阵 -> 位移矫正
const p = {
x: (current.x + current.x1) / 2 - (origin.left + m[12]),
y: (current.y + current.y1) / 2 - (origin.top + m[13]),
};
// 计算位移
const newP = {
x: -p.x * (SCALE - 1),
y: -p.y * (SCALE - 1),
};
return M.translate(newP.x, newP.y, m);
},
var newP = {
x: -p.x * (SCALE - 1),
y: -p.y * (SCALE - 1)
};
return M.translate(newP.x, newP.y, m);
}
};
exports.M = M;
export class Transform {
state = {
var Transform = /*#__PURE__*/function () {
function Transform(m) {
_classCallCheck(this, Transform);
_defineProperty(this, "state", {
scale: 1,
rotate: 0,
x: 0,
y: 0
});
// prettier-ignore
this.m = m || [// 初始状态
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
}
_createClass(Transform, [{
key: "snap",
value: function snap() {
return _objectSpread({}, this.state);
}
}, {
key: "reset",
value: function reset() {
this.state = {
scale: 1,
rotate: 0,
x: 0,
y: 0,
};
constructor(m) {
// prettier-ignore
this.m = m || [
// 初始状态
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
]
y: 0
};
}
}, {
key: "toM",
value: function toM() {
var initM = this.m;
var state = this.state; // const m = M.translate(state.x/state.scale, state.y/state.scale, M.rotate(state.rotate, M.scale(state.scale, initM)))
// 先位移,再放在,再旋转
snap() {
return {
...this.state,
};
var m = M.rotate(state.rotate, M.scale(state.scale, M.translate(state.x, state.y, initM)));
return m;
}
reset() {
this.state = {
scale: 1,
rotate: 0,
x: 0,
y: 0,
};
}, {
key: "toCss",
value: function toCss() {
return ";transform: matrix3D(".concat(this.toM().join(','), ");");
}
}, {
key: "translate",
value: function translate(x, y, snap) {
if (snap) {
this.state.x = x + snap.x;
this.state.y = y + snap.y;
} else {
this.state.x += x;
this.state.y += y;
}
toM() {
const initM = this.m;
const state = this.state;
// const m = M.translate(state.x/state.scale, state.y/state.scale, M.rotate(state.rotate, M.scale(state.scale, initM)))
// 先位移,再放在,再旋转
const m = M.rotate(state.rotate, M.scale(state.scale, M.translate(state.x, state.y, initM)));
return m;
return this.toM();
}
toCss() {
return `;transform: matrix3D(${this.toM().join(',')});`;
}, {
key: "getTranslate",
value: function getTranslate() {
return [this.state.x, this.state.y];
}
translate(x, y, snap) {
if (snap) {
this.state.x = x + snap.x;
this.state.y = y + snap.y;
} else {
this.state.x += x;
this.state.y += y;
}
return this.toM();
}, {
key: "rotate",
value: function rotate(R, origin) {
var baseR = this.state.rotate;
this.state.rotate = baseR + R;
this.fixRotate(origin, baseR, R);
return this.toM();
}
}, {
key: "fixRotate",
value: function fixRotate(origin, baseR, rotate) {
// 在这里,我们设置transform-origin: 0 0;然后所有的计算以图片的左上角为基准,这样方便计算位置变换后的位移
// 1. 计算出center中点相对于左上角的坐标
// 2. 根据缩放比例,计算出中点坐标的相对位移
// 3. 矩阵 -> 缩放后矩阵 -> 位移矫正
var _this$state = this.state,
TX = _this$state.x,
TY = _this$state.y;
var p = {
x: origin.width / 2 + origin.left - (origin.left + TX),
y: origin.height / 2 + origin.top - (origin.top + TY)
};
var len = Math.sqrt(Math.pow(p.x, 2) + Math.pow(p.y, 2));
var ang = Math.atan(p.y / p.x) + rotate;
getTranslate() {
return [this.state.x, this.state.y];
}
if (baseR % (Math.PI * 2) >= Math.PI) {
ang += Math.PI;
}
rotate(R, origin) {
const baseR = this.state.rotate;
this.state.rotate = baseR + R;
this.fixRotate(origin, baseR, R);
return this.toM();
}
var X = Math.sin(ang) * len;
var Y = Math.cos(ang) * len; // 因为每次修改都是90°,所以x,y的坐标需要交换
fixRotate(origin, baseR, rotate) {
// 在这里,我们设置transform-origin: 0 0;然后所有的计算以图片的左上角为基准,这样方便计算位置变换后的位移
// 1. 计算出center中点相对于左上角的坐标
// 2. 根据缩放比例,计算出中点坐标的相对位移
// 3. 矩阵 -> 缩放后矩阵 -> 位移矫正
const { x: TX, y: TY } = this.state;
const p = {
x: origin.width / 2 + origin.left - (origin.left + TX),
y: origin.height / 2 + origin.top - (origin.top + TY),
};
var _ref = [Y, X];
X = _ref[0];
Y = _ref[1];
// 计算位移
var newX = p.x - X;
var newY = -(p.y - Y); // 为什么y要取负数呢?
const len = Math.sqrt(Math.pow(p.x, 2) + Math.pow(p.y, 2));
let ang = Math.atan(p.y / p.x) + rotate;
if (baseR % (Math.PI * 2) >= Math.PI) {
ang += Math.PI;
}
return this.translate(newY, newX);
}
}, {
key: "scale",
value: function scale(S, center, origin, snap) {
if (snap) {
this.state.scale = snap.scale * S;
this.fixScale(center, origin, S - 1, snap);
} else {
this.state.scale *= S; // 根据变化的缩放比例进行位置校正
let X = Math.sin(ang) * len;
let Y = Math.cos(ang) * len;
this.fixScale(center, origin, S - 1);
}
// 因为每次修改都是90°,所以x,y的坐标需要交换
[X, Y] = [Y, X];
// 计算位移
const newX = p.x - X;
const newY = -(p.y - Y); // 为什么y要取负数呢?
return this.translate(newY, newX);
return this.toM();
}
}, {
key: "fixScale",
value: function fixScale(center, origin, scale, snap) {
// 在这里,我们设置transform-origin: 0 0;然后所有的计算以图片的左上角为基准,这样方便计算位置变换后的位移
// 1. 计算出center中点相对于左上角的坐标
// 2. 根据缩放比例,计算出中点坐标的相对位移
// 3. 矩阵 -> 缩放后矩阵 -> 位移矫正
var _ref2 = snap || this.state,
TX = _ref2.x,
TY = _ref2.y;
scale(S, center, origin, snap) {
if (snap) {
this.state.scale = snap.scale * S;
this.fixScale(center, origin, S - 1, snap);
} else {
this.state.scale *= S;
// 根据变化的缩放比例进行位置校正
this.fixScale(center, origin, S - 1);
}
return this.toM();
}
var p = {
x: (center.x + center.x1) / 2 - (origin.left + TX),
y: (center.y + center.y1) / 2 - (origin.top + TY)
}; // 计算位移
fixScale(center, origin, scale, snap) {
// 在这里,我们设置transform-origin: 0 0;然后所有的计算以图片的左上角为基准,这样方便计算位置变换后的位移
// 1. 计算出center中点相对于左上角的坐标
// 2. 根据缩放比例,计算出中点坐标的相对位移
// 3. 矩阵 -> 缩放后矩阵 -> 位移矫正
const { x: TX, y: TY } = snap || this.state;
const p = {
x: (center.x + center.x1) / 2 - (origin.left + TX),
y: (center.y + center.y1) / 2 - (origin.top + TY),
};
// 计算位移
const newX = -p.x * scale;
const newY = -p.y * scale;
return this.translate(newX, newY, snap);
var newX = -p.x * scale;
var newY = -p.y * scale;
return this.translate(newX, newY, snap);
}
getScale() {
return this.state.scale;
}, {
key: "getScale",
value: function getScale() {
return this.state.scale;
}
}
}]);
return Transform;
}();
/**

@@ -245,1 +271,4 @@ * 始终相对左上角进行变换

*/
exports.Transform = Transform;

@@ -1,21 +0,50 @@

const isIos = window.navigator.userAgent.match(/iphone|ios|ipad/i);
const isPhone = window.navigator.userAgent.match(/phone|android|ios/i);
const isPC = !window.navigator.userAgent.match(/phone|android|ios|pad/i);
const [touchstart, touchmove, touchend, touchleave] = isPhone
? ['touchstart', 'touchmove', 'touchend', 'touchcancel']
: ['mousedown', 'mousemove', 'mouseup', 'mouseleave'];
const IOS_SYSTEM_SWIPE_WIDTH = 45; // ios系统返回触发宽度
"use strict";
export {
touchstart, touchmove, touchend, touchleave, isIos, isPhone, isPC, IOS_SYSTEM_SWIPE_WIDTH,
};
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.touchstart = exports.touchmove = exports.touchleave = exports.touchend = exports.isPhone = exports.isPC = exports.isIos = exports.TOUCH_DIRECTION = exports.TOUCH_ACTION = exports.IOS_SYSTEM_SWIPE_WIDTH = void 0;
export const TOUCH_DIRECTION = {
leftToRight: 'lr',
topToBottom: 'ud',
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
var isIos = window.navigator.userAgent.match(/iphone|ios|ipad/i);
exports.isIos = isIos;
var isPhone = window.navigator.userAgent.match(/phone|android|ios/i);
exports.isPhone = isPhone;
var isPC = !window.navigator.userAgent.match(/phone|android|ios|pad/i);
exports.isPC = isPC;
var _ref = isPhone ? ['touchstart', 'touchmove', 'touchend', 'touchcancel'] : ['mousedown', 'mousemove', 'mouseup', 'mouseleave'],
_ref2 = _slicedToArray(_ref, 4),
touchstart = _ref2[0],
touchmove = _ref2[1],
touchend = _ref2[2],
touchleave = _ref2[3];
exports.touchleave = touchleave;
exports.touchend = touchend;
exports.touchmove = touchmove;
exports.touchstart = touchstart;
var IOS_SYSTEM_SWIPE_WIDTH = 45; // ios系统返回触发宽度
exports.IOS_SYSTEM_SWIPE_WIDTH = IOS_SYSTEM_SWIPE_WIDTH;
var TOUCH_DIRECTION = {
leftToRight: 'lr',
topToBottom: 'ud'
};
export const TOUCH_ACTION = {
swipe: 'swipe',
pinch: 'pinch',
}
exports.TOUCH_DIRECTION = TOUCH_DIRECTION;
var TOUCH_ACTION = {
swipe: 'swipe',
pinch: 'pinch'
};
exports.TOUCH_ACTION = TOUCH_ACTION;

@@ -1,37 +0,72 @@

/* eslint-disable max-len */
/* eslint-disable no-multi-assign */
/* eslint-disable no-restricted-properties */
import Event from './Event';
"use strict";
import {
touchstart,
touchmove,
touchend,
touchleave,
isIos,
isPhone,
IOS_SYSTEM_SWIPE_WIDTH,
TOUCH_DIRECTION,
TOUCH_ACTION,
} from './config';
import util from './util';
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _Event2 = _interopRequireDefault(require("./Event"));
var _config = require("./config");
var _util = _interopRequireDefault(require("./util"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
// touches changeTouches targetTouches 的区别
// https://stackoverflow.com/questions/7056026/variation-of-e-touches-e-targettouches-and-e-changedtouches
function distance(x, y, x1, y1) {
return Math.sqrt(Math.pow(x - x1, 2) + Math.pow(y - y1, 2), 2);
return Math.sqrt(Math.pow(x - x1, 2) + Math.pow(y - y1, 2), 2);
}
function getFinger(e) {
return e.touches ? e.touches.length : 1;
return e.touches ? e.touches.length : 1;
}
function prevent(options, event) {
if (event.cancelable) {
options.preventDefault && event.preventDefault();
options.stopPropagation && event.stopPropagation();
}
if (event.cancelable) {
options.preventDefault && event.preventDefault();
options.stopPropagation && event.stopPropagation();
}
}
/*

@@ -50,452 +85,573 @@ * touch core 提供回调

*/
export default class Touch extends Event {
$dom = document.body;
constructor($dom, options = {}) {
super();
this.$dom = $dom;
this.options = {
finger: 1, // 默认为单指
forceResetTime: 500, // 强制reset时长
preventDefault: true, // 阻止默认事件
stopPropagation: false, // 是否冒泡
litenLeaveEvent: true, // 是否监听leave事件
iosSystemSwipe: true,
XYWeight: 1,
ingoreTouchElement: 'ingoreTouchElement', // 忽略touch事件的元素
canScrollElement: 'canScrollElement', // 可滚动元素
listenerOptions: {}, // addEventListener options 处理capture/passive等
activeClassName: '', // 触摸过程中为$dom添加的class
effectElements: [], // 受影响的元素,会在其dom上添加activeClassName
...options,
};
this.init();
this.addEvents();
}
// 初始化
init = () => {
this.inited = true;
this.state = {
start: { x: 0, y: 0 }, // 滑动开始
move: { x: 0, y: 0 }, // 滑动中
moveCache: { x: 0, y: 0 }, // 位移缓存
change: { x: 0, y: 0 }, // x,y位移变化
end: { x: 0, y: 0 }, // 滑动结束
V: { x: 0, y: 0 }, // 位移速度
VCache: [],
overAllV: { x: 0, y: 0 }, // 位移速度
scale: 1, // 缩放比例
scalePer: 1, // 缩放变化
scaleV: 0, // 缩放速度
rotate: 0, // 旋转角度
rotatePer: 0, // 旋转变化
rotateV: 0, // 旋转速度
finger: 0, // 触摸指个数
nativeFingers: 0, // 当前dom上的触摸点个数
enable: false,
swipeX: true,
swipeY: true,
freeze: false,
direction: '', // lr, ud
isMove: false,
action: '', // swipe pinch
};
};
var Touch = /*#__PURE__*/function (_Event) {
_inherits(Touch, _Event);
/**
* 在effectElements切换className
* @param {boolean} [addClass=true]
* @memberof Touch
*/
toggleActiveClass(addClass = true) {
const { effectElements = [], activeClassName } = this.options;
if (activeClassName) {
[this.$dom, ...effectElements].forEach((dom) => {
dom instanceof window.HTMLElement && dom.classList.toggle(activeClassName, addClass);
});
}
}
var _super = _createSuper(Touch);
enable() {
this._isDisable = false;
}
function Touch($dom) {
var _this;
/**
* 阻止任何触摸滑动默认事件,阻止滑动冒泡事件
* @memberof Touch
*/
disable() {
this._isDisable = true;
}
var _options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
destroy() {
this.isDestroy = true;
this.removeEvents();
}
_classCallCheck(this, Touch);
isAddEvent = false;
_this = _super.call(this);
getListenerOptions() {
return {
passive: false,
...this.options.listenerOptions,
};
}
_defineProperty(_assertThisInitialized(_this), "$dom", document.body);
addEvents() {
if (this.isDestroy || this.isAddEvent) return;
this.isAddEvent = true;
this.$dom.addEventListener(touchstart, this.start, this.getListenerOptions());
this.$dom.addEventListener(touchmove, this.move, this.getListenerOptions());
this.$dom.addEventListener(touchend, this.end, this.getListenerOptions());
!isPhone &&
this.options.litenLeaveEvent &&
this.$dom.addEventListener(touchleave, this.end, { passive: false });
}
_defineProperty(_assertThisInitialized(_this), "init", function () {
_this.inited = true;
_this.state = {
start: {
x: 0,
y: 0
},
// 滑动开始
move: {
x: 0,
y: 0
},
// 滑动中
moveCache: {
x: 0,
y: 0
},
// 位移缓存
change: {
x: 0,
y: 0
},
// x,y位移变化
end: {
x: 0,
y: 0
},
// 滑动结束
V: {
x: 0,
y: 0
},
// 位移速度
VCache: [],
overAllV: {
x: 0,
y: 0
},
// 位移速度
scale: 1,
// 缩放比例
scalePer: 1,
// 缩放变化
scaleV: 0,
// 缩放速度
rotate: 0,
// 旋转角度
rotatePer: 0,
// 旋转变化
rotateV: 0,
// 旋转速度
finger: 0,
// 触摸指个数
nativeFingers: 0,
// 当前dom上的触摸点个数
enable: false,
swipeX: true,
swipeY: true,
freeze: false,
direction: '',
// lr, ud
isMove: false,
action: '' // swipe pinch
removeEvents() {
this.$dom.removeEventListener(touchstart, this.start);
this.$dom.removeEventListener(touchmove, this.move);
this.$dom.removeEventListener(touchend, this.end);
!isPhone && this.options.litenLeaveEvent && this.$dom.removeEventListener(touchleave, this.end);
this.isAddEvent = false;
}
};
});
getPosition(e, index = 0) {
let x = isPhone ? e.touches[index].clientX : e.clientX;
let y = isPhone ? e.touches[index].clientY : e.clientY;
// 使用相对位置
if (this.options.useRelativePos) {
const { left, top } = this.$dom.getBoundingClientRect();
x -= left;
y -= top;
}
return {
[`x${index || ''}`]: x,
[`y${index || ''}`]: y,
};
}
_defineProperty(_assertThisInitialized(_this), "isAddEvent", false);
/**
* 因为有些元素可能是可以滚动的,所以只能在滚动到边界的时候才能触发touch事件监听
* @param {*} currentTarget
* @returns
* @memberof Touch
*/
setTouchLimit(currentTarget) {
const { options, state } = this;
if (options.canScrollElement) {
const scrollElement = util.parent(currentTarget, this.$dom, (d) =>
d.classList.contains(options.canScrollElement)
);
if (scrollElement) {
const { clientHeight, scrollHeight, scrollTop } = scrollElement;
_defineProperty(_assertThisInitialized(_this), "start", function (event) {
var _assertThisInitialize = _assertThisInitialized(_this),
options = _assertThisInitialize.options,
state = _assertThisInitialize.state;
if (scrollHeight != clientHeight) {
if (scrollTop == 0) {
// 顶部
state.directionLimit = {
direction: TOUCH_DIRECTION.topToBottom,
only: 1,
scrollElement,
};
} else if (Math.ceil(scrollTop) >= scrollHeight - clientHeight) {
// 底部
state.directionLimit = {
direction: TOUCH_DIRECTION.topToBottom,
only: -1,
scrollElement,
};
} else {
state.directionLimit = {
direction: TOUCH_DIRECTION.topToBottom,
only: 0, // 不限定滚动方向
scrollElement,
};
}
}
}
}
}
_this.removePcEvents && _this.removePcEvents();
if (_this._isDisable) return;
prevent(options, event);
/**
* 判断当前元素是否是可以忽略滑动监听
* @param {*} target
* @returns
* @memberof Touch
*/
checkIsTouchIgnore(currentTarget) {
let { ingoreTouchElement } = this.options;
if (!Array.isArray(ingoreTouchElement)) {
ingoreTouchElement = [ingoreTouchElement];
_this.trigger('nativeStart', event, state); // 0到2 保持稳定
// 2到1 被销毁
// 2 -> 3 只有一个有用
state.nativeFingers = getFinger(event);
_this.trigger('finger:change', state.nativeFingers, state.finger);
if (!state.freeze && !state.isMove) {
if (_this.checkIsTouchIgnore(event.target)) return; // 某些元素在内部滚动到尽头时,可以触发滚动,并且需要锁定滚动方向
_this.setTouchLimit(event.target); // 处理ios系统返回
if (_config.isIos && options.iosSystemSwipe && options.finger === 1 && (event.touches[0].clientX < _config.IOS_SYSTEM_SWIPE_WIDTH || event.touches[0].clientX > window.innerWidth - _config.IOS_SYSTEM_SWIPE_WIDTH)) {
return;
}
const isIngnore =
ingoreTouchElement.length &&
util.parent(
currentTarget,
this.$dom,
(d) =>
ingoreTouchElement.some((item) => d.classList.contains(item)) ||
getComputedStyle(d).overflowX === 'scroll'
);
state.finger = getFinger(event);
state.enable = true;
state.start = state.move = state.moveCache = _objectSpread(_objectSpread({}, _this.getPosition(event)), {}, {
time: Date.now()
});
// options.checkIsTouchIgnore 也可以校验是否可以滑动
return isIngnore || (this.options.checkIsTouchIgnore && this.options.checkIsTouchIgnore(event));
}
_this.toggleActiveClass(); // 如果是双指,记录双指位置
/**
* 判断滑动方向是否受限
* @param {String} direction
* @param {Bumber} change
* @returns
* @memberof Touch
*/
checkTouchLimit(direction, change) {
const { state } = this;
const { directionLimit } = state;
// 判断方向滑动方向是否一致 左右 上下 是否一致
if (directionLimit && directionLimit.direction === direction) {
// 如果<=0 表示,滑动动向相反
if (change * directionLimit.only <= 0) {
return true;
}
if (options.finger == 2 && getFinger(event) >= options.finger) {
state.start = state.move = state.moveCache = _objectSpread(_objectSpread({}, _this.getPosition(event, 1)), state.start);
}
return this.options.checkTouchLimit && this.options.checkTouchLimit(direction, change);
}
_this.trigger('start', state, event);
start = (event) => {
const { options, state } = this;
this.removePcEvents && this.removePcEvents();
if (this._isDisable) return;
_this.trigger('startv2', {
state: state,
event: event
});
}
});
prevent(options, event);
this.trigger('nativeStart', event, state);
_defineProperty(_assertThisInitialized(_this), "move", function (event) {
if (_this._isDisable) {
event.preventDefault();
event.stopPropagation();
return;
}
// 0到2 保持稳定
// 2到1 被销毁
// 2 -> 3 只有一个有用
state.nativeFingers = getFinger(event);
this.trigger('finger:change', state.nativeFingers, state.finger);
if (!state.freeze && !state.isMove) {
if (this.checkIsTouchIgnore(event.target)) return;
// 某些元素在内部滚动到尽头时,可以触发滚动,并且需要锁定滚动方向
var _assertThisInitialize2 = _assertThisInitialized(_this),
state = _assertThisInitialize2.state,
options = _assertThisInitialize2.options;
this.setTouchLimit(event.target);
prevent(options, event); // 如果想自己控制preventDefault 可以监听nativeChange事件,处理event
// 处理ios系统返回
if (
isIos &&
options.iosSystemSwipe &&
options.finger === 1 &&
(event.touches[0].clientX < IOS_SYSTEM_SWIPE_WIDTH ||
event.touches[0].clientX > window.innerWidth - IOS_SYSTEM_SWIPE_WIDTH)
) {
return;
}
_this.trigger('nativeChange', event);
state.finger = getFinger(event);
state.enable = true;
state.start = state.move = state.moveCache = {
...this.getPosition(event),
time: Date.now(),
};
this.toggleActiveClass();
// 如果是双指,记录双指位置
if (options.finger == 2 && getFinger(event) >= options.finger) {
state.start = state.move = state.moveCache = {
...this.getPosition(event, 1),
...state.start,
};
}
this.trigger('start', state, event);
this.trigger('startv2', { state, event });
}
};
var start = state.start,
moveCache = state.moveCache,
swipeX = state.swipeX,
swipeY = state.swipeY;
move = (event) => {
if (this._isDisable) {
event.preventDefault();
event.stopPropagation();
if (state.touchLimit) {
return;
} // 同时只能响应一种手势,滑动 还是 缩放
if (state.enable && !state.freeze) {
var move = _objectSpread(_objectSpread({}, _this.getPosition(event)), {}, {
time: Date.now()
});
var T = (move.time - moveCache.time) * 1000;
if (!state.swipeY || swipeX && Math.abs(move.x - start.x) * options.XYWeight > Math.abs(move.y - start.y)) {
// canScrollElement在可以滚动的区间,不trigger滚动事件,但在touchend后要对state做重置
if (state.swipeY && _this.checkTouchLimit(_config.TOUCH_DIRECTION.leftToRight, move.x - start.x)) {
state.touchLimit = true;
return;
}
state.direction = _config.TOUCH_DIRECTION.leftToRight;
state.isMove = true;
state.swipeY = false;
}
const { state, options } = this;
prevent(options, event);
// 如果想自己控制preventDefault 可以监听nativeChange事件,处理event
this.trigger('nativeChange', event);
if (!state.swipeX || swipeY && Math.abs(move.x - start.x) * options.XYWeight < Math.abs(move.y - start.y) // 注释<=逻辑,否则pc端点击之后,就无法左右滑动了
) {
if (state.swipeX && _this.checkTouchLimit(_config.TOUCH_DIRECTION.topToBottom, move.y - start.y)) {
state.touchLimit = true;
return;
}
const { start, moveCache, swipeX, swipeY } = state;
state.isMove = true;
state.swipeX = false;
state.direction = _config.TOUCH_DIRECTION.topToBottom;
} // 开始滚动前
if (state.touchLimit) {
return;
!state.isMove && _this.trigger('beforeChange', state, event);
if (options.finger === 2 && getFinger(event) === options.finger && state.action !== _config.TOUCH_ACTION.swipe) {
state.action = _config.TOUCH_ACTION.pinch;
move = _objectSpread(_objectSpread({}, _this.getPosition(event, 1)), move);
state.move = move;
state.change = {
x: move.x - start.x,
y: move.y - start.y,
x1: move.x1 - start.x1,
y1: move.y1 - start.y1
}; // 缩放比例
state.scale = distance(move.x, move.y, move.x1, move.y1) / distance(start.x, start.y, start.x1, start.y1);
state.scalePer = distance(move.x, move.y, move.x1, move.y1) / distance(moveCache.x, moveCache.y, moveCache.x1, moveCache.y1);
state.scaleV = state.scalePer / T; // 旋转角度
state.rotate = Math.atan2(move.y - move.y1, move.x - move.x1) - Math.atan2(start.y - start.y1, start.x - start.x1);
state.rotatePer = Math.atan2(move.y - move.y1, move.x - move.x1) - Math.atan2(moveCache.y - moveCache.y1, moveCache.x - moveCache.x1);
state.rotateV = state.rotatePer / T; // 计算滑动速度
state.V = {
x: (move.x - moveCache.x) / T,
y: (move.y - moveCache.y) / T
};
state.VCache.push(state.V);
if (state.VCache.length > 4) {
state.VCache.shift();
} // state.rotate *= 180 / Math.PI
_this.trigger('change', state.change, state, event);
_this.trigger('changev2', {
state: state,
event: event
});
state.moveCache = _objectSpread({}, state.move);
}
// 同时只能响应一种手势,滑动 还是 缩放
if (state.enable && !state.freeze) {
let move = {
...this.getPosition(event),
time: Date.now(),
};
const T = (move.time - moveCache.time) * 1000;
if (getFinger(event) === 1) {
state.action = _config.TOUCH_ACTION.swipe;
state.move = move;
state.change = {
x: move.x - start.x,
y: move.y - start.y
}; // 计算滑动速度
if (
!state.swipeY ||
(swipeX && Math.abs(move.x - start.x) * options.XYWeight > Math.abs(move.y - start.y))
) {
// canScrollElement在可以滚动的区间,不trigger滚动事件,但在touchend后要对state做重置
if (state.swipeY && this.checkTouchLimit(TOUCH_DIRECTION.leftToRight, move.x - start.x)) {
state.touchLimit = true;
return;
}
state.direction = TOUCH_DIRECTION.leftToRight;
state.isMove = true;
state.swipeY = false;
}
state.V = {
x: (move.x - moveCache.x) / T,
y: (move.y - moveCache.y) / T
}; // 保留最近4个瞬时速度,以供消费
if (
!state.swipeX ||
(swipeY && Math.abs(move.x - start.x) * options.XYWeight < Math.abs(move.y - start.y)) // 注释<=逻辑,否则pc端点击之后,就无法左右滑动了
) {
if (state.swipeX && this.checkTouchLimit(TOUCH_DIRECTION.topToBottom, move.y - start.y)) {
state.touchLimit = true;
return;
}
state.isMove = true;
state.swipeX = false;
state.direction = TOUCH_DIRECTION.topToBottom;
}
state.VCache.push(state.V);
// 开始滚动前
!state.isMove && this.trigger('beforeChange', state, event);
if (state.VCache.length > 4) {
state.VCache.shift();
} // 需要提供最后一次有效滑动方向
// 以及滑动速度
// 滑动
// todo,trigger传递的state,应该是不可变state,如果传递引用的话,会导致一些问题
if (options.finger === 2 && getFinger(event) === options.finger && state.action !== TOUCH_ACTION.swipe) {
state.action = TOUCH_ACTION.pinch;
move = {
...this.getPosition(event, 1),
...move,
};
state.move = move;
state.change = {
x: move.x - start.x,
y: move.y - start.y,
x1: move.x1 - start.x1,
y1: move.y1 - start.y1,
};
// 缩放比例
state.scale =
distance(move.x, move.y, move.x1, move.y1) / distance(start.x, start.y, start.x1, start.y1);
state.scalePer =
distance(move.x, move.y, move.x1, move.y1) /
distance(moveCache.x, moveCache.y, moveCache.x1, moveCache.y1);
state.scaleV = state.scalePer / T;
// 旋转角度
state.rotate =
Math.atan2(move.y - move.y1, move.x - move.x1) - Math.atan2(start.y - start.y1, start.x - start.x1);
state.rotatePer =
Math.atan2(move.y - move.y1, move.x - move.x1) -
Math.atan2(moveCache.y - moveCache.y1, moveCache.x - moveCache.x1);
state.rotateV = state.rotatePer / T;
// 计算滑动速度
state.V = {
x: (move.x - moveCache.x) / T,
y: (move.y - moveCache.y) / T,
};
state.VCache.push(state.V);
if (state.VCache.length > 4) {
state.VCache.shift();
}
// state.rotate *= 180 / Math.PI
this.trigger('change', state.change, state, event);
this.trigger('changev2', { state, event });
state.moveCache = { ...state.move };
}
if (getFinger(event) === 1) {
state.action = TOUCH_ACTION.swipe;
state.move = move;
state.change = {
x: move.x - start.x,
y: move.y - start.y,
};
_this.trigger('change', state.change, state, event);
// 计算滑动速度
state.V = {
x: (move.x - moveCache.x) / T,
y: (move.y - moveCache.y) / T,
};
// 保留最近4个瞬时速度,以供消费
state.VCache.push(state.V);
if (state.VCache.length > 4) {
state.VCache.shift();
}
// 需要提供最后一次有效滑动方向
// 以及滑动速度
// 滑动
_this.trigger('changev2', {
state: state,
event: event
});
// todo,trigger传递的state,应该是不可变state,如果传递引用的话,会导致一些问题
this.trigger('change', state.change, state, event);
this.trigger('changev2', { state, event });
state.moveCache = state.move;
}
state.moveCache = state.move;
}
};
}
});
end = (event) => {
if (this._isDisable) return false;
_defineProperty(_assertThisInitialized(_this), "end", function (event) {
if (_this._isDisable) return false;
const { state, options } = this;
if (state.isMove) {
this.removePcEvents = this.ingorePcClick();
var _assertThisInitialize3 = _assertThisInitialized(_this),
state = _assertThisInitialize3.state,
options = _assertThisInitialize3.options;
if (state.isMove) {
_this.removePcEvents = _this.ingorePcClick();
} // 触发
state.nativeFingers = getFinger(event);
_this.trigger('finger:change', state.nativeFingers, state.finger);
_this.trigger('nativeEnd', event); // 只有当前手指个数小于预期个数才有触发touch end的必要
// 这么做的意义在哪里?监听事件可能会被重复触发?
if (state.nativeFingers < options.finger || !_config.isPhone) {
_this.touchend(event);
}
return false;
});
_defineProperty(_assertThisInitialized(_this), "touchend", function (event) {
var _assertThisInitialize4 = _assertThisInitialized(_this),
state = _assertThisInitialize4.state;
var isDone = false;
var timeout;
var done = function done() {
if (!isDone) {
clearTimeout(timeout);
isDone = true;
var scale = _this.state.scale;
_this.init();
_this.state.scale = scale;
_this.toggleActiveClass(false);
}
// 触发
state.nativeFingers = getFinger(event);
this.trigger('finger:change', state.nativeFingers, state.finger);
this.trigger('nativeEnd', event);
// 只有当前手指个数小于预期个数才有触发touch end的必要
// 这么做的意义在哪里?监听事件可能会被重复触发?
if (state.nativeFingers < options.finger || !isPhone) {
this.touchend(event);
}
return false;
};
}; // 避免安卓手机,滑动穿透到body上去
// 根据经验主义,如果滚动穿透到body,点击元素,就会把滚动移交给当前元素
touchend = (event) => {
const { state } = this;
let isDone = false;
let timeout;
const done = () => {
if (!isDone) {
clearTimeout(timeout);
isDone = true;
const { scale } = this.state;
this.init();
this.state.scale = scale;
this.toggleActiveClass(false);
}
};
// 避免安卓手机,滑动穿透到body上去
// 根据经验主义,如果滚动穿透到body,点击元素,就会把滚动移交给当前元素
if (state.directionLimit && state.directionLimit.scrollElement) {
state.directionLimit.scrollElement.click();
if (state.directionLimit && state.directionLimit.scrollElement) {
state.directionLimit.scrollElement.click();
} // 如果是无效滑动依然会在一定时间后执行done,但是没有在touchstart的时候clear定时器
// timeout = setTimeout(done, options.forceResetTime) // 可能由于种种原因导致应该执行done,但是没有执行,这里用来重置
if (state.enable && !state.freeze) {
state.freeze = true; // 冻结,不响应事件
_this.trigger('end', state.change, done, state, event); // 触发onEnd,等待初始化
_this.trigger('endv2', {
done: done,
state: state,
event: event
}); // 如果没有移动就立即终结
if (!state.direction || state.touchLimit) {
done();
}
// 如果是无效滑动依然会在一定时间后执行done,但是没有在touchstart的时候clear定时器
// timeout = setTimeout(done, options.forceResetTime) // 可能由于种种原因导致应该执行done,但是没有执行,这里用来重置
if (state.enable && !state.freeze) {
state.freeze = true; // 冻结,不响应事件
}
});
this.trigger('end', state.change, done, state, event); // 触发onEnd,等待初始化
this.trigger('endv2', { done, state, event });
// 如果没有移动就立即终结
if (!state.direction || state.touchLimit) {
done();
_this.$dom = $dom;
_this.options = _objectSpread({
finger: 1,
// 默认为单指
forceResetTime: 500,
// 强制reset时长
preventDefault: true,
// 阻止默认事件
stopPropagation: false,
// 是否冒泡
litenLeaveEvent: true,
// 是否监听leave事件
iosSystemSwipe: true,
XYWeight: 1,
ingoreTouchElement: 'ingoreTouchElement',
// 忽略touch事件的元素
canScrollElement: 'canScrollElement',
// 可滚动元素
listenerOptions: {},
// addEventListener options 处理capture/passive等
activeClassName: '',
// 触摸过程中为$dom添加的class
effectElements: []
}, _options);
_this.init();
_this.addEvents();
return _this;
} // 初始化
_createClass(Touch, [{
key: "toggleActiveClass",
value:
/**
* 在effectElements切换className
* @param {boolean} [addClass=true]
* @memberof Touch
*/
function toggleActiveClass() {
var addClass = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
var _this$options = this.options,
_this$options$effectE = _this$options.effectElements,
effectElements = _this$options$effectE === void 0 ? [] : _this$options$effectE,
activeClassName = _this$options.activeClassName;
if (activeClassName) {
[this.$dom].concat(_toConsumableArray(effectElements)).forEach(function (dom) {
dom instanceof window.HTMLElement && dom.classList.toggle(activeClassName, addClass);
});
}
}
}, {
key: "enable",
value: function enable() {
this._isDisable = false;
}
/**
* 阻止任何触摸滑动默认事件,阻止滑动冒泡事件
* @memberof Touch
*/
}, {
key: "disable",
value: function disable() {
this._isDisable = true;
}
}, {
key: "destroy",
value: function destroy() {
this.isDestroy = true;
this.removeEvents();
}
}, {
key: "getListenerOptions",
value: function getListenerOptions() {
return _objectSpread({
passive: false
}, this.options.listenerOptions);
}
}, {
key: "addEvents",
value: function addEvents() {
if (this.isDestroy || this.isAddEvent) return;
this.isAddEvent = true;
this.$dom.addEventListener(_config.touchstart, this.start, this.getListenerOptions());
this.$dom.addEventListener(_config.touchmove, this.move, this.getListenerOptions());
this.$dom.addEventListener(_config.touchend, this.end, this.getListenerOptions());
!_config.isPhone && this.options.litenLeaveEvent && this.$dom.addEventListener(_config.touchleave, this.end, {
passive: false
});
}
}, {
key: "removeEvents",
value: function removeEvents() {
this.$dom.removeEventListener(_config.touchstart, this.start);
this.$dom.removeEventListener(_config.touchmove, this.move);
this.$dom.removeEventListener(_config.touchend, this.end);
!_config.isPhone && this.options.litenLeaveEvent && this.$dom.removeEventListener(_config.touchleave, this.end);
this.isAddEvent = false;
}
}, {
key: "getPosition",
value: function getPosition(e) {
var _ref;
var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var x = _config.isPhone ? e.touches[index].clientX : e.clientX;
var y = _config.isPhone ? e.touches[index].clientY : e.clientY; // 使用相对位置
if (this.options.useRelativePos) {
var _this$$dom$getBoundin = this.$dom.getBoundingClientRect(),
left = _this$$dom$getBoundin.left,
top = _this$$dom$getBoundin.top;
x -= left;
y -= top;
}
return _ref = {}, _defineProperty(_ref, "x".concat(index || ''), x), _defineProperty(_ref, "y".concat(index || ''), y), _ref;
}
/**
* 因为有些元素可能是可以滚动的,所以只能在滚动到边界的时候才能触发touch事件监听
* @param {*} currentTarget
* @returns
* @memberof Touch
*/
}, {
key: "setTouchLimit",
value: function setTouchLimit(currentTarget) {
var options = this.options,
state = this.state;
if (options.canScrollElement) {
var scrollElement = _util["default"].parent(currentTarget, this.$dom, function (d) {
return d.classList.contains(options.canScrollElement);
});
if (scrollElement) {
var clientHeight = scrollElement.clientHeight,
scrollHeight = scrollElement.scrollHeight,
scrollTop = scrollElement.scrollTop;
if (scrollHeight != clientHeight) {
if (scrollTop == 0) {
// 顶部
state.directionLimit = {
direction: _config.TOUCH_DIRECTION.topToBottom,
only: 1,
scrollElement: scrollElement
};
} else if (Math.ceil(scrollTop) >= scrollHeight - clientHeight) {
// 底部
state.directionLimit = {
direction: _config.TOUCH_DIRECTION.topToBottom,
only: -1,
scrollElement: scrollElement
};
} else {
state.directionLimit = {
direction: _config.TOUCH_DIRECTION.topToBottom,
only: 0,
// 不限定滚动方向
scrollElement: scrollElement
};
}
}
}
};
}
}
/**
* 判断当前元素是否是可以忽略滑动监听
* @param {*} target
* @returns
* @memberof Touch
*/
}, {
key: "checkIsTouchIgnore",
value: function checkIsTouchIgnore(currentTarget) {
var ingoreTouchElement = this.options.ingoreTouchElement;
if (!Array.isArray(ingoreTouchElement)) {
ingoreTouchElement = [ingoreTouchElement];
}
var isIngnore = ingoreTouchElement.length && _util["default"].parent(currentTarget, this.$dom, function (d) {
return ingoreTouchElement.some(function (item) {
return d.classList.contains(item);
}) || getComputedStyle(d).overflowX === 'scroll';
}); // options.checkIsTouchIgnore 也可以校验是否可以滑动
return isIngnore || this.options.checkIsTouchIgnore && this.options.checkIsTouchIgnore(event);
}
/**
* 判断滑动方向是否受限
* @param {String} direction
* @param {Bumber} change
* @returns
* @memberof Touch
*/
}, {
key: "checkTouchLimit",
value: function checkTouchLimit(direction, change) {
var state = this.state;
var directionLimit = state.directionLimit; // 判断方向滑动方向是否一致 左右 上下 是否一致
if (directionLimit && directionLimit.direction === direction) {
// 如果<=0 表示,滑动动向相反
if (change * directionLimit.only <= 0) {
return true;
}
}
return this.options.checkTouchLimit && this.options.checkTouchLimit(direction, change);
}
}, {
key: "ingorePcClick",
value:
/**
* https://stackoverflow.com/questions/8643739/cancel-click-event-in-the-mouseup-event-handler/8927598

@@ -506,23 +662,27 @@ * 解决pc上mouseup事件结束后,click事件会触发的问题

*/
ingorePcClick() {
if (isPhone) return;
function ingorePcClick() {
if (_config.isPhone) return;
var remove;
let remove;
const handleClick = (e) => {
e.stopPropagation();
remove();
};
var handleClick = function handleClick(e) {
e.stopPropagation();
remove();
};
const option = {
capture: true,
};
var option = {
capture: true
};
remove = () => {
window.removeEventListener('click', handleClick, option);
};
remove = function remove() {
window.removeEventListener('click', handleClick, option);
};
window.addEventListener('click', handleClick, option);
window.addEventListener('click', handleClick, option);
return remove;
}
}]);
return remove;
}
}
return Touch;
}(_Event2["default"]);
exports["default"] = Touch;

@@ -1,36 +0,77 @@

export default class Event {
_cache = {};
"use strict";
on(name, callback) {
const { _cache } = this;
_cache[name] = _cache[name] || [];
if (callback) {
_cache[name].push(callback);
} else {
_cache[name].forEach((cb) => cb());
}
return this;
}
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
off(name, callback) {
const { _cache } = this;
if (!name) {
this._cache = {};
return this;
}
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
if (name && callback) {
_cache[name] = (_cache[name] || []).filter((cb) => cb !== callback);
return this;
}
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
_cache[name] = [];
return this;
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var Event = /*#__PURE__*/function () {
function Event() {
_classCallCheck(this, Event);
_defineProperty(this, "_cache", {});
}
_createClass(Event, [{
key: "on",
value: function on(name, callback) {
var _cache = this._cache;
_cache[name] = _cache[name] || [];
if (callback) {
_cache[name].push(callback);
} else {
_cache[name].forEach(function (cb) {
return cb();
});
}
return this;
}
}, {
key: "off",
value: function off(name, callback) {
var _cache = this._cache;
trigger(name, ...args) {
const { _cache } = this;
(_cache[name] || []).forEach((cb) => cb(...args));
if (!name) {
this._cache = {};
return this;
}
if (name && callback) {
_cache[name] = (_cache[name] || []).filter(function (cb) {
return cb !== callback;
});
return this;
}
_cache[name] = [];
return this;
}
}
}, {
key: "trigger",
value: function trigger(name) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
var _cache = this._cache;
(_cache[name] || []).forEach(function (cb) {
return cb.apply(void 0, args);
});
return this;
}
}]);
return Event;
}();
exports["default"] = Event;

@@ -0,1 +1,8 @@

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
/**

@@ -6,96 +13,89 @@ * 矩阵变换计算

*/
const M = {
// 矩阵 相乘计算
mm(M1, M2, LEN = 4) {
const m = [];
for (let i = 0; i < LEN; i++) {
for (let j = 0; j < LEN; j++) {
let ele = 0;
for (let z = 0; z < LEN; z++) {
ele += M1[i * LEN + z] * M2[j + LEN * z];
}
m.push(ele);
}
var M = {
// 矩阵 相乘计算
mm: function mm(M1, M2) {
var LEN = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4;
var m = [];
for (var i = 0; i < LEN; i++) {
for (var j = 0; j < LEN; j++) {
var ele = 0;
for (var z = 0; z < LEN; z++) {
ele += M1[i * LEN + z] * M2[j + LEN * z];
}
return m.map((i) => +i.toFixed(4));
},
mms(...args) {
return args.reduce((prev, current) => M.mm(current, prev));
},
// 旋转
rotate(R, m) {
// x轴旋转
// const RM = [
// 1, 0, 0, 0,
// 0, Math.cos(R), Math.sin(R), 0,
// 0, -Math.sin(R), Math.cos(R), 0,
// 0, 0, 0, 1,
// ]
// y轴旋转
// const RM = [
// Math.cos(R), 0, -Math.sin(R), 0,
// Math.sin(R), 0, Math.cos(R), 0,
// 0, 0, 1, 0,
// 0, 0, 0, 1,
// ]
m.push(ele);
}
}
// z轴旋转
// prettier-ignore
const RM = [
Math.cos(R), -Math.sin(R), 0, 0,
Math.sin(R), Math.cos(R), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
];
return m.map(function (i) {
return +i.toFixed(4);
});
},
mms: function mms() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return M.mm(RM, m);
},
// 缩放
scale(S, m) {
// prettier-ignore
const RM = [
S, 0, 0, 0,
0, S, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
];
return args.reduce(function (prev, current) {
return M.mm(current, prev);
});
},
// 旋转
rotate: function rotate(R, m) {
// x轴旋转
// const RM = [
// 1, 0, 0, 0,
// 0, Math.cos(R), Math.sin(R), 0,
// 0, -Math.sin(R), Math.cos(R), 0,
// 0, 0, 0, 1,
// ]
// y轴旋转
// const RM = [
// Math.cos(R), 0, -Math.sin(R), 0,
// Math.sin(R), 0, Math.cos(R), 0,
// 0, 0, 1, 0,
// 0, 0, 0, 1,
// ]
// z轴旋转
// prettier-ignore
var RM = [Math.cos(R), -Math.sin(R), 0, 0, Math.sin(R), Math.cos(R), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
return M.mm(RM, m);
},
// 缩放
scale: function scale(S, m) {
// prettier-ignore
var RM = [S, 0, 0, 0, 0, S, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
return M.mm(RM, m);
},
// 位移
translate: function translate(x, y, m) {
// const newM = [...m]
// newM[12] += x
// newM[13] += y
// return newM
// prettier-ignore
var RM = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x / m[0], y / m[0], 0, 1];
return M.mm(RM, m);
},
// 缩放位移矫正
trans: function trans(SCALE, current, origin, m) {
// 在这里,我们设置transform-origin: 0 0;然后所有的计算以图片的左上角为基准,这样方便计算位置变换后的位移
// 1. 计算出current中点相对于左上角的坐标
// 2. 根据缩放比例,计算出中点坐标的相对位移
// 3. 矩阵 -> 缩放后矩阵 -> 位移矫正
var p = {
x: (current.x + current.x1) / 2 - (origin.left + m[12]),
y: (current.y + current.y1) / 2 - (origin.top + m[13])
}; // 计算位移
return M.mm(RM, m);
},
// 位移
translate(x, y, m) {
// const newM = [...m]
// newM[12] += x
// newM[13] += y
// return newM
// prettier-ignore
const RM = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
x / m[0], y / m[0], 0, 1
];
return M.mm(RM, m);
},
// 缩放位移矫正
trans(SCALE, current, origin, m) {
// 在这里,我们设置transform-origin: 0 0;然后所有的计算以图片的左上角为基准,这样方便计算位置变换后的位移
// 1. 计算出current中点相对于左上角的坐标
// 2. 根据缩放比例,计算出中点坐标的相对位移
// 3. 矩阵 -> 缩放后矩阵 -> 位移矫正
const p = {
x: (current.x + current.x1) / 2 - (origin.left + m[12]),
y: (current.y + current.y1) / 2 - (origin.top + m[13]),
};
// 计算位移
const newP = {
x: -p.x * (SCALE - 1),
y: -p.y * (SCALE - 1),
};
return M.translate(newP.x, newP.y, m);
},
var newP = {
x: -p.x * (SCALE - 1),
y: -p.y * (SCALE - 1)
};
return M.translate(newP.x, newP.y, m);
}
};
export default M;
var _default = M;
exports["default"] = _default;

@@ -1,8 +0,58 @@

import TouchEvent from './core';
import Event from './Event';
import { TOUCH_DIRECTION, isPC } from './config';
import util from './util';
import Tap from './Tap';
import { Transform } from './BetterM';
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _core = _interopRequireDefault(require("./core"));
var _Event2 = _interopRequireDefault(require("./Event"));
var _config = require("./config");
var _util = _interopRequireDefault(require("./util"));
var _Tap = _interopRequireDefault(require("./Tap"));
var _BetterM = require("./BetterM");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/**

@@ -16,197 +66,305 @@ * 获取X,Y轴上的变更,对于没有scale == 1的元素,需要对滑动变更进行锁定

function getChangeXY(change, state) {
if (state.scale == 1) {
if (state.direction === TOUCH_DIRECTION.leftToRight) {
return [change.x, 0];
}
if (state.direction === TOUCH_DIRECTION.topToBottom) {
return [0, change.y];
}
if (state.scale == 1) {
if (state.direction === _config.TOUCH_DIRECTION.leftToRight) {
return [change.x, 0];
}
return [change.x, change.y];
if (state.direction === _config.TOUCH_DIRECTION.topToBottom) {
return [0, change.y];
}
}
return [change.x, change.y];
}
export default class Pinch extends Event {
// 被缩放对象是否需要加载
isLoad = false; // 是否可以立即开启
var Pinch = /*#__PURE__*/function (_Event) {
_inherits(Pinch, _Event);
constructor(
$eventDom, // 事件监听元素
$transformDom = $eventDom, // 被缩放元素
/** @type {{maxScale: number, minScale: number, canPinch: boolean, toggleScale: number, $borderCheckDom: HTMLElement, disableBorderCheck: boolean }} */
option = {}
) {
super();
const {
$borderCheckDom = $eventDom, // 边界校验元素
canPinch = true, // 是否可缩放
maxScale = 1,
minScale = 1,
} = option;
this.option = option;
this.canPinch = canPinch;
this.maxScale = maxScale;
this.minScale = minScale;
$transformDom.style.cssText += ';transform-origin: left top; will-change: transform;';
var _super = _createSuper(Pinch);
this.$eventDom = $eventDom;
this.$transformDom = $transformDom;
this.$borderCheckDom = $borderCheckDom;
// 被缩放对象是否需要加载
// 是否可以立即开启
function Pinch(_$eventDom) {
var _this;
// 需要处理是否是图片,是否需要加载的问题
if ($transformDom.tagName.toLowerCase() === 'img') {
this.updateInfo($transformDom);
$transformDom.$$pinch = this;
} else {
this.isLoad = true;
}
this.origin = util.getOrigin(this.$transformDom);
// 未加载,允许左右移动,不允许缩放图片
this.baseOrigin = util.getOrigin(this.$borderCheckDom);
this.addEvents();
var _$transformDom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _$eventDom;
// 矩阵变换逻辑在此
this.trans = new Transform();
var option = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
// 页面resize时,重置baseinfo
if (isPC) {
window.addEventListener('resize', this.setBaseInfo);
this.removeResize = window.removeEventListener('resize', this.setBaseInfo);
}
_classCallCheck(this, Pinch);
_this = _super.call(this);
_defineProperty(_assertThisInitialized(_this), "isLoad", false);
_defineProperty(_assertThisInitialized(_this), "setBaseInfo", function () {
var $img = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.$transformDom;
_this.origin = _util["default"].getOrigin(_this.$transformDom);
_this.baseOrigin = _util["default"].getOrigin(_this.$borderCheckDom);
_this.naturalWidth = $img.naturalWidth;
_this.maxScale = Math.max(_this.naturalWidth / _this.origin.width, _this.maxScale);
});
_defineProperty(_assertThisInitialized(_this), "updateInfo", function () {
var $img = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.$transformDom;
var load = function load() {
$img.removeEventListener('load', load);
if (_this.isDestroy) return; // 图片加载成功,不代表一定可以获取到图片的rect信息,
// 因此这里做个延迟判断,足以覆盖大多数情况,从严谨的角度来讲,可以直接根据img.naturalWidth/Height算出来
_this.timeout = setTimeout(function () {
_this.setBaseInfo();
_this.isLoad = true;
}, 100);
};
$img.addEventListener('load', load);
$img.src = $img.src || $img.originSrc;
if ($img.complete || $img.width || $img.height) {
load();
}
});
_defineProperty(_assertThisInitialized(_this), "timeout", null);
_defineProperty(_assertThisInitialized(_this), "animation", function () {
var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0.4;
var fn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
_this.touch.state.scale = _this.trans.getScale();
var _assertThisInitialize = _assertThisInitialized(_this),
$transformDom = _assertThisInitialize.$transformDom,
$eventDom = _assertThisInitialize.$eventDom; // 也可以使用js动画来控制
_util["default"].transition([$transformDom], time);
$transformDom.clientHeight;
$transformDom.style.cssText += _this.trans.toCss();
clearTimeout(_this.timeout);
var animationEnd = function animationEnd() {
clearTimeout(_this.timeout);
_util["default"].transition([$transformDom, $eventDom]);
fn && fn();
};
_this.animationEnd = animationEnd;
_this.timeout = setTimeout(animationEnd, time * 1000);
return _assertThisInitialized(_this);
});
_defineProperty(_assertThisInitialized(_this), "toggle", function (center) {
if (!_this.isLoad) {
return;
}
var _assertThisInitialize2 = _assertThisInitialized(_this),
minScale = _assertThisInitialize2.minScale,
origin = _assertThisInitialize2.origin;
var initS = _this.trans.getScale();
if (initS > minScale) {
// 此处可选择恢复初始状态或者缩放回原始比例
// this.trans.scale(minScale / initS, center, origin)
_this.trans.reset();
} else {
var _assertThisInitialize3 = _assertThisInitialized(_this),
maxScale = _assertThisInitialize3.maxScale;
var _this$option$toggleSc = _this.option.toggleScale,
toggleScale = _this$option$toggleSc === void 0 ? 1.5 : _this$option$toggleSc; // 双击默认比例
var dbClickScale = Math.min(maxScale, toggleScale);
_this.trans.scale(dbClickScale / initS, center, origin);
}
_this.borderCheck(_this.origin, _this.baseOrigin);
_this.animation();
});
var _option$$borderCheckD = option.$borderCheckDom,
$borderCheckDom = _option$$borderCheckD === void 0 ? _$eventDom : _option$$borderCheckD,
_option$canPinch = option.canPinch,
canPinch = _option$canPinch === void 0 ? true : _option$canPinch,
_option$maxScale = option.maxScale,
_maxScale = _option$maxScale === void 0 ? 1 : _option$maxScale,
_option$minScale = option.minScale,
_minScale = _option$minScale === void 0 ? 1 : _option$minScale;
_this.option = option;
_this.canPinch = canPinch;
_this.maxScale = _maxScale;
_this.minScale = _minScale;
_$transformDom.style.cssText += ';transform-origin: left top; will-change: transform;';
_this.$eventDom = _$eventDom;
_this.$transformDom = _$transformDom;
_this.$borderCheckDom = $borderCheckDom; // 需要处理是否是图片,是否需要加载的问题
if (_$transformDom.tagName.toLowerCase() === 'img') {
_this.updateInfo(_$transformDom);
_$transformDom.$$pinch = _assertThisInitialized(_this);
} else {
_this.isLoad = true;
}
setBaseInfo = ($img = this.$transformDom) => {
this.origin = util.getOrigin(this.$transformDom);
this.baseOrigin = util.getOrigin(this.$borderCheckDom);
this.naturalWidth = $img.naturalWidth;
this.maxScale = Math.max(this.naturalWidth / this.origin.width, this.maxScale);
};
_this.origin = _util["default"].getOrigin(_this.$transformDom); // 未加载,允许左右移动,不允许缩放图片
// 获取图片信息
updateInfo = ($img = this.$transformDom) => {
const load = () => {
$img.removeEventListener('load', load);
if (this.isDestroy) return;
// 图片加载成功,不代表一定可以获取到图片的rect信息,
// 因此这里做个延迟判断,足以覆盖大多数情况,从严谨的角度来讲,可以直接根据img.naturalWidth/Height算出来
this.timeout = setTimeout(() => {
this.setBaseInfo();
this.isLoad = true;
}, 100);
};
$img.addEventListener('load', load);
$img.src = $img.src || $img.originSrc;
if ($img.complete || $img.width || $img.height) {
load();
_this.baseOrigin = _util["default"].getOrigin(_this.$borderCheckDom);
_this.addEvents(); // 矩阵变换逻辑在此
_this.trans = new _BetterM.Transform(); // 页面resize时,重置baseinfo
if (_config.isPC) {
window.addEventListener('resize', _this.setBaseInfo);
_this.removeResize = window.removeEventListener('resize', _this.setBaseInfo);
}
return _this;
}
_createClass(Pinch, [{
key: "addEvents",
value: function addEvents() {
var _this2 = this;
var baseM = [];
this.touch = new _core["default"](this.$eventDom, {
finger: 2,
preventDefault: true,
XYWeight: 2 // x 相对于 y 的权重比例
}) // onStart之前执行
.on('nativeStart', function () {
_this2.trigger('nativeStart'); // 立即终结动画
_this2.animationEnd && _this2.animationEnd();
}).on('startv2', function () {
_this2.trigger('start');
baseM = _this2.trans.snap();
}).on('changev2', function (_ref) {
var state = _ref.state;
var change = state.change;
if (state.finger >= 2) {
if (_this2.isLoad && _this2.canPinch) {
_this2.trans.scale(state.scale, state.move, _this2.origin, baseM);
}
} else {
var _getChangeXY = getChangeXY(change, state),
_getChangeXY2 = _slicedToArray(_getChangeXY, 2),
changeX = _getChangeXY2[0],
changeY = _getChangeXY2[1]; // 单指拖拽
_this2.trans.translate(changeX, changeY, baseM);
var result = _this2.borderCheck(_this2.origin, _this2.baseOrigin); // if (state.finger == 1 && result.isOver) {
// baseM = this.trans.snap()
// // = result.m;
// }
// // 如果元素可以内部滚动,那么不应当可以随意触发change事件
// // 应当在用户有意识的触发change事件时,才触发。避免弹窗关闭的过于敏感
// // 目前的应用场景主要在图片预览组件
if (state.finger == 1 && result.isBigger && !result.isOver) {
state.dontTriggerChange = true;
}
if (result.isOver && !state.dontTriggerChange) {
_this2.trigger('change', result, state); // 触发变化
}
}
};
addEvents() {
let baseM = [];
this.touch = new TouchEvent(this.$eventDom, {
finger: 2,
preventDefault: true,
XYWeight: 2, // x 相对于 y 的权重比例
})
// onStart之前执行
.on('nativeStart', () => {
this.trigger('nativeStart');
// 立即终结动画
this.animationEnd && this.animationEnd();
})
.on('startv2', () => {
this.trigger('start');
baseM = this.trans.snap();
})
.on('changev2', ({ state }) => {
const { change } = state;
if (state.finger >= 2) {
if (this.isLoad && this.canPinch) {
this.trans.scale(state.scale, state.move, this.origin, baseM);
}
} else {
const [changeX, changeY] = getChangeXY(change, state);
// 单指拖拽
this.trans.translate(changeX, changeY, baseM);
const result = this.borderCheck(this.origin, this.baseOrigin);
// if (state.finger == 1 && result.isOver) {
// baseM = this.trans.snap()
// // = result.m;
// }
_util["default"].RAF(function () {
// 触摸点大于2
_this2.$transformDom.style.cssText += _this2.trans.toCss();
});
}).on('endv2', function (_ref2) {
var done = _ref2.done,
state = _ref2.state;
var change = state.change;
// // 如果元素可以内部滚动,那么不应当可以随意触发change事件
// // 应当在用户有意识的触发change事件时,才触发。避免弹窗关闭的过于敏感
// // 目前的应用场景主要在图片预览组件
if (state.finger == 1 && result.isBigger && !result.isOver) {
state.dontTriggerChange = true;
}
_util["default"].RAF(function () {
done();
if (!state.isMove) return;
if (result.isOver && !state.dontTriggerChange) {
this.trigger('change', result, state); // 触发变化
}
}
util.RAF(() => {
// 触摸点大于2
this.$transformDom.style.cssText += this.trans.toCss();
});
})
.on('endv2', ({ done, state }) => {
const { change } = state;
util.RAF(() => {
done();
if (!state.isMove) return;
if (state.finger >= 2) {
if (this.isLoad && this.canPinch && state.isMove) {
// 最大缩放比例校验
if (this.trans.getScale() > this.maxScale) {
const PER = this.maxScale / this.trans.getScale();
this.trans.scale(PER, state.move, this.origin);
}
} else {
return;
}
} else {
const K = 20000; // 滑动系数
const speed = state.VCache.reduce(
(prev, current) => {
prev.x += current.x;
prev.y += current.y;
return prev;
},
{ x: 0, y: 0 }
);
let [finalVX, finalVY] = state.VCache.length
? [(speed.x * K) / state.VCache.length, (speed.y * K) / state.VCache.length]
: [0, 0];
if (state.finger >= 2) {
if (_this2.isLoad && _this2.canPinch && state.isMove) {
// 最大缩放比例校验
if (_this2.trans.getScale() > _this2.maxScale) {
var PER = _this2.maxScale / _this2.trans.getScale();
// 避免抖动
if (Math.abs(finalVX) < 20 && Math.abs(finalVY) < 20) {
finalVX = 0;
finalVY = 0;
}
const [changeX, changeY] = getChangeXY(
{
x: change.x + finalVX,
y: change.y + finalVY,
},
state
);
// 单指拖拽
this.trans.translate(changeX, changeY, baseM);
}
_this2.trans.scale(PER, state.move, _this2.origin);
}
} else {
return;
}
} else {
var K = 20000; // 滑动系数
// 边界校验
const result = this.borderCheck(this.origin, this.baseOrigin, { minScale: this.minScale });
const ANIMATION_TIME = state.nativeFingers >= state.finger ? 0 : 0.4;
// 只有移动才有触发动画的必要【溢出,或者缩小了】
this.animation(ANIMATION_TIME);
var speed = state.VCache.reduce(function (prev, current) {
prev.x += current.x;
prev.y += current.y;
return prev;
}, {
x: 0,
y: 0
});
// 单指触发才有回调的意义
if (state.finger == 1 && result.isOver && !state.dontTriggerChange) {
this.trigger('end', result, state, this);
}
});
});
this.canPinch && this.enablePinch();
var _ref3 = state.VCache.length ? [speed.x * K / state.VCache.length, speed.y * K / state.VCache.length] : [0, 0],
_ref4 = _slicedToArray(_ref3, 2),
finalVX = _ref4[0],
finalVY = _ref4[1]; // 避免抖动
if (Math.abs(finalVX) < 20 && Math.abs(finalVY) < 20) {
finalVX = 0;
finalVY = 0;
}
var _getChangeXY3 = getChangeXY({
x: change.x + finalVX,
y: change.y + finalVY
}, state),
_getChangeXY4 = _slicedToArray(_getChangeXY3, 2),
changeX = _getChangeXY4[0],
changeY = _getChangeXY4[1]; // 单指拖拽
_this2.trans.translate(changeX, changeY, baseM);
} // 边界校验
var result = _this2.borderCheck(_this2.origin, _this2.baseOrigin, {
minScale: _this2.minScale
});
var ANIMATION_TIME = state.nativeFingers >= state.finger ? 0 : 0.4; // 只有移动才有触发动画的必要【溢出,或者缩小了】
_this2.animation(ANIMATION_TIME); // 单指触发才有回调的意义
if (state.finger == 1 && result.isOver && !state.dontTriggerChange) {
_this2.trigger('end', result, state, _this2);
}
});
});
this.canPinch && this.enablePinch();
}
/**

@@ -220,123 +378,125 @@ * 边界校验

*/
borderCheck(o = {}, b = {}, { minScale = 1, maxScale = Infinity } = {}) {
if (this.option.disableBorderCheck) {
return {
x: 0, // X轴溢出距离
y: 0, // Y轴溢出距离
isOver: false, // 是否溢出
isBigger: false, // 被缩放对象是否大于边界尺寸
};
}
let S = this.trans.getScale();
// 处理旋转带来的宽高交换
// let rotate = this.trans.state.rotate
// if (Math.floor(Math.PI / rotate + 1) % 2 == 0) {
}, {
key: "borderCheck",
value: function borderCheck() {
var o = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
// }
var _ref5 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
_ref5$minScale = _ref5.minScale,
minScale = _ref5$minScale === void 0 ? 1 : _ref5$minScale,
_ref5$maxScale = _ref5.maxScale,
maxScale = _ref5$maxScale === void 0 ? Infinity : _ref5$maxScale;
// 如果缩放倍数小于1,还原到1
const defaultCenter = {
x: o.width / 2,
x1: o.width / 2,
y: o.height / 2,
y1: o.height / 2,
if (this.option.disableBorderCheck) {
return {
x: 0,
// X轴溢出距离
y: 0,
// Y轴溢出距离
isOver: false,
// 是否溢出
isBigger: false // 被缩放对象是否大于边界尺寸
};
if (S < minScale) {
this.trans.scale(minScale / S, defaultCenter, o);
} else if (S > maxScale) {
this.trans.scale(maxScale / S, defaultCenter, o);
}
}
S = this.trans.getScale();
var S = this.trans.getScale(); // 处理旋转带来的宽高交换
// let rotate = this.trans.state.rotate
// if (Math.floor(Math.PI / rotate + 1) % 2 == 0) {
// }
// 如果缩放倍数小于1,还原到1
let maxTLR = 0;
let minTLR = 0;
let maxTUD = 0;
let minTUD = 0;
var defaultCenter = {
x: o.width / 2,
x1: o.width / 2,
y: o.height / 2,
y1: o.height / 2
};
// 缩放后大于基础校验宽度
if (o.width * S > b.width) {
maxTLR = b.left - o.left; // 因为transform-origin为left
minTLR = maxTLR - (o.width * S - b.width); // 宽度差
} else {
maxTLR = minTLR = ((1 - S) * o.width) / 2; // 反则就以缩放元素的中心缩放
}
if (S < minScale) {
this.trans.scale(minScale / S, defaultCenter, o);
} else if (S > maxScale) {
this.trans.scale(maxScale / S, defaultCenter, o);
}
if (o.height * S > b.height) {
maxTUD = b.top - o.top;
minTUD = maxTUD - (o.height * S - b.height);
} else {
maxTUD = minTUD = ((1 - S) * o.height) / 2; // 反则就以缩放元素的中心缩放
}
S = this.trans.getScale();
var maxTLR = 0;
var minTLR = 0;
var maxTUD = 0;
var minTUD = 0; // 缩放后大于基础校验宽度
// 获取最大,最小位移
const [x, y] = this.trans.getTranslate();
const newX = Math.max(minTLR, Math.min(maxTLR, x));
const newY = Math.max(minTUD, Math.min(maxTUD, y));
if (o.width * S > b.width) {
maxTLR = b.left - o.left; // 因为transform-origin为left
// newM为校正后的矩阵,
const X = newX - x;
const Y = newY - y;
minTLR = maxTLR - (o.width * S - b.width); // 宽度差
} else {
maxTLR = minTLR = (1 - S) * o.width / 2; // 反则就以缩放元素的中心缩放
}
this.trans.translate(X, Y);
return {
x: -X, // X轴溢出距离
y: -Y, // Y轴溢出距离
isOver: X !== 0 || Y !== 0, // 是否溢出
isBigger: o.width * S > b.width || o.height * S > b.height, // 被缩放对象是否大于边界尺寸
};
}
if (o.height * S > b.height) {
maxTUD = b.top - o.top;
minTUD = maxTUD - (o.height * S - b.height);
} else {
maxTUD = minTUD = (1 - S) * o.height / 2; // 反则就以缩放元素的中心缩放
} // 获取最大,最小位移
disablePinch() {
this.canPinch = false;
this.tap && this.tap.destroy();
}
enablePinch() {
this.canPinch = true;
this.tap && this.tap.destroy();
// 双击放大
this.tap = new Tap(this.$eventDom, 600)
.on(2, (event) => {
const t = event.changedTouches ? event.changedTouches[0] : event;
const center = {
x: t.clientX,
y: t.clientY,
x1: t.clientX,
y1: t.clientY,
};
this.toggle(center);
})
.on(1, () => {
this.trans.getScale() == 1 && this.trigger('close');
});
var _this$trans$getTransl = this.trans.getTranslate(),
_this$trans$getTransl2 = _slicedToArray(_this$trans$getTransl, 2),
x = _this$trans$getTransl2[0],
y = _this$trans$getTransl2[1];
var newX = Math.max(minTLR, Math.min(maxTLR, x));
var newY = Math.max(minTUD, Math.min(maxTUD, y)); // newM为校正后的矩阵,
var X = newX - x;
var Y = newY - y;
this.trans.translate(X, Y);
return {
x: -X,
// X轴溢出距离
y: -Y,
// Y轴溢出距离
isOver: X !== 0 || Y !== 0,
// 是否溢出
isBigger: o.width * S > b.width || o.height * S > b.height // 被缩放对象是否大于边界尺寸
};
}
}, {
key: "disablePinch",
value: function disablePinch() {
this.canPinch = false;
this.tap && this.tap.destroy();
}
}, {
key: "enablePinch",
value: function enablePinch() {
var _this3 = this;
timeout = null;
this.canPinch = true;
this.tap && this.tap.destroy(); // 双击放大
// 执行动画
animation = (time = 0.4, fn = () => {}) => {
this.touch.state.scale = this.trans.getScale();
const { $transformDom, $eventDom } = this;
// 也可以使用js动画来控制
util.transition([$transformDom], time);
$transformDom.clientHeight;
$transformDom.style.cssText += this.trans.toCss();
clearTimeout(this.timeout);
const animationEnd = () => {
clearTimeout(this.timeout);
util.transition([$transformDom, $eventDom]);
fn && fn();
this.tap = new _Tap["default"](this.$eventDom, 600).on(2, function (event) {
var t = event.changedTouches ? event.changedTouches[0] : event;
var center = {
x: t.clientX,
y: t.clientY,
x1: t.clientX,
y1: t.clientY
};
this.animationEnd = animationEnd;
this.timeout = setTimeout(animationEnd, time * 1000);
return this;
};
rotate(R) {
this.trans.rotate(R, this.origin);
this.animation();
_this3.toggle(center);
}).on(1, function () {
_this3.trans.getScale() == 1 && _this3.trigger('close');
});
}
}, {
key: "rotate",
value: function rotate(R) {
this.trans.rotate(R, this.origin);
this.animation();
}
/**

@@ -347,47 +507,50 @@ * 放大缩小切换

*/
toggle = (center) => {
if (!this.isLoad) {
return;
}
const { minScale, origin } = this;
const initS = this.trans.getScale();
if (initS > minScale) {
// 此处可选择恢复初始状态或者缩放回原始比例
// this.trans.scale(minScale / initS, center, origin)
this.trans.reset();
} else {
const { maxScale } = this;
const { toggleScale = 1.5 } = this.option; // 双击默认比例
const dbClickScale = Math.min(maxScale, toggleScale);
this.trans.scale(dbClickScale / initS, center, origin);
}
this.borderCheck(this.origin, this.baseOrigin);
this.animation();
};
// 销毁
destroy() {
[this.tap, this.touch].filter((i) => i).forEach((i) => i.destroy());
this.isDestroy = true;
if (this.$transformDom) {
this.$transformDom.style.cssText += ';transform: none;';
}
}, {
key: "destroy",
value: // 销毁
function destroy() {
[this.tap, this.touch].filter(function (i) {
return i;
}).forEach(function (i) {
return i.destroy();
});
this.isDestroy = true;
if (this.removeResize) {
this.removeResize();
}
if (this.$transformDom) {
this.$transformDom.style.cssText += ';transform: none;';
}
return this;
}
if (this.removeResize) {
this.removeResize();
}
// 开启
enable() {
[this.tap, this.touch].filter((i) => i).forEach((i) => i.enable());
return this;
return this;
} // 开启
}, {
key: "enable",
value: function enable() {
[this.tap, this.touch].filter(function (i) {
return i;
}).forEach(function (i) {
return i.enable();
});
return this;
}
}, {
key: "disable",
value: function disable() {
[this.tap, this.touch].filter(function (i) {
return i;
}).forEach(function (i) {
return i.disable();
});
return this;
}
}]);
disable() {
[this.tap, this.touch].filter((i) => i).forEach((i) => i.disable());
return this;
}
}
return Pinch;
}(_Event2["default"]);
exports["default"] = Pinch;

@@ -1,9 +0,53 @@

import Event from './Event';
"use strict";
import { touchstart, touchmove, touchend } from './config';
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _Event2 = _interopRequireDefault(require("./Event"));
var _config = require("./config");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function getTouch(event) {
return event.touches ? event.touches[0] : event;
return event.touches ? event.touches[0] : event;
}
/**

@@ -15,121 +59,167 @@ * 监听双击/点击/长按事件

*/
class Tap extends Event {
constructor($ele, TIME = 300, longTime = TIME) {
super();
this.$ele = $ele;
this.TIME = TIME;
this.longTime = Math.max(longTime, TIME);
this.reset();
this._addEvents();
}
reset() {
this.state = {
clickRecord: [],
recording: false,
first: false,
};
}
_touchstart = (event) => {
clearTimeout(this._timeout);
const { state } = this;
const touch = getTouch(event);
state.clickRecord.push({
start: Date.now(),
x: touch.clientX,
y: touch.clientY,
});
state.recording = true;
};
var Tap = /*#__PURE__*/function (_Event) {
_inherits(Tap, _Event);
_touchmove = () => {
this.state.recording = false;
};
var _super = _createSuper(Tap);
_touchend = (event) => {
const { state, TIME } = this;
// 得到连续点击次数,判断有没有比当前连续点击次数更大的事件监听,如果有就setTimeout,没有立即执行
// 在下次touchstart的时候,清除所有setTimeout,因为按理说你已经执行了
if (state.recording) {
const lastItem = state.clickRecord[state.clickRecord.length - 1];
const endTime = Date.now();
lastItem.end = endTime;
// 处理长按事件
if (lastItem.end - lastItem.start >= this.longTime) {
this.trigger('long', event);
this.reset();
return;
}
function Tap($ele) {
var _this;
const clickedTimes = state.clickRecord.length;
var _TIME = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 300;
// 判断点击位置是否稳定
if (state.clickRecord.length > 1) {
const isPositionStable = state.clickRecord.slice(0, -1).every((item, index) => {
const next = state.clickRecord[index + 1];
return Math.abs(item.x - next.x) < 10 && Math.abs(item.y - next.y) < 10;
});
if (!isPositionStable) {
this.reset();
return;
}
}
var longTime = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _TIME;
// 有一个问题,如果click dbclick,那么dbclick也会触发两次click
// 这不是我们想要的,因此我们拿到监听click事件做次数
// 过滤long也就是非数字key
const keys = Object.keys(this._cache)
.filter((i) => /\d+/.test(i))
.map((i) => +i);
const maxListenClickNums = Math.max(...keys);
_classCallCheck(this, Tap);
if (clickedTimes === maxListenClickNums) {
this.trigger(clickedTimes, event);
this.reset();
} else {
this._timeout = setTimeout(() => {
this.trigger(clickedTimes, event);
this.reset();
}, TIME);
}
_this = _super.call(this);
_defineProperty(_assertThisInitialized(_this), "_touchstart", function (event) {
clearTimeout(_this._timeout);
var _assertThisInitialize = _assertThisInitialized(_this),
state = _assertThisInitialize.state;
var touch = getTouch(event);
state.clickRecord.push({
start: Date.now(),
x: touch.clientX,
y: touch.clientY
});
state.recording = true;
});
_defineProperty(_assertThisInitialized(_this), "_touchmove", function () {
_this.state.recording = false;
});
_defineProperty(_assertThisInitialized(_this), "_touchend", function (event) {
var _assertThisInitialize2 = _assertThisInitialized(_this),
state = _assertThisInitialize2.state,
TIME = _assertThisInitialize2.TIME; // 得到连续点击次数,判断有没有比当前连续点击次数更大的事件监听,如果有就setTimeout,没有立即执行
// 在下次touchstart的时候,清除所有setTimeout,因为按理说你已经执行了
if (state.recording) {
var lastItem = state.clickRecord[state.clickRecord.length - 1];
var endTime = Date.now();
lastItem.end = endTime; // 处理长按事件
if (lastItem.end - lastItem.start >= _this.longTime) {
_this.trigger('long', event);
_this.reset();
return;
}
var clickedTimes = state.clickRecord.length; // 判断点击位置是否稳定
if (state.clickRecord.length > 1) {
var isPositionStable = state.clickRecord.slice(0, -1).every(function (item, index) {
var next = state.clickRecord[index + 1];
return Math.abs(item.x - next.x) < 10 && Math.abs(item.y - next.y) < 10;
});
if (!isPositionStable) {
_this.reset();
return;
}
} // 有一个问题,如果click dbclick,那么dbclick也会触发两次click
// 这不是我们想要的,因此我们拿到监听click事件做次数
// 过滤long也就是非数字key
var keys = Object.keys(_this._cache).filter(function (i) {
return /\d+/.test(i);
}).map(function (i) {
return +i;
});
var maxListenClickNums = Math.max.apply(Math, _toConsumableArray(keys));
if (clickedTimes === maxListenClickNums) {
_this.trigger(clickedTimes, event);
_this.reset();
} else {
this.reset();
_this._timeout = setTimeout(function () {
_this.trigger(clickedTimes, event);
_this.reset();
}, TIME);
}
};
} else {
_this.reset();
}
});
_addEvents() {
if (this.isDestroy) return;
const { $ele } = this;
$ele.addEventListener(touchstart, this._touchstart);
$ele.addEventListener(touchmove, this._touchmove);
$ele.addEventListener(touchend, this._touchend);
}
_this.$ele = $ele;
_this.TIME = _TIME;
_this.longTime = Math.max(longTime, _TIME);
_removeEvents() {
const { $ele } = this;
$ele.removeEventListener(touchstart, this._touchstart);
$ele.removeEventListener(touchmove, this._touchmove);
$ele.removeEventListener(touchend, this._touchend);
_this.reset();
_this._addEvents();
return _this;
}
_createClass(Tap, [{
key: "reset",
value: function reset() {
this.state = {
clickRecord: [],
recording: false,
first: false
};
}
}, {
key: "_addEvents",
value: function _addEvents() {
if (this.isDestroy) return;
var $ele = this.$ele;
$ele.addEventListener(_config.touchstart, this._touchstart);
$ele.addEventListener(_config.touchmove, this._touchmove);
$ele.addEventListener(_config.touchend, this._touchend);
}
}, {
key: "_removeEvents",
value: function _removeEvents() {
var $ele = this.$ele;
$ele.removeEventListener(_config.touchstart, this._touchstart);
$ele.removeEventListener(_config.touchmove, this._touchmove);
$ele.removeEventListener(_config.touchend, this._touchend);
}
}, {
key: "enable",
value: function enable() {
if (this._isDisable) {
this._isDisable = false;
enable() {
if (this._isDisable) {
this._isDisable = false;
this._addEvents();
}
this._addEvents();
}
}
}, {
key: "disable",
value: function disable() {
this._isDisable = true;
disable() {
this._isDisable = true;
this._removeEvents();
this._removeEvents();
}
}, {
key: "destroy",
value: function destroy() {
this.isDestroy = true;
this.off();
destroy() {
this.isDestroy = true;
this.off();
this._removeEvents();
this._removeEvents();
}
}
}]);
export default Tap;
return Tap;
}(_Event2["default"]);
var _default = Tap;
exports["default"] = _default;

@@ -0,144 +1,227 @@

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
// 小工具
export default {
classname(...anys) {
const classes = [];
const getType = (any) =>
Object.prototype.toString
.call(any)
.match(/([^\s]+)]$/)[1]
.toLowerCase();
const handle = (any) => {
switch (getType(any)) {
case 'string':
case 'number':
classes.push(any);
break;
case 'array':
any.forEach(handle);
break;
case 'object':
Object.keys(any).forEach((key) => {
any[key] && classes.push(key);
});
break;
default:
break;
}
};
var _default = {
classname: function classname() {
var classes = [];
anys.forEach(handle);
var getType = function getType(any) {
return Object.prototype.toString.call(any).match(/([^\s]+)]$/)[1].toLowerCase();
};
return classes.join(' ');
},
/**
* 获取指定的父级元素
* @param {*} child
* @param {*} [root=document.body]
* @param {*} fn
* @returns {HTMLElement}
*/
parent(child, root = document.body, fn) {
let parent = child;
while (parent && parent !== root) {
const result = parent instanceof HTMLElement && fn(parent);
if (result) {
return parent;
}
parent = parent.parentElement;
}
return null;
},
style($dom, styles) {
$dom.style.cssText += styles;
},
Timeout: class {
queue = [];
var handle = function handle(any) {
switch (getType(any)) {
case 'string':
case 'number':
classes.push(any);
break;
add(fn, time) {
if (time > 0) {
let t;
const item = (exec = true) => {
clearTimeout(t);
exec && fn();
};
t = setTimeout(() => {
fn();
this.queue = this.queue.filter((i) => i !== item);
}, time);
this.queue.push(item);
} else {
fn();
}
return this;
}
case 'array':
any.forEach(handle);
break;
clear() {
this.queue.forEach((i) => i(false));
this.queue = [];
return this;
}
case 'object':
Object.keys(any).forEach(function (key) {
any[key] && classes.push(key);
});
break;
done() {
this.queue.forEach((i) => i());
this.queue = [];
return this;
}
},
setTimeout(fn = () => {}, time = 0) {
default:
break;
}
};
for (var _len = arguments.length, anys = new Array(_len), _key = 0; _key < _len; _key++) {
anys[_key] = arguments[_key];
}
anys.forEach(handle);
return classes.join(' ');
},
/**
* 获取指定的父级元素
* @param {*} child
* @param {*} [root=document.body]
* @param {*} fn
* @returns {HTMLElement}
*/
parent: function parent(child) {
var root = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document.body;
var fn = arguments.length > 2 ? arguments[2] : undefined;
var parent = child;
while (parent && parent !== root) {
var result = parent instanceof HTMLElement && fn(parent);
if (result) {
return parent;
}
parent = parent.parentElement;
}
return null;
},
style: function style($dom, styles) {
$dom.style.cssText += styles;
},
Timeout: /*#__PURE__*/function () {
function Timeout() {
_classCallCheck(this, Timeout);
_defineProperty(this, "queue", []);
}
_createClass(Timeout, [{
key: "add",
value: function add(fn, time) {
var _this = this;
if (time > 0) {
return setTimeout(fn, time);
var t;
var item = function item() {
var exec = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
clearTimeout(t);
exec && fn();
};
t = setTimeout(function () {
fn();
_this.queue = _this.queue.filter(function (i) {
return i !== item;
});
}, time);
this.queue.push(item);
} else {
fn();
}
return fn();
},
// requestAnimationFrame 提升性能
RAF(...fns) {
fns.forEach((fn) => (window.requestAnimationFrame ? requestAnimationFrame(fn) : fn()));
},
// 数组对比
equalArr(arr1 = [], arr2 = []) {
return arr1.length == arr2.length && arr1.every((i, index) => arr2[index] == i);
},
position(ele) {
const eleRect = ele.getBoundingClientRect();
const pRect = ele.parentElement.getBoundingClientRect();
return {
left: eleRect.left - pRect.left,
top: eleRect.top - pRect.top,
};
},
getOrigin($dom) {
const { left, right, top, bottom, width, height } = $dom.getBoundingClientRect();
return {
left,
right,
top,
bottom,
width,
height,
};
},
transition($doms = [], time = 0) {
const transition = time > 0 ? `${time}s cubic-bezier(0.25, 0.8, 0.25, 1)` : 'none';
$doms.forEach((ele) => {
ele.style.cssText += `;
-webkit-transition: ${transition};
transition: ${transition};
`;
return this;
}
}, {
key: "clear",
value: function clear() {
this.queue.forEach(function (i) {
return i(false);
});
},
getParent(child, parent) {
// parent 可以是dom/class str/id str
let $p = child;
let match = false;
while ($p !== document.body) {
if ($p === parent) {
match = true;
break;
} else {
$p = $p.parentElement;
}
}
return match ? $p : null;
},
this.queue = [];
return this;
}
}, {
key: "done",
value: function done() {
this.queue.forEach(function (i) {
return i();
});
this.queue = [];
return this;
}
}]);
return Timeout;
}(),
setTimeout: function (_setTimeout) {
function setTimeout() {
return _setTimeout.apply(this, arguments);
}
setTimeout.toString = function () {
return _setTimeout.toString();
};
return setTimeout;
}(function () {
var fn = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
var time = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
if (time > 0) {
return setTimeout(fn, time);
}
return fn();
}),
// requestAnimationFrame 提升性能
RAF: function RAF() {
for (var _len2 = arguments.length, fns = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
fns[_key2] = arguments[_key2];
}
fns.forEach(function (fn) {
return window.requestAnimationFrame ? requestAnimationFrame(fn) : fn();
});
},
// 数组对比
equalArr: function equalArr() {
var arr1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var arr2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
return arr1.length == arr2.length && arr1.every(function (i, index) {
return arr2[index] == i;
});
},
position: function position(ele) {
var eleRect = ele.getBoundingClientRect();
var pRect = ele.parentElement.getBoundingClientRect();
return {
left: eleRect.left - pRect.left,
top: eleRect.top - pRect.top
};
},
getOrigin: function getOrigin($dom) {
var _$dom$getBoundingClie = $dom.getBoundingClientRect(),
left = _$dom$getBoundingClie.left,
right = _$dom$getBoundingClie.right,
top = _$dom$getBoundingClie.top,
bottom = _$dom$getBoundingClie.bottom,
width = _$dom$getBoundingClie.width,
height = _$dom$getBoundingClie.height;
return {
left: left,
right: right,
top: top,
bottom: bottom,
width: width,
height: height
};
},
transition: function transition() {
var $doms = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var time = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var transition = time > 0 ? "".concat(time, "s cubic-bezier(0.25, 0.8, 0.25, 1)") : 'none';
$doms.forEach(function (ele) {
ele.style.cssText += ";\n -webkit-transition: ".concat(transition, ";\n transition: ").concat(transition, ";\n ");
});
},
getParent: function getParent(child, parent) {
// parent 可以是dom/class str/id str
var $p = child;
var match = false;
while ($p !== document.body) {
if ($p === parent) {
match = true;
break;
} else {
$p = $p.parentElement;
}
}
return match ? $p : null;
}
};
exports["default"] = _default;
{
"name": "a-touch",
"version": "0.0.1",
"version": "0.0.2",
"description": "a touch for web",

@@ -14,3 +14,12 @@ "main": "index.js",

"author": "lingyan",
"license": "ISC"
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.17.10",
"@babel/preset-env": "^7.17.10",
"eslint": "^8.14.0",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",
"husky": "^7.0.4",
"prettier": "^2.6.2"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc