tools-library
Version:
670 lines (669 loc) • 22.5 kB
JavaScript
import { ref as B, onMounted as L, onBeforeUnmount as U, openBlock as C, createElementBlock as q } from "vue";
const w = {
__name: "localMedia",
props: {
videoConfig: {
type: Object,
default: () => ({
width: 320,
height: 240,
video: {
facingMode: "user"
}
})
}
},
emits: ["success", "error"],
setup(t, { expose: n, emit: s }) {
const i = t, r = B(null);
L(() => {
a();
}), U(() => {
u();
});
const a = () => {
navigator.mediaDevices.getUserMedia || navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia ? o(i.videoConfig, c, h) : console.log("getUserMedia is not supported");
}, o = (d, g, f) => {
navigator.mediaDevices.getUserMedia ? navigator.mediaDevices.getUserMedia(d).then(g).catch(f) : navigator.webkitGetUserMedia ? navigator.webkitGetUserMedia(d, g, f) : navigator.mozGetUserMedia ? navigator.mozGetUserMedia(d, g, f) : navigator.getUserMedia && navigator.getUserMedia(d, g, f);
}, l = s, c = (d) => {
r.value.srcObject = d, l("success", d);
}, h = (d) => {
l("error", d);
}, u = () => {
r.value.srcObject && (r.value.srcObject.getTracks().forEach((g) => g.stop()), r.value.srcObject = null);
};
return n({
close: u
}), (d, g) => (C(), q("video", {
ref_key: "videoRef",
ref: r,
autoplay: ""
}, null, 512));
}
};
w.install = (t) => {
t.component("LocalMedia", w);
};
const R = {
install(t, n) {
w.install(t);
}
};
let x = null;
const k = {
// 在绑定元素的 attribute 前
// 或事件监听器应用前调用
created(t, n, s, i) {
},
// 在元素被插入到 DOM 前调用
beforeMount(t, n, s, i) {
},
// 在绑定元素的父组件
// 及他自己的所有子节点都挂载完成后调用
mounted(t, n, s, i) {
t.parentNode.style.overflow = "hidden", t.parentNode.style.position = "relative", t.parentNode.style.cursor = "crosshair", t.style.cursor = "move", t.style.position = "absolute", t.style.top = "0px", t.style.left = "0px", t.onmousedown = (r) => {
r.preventDefault();
let a = 0, o = 0, l = r.target.style.top || 0, c = r.target.style.left || 0, h = r.clientX, u = r.clientY;
t.onmousemove = (d) => {
d.preventDefault(), a = d.clientX - h, o = d.clientY - u, d.target.style.top = parseInt(l) + o + "px", d.target.style.left = parseInt(c) + a + "px";
}, t.onmouseup = (d) => {
t.onmousemove = null;
};
}, t.parentNode.addEventListener("mousewheel", (r) => {
r.preventDefault();
let a = t.style.transform, o = a.indexOf("scale") != -1 ? +a.split("(")[1].split(")")[0] : 1;
o += r.wheelDelta / 1e3, o > 0.1 && o < 5 && (t.style.transform = `scale(${o})`);
}), t.parentNode.addEventListener("mouseup", (r) => {
t.onmousemove = null;
}), t.parentNode.addEventListener("mouseout", (r) => {
t.onmousemove = null;
});
},
// 绑定元素的父组件更新前调用
beforeUpdate(t, n, s, i) {
},
// 在绑定元素的父组件
// 及他自己的所有子节点都更新后调用
updated(t, n, s, i) {
},
// 绑定元素的父组件卸载前调用
beforeUnmount(t, n, s, i) {
},
// 绑定元素的父组件卸载后调用
unmounted(t, n, s, i) {
}
}, V = {
// 在绑定元素的 attribute 前
// 或事件监听器应用前调用
created(t, n, s, i) {
},
// 在元素被插入到 DOM 前调用
beforeMount(t, n, s, i) {
},
// 在绑定元素的父组件
// 及他自己的所有子节点都挂载完成后调用
mounted(t, n, s, i) {
t.parentNode.style.overflow = "hidden", t.parentNode.style.position = "relative", t.style.position = "absolute", t.style.top = "0px", t.style.left = "0px";
let r = {
x: null,
y: null
}, a = {
x: null,
y: null
}, o = {
x: null,
y: null,
initLen: 0,
initScale: 1,
tmpScale: 1,
minScale: 1,
maxScale: 5
};
t.addEventListener("touchstart", (l) => {
if (l.preventDefault(), l.targetTouches.length === 2 && (r.x = l.targetTouches[0].clientX, r.y = l.targetTouches[0].clientY, a.x = l.targetTouches[1].clientX, a.y = l.targetTouches[1].clientY, r.x === a.x && r.y !== a.y ? o.initLen = Math.abs(r.y - a.y) : r.y === a.y && r.x !== a.x ? o.initLen = Math.abs(r.x - a.x) : o.initLen = Math.sqrt(Math.pow(Math.abs(r.x - a.x), 2) + Math.pow(Math.abs(r.y - a.y), 2))), l.targetTouches.length === 1) {
let c = 0, h = 0, u = l.targetTouches[0].target.style.top || 0, d = l.targetTouches[0].target.style.left || 0, g = l.targetTouches[0].clientX, f = l.targetTouches[0].clientY;
t.addEventListener("touchmove", (p) => {
p.preventDefault(), c = p.targetTouches[0].clientX - g, h = p.targetTouches[0].clientY - f, p.targetTouches[0].target.style.top = parseInt(u) + h + "px", p.targetTouches[0].target.style.left = parseInt(d) + c + "px";
}), t.addEventListener("touchend", (p) => {
p.preventDefault(), t.addEventListener("touchmove", (m) => {
});
});
}
}), t.addEventListener("touchmove", (l) => {
l.preventDefault();
const c = () => {
if (l.targetTouches.length === 2) {
r.x = l.targetTouches[0].clientX, r.y = l.targetTouches[0].clientY, a.x = l.targetTouches[1].clientX, a.y = l.targetTouches[1].clientY;
let u;
r.x === a.x && r.y !== a.y ? u = Math.abs(r.y - a.y) - o.initLen : r.y === a.y && r.x !== a.x ? u = Math.abs(r.x - a.x) - o.initLen : u = Math.sqrt(Math.pow(Math.abs(r.x - a.x), 2) + Math.pow(Math.abs(r.y - a.y), 2)) - o.initLen, e.children[0].style.transform = `scale(${o.initScale + u / 100})`, o.tmpScale = o.initScale + u / 100, o.tmpScale < o.minScale ? (e.children[0].style.transform = "scale(1)", o.initScale = 1) : o.tmpScale > o.maxScale && (e.children[0].style.transform = "scale(5)", o.initScale = 5);
}
};
let h = null;
clearTimeout(h), h = setTimeout(c(), 500);
}), t.addEventListener("touchend", (l) => {
l.preventDefault(), o.initScale = o.tmpScale;
});
},
// 绑定元素的父组件更新前调用
beforeUpdate(t, n, s, i) {
},
// 在绑定元素的父组件
// 及他自己的所有子节点都更新后调用
updated(t, n, s, i) {
},
// 绑定元素的父组件卸载前调用
beforeUnmount(t, n, s, i) {
},
// 绑定元素的父组件卸载后调用
unmounted(t, n, s, i) {
}
};
let A = navigator.userAgent;
/(Android|webOS|iPhone|iPod|BlackBerry)/.test(A) ? x = V : x = k;
const E = x, H = {
// 在绑定元素的 attribute 前
// 或事件监听器应用前调用
created(t, n, s, i) {
},
// 在元素被插入到 DOM 前调用
beforeMount(t, n, s, i) {
},
// 在绑定元素的父组件
// 及他自己的所有子节点都挂载完成后调用
mounted(t, n, s, i) {
const r = (h) => {
let u = h.offsetTop, d = h.offsetParent;
for (; d; )
u += d.offsetTop, d = d.offsetParent;
return u;
}, a = (h) => {
let u = h.offsetLeft, d = h.offsetParent;
for (; d; )
u += d.offsetLeft, d = d.offsetParent;
return u;
};
let o = Object.assign({
magnifierSize: "100px",
borderColor: "#e1d5d5",
circular: !1,
scale: 2
}, n.value);
t.style.position = "relative", t.style.cursor = "none";
let l = document.createElement("div");
l.style.width = o.magnifierSize, l.style.height = o.magnifierSize, l.style.position = "absolute", l.style.top = "0px", l.style.left = "0px", l.style.display = "none", l.style.overflow = "hidden", l.style.border = `1px solid ${o.borderColor}`, o.circular && (l.style.borderRadius = "50%");
let c = t.cloneNode(!0);
c.style.position = "absolute", c.style.top = "0px", c.style.left = "0px", c.style.margin = "0px", c.style.padding = "0px", c.style.transform = `scale(${o.scale})`, c.style.transformOrigin = "0% 0%", l.appendChild(c), t.appendChild(l), t.onmousemove = (h) => {
h.preventDefault(), l.style.display = "block";
let u = h.pageX - a(t) - parseInt(o.magnifierSize) / 2, d = h.pageY - r(t) - parseInt(o.magnifierSize) / 2;
l.style.top = d + "px", l.style.left = u + "px", c.style.top = parseInt(o.magnifierSize) / 2 - (parseInt(l.style.top) + parseInt(o.magnifierSize) / 2) * o.scale + "px", c.style.left = parseInt(o.magnifierSize) / 2 - (parseInt(l.style.left) + parseInt(o.magnifierSize) / 2) * o.scale + "px";
}, t.onmouseout = (h) => {
l.style.display = "none";
};
},
// 绑定元素的父组件更新前调用
beforeUpdate(t, n, s, i) {
},
// 在绑定元素的父组件
// 及他自己的所有子节点都更新后调用
updated(t, n, s, i) {
},
// 绑定元素的父组件卸载前调用
beforeUnmount(t, n, s, i) {
},
// 绑定元素的父组件卸载后调用
unmounted(t, n, s, i) {
}
}, z = (t, n = "yyyy-MM-dd HH:mm:ss") => {
if (!t)
return;
const s = n || "yyyy-MM-dd HH:mm:ss";
let i = "";
if (t instanceof Date)
i = t;
else {
typeof t == "string" && /^[0-9]+$/.test(t) && (t = parseInt(t)), typeof t == "number" && t.toString().length === 10 && (t = t * 1e3);
try {
i = new Date(t);
} catch {
return;
}
}
const r = (o) => (o = typeof o == "string" ? o : o.toString(), o.replace(/^(\d)$/, "0$1")), a = {
yyyy: i.getFullYear().toString(),
yy: i.getFullYear().toString().substring(2),
M: (i.getMonth() + 1).toString(),
MM: r(i.getMonth() + 1),
d: i.getDate().toString(),
dd: r(i.getDate()),
HH: r(i.getHours()),
mm: r(i.getMinutes()),
ss: r(i.getSeconds())
};
return s.replace(/([a-z])(\1)*/gi, (o) => a[o]);
}, Y = class {
constructor(n = {}) {
this.url = n.url || "", this.autoReconnectInterval = n.autoReconnectInterval || 5e3, this.enableHeartbeat = n.enableHeartbeat || !0, this.heartbeatInterval = n.heartbeatInterval || 3e4, this.heartbeatData = n.heartbeatData || "ping", this.maxReconnectSum = n.maxReconnectSum || 3, this.reconnectNum = 0, this.message = n.message || function(s) {
console.log(s);
}, this.error = n.error || function(s) {
console.log(s);
}, this.close = n.close || function() {
console.log("close");
}, this.websocket = null, this.reconnectTimer = null, this.heartbeatTimer = null, this.isConnected = !1, this.isClose = !1, this.connect();
}
/**
* @name: connect
* @author: wangtong
* @Date: 2023-08-30 17:56:24
* @type: Function (Function | Variable | Computed | ...)
* @description: 连接 WebSocket
* @return {*}
* @example: 怎么使用该方法
* @无(): // 无
*/
connect() {
this.websocket = new WebSocket(this.url), this.websocket.onopen = () => {
console.log("WebSocket 连接成功"), this.isConnected = !0, this.clearReconnectTimer(), this.startHeartbeat();
}, this.websocket.onclose = () => {
this.close(), console.warn("WebSocket 连接关闭"), this.isConnected = !1, this.isClose || this.createReconnectTimer(), this.stopHeartbeat();
}, this.websocket.onerror = (n) => {
this.error(n), console.error("WebSocket 连接错误", n), this.isConnected = !1, this.isClose || this.createReconnectTimer(), this.stopHeartbeat();
}, this.websocket.onmessage = (n) => {
this.message(n.data);
};
}
/**
* @name: send
* @author: wangtong
* @Date: 2023-08-30 17:57:07
* @type: Function (Function | Variable | Computed | ...)
* @description: 发送 WebSocket 消息
* @return {*}
* @example: 怎么使用该方法
* @无(): // 无
* @param {*} data
*/
send(n) {
return new Promise((s, i) => {
if (!this.isConnected) {
i(new Error("WebSocket 未连接"));
return;
}
this.websocket.send(n), s();
});
}
/**
* @name: createReconnectTimer
* @author: wangtong
* @Date: 2023-08-30 17:57:31
* @type: Function (Function | Variable | Computed | ...)
* @description: 创建重连定时器
* @return {*}
* @example: 怎么使用该方法
* @无(): // 无
*/
createReconnectTimer() {
if (this.reconnectNum >= this.maxReconnectSum) {
this.reconnectNum = 0, this.clearReconnectTimer(), this.message(!1), this.isClose = !0;
return;
}
this.reconnectTimer || (this.reconnectTimer = setInterval(() => {
console.log("尝试重新连接 WebSocket ..."), this.isConnected || (this.reconnectNum++, this.connect());
}, this.autoReconnectInterval));
}
/**
* @name: clearReconnectTimer
* @author: wangtong
* @Date: 2023-08-30 17:57:45
* @type: Function (Function | Variable | Computed | ...)
* @description: 清除重连定时器
* @return {*}
* @example: 怎么使用该方法
* @无(): // 无
*/
clearReconnectTimer() {
this.reconnectTimer && (clearInterval(this.reconnectTimer), this.reconnectTimer = null);
}
/**
* @name: startHeartbeat
* @author: wangtong
* @Date: 2023-08-30 17:58:01
* @type: Function (Function | Variable | Computed | ...)
* @description: 开始心跳
* @return {*}
* @example: 怎么使用该方法
* @无(): // 无
*/
startHeartbeat() {
this.enableHeartbeat && !this.heartbeatTimer && (this.heartbeatTimer = setInterval(() => {
console.log("websocketHeart:", this.heartbeatData), this.send(this.heartbeatData);
}, this.heartbeatInterval));
}
/**
* @name: stopHeartbeat
* @author: wangtong
* @Date: 2023-08-30 17:58:19
* @type: Function (Function | Variable | Computed | ...)
* @description: 停止心跳
* @return {*}
* @example: 怎么使用该方法
* @无(): // 无
*/
stopHeartbeat() {
this.heartbeatTimer && (clearInterval(this.heartbeatTimer), this.heartbeatTimer = null);
}
/**
* @name: close
* @author: wangtong
* @Date: 2023-08-30 17:58:35
* @type: Function (Function | Variable | Computed | ...)
* @description: 关闭 WebSocket
* @return {*}
* @example: 怎么使用该方法
* @无(): // 无
*/
close() {
console.log("WebSocket 手动关闭"), this.isClose = !0, this.websocket.close();
}
}, X = (t, n = 1, s) => new Promise((i, r) => {
let a = window.indexedDB || window.webkitindexedDB || window.msIndexedDB || window.mozIndexedDB, o;
const l = a.open(t, n);
l.onsuccess = (c) => {
o = c.target.result, i(o);
}, l.onerror = (c) => {
r(c);
}, l.onupgradeneeded = (c) => {
if (o = c.target.result, !o.objectStoreNames.contains(s.name)) {
let h = o.createObjectStore(s.name, {
keyPath: s.id || "id",
autoIncrement: !s.id
});
s.index.forEach((u) => {
h.createIndex(u.indexName, u.name, {
unique: u.unique || !1
});
});
}
};
}), P = (t, n, s) => {
if (s instanceof Array)
return Promise.all(s.map((i) => {
const r = t.transaction(n, "readwrite").objectStore(n).add(i);
return new Promise((a, o) => {
r.onsuccess = (l) => {
a(l);
}, r.onerror = (l) => {
o(l);
};
});
}));
{
const i = t.transaction(n, "readwrite").objectStore(n).add(s);
return new Promise((r, a) => {
i.onsuccess = (o) => {
r(o);
}, i.onerror = (o) => {
a(o);
};
});
}
}, F = (t, n, s) => {
if (s instanceof Array)
return Promise.all(s.map((i) => {
const r = t.transaction(n, "readwrite").objectStore(n).put(i);
return new Promise((a, o) => {
r.onsuccess = (l) => {
a(l);
}, r.onerror = (l) => {
o(l);
};
});
}));
{
const i = t.transaction(n, "readwrite").objectStore(n).put(s);
return new Promise((r, a) => {
i.onsuccess = (o) => {
r(o);
}, i.onerror = (o) => {
a(o);
};
});
}
}, $ = (t, n, s) => {
const i = t.transaction(n).objectStore(n).get(s);
return new Promise((r, a) => {
i.onsuccess = (o) => {
r(o);
}, i.onerror = (o) => {
a(o);
};
});
}, G = (t, n, s, i) => {
const a = t.transaction(n).objectStore(n).index(s).get(i);
return new Promise((o, l) => {
a.onsuccess = (c) => {
o(c);
}, a.onerror = (c) => {
l(c);
};
});
}, W = (t, n) => {
let s = [], r = t.transaction(n).objectStore(n).openCursor();
return new Promise((a, o) => {
r.onsuccess = (l) => {
let c = l.target.result;
c ? (s.push(c.value), c.continue()) : a(s);
}, r.onerror = (l) => {
o(l);
};
});
}, j = (t, n, s, i) => {
let r = [], o = t.transaction(n).objectStore(n).index(s).openCursor(IDBKeyRange.only(i));
return new Promise((l, c) => {
o.onsuccess = (h) => {
let u = h.target.result;
u ? (r.push(u.value), u.continue()) : l(r);
}, o.onerror = (h) => {
c(h);
};
});
}, _ = (t, n, s) => {
if (s instanceof Array)
return Promise.all(s.map((i) => {
const r = t.transaction(n, "readwrite").objectStore(n).delete(i);
return new Promise((a, o) => {
r.onsuccess = (l) => {
a(l);
}, r.onerror = (l) => {
o(l);
};
});
}));
{
const i = t.transaction(n, "readwrite").objectStore(n).delete(s);
return new Promise((r, a) => {
i.onsuccess = (o) => {
r(o);
}, i.onerror = (o) => {
a(o);
};
});
}
}, N = (t, n) => {
const s = t.transaction(n, "readwrite").objectStore(n);
return new Promise((i, r) => {
const a = s.clear();
a.onsuccess = (o) => {
i(o);
}, a.onerror = (o) => {
r(o);
};
});
}, O = (t) => {
const n = window.indexedDB.deleteDatabase(t);
return new Promise((s, i) => {
n.onsuccess = (r) => {
s(r);
}, n.onerror = (r) => {
i(r);
};
});
}, K = (t) => {
t.close();
}, Z = {
openDB: X,
addData: P,
updateData: F,
getDataByKey: $,
getDataByIndex: G,
cursorGetAllData: W,
cursorGetDataByIndex: j,
deleteData: _,
clearData: N,
deleteDb: O,
closeDB: K
}, T = (t) => {
let n = t.split(","), s = n[0].match(/:(.*?);/)[1], i = atob(n[1]), r = i.length, a = new Uint8Array(r);
for (; r--; )
a[r] = i.charCodeAt(r);
return new Blob([a], { type: s });
}, J = (t, n) => new File([t], n), Q = (t, n) => S(T(t)), ee = (t) => {
const n = (i, r, a) => {
let o = document.createElement("canvas");
return o.width = r || i.width, o.height = a || i.height, o.getContext("2d").drawImage(i, 0, 0, o.width, o.height), o.toDataURL();
};
let s = new Image();
return s.crossOrigin = "", s.src = t, new Promise((i, r) => {
s.onload = () => {
i(n(s));
};
});
}, D = (t) => new Blob([t], { type: t.type }), S = (t) => new Promise((n, s) => {
const i = new FileReader();
i.readAsDataURL(t), i.onloadend = () => n(i.result.split(",")[1]), i.onerror = s(null);
}), te = (t) => S(D(t)), ne = (t, n = 80) => {
const s = new Image();
return s.crossOrigin = "", s.src = t, new Promise((i, r) => {
s.onload = () => {
const a = document.getElementById("canvas");
a.width = s.width, a.height = s.height, a.getContext("2d").drawImage(s, 0, 0, s.width, s.height);
const l = a.toDataURL("image/jpeg", n / 100);
i(l);
};
});
}, I = (t) => {
const n = t.indexOf("base64,");
if (n < 0)
return -1;
const s = t.substr(n + 6);
return parseFloat((s.length * 0.75).toFixed(2));
}, b = (t, n, s, i = 0, r = null, a = null) => {
const o = new Image();
o.crossOrigin = "", o.src = t, o.onload = () => {
let l = o.width * ((n == null ? void 0 : n.ratio) / 100 || 1), c = o.height * ((n == null ? void 0 : n.ratio) / 100 || 1), h = l / c;
l = n.width || l, c = n.height && n.height * (l / h) || c;
let u = document.createElement("canvas"), d = u.getContext("2d");
u.width = l, u.height = c, d.drawImage(o, 0, 0, l, c);
let g = 80;
n.quality && n.quality > 0 && n.quality <= 100 && (g = n.quality);
let f = u.toDataURL("image/jpeg", g / 100), p = I(f);
if (i <= r) {
a === null && (a = g);
const m = [], M = 1;
for (let v = M; v <= a; v += M)
m.push(parseFloat(v));
r === null && (r = m.length);
const y = Math.floor((i + r) / 2);
p > s ? b(
t,
{
quality: m[y],
// 设置宽高压缩率对图像进行宽高压缩,降低图像被压缩后出现彩虹斑的情况
ratio: 50
},
s,
i,
y - 1,
a
) : b(
t,
{
quality: m[y],
// 设置宽高压缩率对图像进行宽高压缩,降低图像被压缩后出现彩虹斑的情况
ratio: 50
},
s,
y + 1,
r,
a
);
} else if (p > s)
b(
f,
{
quality: 80,
// 设置宽高压缩率对图像进行宽高压缩,降低图像被压缩后出现彩虹斑的情况
ratio: 50
},
s,
i = 1,
r = null,
a
);
else
return f;
};
}, oe = {
base64ToBlob: T,
fileToBlob: D,
blobToFile: J,
base64ToFile: Q,
blobToBase64: S,
fileToBase64: te,
urlToBase64: ee,
imgUrlCompressor: ne,
getBase64ImageSize: I,
uploadImageCompressor: b
}, re = (t, n) => {
if (!/^[a-zA-Z0-9]{36}$/.test(t))
return;
let s = t.length, i = t.split(""), r = "", a = "", o = "", l = "", c = "";
for (let h = 0; h < n.length; h++)
a = n.charCodeAt(h), o = a % s, a = (a - o) / s, l = a % s, a = (a - l) / s, c = a % s, r += i[c] + i[l] + i[o];
return r;
}, se = (t, n) => {
if (!/^[a-zA-Z0-9]{36}$/.test(t))
return;
let s = t.length;
t.split("");
let i = 0, r = new Array(Math.floor(n.length / 3)), a = "", o = "", l = "";
for (let c = 0; c < n.length; c++)
a = t.indexOf(n.charAt(i)), i++, o = t.indexOf(n.charAt(i)), i++, l = t.indexOf(n.charAt(i)), i++, r[c] = a * s * s + o * s + l;
return String.fromCharCode.apply(null, r);
}, ie = {
encrypt: re,
decrypt: se
}, ae = {
directiveMoveScale: E,
directiveMagnifier: H,
formatTime: z,
WS: Y,
IndexDb: Z,
fileBase64: oe,
Encry: ie
}, de = {
components: R,
tools: ae
};
export {
ie as Encry,
Z as IndexDb,
w as LocalMedia,
Y as WS,
R as components,
de as default,
H as directiveMagnifier,
E as directiveMoveScale,
oe as fileBase64,
z as formatTime,
ae as tools
};