Created
February 1, 2020 14:45
-
-
Save observerss/35a0ac62756892ff8ce90c4b856ce6d7 to your computer and use it in GitHub Desktop.
dmss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
! function (t) { | |
if ("object" == typeof exports && "undefined" != typeof module) module.exports = t(); | |
else if ("function" == typeof define && define.amd) define([], t); | |
else { | |
("undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : this).buffer = t() | |
} | |
}(function () { | |
return function () { | |
return function t(r, e, n) { | |
function i(f, u) { | |
if (!e[f]) { | |
if (!r[f]) { | |
var s = "function" == typeof require && require; | |
if (!u && s) return s(f, !0); | |
if (o) return o(f, !0); | |
var h = new Error("Cannot find module '" + f + "'"); | |
throw h.code = "MODULE_NOT_FOUND", h | |
} | |
var a = e[f] = { | |
exports: {} | |
}; | |
r[f][0].call(a.exports, function (t) { | |
return i(r[f][1][t] || t) | |
}, a, a.exports, t, r, e, n) | |
} | |
return e[f].exports | |
} | |
for (var o = "function" == typeof require && require, f = 0; f < n.length; f++) i(n[f]); | |
return i | |
} | |
}()({ | |
1: [function (t, r, e) { | |
(function (r) { | |
"use strict"; | |
var n = t("base64-js"), | |
i = t("ieee754"), | |
o = "function" == typeof Symbol && "function" == typeof Symbol.for ? Symbol.for("nodejs.util.inspect.custom") : null; | |
e.Buffer = r, e.SlowBuffer = function (t) { | |
+t != t && (t = 0); | |
return r.alloc(+t) | |
}, e.INSPECT_MAX_BYTES = 50; | |
var f = 2147483647; | |
function u(t) { | |
if (t > f) throw new RangeError('The value "' + t + '" is invalid for option "size"'); | |
var e = new Uint8Array(t); | |
return Object.setPrototypeOf(e, r.prototype), e | |
} | |
function r(t, r, e) { | |
if ("number" == typeof t) { | |
if ("string" == typeof r) throw new TypeError('The "string" argument must be of type string. Received type number'); | |
return a(t) | |
} | |
return s(t, r, e) | |
} | |
function s(t, e, n) { | |
if ("string" == typeof t) return function (t, e) { | |
"string" == typeof e && "" !== e || (e = "utf8"); | |
if (!r.isEncoding(e)) throw new TypeError("Unknown encoding: " + e); | |
var n = 0 | l(t, e), | |
i = u(n), | |
o = i.write(t, e); | |
o !== n && (i = i.slice(0, o)); | |
return i | |
}(t, e); | |
if (ArrayBuffer.isView(t)) return p(t); | |
if (null == t) throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type " + typeof t); | |
if (z(t, ArrayBuffer) || t && z(t.buffer, ArrayBuffer)) return function (t, e, n) { | |
if (e < 0 || t.byteLength < e) throw new RangeError('"offset" is outside of buffer bounds'); | |
if (t.byteLength < e + (n || 0)) throw new RangeError('"length" is outside of buffer bounds'); | |
var i; | |
i = void 0 === e && void 0 === n ? new Uint8Array(t) : void 0 === n ? new Uint8Array(t, e) : new Uint8Array(t, e, n); | |
return Object.setPrototypeOf(i, r.prototype), i | |
}(t, e, n); | |
if ("number" == typeof t) throw new TypeError('The "value" argument must not be of type number. Received type number'); | |
var i = t.valueOf && t.valueOf(); | |
if (null != i && i !== t) return r.from(i, e, n); | |
var o = function (t) { | |
if (r.isBuffer(t)) { | |
var e = 0 | c(t.length), | |
n = u(e); | |
return 0 === n.length ? n : (t.copy(n, 0, 0, e), n) | |
} | |
if (void 0 !== t.length) return "number" != typeof t.length || D(t.length) ? u(0) : p(t); | |
if ("Buffer" === t.type && Array.isArray(t.data)) return p(t.data) | |
}(t); | |
if (o) return o; | |
if ("undefined" != typeof Symbol && null != Symbol.toPrimitive && "function" == typeof t[Symbol.toPrimitive]) return r.from(t[Symbol.toPrimitive]("string"), e, n); | |
throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type " + typeof t) | |
} | |
function h(t) { | |
if ("number" != typeof t) throw new TypeError('"size" argument must be of type number'); | |
if (t < 0) throw new RangeError('The value "' + t + '" is invalid for option "size"') | |
} | |
function a(t) { | |
return h(t), u(t < 0 ? 0 : 0 | c(t)) | |
} | |
function p(t) { | |
for (var r = t.length < 0 ? 0 : 0 | c(t.length), e = u(r), n = 0; n < r; n += 1) e[n] = 255 & t[n]; | |
return e | |
} | |
function c(t) { | |
if (t >= f) throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x" + f.toString(16) + " bytes"); | |
return 0 | t | |
} | |
function l(t, e) { | |
if (r.isBuffer(t)) return t.length; | |
if (ArrayBuffer.isView(t) || z(t, ArrayBuffer)) return t.byteLength; | |
if ("string" != typeof t) throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type ' + typeof t); | |
var n = t.length, | |
i = arguments.length > 2 && !0 === arguments[2]; | |
if (!i && 0 === n) return 0; | |
for (var o = !1;;) switch (e) { | |
case "ascii": | |
case "latin1": | |
case "binary": | |
return n; | |
case "utf8": | |
case "utf-8": | |
return P(t).length; | |
case "ucs2": | |
case "ucs-2": | |
case "utf16le": | |
case "utf-16le": | |
return 2 * n; | |
case "hex": | |
return n >>> 1; | |
case "base64": | |
return j(t).length; | |
default: | |
if (o) return i ? -1 : P(t).length; | |
e = ("" + e).toLowerCase(), o = !0 | |
} | |
} | |
function y(t, r, e) { | |
var n = t[r]; | |
t[r] = t[e], t[e] = n | |
} | |
function g(t, e, n, i, o) { | |
if (0 === t.length) return -1; | |
if ("string" == typeof n ? (i = n, n = 0) : n > 2147483647 ? n = 2147483647 : n < -2147483648 && (n = -2147483648), D(n = +n) && (n = o ? 0 : t.length - 1), n < 0 && (n = t.length + n), n >= t.length) { | |
if (o) return -1; | |
n = t.length - 1 | |
} else if (n < 0) { | |
if (!o) return -1; | |
n = 0 | |
} | |
if ("string" == typeof e && (e = r.from(e, i)), r.isBuffer(e)) return 0 === e.length ? -1 : w(t, e, n, i, o); | |
if ("number" == typeof e) return e &= 255, "function" == typeof Uint8Array.prototype.indexOf ? o ? Uint8Array.prototype.indexOf.call(t, e, n) : Uint8Array.prototype.lastIndexOf.call(t, e, n) : w(t, [e], n, i, o); | |
throw new TypeError("val must be string, number or Buffer") | |
} | |
function w(t, r, e, n, i) { | |
var o, f = 1, | |
u = t.length, | |
s = r.length; | |
if (void 0 !== n && ("ucs2" === (n = String(n).toLowerCase()) || "ucs-2" === n || "utf16le" === n || "utf-16le" === n)) { | |
if (t.length < 2 || r.length < 2) return -1; | |
f = 2, u /= 2, s /= 2, e /= 2 | |
} | |
function h(t, r) { | |
return 1 === f ? t[r] : t.readUInt16BE(r * f) | |
} | |
if (i) { | |
var a = -1; | |
for (o = e; o < u; o++) | |
if (h(t, o) === h(r, -1 === a ? 0 : o - a)) { | |
if (-1 === a && (a = o), o - a + 1 === s) return a * f | |
} else -1 !== a && (o -= o - a), a = -1 | |
} else | |
for (e + s > u && (e = u - s), o = e; o >= 0; o--) { | |
for (var p = !0, c = 0; c < s; c++) | |
if (h(t, o + c) !== h(r, c)) { | |
p = !1; | |
break | |
} if (p) return o | |
} | |
return -1 | |
} | |
function d(t, r, e, n) { | |
e = Number(e) || 0; | |
var i = t.length - e; | |
n ? (n = Number(n)) > i && (n = i) : n = i; | |
var o = r.length; | |
n > o / 2 && (n = o / 2); | |
for (var f = 0; f < n; ++f) { | |
var u = parseInt(r.substr(2 * f, 2), 16); | |
if (D(u)) return f; | |
t[e + f] = u | |
} | |
return f | |
} | |
function v(t, r, e, n) { | |
return N(P(r, t.length - e), t, e, n) | |
} | |
function b(t, r, e, n) { | |
return N(function (t) { | |
for (var r = [], e = 0; e < t.length; ++e) r.push(255 & t.charCodeAt(e)); | |
return r | |
}(r), t, e, n) | |
} | |
function m(t, r, e, n) { | |
return b(t, r, e, n) | |
} | |
function E(t, r, e, n) { | |
return N(j(r), t, e, n) | |
} | |
function B(t, r, e, n) { | |
return N(function (t, r) { | |
for (var e, n, i, o = [], f = 0; f < t.length && !((r -= 2) < 0); ++f) e = t.charCodeAt(f), n = e >> 8, i = e % 256, o.push(i), o.push(n); | |
return o | |
}(r, t.length - e), t, e, n) | |
} | |
function A(t, r, e) { | |
return 0 === r && e === t.length ? n.fromByteArray(t) : n.fromByteArray(t.slice(r, e)) | |
} | |
function U(t, r, e) { | |
e = Math.min(t.length, e); | |
for (var n = [], i = r; i < e;) { | |
var o, f, u, s, h = t[i], | |
a = null, | |
p = h > 239 ? 4 : h > 223 ? 3 : h > 191 ? 2 : 1; | |
if (i + p <= e) switch (p) { | |
case 1: | |
h < 128 && (a = h); | |
break; | |
case 2: | |
128 == (192 & (o = t[i + 1])) && (s = (31 & h) << 6 | 63 & o) > 127 && (a = s); | |
break; | |
case 3: | |
o = t[i + 1], f = t[i + 2], 128 == (192 & o) && 128 == (192 & f) && (s = (15 & h) << 12 | (63 & o) << 6 | 63 & f) > 2047 && (s < 55296 || s > 57343) && (a = s); | |
break; | |
case 4: | |
o = t[i + 1], f = t[i + 2], u = t[i + 3], 128 == (192 & o) && 128 == (192 & f) && 128 == (192 & u) && (s = (15 & h) << 18 | (63 & o) << 12 | (63 & f) << 6 | 63 & u) > 65535 && s < 1114112 && (a = s) | |
} | |
null === a ? (a = 65533, p = 1) : a > 65535 && (a -= 65536, n.push(a >>> 10 & 1023 | 55296), a = 56320 | 1023 & a), n.push(a), i += p | |
} | |
return function (t) { | |
var r = t.length; | |
if (r <= T) return String.fromCharCode.apply(String, t); | |
var e = "", | |
n = 0; | |
for (; n < r;) e += String.fromCharCode.apply(String, t.slice(n, n += T)); | |
return e | |
}(n) | |
} | |
e.kMaxLength = f, r.TYPED_ARRAY_SUPPORT = function () { | |
try { | |
var t = new Uint8Array(1), | |
r = { | |
foo: function () { | |
return 42 | |
} | |
}; | |
return Object.setPrototypeOf(r, Uint8Array.prototype), Object.setPrototypeOf(t, r), 42 === t.foo() | |
} catch (t) { | |
return !1 | |
} | |
}(), r.TYPED_ARRAY_SUPPORT || "undefined" == typeof console || "function" != typeof console.error || console.error("This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support."), Object.defineProperty(r.prototype, "parent", { | |
enumerable: !0, | |
get: function () { | |
if (r.isBuffer(this)) return this.buffer | |
} | |
}), Object.defineProperty(r.prototype, "offset", { | |
enumerable: !0, | |
get: function () { | |
if (r.isBuffer(this)) return this.byteOffset | |
} | |
}), "undefined" != typeof Symbol && null != Symbol.species && r[Symbol.species] === r && Object.defineProperty(r, Symbol.species, { | |
value: null, | |
configurable: !0, | |
enumerable: !1, | |
writable: !1 | |
}), r.poolSize = 8192, r.from = function (t, r, e) { | |
return s(t, r, e) | |
}, Object.setPrototypeOf(r.prototype, Uint8Array.prototype), Object.setPrototypeOf(r, Uint8Array), r.alloc = function (t, r, e) { | |
return function (t, r, e) { | |
return h(t), t <= 0 ? u(t) : void 0 !== r ? "string" == typeof e ? u(t).fill(r, e) : u(t).fill(r) : u(t) | |
}(t, r, e) | |
}, r.allocUnsafe = function (t) { | |
return a(t) | |
}, r.allocUnsafeSlow = function (t) { | |
return a(t) | |
}, r.isBuffer = function (t) { | |
return null != t && !0 === t._isBuffer && t !== r.prototype | |
}, r.compare = function (t, e) { | |
if (z(t, Uint8Array) && (t = r.from(t, t.offset, t.byteLength)), z(e, Uint8Array) && (e = r.from(e, e.offset, e.byteLength)), !r.isBuffer(t) || !r.isBuffer(e)) throw new TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'); | |
if (t === e) return 0; | |
for (var n = t.length, i = e.length, o = 0, f = Math.min(n, i); o < f; ++o) | |
if (t[o] !== e[o]) { | |
n = t[o], i = e[o]; | |
break | |
} return n < i ? -1 : i < n ? 1 : 0 | |
}, r.isEncoding = function (t) { | |
switch (String(t).toLowerCase()) { | |
case "hex": | |
case "utf8": | |
case "utf-8": | |
case "ascii": | |
case "latin1": | |
case "binary": | |
case "base64": | |
case "ucs2": | |
case "ucs-2": | |
case "utf16le": | |
case "utf-16le": | |
return !0; | |
default: | |
return !1 | |
} | |
}, r.concat = function (t, e) { | |
if (!Array.isArray(t)) throw new TypeError('"list" argument must be an Array of Buffers'); | |
if (0 === t.length) return r.alloc(0); | |
var n; | |
if (void 0 === e) | |
for (e = 0, n = 0; n < t.length; ++n) e += t[n].length; | |
var i = r.allocUnsafe(e), | |
o = 0; | |
for (n = 0; n < t.length; ++n) { | |
var f = t[n]; | |
if (z(f, Uint8Array) && (f = r.from(f)), !r.isBuffer(f)) throw new TypeError('"list" argument must be an Array of Buffers'); | |
f.copy(i, o), o += f.length | |
} | |
return i | |
}, r.byteLength = l, r.prototype._isBuffer = !0, r.prototype.swap16 = function () { | |
var t = this.length; | |
if (t % 2 != 0) throw new RangeError("Buffer size must be a multiple of 16-bits"); | |
for (var r = 0; r < t; r += 2) y(this, r, r + 1); | |
return this | |
}, r.prototype.swap32 = function () { | |
var t = this.length; | |
if (t % 4 != 0) throw new RangeError("Buffer size must be a multiple of 32-bits"); | |
for (var r = 0; r < t; r += 4) y(this, r, r + 3), y(this, r + 1, r + 2); | |
return this | |
}, r.prototype.swap64 = function () { | |
var t = this.length; | |
if (t % 8 != 0) throw new RangeError("Buffer size must be a multiple of 64-bits"); | |
for (var r = 0; r < t; r += 8) y(this, r, r + 7), y(this, r + 1, r + 6), y(this, r + 2, r + 5), y(this, r + 3, r + 4); | |
return this | |
}, r.prototype.toString = function () { | |
var t = this.length; | |
return 0 === t ? "" : 0 === arguments.length ? U(this, 0, t) : function (t, r, e) { | |
var n = !1; | |
if ((void 0 === r || r < 0) && (r = 0), r > this.length) return ""; | |
if ((void 0 === e || e > this.length) && (e = this.length), e <= 0) return ""; | |
if ((e >>>= 0) <= (r >>>= 0)) return ""; | |
for (t || (t = "utf8");;) switch (t) { | |
case "hex": | |
return L(this, r, e); | |
case "utf8": | |
case "utf-8": | |
return U(this, r, e); | |
case "ascii": | |
return I(this, r, e); | |
case "latin1": | |
case "binary": | |
return S(this, r, e); | |
case "base64": | |
return A(this, r, e); | |
case "ucs2": | |
case "ucs-2": | |
case "utf16le": | |
case "utf-16le": | |
return R(this, r, e); | |
default: | |
if (n) throw new TypeError("Unknown encoding: " + t); | |
t = (t + "").toLowerCase(), n = !0 | |
} | |
}.apply(this, arguments) | |
}, r.prototype.toLocaleString = r.prototype.toString, r.prototype.equals = function (t) { | |
if (!r.isBuffer(t)) throw new TypeError("Argument must be a Buffer"); | |
return this === t || 0 === r.compare(this, t) | |
}, r.prototype.inspect = function () { | |
var t = "", | |
r = e.INSPECT_MAX_BYTES; | |
return t = this.toString("hex", 0, r).replace(/(.{2})/g, "$1 ").trim(), this.length > r && (t += " ... "), "<Buffer " + t + ">" | |
}, o && (r.prototype[o] = r.prototype.inspect), r.prototype.compare = function (t, e, n, i, o) { | |
if (z(t, Uint8Array) && (t = r.from(t, t.offset, t.byteLength)), !r.isBuffer(t)) throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type ' + typeof t); | |
if (void 0 === e && (e = 0), void 0 === n && (n = t ? t.length : 0), void 0 === i && (i = 0), void 0 === o && (o = this.length), e < 0 || n > t.length || i < 0 || o > this.length) throw new RangeError("out of range index"); | |
if (i >= o && e >= n) return 0; | |
if (i >= o) return -1; | |
if (e >= n) return 1; | |
if (this === t) return 0; | |
for (var f = (o >>>= 0) - (i >>>= 0), u = (n >>>= 0) - (e >>>= 0), s = Math.min(f, u), h = this.slice(i, o), a = t.slice(e, n), p = 0; p < s; ++p) | |
if (h[p] !== a[p]) { | |
f = h[p], u = a[p]; | |
break | |
} return f < u ? -1 : u < f ? 1 : 0 | |
}, r.prototype.includes = function (t, r, e) { | |
return -1 !== this.indexOf(t, r, e) | |
}, r.prototype.indexOf = function (t, r, e) { | |
return g(this, t, r, e, !0) | |
}, r.prototype.lastIndexOf = function (t, r, e) { | |
return g(this, t, r, e, !1) | |
}, r.prototype.write = function (t, r, e, n) { | |
if (void 0 === r) n = "utf8", e = this.length, r = 0; | |
else if (void 0 === e && "string" == typeof r) n = r, e = this.length, r = 0; | |
else { | |
if (!isFinite(r)) throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported"); | |
r >>>= 0, isFinite(e) ? (e >>>= 0, void 0 === n && (n = "utf8")) : (n = e, e = void 0) | |
} | |
var i = this.length - r; | |
if ((void 0 === e || e > i) && (e = i), t.length > 0 && (e < 0 || r < 0) || r > this.length) throw new RangeError("Attempt to write outside buffer bounds"); | |
n || (n = "utf8"); | |
for (var o = !1;;) switch (n) { | |
case "hex": | |
return d(this, t, r, e); | |
case "utf8": | |
case "utf-8": | |
return v(this, t, r, e); | |
case "ascii": | |
return b(this, t, r, e); | |
case "latin1": | |
case "binary": | |
return m(this, t, r, e); | |
case "base64": | |
return E(this, t, r, e); | |
case "ucs2": | |
case "ucs-2": | |
case "utf16le": | |
case "utf-16le": | |
return B(this, t, r, e); | |
default: | |
if (o) throw new TypeError("Unknown encoding: " + n); | |
n = ("" + n).toLowerCase(), o = !0 | |
} | |
}, r.prototype.toJSON = function () { | |
return { | |
type: "Buffer", | |
data: Array.prototype.slice.call(this._arr || this, 0) | |
} | |
}; | |
var T = 4096; | |
function I(t, r, e) { | |
var n = ""; | |
e = Math.min(t.length, e); | |
for (var i = r; i < e; ++i) n += String.fromCharCode(127 & t[i]); | |
return n | |
} | |
function S(t, r, e) { | |
var n = ""; | |
e = Math.min(t.length, e); | |
for (var i = r; i < e; ++i) n += String.fromCharCode(t[i]); | |
return n | |
} | |
function L(t, r, e) { | |
var n = t.length; | |
(!r || r < 0) && (r = 0), (!e || e < 0 || e > n) && (e = n); | |
for (var i = "", o = r; o < e; ++o) i += F[t[o]]; | |
return i | |
} | |
function R(t, r, e) { | |
for (var n = t.slice(r, e), i = "", o = 0; o < n.length; o += 2) i += String.fromCharCode(n[o] + 256 * n[o + 1]); | |
return i | |
} | |
function C(t, r, e) { | |
if (t % 1 != 0 || t < 0) throw new RangeError("offset is not uint"); | |
if (t + r > e) throw new RangeError("Trying to access beyond buffer length") | |
} | |
function O(t, e, n, i, o, f) { | |
if (!r.isBuffer(t)) throw new TypeError('"buffer" argument must be a Buffer instance'); | |
if (e > o || e < f) throw new RangeError('"value" argument is out of bounds'); | |
if (n + i > t.length) throw new RangeError("Index out of range") | |
} | |
function _(t, r, e, n, i, o) { | |
if (e + n > t.length) throw new RangeError("Index out of range"); | |
if (e < 0) throw new RangeError("Index out of range") | |
} | |
function x(t, r, e, n, o) { | |
return r = +r, e >>>= 0, o || _(t, 0, e, 4), i.write(t, r, e, n, 23, 4), e + 4 | |
} | |
function M(t, r, e, n, o) { | |
return r = +r, e >>>= 0, o || _(t, 0, e, 8), i.write(t, r, e, n, 52, 8), e + 8 | |
} | |
r.prototype.slice = function (t, e) { | |
var n = this.length; | |
(t = ~~t) < 0 ? (t += n) < 0 && (t = 0) : t > n && (t = n), (e = void 0 === e ? n : ~~e) < 0 ? (e += n) < 0 && (e = 0) : e > n && (e = n), e < t && (e = t); | |
var i = this.subarray(t, e); | |
return Object.setPrototypeOf(i, r.prototype), i | |
}, r.prototype.readUIntLE = function (t, r, e) { | |
t >>>= 0, r >>>= 0, e || C(t, r, this.length); | |
for (var n = this[t], i = 1, o = 0; ++o < r && (i *= 256);) n += this[t + o] * i; | |
return n | |
}, r.prototype.readUIntBE = function (t, r, e) { | |
t >>>= 0, r >>>= 0, e || C(t, r, this.length); | |
for (var n = this[t + --r], i = 1; r > 0 && (i *= 256);) n += this[t + --r] * i; | |
return n | |
}, r.prototype.readUInt8 = function (t, r) { | |
return t >>>= 0, r || C(t, 1, this.length), this[t] | |
}, r.prototype.readUInt16LE = function (t, r) { | |
return t >>>= 0, r || C(t, 2, this.length), this[t] | this[t + 1] << 8 | |
}, r.prototype.readUInt16BE = function (t, r) { | |
return t >>>= 0, r || C(t, 2, this.length), this[t] << 8 | this[t + 1] | |
}, r.prototype.readUInt32LE = function (t, r) { | |
return t >>>= 0, r || C(t, 4, this.length), (this[t] | this[t + 1] << 8 | this[t + 2] << 16) + 16777216 * this[t + 3] | |
}, r.prototype.readUInt32BE = function (t, r) { | |
return t >>>= 0, r || C(t, 4, this.length), 16777216 * this[t] + (this[t + 1] << 16 | this[t + 2] << 8 | this[t + 3]) | |
}, r.prototype.readIntLE = function (t, r, e) { | |
t >>>= 0, r >>>= 0, e || C(t, r, this.length); | |
for (var n = this[t], i = 1, o = 0; ++o < r && (i *= 256);) n += this[t + o] * i; | |
return n >= (i *= 128) && (n -= Math.pow(2, 8 * r)), n | |
}, r.prototype.readIntBE = function (t, r, e) { | |
t >>>= 0, r >>>= 0, e || C(t, r, this.length); | |
for (var n = r, i = 1, o = this[t + --n]; n > 0 && (i *= 256);) o += this[t + --n] * i; | |
return o >= (i *= 128) && (o -= Math.pow(2, 8 * r)), o | |
}, r.prototype.readInt8 = function (t, r) { | |
return t >>>= 0, r || C(t, 1, this.length), 128 & this[t] ? -1 * (255 - this[t] + 1) : this[t] | |
}, r.prototype.readInt16LE = function (t, r) { | |
t >>>= 0, r || C(t, 2, this.length); | |
var e = this[t] | this[t + 1] << 8; | |
return 32768 & e ? 4294901760 | e : e | |
}, r.prototype.readInt16BE = function (t, r) { | |
t >>>= 0, r || C(t, 2, this.length); | |
var e = this[t + 1] | this[t] << 8; | |
return 32768 & e ? 4294901760 | e : e | |
}, r.prototype.readInt32LE = function (t, r) { | |
return t >>>= 0, r || C(t, 4, this.length), this[t] | this[t + 1] << 8 | this[t + 2] << 16 | this[t + 3] << 24 | |
}, r.prototype.readInt32BE = function (t, r) { | |
return t >>>= 0, r || C(t, 4, this.length), this[t] << 24 | this[t + 1] << 16 | this[t + 2] << 8 | this[t + 3] | |
}, r.prototype.readFloatLE = function (t, r) { | |
return t >>>= 0, r || C(t, 4, this.length), i.read(this, t, !0, 23, 4) | |
}, r.prototype.readFloatBE = function (t, r) { | |
return t >>>= 0, r || C(t, 4, this.length), i.read(this, t, !1, 23, 4) | |
}, r.prototype.readDoubleLE = function (t, r) { | |
return t >>>= 0, r || C(t, 8, this.length), i.read(this, t, !0, 52, 8) | |
}, r.prototype.readDoubleBE = function (t, r) { | |
return t >>>= 0, r || C(t, 8, this.length), i.read(this, t, !1, 52, 8) | |
}, r.prototype.writeUIntLE = function (t, r, e, n) { | |
(t = +t, r >>>= 0, e >>>= 0, n) || O(this, t, r, e, Math.pow(2, 8 * e) - 1, 0); | |
var i = 1, | |
o = 0; | |
for (this[r] = 255 & t; ++o < e && (i *= 256);) this[r + o] = t / i & 255; | |
return r + e | |
}, r.prototype.writeUIntBE = function (t, r, e, n) { | |
(t = +t, r >>>= 0, e >>>= 0, n) || O(this, t, r, e, Math.pow(2, 8 * e) - 1, 0); | |
var i = e - 1, | |
o = 1; | |
for (this[r + i] = 255 & t; --i >= 0 && (o *= 256);) this[r + i] = t / o & 255; | |
return r + e | |
}, r.prototype.writeUInt8 = function (t, r, e) { | |
return t = +t, r >>>= 0, e || O(this, t, r, 1, 255, 0), this[r] = 255 & t, r + 1 | |
}, r.prototype.writeUInt16LE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || O(this, t, r, 2, 65535, 0), this[r] = 255 & t, this[r + 1] = t >>> 8, r + 2 | |
}, r.prototype.writeUInt16BE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || O(this, t, r, 2, 65535, 0), this[r] = t >>> 8, this[r + 1] = 255 & t, r + 2 | |
}, r.prototype.writeUInt32LE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || O(this, t, r, 4, 4294967295, 0), this[r + 3] = t >>> 24, this[r + 2] = t >>> 16, this[r + 1] = t >>> 8, this[r] = 255 & t, r + 4 | |
}, r.prototype.writeUInt32BE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || O(this, t, r, 4, 4294967295, 0), this[r] = t >>> 24, this[r + 1] = t >>> 16, this[r + 2] = t >>> 8, this[r + 3] = 255 & t, r + 4 | |
}, r.prototype.writeIntLE = function (t, r, e, n) { | |
if (t = +t, r >>>= 0, !n) { | |
var i = Math.pow(2, 8 * e - 1); | |
O(this, t, r, e, i - 1, -i) | |
} | |
var o = 0, | |
f = 1, | |
u = 0; | |
for (this[r] = 255 & t; ++o < e && (f *= 256);) t < 0 && 0 === u && 0 !== this[r + o - 1] && (u = 1), this[r + o] = (t / f >> 0) - u & 255; | |
return r + e | |
}, r.prototype.writeIntBE = function (t, r, e, n) { | |
if (t = +t, r >>>= 0, !n) { | |
var i = Math.pow(2, 8 * e - 1); | |
O(this, t, r, e, i - 1, -i) | |
} | |
var o = e - 1, | |
f = 1, | |
u = 0; | |
for (this[r + o] = 255 & t; --o >= 0 && (f *= 256);) t < 0 && 0 === u && 0 !== this[r + o + 1] && (u = 1), this[r + o] = (t / f >> 0) - u & 255; | |
return r + e | |
}, r.prototype.writeInt8 = function (t, r, e) { | |
return t = +t, r >>>= 0, e || O(this, t, r, 1, 127, -128), t < 0 && (t = 255 + t + 1), this[r] = 255 & t, r + 1 | |
}, r.prototype.writeInt16LE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || O(this, t, r, 2, 32767, -32768), this[r] = 255 & t, this[r + 1] = t >>> 8, r + 2 | |
}, r.prototype.writeInt16BE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || O(this, t, r, 2, 32767, -32768), this[r] = t >>> 8, this[r + 1] = 255 & t, r + 2 | |
}, r.prototype.writeInt32LE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || O(this, t, r, 4, 2147483647, -2147483648), this[r] = 255 & t, this[r + 1] = t >>> 8, this[r + 2] = t >>> 16, this[r + 3] = t >>> 24, r + 4 | |
}, r.prototype.writeInt32BE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || O(this, t, r, 4, 2147483647, -2147483648), t < 0 && (t = 4294967295 + t + 1), this[r] = t >>> 24, this[r + 1] = t >>> 16, this[r + 2] = t >>> 8, this[r + 3] = 255 & t, r + 4 | |
}, r.prototype.writeFloatLE = function (t, r, e) { | |
return x(this, t, r, !0, e) | |
}, r.prototype.writeFloatBE = function (t, r, e) { | |
return x(this, t, r, !1, e) | |
}, r.prototype.writeDoubleLE = function (t, r, e) { | |
return M(this, t, r, !0, e) | |
}, r.prototype.writeDoubleBE = function (t, r, e) { | |
return M(this, t, r, !1, e) | |
}, r.prototype.copy = function (t, e, n, i) { | |
if (!r.isBuffer(t)) throw new TypeError("argument should be a Buffer"); | |
if (n || (n = 0), i || 0 === i || (i = this.length), e >= t.length && (e = t.length), e || (e = 0), i > 0 && i < n && (i = n), i === n) return 0; | |
if (0 === t.length || 0 === this.length) return 0; | |
if (e < 0) throw new RangeError("targetStart out of bounds"); | |
if (n < 0 || n >= this.length) throw new RangeError("Index out of range"); | |
if (i < 0) throw new RangeError("sourceEnd out of bounds"); | |
i > this.length && (i = this.length), t.length - e < i - n && (i = t.length - e + n); | |
var o = i - n; | |
if (this === t && "function" == typeof Uint8Array.prototype.copyWithin) this.copyWithin(e, n, i); | |
else if (this === t && n < e && e < i) | |
for (var f = o - 1; f >= 0; --f) t[f + e] = this[f + n]; | |
else Uint8Array.prototype.set.call(t, this.subarray(n, i), e); | |
return o | |
}, r.prototype.fill = function (t, e, n, i) { | |
if ("string" == typeof t) { | |
if ("string" == typeof e ? (i = e, e = 0, n = this.length) : "string" == typeof n && (i = n, n = this.length), void 0 !== i && "string" != typeof i) throw new TypeError("encoding must be a string"); | |
if ("string" == typeof i && !r.isEncoding(i)) throw new TypeError("Unknown encoding: " + i); | |
if (1 === t.length) { | |
var o = t.charCodeAt(0); | |
("utf8" === i && o < 128 || "latin1" === i) && (t = o) | |
} | |
} else "number" == typeof t ? t &= 255 : "boolean" == typeof t && (t = Number(t)); | |
if (e < 0 || this.length < e || this.length < n) throw new RangeError("Out of range index"); | |
if (n <= e) return this; | |
var f; | |
if (e >>>= 0, n = void 0 === n ? this.length : n >>> 0, t || (t = 0), "number" == typeof t) | |
for (f = e; f < n; ++f) this[f] = t; | |
else { | |
var u = r.isBuffer(t) ? t : r.from(t, i), | |
s = u.length; | |
if (0 === s) throw new TypeError('The value "' + t + '" is invalid for argument "value"'); | |
for (f = 0; f < n - e; ++f) this[f + e] = u[f % s] | |
} | |
return this | |
}; | |
var k = /[^+\/0-9A-Za-z-_]/g; | |
function P(t, r) { | |
var e; | |
r = r || 1 / 0; | |
for (var n = t.length, i = null, o = [], f = 0; f < n; ++f) { | |
if ((e = t.charCodeAt(f)) > 55295 && e < 57344) { | |
if (!i) { | |
if (e > 56319) { | |
(r -= 3) > -1 && o.push(239, 191, 189); | |
continue | |
} | |
if (f + 1 === n) { | |
(r -= 3) > -1 && o.push(239, 191, 189); | |
continue | |
} | |
i = e; | |
continue | |
} | |
if (e < 56320) { | |
(r -= 3) > -1 && o.push(239, 191, 189), i = e; | |
continue | |
} | |
e = 65536 + (i - 55296 << 10 | e - 56320) | |
} else i && (r -= 3) > -1 && o.push(239, 191, 189); | |
if (i = null, e < 128) { | |
if ((r -= 1) < 0) break; | |
o.push(e) | |
} else if (e < 2048) { | |
if ((r -= 2) < 0) break; | |
o.push(e >> 6 | 192, 63 & e | 128) | |
} else if (e < 65536) { | |
if ((r -= 3) < 0) break; | |
o.push(e >> 12 | 224, e >> 6 & 63 | 128, 63 & e | 128) | |
} else { | |
if (!(e < 1114112)) throw new Error("Invalid code point"); | |
if ((r -= 4) < 0) break; | |
o.push(e >> 18 | 240, e >> 12 & 63 | 128, e >> 6 & 63 | 128, 63 & e | 128) | |
} | |
} | |
return o | |
} | |
function j(t) { | |
return n.toByteArray(function (t) { | |
if ((t = (t = t.split("=")[0]).trim().replace(k, "")).length < 2) return ""; | |
for (; t.length % 4 != 0;) t += "="; | |
return t | |
}(t)) | |
} | |
function N(t, r, e, n) { | |
for (var i = 0; i < n && !(i + e >= r.length || i >= t.length); ++i) r[i + e] = t[i]; | |
return i | |
} | |
function z(t, r) { | |
return t instanceof r || null != t && null != t.constructor && null != t.constructor.name && t.constructor.name === r.name | |
} | |
function D(t) { | |
return t != t | |
} | |
var F = function () { | |
for (var t = new Array(256), r = 0; r < 16; ++r) | |
for (var e = 16 * r, n = 0; n < 16; ++n) t[e + n] = "0123456789abcdef" [r] + "0123456789abcdef" [n]; | |
return t | |
}() | |
}).call(this, t("buffer").Buffer) | |
}, { | |
"base64-js": 2, | |
buffer: 5, | |
ieee754: 3 | |
}], | |
2: [function (t, r, e) { | |
"use strict"; | |
e.byteLength = function (t) { | |
var r = h(t), | |
e = r[0], | |
n = r[1]; | |
return 3 * (e + n) / 4 - n | |
}, e.toByteArray = function (t) { | |
var r, e, n = h(t), | |
f = n[0], | |
u = n[1], | |
s = new o(function (t, r, e) { | |
return 3 * (r + e) / 4 - e | |
}(0, f, u)), | |
a = 0, | |
p = u > 0 ? f - 4 : f; | |
for (e = 0; e < p; e += 4) r = i[t.charCodeAt(e)] << 18 | i[t.charCodeAt(e + 1)] << 12 | i[t.charCodeAt(e + 2)] << 6 | i[t.charCodeAt(e + 3)], s[a++] = r >> 16 & 255, s[a++] = r >> 8 & 255, s[a++] = 255 & r; | |
2 === u && (r = i[t.charCodeAt(e)] << 2 | i[t.charCodeAt(e + 1)] >> 4, s[a++] = 255 & r); | |
1 === u && (r = i[t.charCodeAt(e)] << 10 | i[t.charCodeAt(e + 1)] << 4 | i[t.charCodeAt(e + 2)] >> 2, s[a++] = r >> 8 & 255, s[a++] = 255 & r); | |
return s | |
}, e.fromByteArray = function (t) { | |
for (var r, e = t.length, i = e % 3, o = [], f = 0, u = e - i; f < u; f += 16383) o.push(a(t, f, f + 16383 > u ? u : f + 16383)); | |
1 === i ? (r = t[e - 1], o.push(n[r >> 2] + n[r << 4 & 63] + "==")) : 2 === i && (r = (t[e - 2] << 8) + t[e - 1], o.push(n[r >> 10] + n[r >> 4 & 63] + n[r << 2 & 63] + "=")); | |
return o.join("") | |
}; | |
for (var n = [], i = [], o = "undefined" != typeof Uint8Array ? Uint8Array : Array, f = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", u = 0, s = f.length; u < s; ++u) n[u] = f[u], i[f.charCodeAt(u)] = u; | |
function h(t) { | |
var r = t.length; | |
if (r % 4 > 0) throw new Error("Invalid string. Length must be a multiple of 4"); | |
var e = t.indexOf("="); | |
return -1 === e && (e = r), [e, e === r ? 0 : 4 - e % 4] | |
} | |
function a(t, r, e) { | |
for (var i, o, f = [], u = r; u < e; u += 3) i = (t[u] << 16 & 16711680) + (t[u + 1] << 8 & 65280) + (255 & t[u + 2]), f.push(n[(o = i) >> 18 & 63] + n[o >> 12 & 63] + n[o >> 6 & 63] + n[63 & o]); | |
return f.join("") | |
} | |
i["-".charCodeAt(0)] = 62, i["_".charCodeAt(0)] = 63 | |
}, {}], | |
3: [function (t, r, e) { | |
e.read = function (t, r, e, n, i) { | |
var o, f, u = 8 * i - n - 1, | |
s = (1 << u) - 1, | |
h = s >> 1, | |
a = -7, | |
p = e ? i - 1 : 0, | |
c = e ? -1 : 1, | |
l = t[r + p]; | |
for (p += c, o = l & (1 << -a) - 1, l >>= -a, a += u; a > 0; o = 256 * o + t[r + p], p += c, a -= 8); | |
for (f = o & (1 << -a) - 1, o >>= -a, a += n; a > 0; f = 256 * f + t[r + p], p += c, a -= 8); | |
if (0 === o) o = 1 - h; | |
else { | |
if (o === s) return f ? NaN : 1 / 0 * (l ? -1 : 1); | |
f += Math.pow(2, n), o -= h | |
} | |
return (l ? -1 : 1) * f * Math.pow(2, o - n) | |
}, e.write = function (t, r, e, n, i, o) { | |
var f, u, s, h = 8 * o - i - 1, | |
a = (1 << h) - 1, | |
p = a >> 1, | |
c = 23 === i ? Math.pow(2, -24) - Math.pow(2, -77) : 0, | |
l = n ? 0 : o - 1, | |
y = n ? 1 : -1, | |
g = r < 0 || 0 === r && 1 / r < 0 ? 1 : 0; | |
for (r = Math.abs(r), isNaN(r) || r === 1 / 0 ? (u = isNaN(r) ? 1 : 0, f = a) : (f = Math.floor(Math.log(r) / Math.LN2), r * (s = Math.pow(2, -f)) < 1 && (f--, s *= 2), (r += f + p >= 1 ? c / s : c * Math.pow(2, 1 - p)) * s >= 2 && (f++, s /= 2), f + p >= a ? (u = 0, f = a) : f + p >= 1 ? (u = (r * s - 1) * Math.pow(2, i), f += p) : (u = r * Math.pow(2, p - 1) * Math.pow(2, i), f = 0)); i >= 8; t[e + l] = 255 & u, l += y, u /= 256, i -= 8); | |
for (f = f << i | u, h += i; h > 0; t[e + l] = 255 & f, l += y, f /= 256, h -= 8); | |
t[e + l - y] |= 128 * g | |
} | |
}, {}], | |
4: [function (t, r, e) { | |
arguments[4][2][0].apply(e, arguments) | |
}, { | |
dup: 2 | |
}], | |
5: [function (t, r, e) { | |
(function (r) { | |
"use strict"; | |
var n = t("base64-js"), | |
i = t("ieee754"); | |
e.Buffer = r, e.SlowBuffer = function (t) { | |
+t != t && (t = 0); | |
return r.alloc(+t) | |
}, e.INSPECT_MAX_BYTES = 50; | |
var o = 2147483647; | |
function f(t) { | |
if (t > o) throw new RangeError('The value "' + t + '" is invalid for option "size"'); | |
var e = new Uint8Array(t); | |
return e.__proto__ = r.prototype, e | |
} | |
function r(t, r, e) { | |
if ("number" == typeof t) { | |
if ("string" == typeof r) throw new TypeError('The "string" argument must be of type string. Received type number'); | |
return h(t) | |
} | |
return u(t, r, e) | |
} | |
function u(t, e, n) { | |
if ("string" == typeof t) return function (t, e) { | |
"string" == typeof e && "" !== e || (e = "utf8"); | |
if (!r.isEncoding(e)) throw new TypeError("Unknown encoding: " + e); | |
var n = 0 | c(t, e), | |
i = f(n), | |
o = i.write(t, e); | |
o !== n && (i = i.slice(0, o)); | |
return i | |
}(t, e); | |
if (ArrayBuffer.isView(t)) return a(t); | |
if (null == t) throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type " + typeof t); | |
if (z(t, ArrayBuffer) || t && z(t.buffer, ArrayBuffer)) return function (t, e, n) { | |
if (e < 0 || t.byteLength < e) throw new RangeError('"offset" is outside of buffer bounds'); | |
if (t.byteLength < e + (n || 0)) throw new RangeError('"length" is outside of buffer bounds'); | |
var i; | |
i = void 0 === e && void 0 === n ? new Uint8Array(t) : void 0 === n ? new Uint8Array(t, e) : new Uint8Array(t, e, n); | |
return i.__proto__ = r.prototype, i | |
}(t, e, n); | |
if ("number" == typeof t) throw new TypeError('The "value" argument must not be of type number. Received type number'); | |
var i = t.valueOf && t.valueOf(); | |
if (null != i && i !== t) return r.from(i, e, n); | |
var o = function (t) { | |
if (r.isBuffer(t)) { | |
var e = 0 | p(t.length), | |
n = f(e); | |
return 0 === n.length ? n : (t.copy(n, 0, 0, e), n) | |
} | |
if (void 0 !== t.length) return "number" != typeof t.length || D(t.length) ? f(0) : a(t); | |
if ("Buffer" === t.type && Array.isArray(t.data)) return a(t.data) | |
}(t); | |
if (o) return o; | |
if ("undefined" != typeof Symbol && null != Symbol.toPrimitive && "function" == typeof t[Symbol.toPrimitive]) return r.from(t[Symbol.toPrimitive]("string"), e, n); | |
throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type " + typeof t) | |
} | |
function s(t) { | |
if ("number" != typeof t) throw new TypeError('"size" argument must be of type number'); | |
if (t < 0) throw new RangeError('The value "' + t + '" is invalid for option "size"') | |
} | |
function h(t) { | |
return s(t), f(t < 0 ? 0 : 0 | p(t)) | |
} | |
function a(t) { | |
for (var r = t.length < 0 ? 0 : 0 | p(t.length), e = f(r), n = 0; n < r; n += 1) e[n] = 255 & t[n]; | |
return e | |
} | |
function p(t) { | |
if (t >= o) throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x" + o.toString(16) + " bytes"); | |
return 0 | t | |
} | |
function c(t, e) { | |
if (r.isBuffer(t)) return t.length; | |
if (ArrayBuffer.isView(t) || z(t, ArrayBuffer)) return t.byteLength; | |
if ("string" != typeof t) throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type ' + typeof t); | |
var n = t.length, | |
i = arguments.length > 2 && !0 === arguments[2]; | |
if (!i && 0 === n) return 0; | |
for (var o = !1;;) switch (e) { | |
case "ascii": | |
case "latin1": | |
case "binary": | |
return n; | |
case "utf8": | |
case "utf-8": | |
return P(t).length; | |
case "ucs2": | |
case "ucs-2": | |
case "utf16le": | |
case "utf-16le": | |
return 2 * n; | |
case "hex": | |
return n >>> 1; | |
case "base64": | |
return j(t).length; | |
default: | |
if (o) return i ? -1 : P(t).length; | |
e = ("" + e).toLowerCase(), o = !0 | |
} | |
} | |
function l(t, r, e) { | |
var n = t[r]; | |
t[r] = t[e], t[e] = n | |
} | |
function y(t, e, n, i, o) { | |
if (0 === t.length) return -1; | |
if ("string" == typeof n ? (i = n, n = 0) : n > 2147483647 ? n = 2147483647 : n < -2147483648 && (n = -2147483648), D(n = +n) && (n = o ? 0 : t.length - 1), n < 0 && (n = t.length + n), n >= t.length) { | |
if (o) return -1; | |
n = t.length - 1 | |
} else if (n < 0) { | |
if (!o) return -1; | |
n = 0 | |
} | |
if ("string" == typeof e && (e = r.from(e, i)), r.isBuffer(e)) return 0 === e.length ? -1 : g(t, e, n, i, o); | |
if ("number" == typeof e) return e &= 255, "function" == typeof Uint8Array.prototype.indexOf ? o ? Uint8Array.prototype.indexOf.call(t, e, n) : Uint8Array.prototype.lastIndexOf.call(t, e, n) : g(t, [e], n, i, o); | |
throw new TypeError("val must be string, number or Buffer") | |
} | |
function g(t, r, e, n, i) { | |
var o, f = 1, | |
u = t.length, | |
s = r.length; | |
if (void 0 !== n && ("ucs2" === (n = String(n).toLowerCase()) || "ucs-2" === n || "utf16le" === n || "utf-16le" === n)) { | |
if (t.length < 2 || r.length < 2) return -1; | |
f = 2, u /= 2, s /= 2, e /= 2 | |
} | |
function h(t, r) { | |
return 1 === f ? t[r] : t.readUInt16BE(r * f) | |
} | |
if (i) { | |
var a = -1; | |
for (o = e; o < u; o++) | |
if (h(t, o) === h(r, -1 === a ? 0 : o - a)) { | |
if (-1 === a && (a = o), o - a + 1 === s) return a * f | |
} else -1 !== a && (o -= o - a), a = -1 | |
} else | |
for (e + s > u && (e = u - s), o = e; o >= 0; o--) { | |
for (var p = !0, c = 0; c < s; c++) | |
if (h(t, o + c) !== h(r, c)) { | |
p = !1; | |
break | |
} if (p) return o | |
} | |
return -1 | |
} | |
function w(t, r, e, n) { | |
e = Number(e) || 0; | |
var i = t.length - e; | |
n ? (n = Number(n)) > i && (n = i) : n = i; | |
var o = r.length; | |
n > o / 2 && (n = o / 2); | |
for (var f = 0; f < n; ++f) { | |
var u = parseInt(r.substr(2 * f, 2), 16); | |
if (D(u)) return f; | |
t[e + f] = u | |
} | |
return f | |
} | |
function d(t, r, e, n) { | |
return N(P(r, t.length - e), t, e, n) | |
} | |
function v(t, r, e, n) { | |
return N(function (t) { | |
for (var r = [], e = 0; e < t.length; ++e) r.push(255 & t.charCodeAt(e)); | |
return r | |
}(r), t, e, n) | |
} | |
function b(t, r, e, n) { | |
return v(t, r, e, n) | |
} | |
function m(t, r, e, n) { | |
return N(j(r), t, e, n) | |
} | |
function E(t, r, e, n) { | |
return N(function (t, r) { | |
for (var e, n, i, o = [], f = 0; f < t.length && !((r -= 2) < 0); ++f) e = t.charCodeAt(f), n = e >> 8, i = e % 256, o.push(i), o.push(n); | |
return o | |
}(r, t.length - e), t, e, n) | |
} | |
function B(t, r, e) { | |
return 0 === r && e === t.length ? n.fromByteArray(t) : n.fromByteArray(t.slice(r, e)) | |
} | |
function A(t, r, e) { | |
e = Math.min(t.length, e); | |
for (var n = [], i = r; i < e;) { | |
var o, f, u, s, h = t[i], | |
a = null, | |
p = h > 239 ? 4 : h > 223 ? 3 : h > 191 ? 2 : 1; | |
if (i + p <= e) switch (p) { | |
case 1: | |
h < 128 && (a = h); | |
break; | |
case 2: | |
128 == (192 & (o = t[i + 1])) && (s = (31 & h) << 6 | 63 & o) > 127 && (a = s); | |
break; | |
case 3: | |
o = t[i + 1], f = t[i + 2], 128 == (192 & o) && 128 == (192 & f) && (s = (15 & h) << 12 | (63 & o) << 6 | 63 & f) > 2047 && (s < 55296 || s > 57343) && (a = s); | |
break; | |
case 4: | |
o = t[i + 1], f = t[i + 2], u = t[i + 3], 128 == (192 & o) && 128 == (192 & f) && 128 == (192 & u) && (s = (15 & h) << 18 | (63 & o) << 12 | (63 & f) << 6 | 63 & u) > 65535 && s < 1114112 && (a = s) | |
} | |
null === a ? (a = 65533, p = 1) : a > 65535 && (a -= 65536, n.push(a >>> 10 & 1023 | 55296), a = 56320 | 1023 & a), n.push(a), i += p | |
} | |
return function (t) { | |
var r = t.length; | |
if (r <= U) return String.fromCharCode.apply(String, t); | |
var e = "", | |
n = 0; | |
for (; n < r;) e += String.fromCharCode.apply(String, t.slice(n, n += U)); | |
return e | |
}(n) | |
} | |
e.kMaxLength = o, r.TYPED_ARRAY_SUPPORT = function () { | |
try { | |
var t = new Uint8Array(1); | |
return t.__proto__ = { | |
__proto__: Uint8Array.prototype, | |
foo: function () { | |
return 42 | |
} | |
}, 42 === t.foo() | |
} catch (t) { | |
return !1 | |
} | |
}(), r.TYPED_ARRAY_SUPPORT || "undefined" == typeof console || "function" != typeof console.error || console.error("This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support."), Object.defineProperty(r.prototype, "parent", { | |
enumerable: !0, | |
get: function () { | |
if (r.isBuffer(this)) return this.buffer | |
} | |
}), Object.defineProperty(r.prototype, "offset", { | |
enumerable: !0, | |
get: function () { | |
if (r.isBuffer(this)) return this.byteOffset | |
} | |
}), "undefined" != typeof Symbol && null != Symbol.species && r[Symbol.species] === r && Object.defineProperty(r, Symbol.species, { | |
value: null, | |
configurable: !0, | |
enumerable: !1, | |
writable: !1 | |
}), r.poolSize = 8192, r.from = function (t, r, e) { | |
return u(t, r, e) | |
}, r.prototype.__proto__ = Uint8Array.prototype, r.__proto__ = Uint8Array, r.alloc = function (t, r, e) { | |
return function (t, r, e) { | |
return s(t), t <= 0 ? f(t) : void 0 !== r ? "string" == typeof e ? f(t).fill(r, e) : f(t).fill(r) : f(t) | |
}(t, r, e) | |
}, r.allocUnsafe = function (t) { | |
return h(t) | |
}, r.allocUnsafeSlow = function (t) { | |
return h(t) | |
}, r.isBuffer = function (t) { | |
return null != t && !0 === t._isBuffer && t !== r.prototype | |
}, r.compare = function (t, e) { | |
if (z(t, Uint8Array) && (t = r.from(t, t.offset, t.byteLength)), z(e, Uint8Array) && (e = r.from(e, e.offset, e.byteLength)), !r.isBuffer(t) || !r.isBuffer(e)) throw new TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'); | |
if (t === e) return 0; | |
for (var n = t.length, i = e.length, o = 0, f = Math.min(n, i); o < f; ++o) | |
if (t[o] !== e[o]) { | |
n = t[o], i = e[o]; | |
break | |
} return n < i ? -1 : i < n ? 1 : 0 | |
}, r.isEncoding = function (t) { | |
switch (String(t).toLowerCase()) { | |
case "hex": | |
case "utf8": | |
case "utf-8": | |
case "ascii": | |
case "latin1": | |
case "binary": | |
case "base64": | |
case "ucs2": | |
case "ucs-2": | |
case "utf16le": | |
case "utf-16le": | |
return !0; | |
default: | |
return !1 | |
} | |
}, r.concat = function (t, e) { | |
if (!Array.isArray(t)) throw new TypeError('"list" argument must be an Array of Buffers'); | |
if (0 === t.length) return r.alloc(0); | |
var n; | |
if (void 0 === e) | |
for (e = 0, n = 0; n < t.length; ++n) e += t[n].length; | |
var i = r.allocUnsafe(e), | |
o = 0; | |
for (n = 0; n < t.length; ++n) { | |
var f = t[n]; | |
if (z(f, Uint8Array) && (f = r.from(f)), !r.isBuffer(f)) throw new TypeError('"list" argument must be an Array of Buffers'); | |
f.copy(i, o), o += f.length | |
} | |
return i | |
}, r.byteLength = c, r.prototype._isBuffer = !0, r.prototype.swap16 = function () { | |
var t = this.length; | |
if (t % 2 != 0) throw new RangeError("Buffer size must be a multiple of 16-bits"); | |
for (var r = 0; r < t; r += 2) l(this, r, r + 1); | |
return this | |
}, r.prototype.swap32 = function () { | |
var t = this.length; | |
if (t % 4 != 0) throw new RangeError("Buffer size must be a multiple of 32-bits"); | |
for (var r = 0; r < t; r += 4) l(this, r, r + 3), l(this, r + 1, r + 2); | |
return this | |
}, r.prototype.swap64 = function () { | |
var t = this.length; | |
if (t % 8 != 0) throw new RangeError("Buffer size must be a multiple of 64-bits"); | |
for (var r = 0; r < t; r += 8) l(this, r, r + 7), l(this, r + 1, r + 6), l(this, r + 2, r + 5), l(this, r + 3, r + 4); | |
return this | |
}, r.prototype.toString = function () { | |
var t = this.length; | |
return 0 === t ? "" : 0 === arguments.length ? A(this, 0, t) : function (t, r, e) { | |
var n = !1; | |
if ((void 0 === r || r < 0) && (r = 0), r > this.length) return ""; | |
if ((void 0 === e || e > this.length) && (e = this.length), e <= 0) return ""; | |
if ((e >>>= 0) <= (r >>>= 0)) return ""; | |
for (t || (t = "utf8");;) switch (t) { | |
case "hex": | |
return S(this, r, e); | |
case "utf8": | |
case "utf-8": | |
return A(this, r, e); | |
case "ascii": | |
return T(this, r, e); | |
case "latin1": | |
case "binary": | |
return I(this, r, e); | |
case "base64": | |
return B(this, r, e); | |
case "ucs2": | |
case "ucs-2": | |
case "utf16le": | |
case "utf-16le": | |
return L(this, r, e); | |
default: | |
if (n) throw new TypeError("Unknown encoding: " + t); | |
t = (t + "").toLowerCase(), n = !0 | |
} | |
}.apply(this, arguments) | |
}, r.prototype.toLocaleString = r.prototype.toString, r.prototype.equals = function (t) { | |
if (!r.isBuffer(t)) throw new TypeError("Argument must be a Buffer"); | |
return this === t || 0 === r.compare(this, t) | |
}, r.prototype.inspect = function () { | |
var t = "", | |
r = e.INSPECT_MAX_BYTES; | |
return t = this.toString("hex", 0, r).replace(/(.{2})/g, "$1 ").trim(), this.length > r && (t += " ... "), "<Buffer " + t + ">" | |
}, r.prototype.compare = function (t, e, n, i, o) { | |
if (z(t, Uint8Array) && (t = r.from(t, t.offset, t.byteLength)), !r.isBuffer(t)) throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type ' + typeof t); | |
if (void 0 === e && (e = 0), void 0 === n && (n = t ? t.length : 0), void 0 === i && (i = 0), void 0 === o && (o = this.length), e < 0 || n > t.length || i < 0 || o > this.length) throw new RangeError("out of range index"); | |
if (i >= o && e >= n) return 0; | |
if (i >= o) return -1; | |
if (e >= n) return 1; | |
if (this === t) return 0; | |
for (var f = (o >>>= 0) - (i >>>= 0), u = (n >>>= 0) - (e >>>= 0), s = Math.min(f, u), h = this.slice(i, o), a = t.slice(e, n), p = 0; p < s; ++p) | |
if (h[p] !== a[p]) { | |
f = h[p], u = a[p]; | |
break | |
} return f < u ? -1 : u < f ? 1 : 0 | |
}, r.prototype.includes = function (t, r, e) { | |
return -1 !== this.indexOf(t, r, e) | |
}, r.prototype.indexOf = function (t, r, e) { | |
return y(this, t, r, e, !0) | |
}, r.prototype.lastIndexOf = function (t, r, e) { | |
return y(this, t, r, e, !1) | |
}, r.prototype.write = function (t, r, e, n) { | |
if (void 0 === r) n = "utf8", e = this.length, r = 0; | |
else if (void 0 === e && "string" == typeof r) n = r, e = this.length, r = 0; | |
else { | |
if (!isFinite(r)) throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported"); | |
r >>>= 0, isFinite(e) ? (e >>>= 0, void 0 === n && (n = "utf8")) : (n = e, e = void 0) | |
} | |
var i = this.length - r; | |
if ((void 0 === e || e > i) && (e = i), t.length > 0 && (e < 0 || r < 0) || r > this.length) throw new RangeError("Attempt to write outside buffer bounds"); | |
n || (n = "utf8"); | |
for (var o = !1;;) switch (n) { | |
case "hex": | |
return w(this, t, r, e); | |
case "utf8": | |
case "utf-8": | |
return d(this, t, r, e); | |
case "ascii": | |
return v(this, t, r, e); | |
case "latin1": | |
case "binary": | |
return b(this, t, r, e); | |
case "base64": | |
return m(this, t, r, e); | |
case "ucs2": | |
case "ucs-2": | |
case "utf16le": | |
case "utf-16le": | |
return E(this, t, r, e); | |
default: | |
if (o) throw new TypeError("Unknown encoding: " + n); | |
n = ("" + n).toLowerCase(), o = !0 | |
} | |
}, r.prototype.toJSON = function () { | |
return { | |
type: "Buffer", | |
data: Array.prototype.slice.call(this._arr || this, 0) | |
} | |
}; | |
var U = 4096; | |
function T(t, r, e) { | |
var n = ""; | |
e = Math.min(t.length, e); | |
for (var i = r; i < e; ++i) n += String.fromCharCode(127 & t[i]); | |
return n | |
} | |
function I(t, r, e) { | |
var n = ""; | |
e = Math.min(t.length, e); | |
for (var i = r; i < e; ++i) n += String.fromCharCode(t[i]); | |
return n | |
} | |
function S(t, r, e) { | |
var n = t.length; | |
(!r || r < 0) && (r = 0), (!e || e < 0 || e > n) && (e = n); | |
for (var i = "", o = r; o < e; ++o) i += k(t[o]); | |
return i | |
} | |
function L(t, r, e) { | |
for (var n = t.slice(r, e), i = "", o = 0; o < n.length; o += 2) i += String.fromCharCode(n[o] + 256 * n[o + 1]); | |
return i | |
} | |
function R(t, r, e) { | |
if (t % 1 != 0 || t < 0) throw new RangeError("offset is not uint"); | |
if (t + r > e) throw new RangeError("Trying to access beyond buffer length") | |
} | |
function C(t, e, n, i, o, f) { | |
if (!r.isBuffer(t)) throw new TypeError('"buffer" argument must be a Buffer instance'); | |
if (e > o || e < f) throw new RangeError('"value" argument is out of bounds'); | |
if (n + i > t.length) throw new RangeError("Index out of range") | |
} | |
function O(t, r, e, n, i, o) { | |
if (e + n > t.length) throw new RangeError("Index out of range"); | |
if (e < 0) throw new RangeError("Index out of range") | |
} | |
function _(t, r, e, n, o) { | |
return r = +r, e >>>= 0, o || O(t, 0, e, 4), i.write(t, r, e, n, 23, 4), e + 4 | |
} | |
function x(t, r, e, n, o) { | |
return r = +r, e >>>= 0, o || O(t, 0, e, 8), i.write(t, r, e, n, 52, 8), e + 8 | |
} | |
r.prototype.slice = function (t, e) { | |
var n = this.length; | |
(t = ~~t) < 0 ? (t += n) < 0 && (t = 0) : t > n && (t = n), (e = void 0 === e ? n : ~~e) < 0 ? (e += n) < 0 && (e = 0) : e > n && (e = n), e < t && (e = t); | |
var i = this.subarray(t, e); | |
return i.__proto__ = r.prototype, i | |
}, r.prototype.readUIntLE = function (t, r, e) { | |
t >>>= 0, r >>>= 0, e || R(t, r, this.length); | |
for (var n = this[t], i = 1, o = 0; ++o < r && (i *= 256);) n += this[t + o] * i; | |
return n | |
}, r.prototype.readUIntBE = function (t, r, e) { | |
t >>>= 0, r >>>= 0, e || R(t, r, this.length); | |
for (var n = this[t + --r], i = 1; r > 0 && (i *= 256);) n += this[t + --r] * i; | |
return n | |
}, r.prototype.readUInt8 = function (t, r) { | |
return t >>>= 0, r || R(t, 1, this.length), this[t] | |
}, r.prototype.readUInt16LE = function (t, r) { | |
return t >>>= 0, r || R(t, 2, this.length), this[t] | this[t + 1] << 8 | |
}, r.prototype.readUInt16BE = function (t, r) { | |
return t >>>= 0, r || R(t, 2, this.length), this[t] << 8 | this[t + 1] | |
}, r.prototype.readUInt32LE = function (t, r) { | |
return t >>>= 0, r || R(t, 4, this.length), (this[t] | this[t + 1] << 8 | this[t + 2] << 16) + 16777216 * this[t + 3] | |
}, r.prototype.readUInt32BE = function (t, r) { | |
return t >>>= 0, r || R(t, 4, this.length), 16777216 * this[t] + (this[t + 1] << 16 | this[t + 2] << 8 | this[t + 3]) | |
}, r.prototype.readIntLE = function (t, r, e) { | |
t >>>= 0, r >>>= 0, e || R(t, r, this.length); | |
for (var n = this[t], i = 1, o = 0; ++o < r && (i *= 256);) n += this[t + o] * i; | |
return n >= (i *= 128) && (n -= Math.pow(2, 8 * r)), n | |
}, r.prototype.readIntBE = function (t, r, e) { | |
t >>>= 0, r >>>= 0, e || R(t, r, this.length); | |
for (var n = r, i = 1, o = this[t + --n]; n > 0 && (i *= 256);) o += this[t + --n] * i; | |
return o >= (i *= 128) && (o -= Math.pow(2, 8 * r)), o | |
}, r.prototype.readInt8 = function (t, r) { | |
return t >>>= 0, r || R(t, 1, this.length), 128 & this[t] ? -1 * (255 - this[t] + 1) : this[t] | |
}, r.prototype.readInt16LE = function (t, r) { | |
t >>>= 0, r || R(t, 2, this.length); | |
var e = this[t] | this[t + 1] << 8; | |
return 32768 & e ? 4294901760 | e : e | |
}, r.prototype.readInt16BE = function (t, r) { | |
t >>>= 0, r || R(t, 2, this.length); | |
var e = this[t + 1] | this[t] << 8; | |
return 32768 & e ? 4294901760 | e : e | |
}, r.prototype.readInt32LE = function (t, r) { | |
return t >>>= 0, r || R(t, 4, this.length), this[t] | this[t + 1] << 8 | this[t + 2] << 16 | this[t + 3] << 24 | |
}, r.prototype.readInt32BE = function (t, r) { | |
return t >>>= 0, r || R(t, 4, this.length), this[t] << 24 | this[t + 1] << 16 | this[t + 2] << 8 | this[t + 3] | |
}, r.prototype.readFloatLE = function (t, r) { | |
return t >>>= 0, r || R(t, 4, this.length), i.read(this, t, !0, 23, 4) | |
}, r.prototype.readFloatBE = function (t, r) { | |
return t >>>= 0, r || R(t, 4, this.length), i.read(this, t, !1, 23, 4) | |
}, r.prototype.readDoubleLE = function (t, r) { | |
return t >>>= 0, r || R(t, 8, this.length), i.read(this, t, !0, 52, 8) | |
}, r.prototype.readDoubleBE = function (t, r) { | |
return t >>>= 0, r || R(t, 8, this.length), i.read(this, t, !1, 52, 8) | |
}, r.prototype.writeUIntLE = function (t, r, e, n) { | |
(t = +t, r >>>= 0, e >>>= 0, n) || C(this, t, r, e, Math.pow(2, 8 * e) - 1, 0); | |
var i = 1, | |
o = 0; | |
for (this[r] = 255 & t; ++o < e && (i *= 256);) this[r + o] = t / i & 255; | |
return r + e | |
}, r.prototype.writeUIntBE = function (t, r, e, n) { | |
(t = +t, r >>>= 0, e >>>= 0, n) || C(this, t, r, e, Math.pow(2, 8 * e) - 1, 0); | |
var i = e - 1, | |
o = 1; | |
for (this[r + i] = 255 & t; --i >= 0 && (o *= 256);) this[r + i] = t / o & 255; | |
return r + e | |
}, r.prototype.writeUInt8 = function (t, r, e) { | |
return t = +t, r >>>= 0, e || C(this, t, r, 1, 255, 0), this[r] = 255 & t, r + 1 | |
}, r.prototype.writeUInt16LE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || C(this, t, r, 2, 65535, 0), this[r] = 255 & t, this[r + 1] = t >>> 8, r + 2 | |
}, r.prototype.writeUInt16BE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || C(this, t, r, 2, 65535, 0), this[r] = t >>> 8, this[r + 1] = 255 & t, r + 2 | |
}, r.prototype.writeUInt32LE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || C(this, t, r, 4, 4294967295, 0), this[r + 3] = t >>> 24, this[r + 2] = t >>> 16, this[r + 1] = t >>> 8, this[r] = 255 & t, r + 4 | |
}, r.prototype.writeUInt32BE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || C(this, t, r, 4, 4294967295, 0), this[r] = t >>> 24, this[r + 1] = t >>> 16, this[r + 2] = t >>> 8, this[r + 3] = 255 & t, r + 4 | |
}, r.prototype.writeIntLE = function (t, r, e, n) { | |
if (t = +t, r >>>= 0, !n) { | |
var i = Math.pow(2, 8 * e - 1); | |
C(this, t, r, e, i - 1, -i) | |
} | |
var o = 0, | |
f = 1, | |
u = 0; | |
for (this[r] = 255 & t; ++o < e && (f *= 256);) t < 0 && 0 === u && 0 !== this[r + o - 1] && (u = 1), this[r + o] = (t / f >> 0) - u & 255; | |
return r + e | |
}, r.prototype.writeIntBE = function (t, r, e, n) { | |
if (t = +t, r >>>= 0, !n) { | |
var i = Math.pow(2, 8 * e - 1); | |
C(this, t, r, e, i - 1, -i) | |
} | |
var o = e - 1, | |
f = 1, | |
u = 0; | |
for (this[r + o] = 255 & t; --o >= 0 && (f *= 256);) t < 0 && 0 === u && 0 !== this[r + o + 1] && (u = 1), this[r + o] = (t / f >> 0) - u & 255; | |
return r + e | |
}, r.prototype.writeInt8 = function (t, r, e) { | |
return t = +t, r >>>= 0, e || C(this, t, r, 1, 127, -128), t < 0 && (t = 255 + t + 1), this[r] = 255 & t, r + 1 | |
}, r.prototype.writeInt16LE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || C(this, t, r, 2, 32767, -32768), this[r] = 255 & t, this[r + 1] = t >>> 8, r + 2 | |
}, r.prototype.writeInt16BE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || C(this, t, r, 2, 32767, -32768), this[r] = t >>> 8, this[r + 1] = 255 & t, r + 2 | |
}, r.prototype.writeInt32LE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || C(this, t, r, 4, 2147483647, -2147483648), this[r] = 255 & t, this[r + 1] = t >>> 8, this[r + 2] = t >>> 16, this[r + 3] = t >>> 24, r + 4 | |
}, r.prototype.writeInt32BE = function (t, r, e) { | |
return t = +t, r >>>= 0, e || C(this, t, r, 4, 2147483647, -2147483648), t < 0 && (t = 4294967295 + t + 1), this[r] = t >>> 24, this[r + 1] = t >>> 16, this[r + 2] = t >>> 8, this[r + 3] = 255 & t, r + 4 | |
}, r.prototype.writeFloatLE = function (t, r, e) { | |
return _(this, t, r, !0, e) | |
}, r.prototype.writeFloatBE = function (t, r, e) { | |
return _(this, t, r, !1, e) | |
}, r.prototype.writeDoubleLE = function (t, r, e) { | |
return x(this, t, r, !0, e) | |
}, r.prototype.writeDoubleBE = function (t, r, e) { | |
return x(this, t, r, !1, e) | |
}, r.prototype.copy = function (t, e, n, i) { | |
if (!r.isBuffer(t)) throw new TypeError("argument should be a Buffer"); | |
if (n || (n = 0), i || 0 === i || (i = this.length), e >= t.length && (e = t.length), e || (e = 0), i > 0 && i < n && (i = n), i === n) return 0; | |
if (0 === t.length || 0 === this.length) return 0; | |
if (e < 0) throw new RangeError("targetStart out of bounds"); | |
if (n < 0 || n >= this.length) throw new RangeError("Index out of range"); | |
if (i < 0) throw new RangeError("sourceEnd out of bounds"); | |
i > this.length && (i = this.length), t.length - e < i - n && (i = t.length - e + n); | |
var o = i - n; | |
if (this === t && "function" == typeof Uint8Array.prototype.copyWithin) this.copyWithin(e, n, i); | |
else if (this === t && n < e && e < i) | |
for (var f = o - 1; f >= 0; --f) t[f + e] = this[f + n]; | |
else Uint8Array.prototype.set.call(t, this.subarray(n, i), e); | |
return o | |
}, r.prototype.fill = function (t, e, n, i) { | |
if ("string" == typeof t) { | |
if ("string" == typeof e ? (i = e, e = 0, n = this.length) : "string" == typeof n && (i = n, n = this.length), void 0 !== i && "string" != typeof i) throw new TypeError("encoding must be a string"); | |
if ("string" == typeof i && !r.isEncoding(i)) throw new TypeError("Unknown encoding: " + i); | |
if (1 === t.length) { | |
var o = t.charCodeAt(0); | |
("utf8" === i && o < 128 || "latin1" === i) && (t = o) | |
} | |
} else "number" == typeof t && (t &= 255); | |
if (e < 0 || this.length < e || this.length < n) throw new RangeError("Out of range index"); | |
if (n <= e) return this; | |
var f; | |
if (e >>>= 0, n = void 0 === n ? this.length : n >>> 0, t || (t = 0), "number" == typeof t) | |
for (f = e; f < n; ++f) this[f] = t; | |
else { | |
var u = r.isBuffer(t) ? t : r.from(t, i), | |
s = u.length; | |
if (0 === s) throw new TypeError('The value "' + t + '" is invalid for argument "value"'); | |
for (f = 0; f < n - e; ++f) this[f + e] = u[f % s] | |
} | |
return this | |
}; | |
var M = /[^+\/0-9A-Za-z-_]/g; | |
function k(t) { | |
return t < 16 ? "0" + t.toString(16) : t.toString(16) | |
} | |
function P(t, r) { | |
var e; | |
r = r || 1 / 0; | |
for (var n = t.length, i = null, o = [], f = 0; f < n; ++f) { | |
if ((e = t.charCodeAt(f)) > 55295 && e < 57344) { | |
if (!i) { | |
if (e > 56319) { | |
(r -= 3) > -1 && o.push(239, 191, 189); | |
continue | |
} | |
if (f + 1 === n) { | |
(r -= 3) > -1 && o.push(239, 191, 189); | |
continue | |
} | |
i = e; | |
continue | |
} | |
if (e < 56320) { | |
(r -= 3) > -1 && o.push(239, 191, 189), i = e; | |
continue | |
} | |
e = 65536 + (i - 55296 << 10 | e - 56320) | |
} else i && (r -= 3) > -1 && o.push(239, 191, 189); | |
if (i = null, e < 128) { | |
if ((r -= 1) < 0) break; | |
o.push(e) | |
} else if (e < 2048) { | |
if ((r -= 2) < 0) break; | |
o.push(e >> 6 | 192, 63 & e | 128) | |
} else if (e < 65536) { | |
if ((r -= 3) < 0) break; | |
o.push(e >> 12 | 224, e >> 6 & 63 | 128, 63 & e | 128) | |
} else { | |
if (!(e < 1114112)) throw new Error("Invalid code point"); | |
if ((r -= 4) < 0) break; | |
o.push(e >> 18 | 240, e >> 12 & 63 | 128, e >> 6 & 63 | 128, 63 & e | 128) | |
} | |
} | |
return o | |
} | |
function j(t) { | |
return n.toByteArray(function (t) { | |
if ((t = (t = t.split("=")[0]).trim().replace(M, "")).length < 2) return ""; | |
for (; t.length % 4 != 0;) t += "="; | |
return t | |
}(t)) | |
} | |
function N(t, r, e, n) { | |
for (var i = 0; i < n && !(i + e >= r.length || i >= t.length); ++i) r[i + e] = t[i]; | |
return i | |
} | |
function z(t, r) { | |
return t instanceof r || null != t && null != t.constructor && null != t.constructor.name && t.constructor.name === r.name | |
} | |
function D(t) { | |
return t != t | |
} | |
}).call(this, t("buffer").Buffer) | |
}, { | |
"base64-js": 4, | |
buffer: 5, | |
ieee754: 6 | |
}], | |
6: [function (t, r, e) { | |
arguments[4][3][0].apply(e, arguments) | |
}, { | |
dup: 3 | |
}] | |
}, {}, [1])(1) | |
}); | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.DamaiSelectSeat = {}))); | |
}(this, (function (exports) { | |
'use strict'; | |
function createCommonjsModule(fn, module) { | |
return module = { | |
exports: {} | |
}, fn(module, module.exports), module.exports; | |
} | |
var runtime = createCommonjsModule(function (module) { | |
/** | |
* Copyright (c) 2014-present, Facebook, Inc. | |
* | |
* This source code is licensed under the MIT license found in the | |
* LICENSE file in the root directory of this source tree. | |
*/ | |
!(function (global) { | |
var Op = Object.prototype; | |
var hasOwn = Op.hasOwnProperty; | |
var undefined; // More compressible than void 0. | |
var $Symbol = typeof Symbol === "function" ? Symbol : {}; | |
var iteratorSymbol = $Symbol.iterator || "@@iterator"; | |
var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; | |
var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; | |
var inModule = 'object' === "object"; | |
var runtime = global.regeneratorRuntime; | |
if (runtime) { | |
if (inModule) { | |
// If regeneratorRuntime is defined globally and we're in a module, | |
// make the exports object identical to regeneratorRuntime. | |
module.exports = runtime; | |
} | |
// Don't bother evaluating the rest of this file if the runtime was | |
// already defined globally. | |
return; | |
} | |
// Define the runtime globally (as expected by generated code) as either | |
// module.exports (if we're in a module) or a new, empty object. | |
runtime = global.regeneratorRuntime = inModule ? module.exports : {}; | |
function wrap(innerFn, outerFn, self, tryLocsList) { | |
// If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. | |
var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; | |
var generator = Object.create(protoGenerator.prototype); | |
var context = new Context(tryLocsList || []); | |
// The ._invoke method unifies the implementations of the .next, | |
// .throw, and .return methods. | |
generator._invoke = makeInvokeMethod(innerFn, self, context); | |
return generator; | |
} | |
runtime.wrap = wrap; | |
// Try/catch helper to minimize deoptimizations. Returns a completion | |
// record like context.tryEntries[i].completion. This interface could | |
// have been (and was previously) designed to take a closure to be | |
// invoked without arguments, but in all the cases we care about we | |
// already have an existing method we want to call, so there's no need | |
// to create a new function object. We can even get away with assuming | |
// the method takes exactly one argument, since that happens to be true | |
// in every case, so we don't have to touch the arguments object. The | |
// only additional allocation required is the completion record, which | |
// has a stable shape and so hopefully should be cheap to allocate. | |
function tryCatch(fn, obj, arg) { | |
try { | |
return { | |
type: "normal", | |
arg: fn.call(obj, arg) | |
}; | |
} catch (err) { | |
return { | |
type: "throw", | |
arg: err | |
}; | |
} | |
} | |
var GenStateSuspendedStart = "suspendedStart"; | |
var GenStateSuspendedYield = "suspendedYield"; | |
var GenStateExecuting = "executing"; | |
var GenStateCompleted = "completed"; | |
// Returning this object from the innerFn has the same effect as | |
// breaking out of the dispatch switch statement. | |
var ContinueSentinel = {}; | |
// Dummy constructor functions that we use as the .constructor and | |
// .constructor.prototype properties for functions that return Generator | |
// objects. For full spec compliance, you may wish to configure your | |
// minifier not to mangle the names of these two functions. | |
function Generator() {} | |
function GeneratorFunction() {} | |
function GeneratorFunctionPrototype() {} | |
// This is a polyfill for %IteratorPrototype% for environments that | |
// don't natively support it. | |
var IteratorPrototype = {}; | |
IteratorPrototype[iteratorSymbol] = function () { | |
return this; | |
}; | |
var getProto = Object.getPrototypeOf; | |
var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); | |
if (NativeIteratorPrototype && | |
NativeIteratorPrototype !== Op && | |
hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { | |
// This environment has a native %IteratorPrototype%; use it instead | |
// of the polyfill. | |
IteratorPrototype = NativeIteratorPrototype; | |
} | |
var Gp = GeneratorFunctionPrototype.prototype = | |
Generator.prototype = Object.create(IteratorPrototype); | |
GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; | |
GeneratorFunctionPrototype.constructor = GeneratorFunction; | |
GeneratorFunctionPrototype[toStringTagSymbol] = | |
GeneratorFunction.displayName = "GeneratorFunction"; | |
// Helper for defining the .next, .throw, and .return methods of the | |
// Iterator interface in terms of a single ._invoke method. | |
function defineIteratorMethods(prototype) { | |
["next", "throw", "return"].forEach(function (method) { | |
prototype[method] = function (arg) { | |
return this._invoke(method, arg); | |
}; | |
}); | |
} | |
runtime.isGeneratorFunction = function (genFun) { | |
var ctor = typeof genFun === "function" && genFun.constructor; | |
return ctor ? | |
ctor === GeneratorFunction || | |
// For the native GeneratorFunction constructor, the best we can | |
// do is to check its .name property. | |
(ctor.displayName || ctor.name) === "GeneratorFunction" : | |
false; | |
}; | |
runtime.mark = function (genFun) { | |
if (Object.setPrototypeOf) { | |
Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); | |
} else { | |
genFun.__proto__ = GeneratorFunctionPrototype; | |
if (!(toStringTagSymbol in genFun)) { | |
genFun[toStringTagSymbol] = "GeneratorFunction"; | |
} | |
} | |
genFun.prototype = Object.create(Gp); | |
return genFun; | |
}; | |
// Within the body of any async function, `await x` is transformed to | |
// `yield regeneratorRuntime.awrap(x)`, so that the runtime can test | |
// `hasOwn.call(value, "__await")` to determine if the yielded value is | |
// meant to be awaited. | |
runtime.awrap = function (arg) { | |
return { | |
__await: arg | |
}; | |
}; | |
function AsyncIterator(generator) { | |
function invoke(method, arg, resolve, reject) { | |
var record = tryCatch(generator[method], generator, arg); | |
if (record.type === "throw") { | |
reject(record.arg); | |
} else { | |
var result = record.arg; | |
var value = result.value; | |
if (value && | |
typeof value === "object" && | |
hasOwn.call(value, "__await")) { | |
return Promise.resolve(value.__await).then(function (value) { | |
invoke("next", value, resolve, reject); | |
}, function (err) { | |
invoke("throw", err, resolve, reject); | |
}); | |
} | |
return Promise.resolve(value).then(function (unwrapped) { | |
// When a yielded Promise is resolved, its final value becomes | |
// the .value of the Promise<{value,done}> result for the | |
// current iteration. If the Promise is rejected, however, the | |
// result for this iteration will be rejected with the same | |
// reason. Note that rejections of yielded Promises are not | |
// thrown back into the generator function, as is the case | |
// when an awaited Promise is rejected. This difference in | |
// behavior between yield and await is important, because it | |
// allows the consumer to decide what to do with the yielded | |
// rejection (swallow it and continue, manually .throw it back | |
// into the generator, abandon iteration, whatever). With | |
// await, by contrast, there is no opportunity to examine the | |
// rejection reason outside the generator function, so the | |
// only option is to throw it from the await expression, and | |
// let the generator function handle the exception. | |
result.value = unwrapped; | |
resolve(result); | |
}, reject); | |
} | |
} | |
var previousPromise; | |
function enqueue(method, arg) { | |
function callInvokeWithMethodAndArg() { | |
return new Promise(function (resolve, reject) { | |
invoke(method, arg, resolve, reject); | |
}); | |
} | |
return previousPromise = | |
// If enqueue has been called before, then we want to wait until | |
// all previous Promises have been resolved before calling invoke, | |
// so that results are always delivered in the correct order. If | |
// enqueue has not been called before, then it is important to | |
// call invoke immediately, without waiting on a callback to fire, | |
// so that the async generator function has the opportunity to do | |
// any necessary setup in a predictable way. This predictability | |
// is why the Promise constructor synchronously invokes its | |
// executor callback, and why async functions synchronously | |
// execute code before the first await. Since we implement simple | |
// async functions in terms of async generators, it is especially | |
// important to get this right, even though it requires care. | |
previousPromise ? previousPromise.then( | |
callInvokeWithMethodAndArg, | |
// Avoid propagating failures to Promises returned by later | |
// invocations of the iterator. | |
callInvokeWithMethodAndArg | |
) : callInvokeWithMethodAndArg(); | |
} | |
// Define the unified helper method that is used to implement .next, | |
// .throw, and .return (see defineIteratorMethods). | |
this._invoke = enqueue; | |
} | |
defineIteratorMethods(AsyncIterator.prototype); | |
AsyncIterator.prototype[asyncIteratorSymbol] = function () { | |
return this; | |
}; | |
runtime.AsyncIterator = AsyncIterator; | |
// Note that simple async functions are implemented on top of | |
// AsyncIterator objects; they just return a Promise for the value of | |
// the final result produced by the iterator. | |
runtime.async = function (innerFn, outerFn, self, tryLocsList) { | |
var iter = new AsyncIterator( | |
wrap(innerFn, outerFn, self, tryLocsList) | |
); | |
return runtime.isGeneratorFunction(outerFn) ? | |
iter // If outerFn is a generator, return the full iterator. | |
: | |
iter.next().then(function (result) { | |
return result.done ? result.value : iter.next(); | |
}); | |
}; | |
function makeInvokeMethod(innerFn, self, context) { | |
var state = GenStateSuspendedStart; | |
return function invoke(method, arg) { | |
if (state === GenStateExecuting) { | |
throw new Error("Generator is already running"); | |
} | |
if (state === GenStateCompleted) { | |
if (method === "throw") { | |
throw arg; | |
} | |
// Be forgiving, per 25.3.3.3.3 of the spec: | |
// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume | |
return doneResult(); | |
} | |
context.method = method; | |
context.arg = arg; | |
while (true) { | |
var delegate = context.delegate; | |
if (delegate) { | |
var delegateResult = maybeInvokeDelegate(delegate, context); | |
if (delegateResult) { | |
if (delegateResult === ContinueSentinel) continue; | |
return delegateResult; | |
} | |
} | |
if (context.method === "next") { | |
// Setting context._sent for legacy support of Babel's | |
// function.sent implementation. | |
context.sent = context._sent = context.arg; | |
} else if (context.method === "throw") { | |
if (state === GenStateSuspendedStart) { | |
state = GenStateCompleted; | |
throw context.arg; | |
} | |
context.dispatchException(context.arg); | |
} else if (context.method === "return") { | |
context.abrupt("return", context.arg); | |
} | |
state = GenStateExecuting; | |
var record = tryCatch(innerFn, self, context); | |
if (record.type === "normal") { | |
// If an exception is thrown from innerFn, we leave state === | |
// GenStateExecuting and loop back for another invocation. | |
state = context.done ? | |
GenStateCompleted : | |
GenStateSuspendedYield; | |
if (record.arg === ContinueSentinel) { | |
continue; | |
} | |
return { | |
value: record.arg, | |
done: context.done | |
}; | |
} else if (record.type === "throw") { | |
state = GenStateCompleted; | |
// Dispatch the exception by looping back around to the | |
// context.dispatchException(context.arg) call above. | |
context.method = "throw"; | |
context.arg = record.arg; | |
} | |
} | |
}; | |
} | |
// Call delegate.iterator[context.method](context.arg) and handle the | |
// result, either by returning a { value, done } result from the | |
// delegate iterator, or by modifying context.method and context.arg, | |
// setting context.delegate to null, and returning the ContinueSentinel. | |
function maybeInvokeDelegate(delegate, context) { | |
var method = delegate.iterator[context.method]; | |
if (method === undefined) { | |
// A .throw or .return when the delegate iterator has no .throw | |
// method always terminates the yield* loop. | |
context.delegate = null; | |
if (context.method === "throw") { | |
if (delegate.iterator.return) { | |
// If the delegate iterator has a return method, give it a | |
// chance to clean up. | |
context.method = "return"; | |
context.arg = undefined; | |
maybeInvokeDelegate(delegate, context); | |
if (context.method === "throw") { | |
// If maybeInvokeDelegate(context) changed context.method from | |
// "return" to "throw", let that override the TypeError below. | |
return ContinueSentinel; | |
} | |
} | |
context.method = "throw"; | |
context.arg = new TypeError( | |
"The iterator does not provide a 'throw' method"); | |
} | |
return ContinueSentinel; | |
} | |
var record = tryCatch(method, delegate.iterator, context.arg); | |
if (record.type === "throw") { | |
context.method = "throw"; | |
context.arg = record.arg; | |
context.delegate = null; | |
return ContinueSentinel; | |
} | |
var info = record.arg; | |
if (!info) { | |
context.method = "throw"; | |
context.arg = new TypeError("iterator result is not an object"); | |
context.delegate = null; | |
return ContinueSentinel; | |
} | |
if (info.done) { | |
// Assign the result of the finished delegate to the temporary | |
// variable specified by delegate.resultName (see delegateYield). | |
context[delegate.resultName] = info.value; | |
// Resume execution at the desired location (see delegateYield). | |
context.next = delegate.nextLoc; | |
// If context.method was "throw" but the delegate handled the | |
// exception, let the outer generator proceed normally. If | |
// context.method was "next", forget context.arg since it has been | |
// "consumed" by the delegate iterator. If context.method was | |
// "return", allow the original .return call to continue in the | |
// outer generator. | |
if (context.method !== "return") { | |
context.method = "next"; | |
context.arg = undefined; | |
} | |
} else { | |
// Re-yield the result returned by the delegate method. | |
return info; | |
} | |
// The delegate iterator is finished, so forget it and continue with | |
// the outer generator. | |
context.delegate = null; | |
return ContinueSentinel; | |
} | |
// Define Generator.prototype.{next,throw,return} in terms of the | |
// unified ._invoke helper method. | |
defineIteratorMethods(Gp); | |
Gp[toStringTagSymbol] = "Generator"; | |
// A Generator should always return itself as the iterator object when the | |
// @@iterator function is called on it. Some browsers' implementations of the | |
// iterator prototype chain incorrectly implement this, causing the Generator | |
// object to not be returned from this call. This ensures that doesn't happen. | |
// See https://github.com/facebook/regenerator/issues/274 for more details. | |
Gp[iteratorSymbol] = function () { | |
return this; | |
}; | |
Gp.toString = function () { | |
return "[object Generator]"; | |
}; | |
function pushTryEntry(locs) { | |
var entry = { | |
tryLoc: locs[0] | |
}; | |
if (1 in locs) { | |
entry.catchLoc = locs[1]; | |
} | |
if (2 in locs) { | |
entry.finallyLoc = locs[2]; | |
entry.afterLoc = locs[3]; | |
} | |
this.tryEntries.push(entry); | |
} | |
function resetTryEntry(entry) { | |
var record = entry.completion || {}; | |
record.type = "normal"; | |
delete record.arg; | |
entry.completion = record; | |
} | |
function Context(tryLocsList) { | |
// The root entry object (effectively a try statement without a catch | |
// or a finally block) gives us a place to store values thrown from | |
// locations where there is no enclosing try statement. | |
this.tryEntries = [{ | |
tryLoc: "root" | |
}]; | |
tryLocsList.forEach(pushTryEntry, this); | |
this.reset(true); | |
} | |
runtime.keys = function (object) { | |
var keys = []; | |
for (var key in object) { | |
keys.push(key); | |
} | |
keys.reverse(); | |
// Rather than returning an object with a next method, we keep | |
// things simple and return the next function itself. | |
return function next() { | |
while (keys.length) { | |
var key = keys.pop(); | |
if (key in object) { | |
next.value = key; | |
next.done = false; | |
return next; | |
} | |
} | |
// To avoid creating an additional object, we just hang the .value | |
// and .done properties off the next function object itself. This | |
// also ensures that the minifier will not anonymize the function. | |
next.done = true; | |
return next; | |
}; | |
}; | |
function values(iterable) { | |
if (iterable) { | |
var iteratorMethod = iterable[iteratorSymbol]; | |
if (iteratorMethod) { | |
return iteratorMethod.call(iterable); | |
} | |
if (typeof iterable.next === "function") { | |
return iterable; | |
} | |
if (!isNaN(iterable.length)) { | |
var i = -1, | |
next = function next() { | |
while (++i < iterable.length) { | |
if (hasOwn.call(iterable, i)) { | |
next.value = iterable[i]; | |
next.done = false; | |
return next; | |
} | |
} | |
next.value = undefined; | |
next.done = true; | |
return next; | |
}; | |
return next.next = next; | |
} | |
} | |
// Return an iterator with no values. | |
return { | |
next: doneResult | |
}; | |
} | |
runtime.values = values; | |
function doneResult() { | |
return { | |
value: undefined, | |
done: true | |
}; | |
} | |
Context.prototype = { | |
constructor: Context, | |
reset: function (skipTempReset) { | |
this.prev = 0; | |
this.next = 0; | |
// Resetting context._sent for legacy support of Babel's | |
// function.sent implementation. | |
this.sent = this._sent = undefined; | |
this.done = false; | |
this.delegate = null; | |
this.method = "next"; | |
this.arg = undefined; | |
this.tryEntries.forEach(resetTryEntry); | |
if (!skipTempReset) { | |
for (var name in this) { | |
// Not sure about the optimal order of these conditions: | |
if (name.charAt(0) === "t" && | |
hasOwn.call(this, name) && | |
!isNaN(+name.slice(1))) { | |
this[name] = undefined; | |
} | |
} | |
} | |
}, | |
stop: function () { | |
this.done = true; | |
var rootEntry = this.tryEntries[0]; | |
var rootRecord = rootEntry.completion; | |
if (rootRecord.type === "throw") { | |
throw rootRecord.arg; | |
} | |
return this.rval; | |
}, | |
dispatchException: function (exception) { | |
if (this.done) { | |
throw exception; | |
} | |
var context = this; | |
function handle(loc, caught) { | |
record.type = "throw"; | |
record.arg = exception; | |
context.next = loc; | |
if (caught) { | |
// If the dispatched exception was caught by a catch block, | |
// then let that catch block handle the exception normally. | |
context.method = "next"; | |
context.arg = undefined; | |
} | |
return !!caught; | |
} | |
for (var i = this.tryEntries.length - 1; i >= 0; --i) { | |
var entry = this.tryEntries[i]; | |
var record = entry.completion; | |
if (entry.tryLoc === "root") { | |
// Exception thrown outside of any try block that could handle | |
// it, so set the completion value of the entire function to | |
// throw the exception. | |
return handle("end"); | |
} | |
if (entry.tryLoc <= this.prev) { | |
var hasCatch = hasOwn.call(entry, "catchLoc"); | |
var hasFinally = hasOwn.call(entry, "finallyLoc"); | |
if (hasCatch && hasFinally) { | |
if (this.prev < entry.catchLoc) { | |
return handle(entry.catchLoc, true); | |
} else if (this.prev < entry.finallyLoc) { | |
return handle(entry.finallyLoc); | |
} | |
} else if (hasCatch) { | |
if (this.prev < entry.catchLoc) { | |
return handle(entry.catchLoc, true); | |
} | |
} else if (hasFinally) { | |
if (this.prev < entry.finallyLoc) { | |
return handle(entry.finallyLoc); | |
} | |
} else { | |
throw new Error("try statement without catch or finally"); | |
} | |
} | |
} | |
}, | |
abrupt: function (type, arg) { | |
for (var i = this.tryEntries.length - 1; i >= 0; --i) { | |
var entry = this.tryEntries[i]; | |
if (entry.tryLoc <= this.prev && | |
hasOwn.call(entry, "finallyLoc") && | |
this.prev < entry.finallyLoc) { | |
var finallyEntry = entry; | |
break; | |
} | |
} | |
if (finallyEntry && | |
(type === "break" || | |
type === "continue") && | |
finallyEntry.tryLoc <= arg && | |
arg <= finallyEntry.finallyLoc) { | |
// Ignore the finally entry if control is not jumping to a | |
// location outside the try/catch block. | |
finallyEntry = null; | |
} | |
var record = finallyEntry ? finallyEntry.completion : {}; | |
record.type = type; | |
record.arg = arg; | |
if (finallyEntry) { | |
this.method = "next"; | |
this.next = finallyEntry.finallyLoc; | |
return ContinueSentinel; | |
} | |
return this.complete(record); | |
}, | |
complete: function (record, afterLoc) { | |
if (record.type === "throw") { | |
throw record.arg; | |
} | |
if (record.type === "break" || | |
record.type === "continue") { | |
this.next = record.arg; | |
} else if (record.type === "return") { | |
this.rval = this.arg = record.arg; | |
this.method = "return"; | |
this.next = "end"; | |
} else if (record.type === "normal" && afterLoc) { | |
this.next = afterLoc; | |
} | |
return ContinueSentinel; | |
}, | |
finish: function (finallyLoc) { | |
for (var i = this.tryEntries.length - 1; i >= 0; --i) { | |
var entry = this.tryEntries[i]; | |
if (entry.finallyLoc === finallyLoc) { | |
this.complete(entry.completion, entry.afterLoc); | |
resetTryEntry(entry); | |
return ContinueSentinel; | |
} | |
} | |
}, | |
"catch": function (tryLoc) { | |
for (var i = this.tryEntries.length - 1; i >= 0; --i) { | |
var entry = this.tryEntries[i]; | |
if (entry.tryLoc === tryLoc) { | |
var record = entry.completion; | |
if (record.type === "throw") { | |
var thrown = record.arg; | |
resetTryEntry(entry); | |
} | |
return thrown; | |
} | |
} | |
// The context.catch method must only be called with a location | |
// argument that corresponds to a known catch block. | |
throw new Error("illegal catch attempt"); | |
}, | |
delegateYield: function (iterable, resultName, nextLoc) { | |
this.delegate = { | |
iterator: values(iterable), | |
resultName: resultName, | |
nextLoc: nextLoc | |
}; | |
if (this.method === "next") { | |
// Deliberately forget the last sent value so that we don't | |
// accidentally pass it on to the delegate. | |
this.arg = undefined; | |
} | |
return ContinueSentinel; | |
} | |
}; | |
})( | |
// In sloppy mode, unbound `this` refers to the global object, fallback to | |
// Function constructor if we're in global strict mode. That is sadly a form | |
// of indirect eval which violates Content Security Policy. | |
(function () { | |
return this | |
})() || Function("return this")() | |
); | |
}); | |
/** | |
* Copyright (c) 2014-present, Facebook, Inc. | |
* | |
* This source code is licensed under the MIT license found in the | |
* LICENSE file in the root directory of this source tree. | |
*/ | |
// This method of obtaining a reference to the global object needs to be | |
// kept identical to the way it is obtained in runtime.js | |
var g = (function () { | |
return this | |
})() || Function("return this")(); | |
// Use `getOwnPropertyNames` because not all browsers support calling | |
// `hasOwnProperty` on the global `self` object in a worker. See #183. | |
var hadRuntime = g.regeneratorRuntime && | |
Object.getOwnPropertyNames(g).indexOf("regeneratorRuntime") >= 0; | |
// Save the old regeneratorRuntime in case it needs to be restored later. | |
var oldRuntime = hadRuntime && g.regeneratorRuntime; | |
// Force reevalutation of runtime.js. | |
g.regeneratorRuntime = undefined; | |
if (hadRuntime) { | |
// Restore the original runtime. | |
g.regeneratorRuntime = oldRuntime; | |
} else { | |
// Remove the global property added by runtime.js. | |
try { | |
delete g.regeneratorRuntime; | |
} catch (e) { | |
g.regeneratorRuntime = undefined; | |
} | |
} | |
(function (arr) { | |
arr.forEach(function (item) { | |
if (Object.prototype.hasOwnProperty.call(item, 'remove')) { | |
return; | |
} | |
Object.defineProperty(item, 'remove', { | |
configurable: true, | |
enumerable: true, | |
writable: true, | |
value: function remove() { | |
this.parentNode.removeChild(this); | |
} | |
}); | |
}); | |
})([Element.prototype, CharacterData.prototype, DocumentType.prototype]); | |
function _typeof(obj) { | |
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { | |
_typeof = function _typeof(obj) { | |
return typeof obj; | |
}; | |
} else { | |
_typeof = function _typeof(obj) { | |
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; | |
}; | |
} | |
return _typeof(obj); | |
} | |
/** | |
* Return a descriptor removing the value and returning a getter | |
* The getter will return a .bind version of the function | |
* and memoize the result against a symbol on the instance | |
*/ | |
function boundMethod(target, key, descriptor) { | |
var fn = descriptor.value; | |
if (typeof fn !== 'function') { | |
throw new TypeError("@boundMethod decorator can only be applied to methods not: ".concat(_typeof(fn))); | |
} // In IE11 calling Object.defineProperty has a side-effect of evaluating the | |
// getter for the property which is being replaced. This causes infinite | |
// recursion and an "Out of stack space" error. | |
var definingProperty = false; | |
return { | |
configurable: true, | |
get: function get() { | |
// eslint-disable-next-line no-prototype-builtins | |
if (definingProperty || this === target.prototype || this.hasOwnProperty(key) || typeof fn !== 'function') { | |
return fn; | |
} | |
var boundFn = fn.bind(this); | |
definingProperty = true; | |
Object.defineProperty(this, key, { | |
configurable: true, | |
get: function get() { | |
return boundFn; | |
}, | |
set: function set(value) { | |
fn = value; | |
delete this[key]; | |
} | |
}); | |
definingProperty = false; | |
return boundFn; | |
}, | |
set: function set(value) { | |
fn = value; | |
} | |
}; | |
} | |
/** | |
* Use boundMethod to bind all methods on the target.prototype | |
*/ | |
function boundClass(target) { | |
// (Using reflect to get all keys including symbols) | |
var keys; // Use Reflect if exists | |
if (typeof Reflect !== 'undefined' && typeof Reflect.ownKeys === 'function') { | |
keys = Reflect.ownKeys(target.prototype); | |
} else { | |
keys = Object.getOwnPropertyNames(target.prototype); // Use symbols if support is provided | |
if (typeof Object.getOwnPropertySymbols === 'function') { | |
keys = keys.concat(Object.getOwnPropertySymbols(target.prototype)); | |
} | |
} | |
keys.forEach(function (key) { | |
// Ignore special case target method | |
if (key === 'constructor') { | |
return; | |
} | |
var descriptor = Object.getOwnPropertyDescriptor(target.prototype, key); // Only methods need binding | |
if (typeof descriptor.value === 'function') { | |
Object.defineProperty(target.prototype, key, boundMethod(target, key, descriptor)); | |
} | |
}); | |
return target; | |
} | |
function autobind() { | |
if (arguments.length === 1) { | |
return boundClass.apply(void 0, arguments); | |
} | |
return boundMethod.apply(void 0, arguments); | |
} | |
var prefixProperties = { | |
'border-radius': 1, | |
'border-top-left-radius': 1, | |
'border-top-right-radius': 1, | |
'border-bottom-left-radius': 1, | |
'border-bottom-right-radius': 1, | |
'box-shadow': 1, | |
'order': 1, | |
'flex': function (name, prefix) { | |
return [prefix + 'box-flex'] | |
}, | |
'box-flex': 1, | |
'box-align': 1, | |
'animation': 1, | |
'animation-duration': 1, | |
'animation-name': 1, | |
'transition': 1, | |
'transition-duration': 1, | |
'transform': 1, | |
'transform-style': 1, | |
'transform-origin': 1, | |
'backface-visibility': 1, | |
'perspective': 1, | |
'box-pack': 1 | |
}; | |
//make sure properties are in hyphenated form | |
var cssUnitless = { | |
'animation': 1, | |
'column-count': 1, | |
'columns': 1, | |
'font-weight': 1, | |
'opacity': 1, | |
'order ': 1, | |
'z-index': 1, | |
'zoom': 1, | |
'flex': 1, | |
'box-flex': 1, | |
'transform': 1, | |
'perspective': 1, | |
'box-pack': 1, | |
'box-align': 1, | |
'colspan': 1, | |
'rowspan': 1 | |
}; | |
var toUpperFirst = function (value) { | |
return value.length ? | |
value.charAt(0).toUpperCase() + value.substring(1) : | |
value | |
}; | |
var re = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/; | |
var docStyle = typeof document == 'undefined' ? {} : | |
document.documentElement.style; | |
var prefixInfo = (function () { | |
var prefix = (function () { | |
for (var prop in docStyle) { | |
if (re.test(prop)) { | |
// test is faster than match, so it's better to perform | |
// that on the lot and match only when necessary | |
return prop.match(re)[0] | |
} | |
} | |
// Nothing found so far? Webkit does not enumerate over the CSS properties of the style object. | |
// However (prop in style) returns the correct value, so we'll have to test for | |
// the precence of a specific property | |
if ('WebkitOpacity' in docStyle) { | |
return 'Webkit' | |
} | |
if ('KhtmlOpacity' in docStyle) { | |
return 'Khtml' | |
} | |
return '' | |
})(), | |
lower = prefix.toLowerCase(); | |
return { | |
style: prefix, | |
css: '-' + lower + '-', | |
dom: ({ | |
Webkit: 'WebKit', | |
ms: 'MS', | |
o: 'WebKit' | |
})[prefix] || toUpperFirst(prefix) | |
} | |
})(); | |
var prefixInfo_1 = prefixInfo; | |
var hyphenRe = /[-\s]+(.)?/g; | |
var toCamelFn = function (str, letter) { | |
return letter ? letter.toUpperCase() : '' | |
}; | |
var camelize = function (str) { | |
return str ? | |
str.replace(hyphenRe, toCamelFn) : | |
'' | |
}; | |
var doubleColonRe = /::/g; | |
var upperToLowerRe = /([A-Z]+)([A-Z][a-z])/g; | |
var lowerToUpperRe = /([a-z\d])([A-Z])/g; | |
var underscoreToDashRe = /_/g; | |
var separate = function (name, separator) { | |
return name ? | |
name.replace(doubleColonRe, '/') | |
.replace(upperToLowerRe, '$1_$2') | |
.replace(lowerToUpperRe, '$1_$2') | |
.replace(underscoreToDashRe, separator || '-') : | |
'' | |
}; | |
var hyphenate = function (name) { | |
return separate(name).toLowerCase() | |
}; | |
var toLowerFirst = function (value) { | |
return value.length ? | |
value.charAt(0).toLowerCase() + value.substring(1) : | |
value | |
}; | |
var docStyle$1 = typeof document == 'undefined' ? {} : | |
document.documentElement.style; | |
var prefixer = function (asStylePrefix) { | |
return function (name, config) { | |
config = config || {}; | |
var styleName = toLowerFirst(camelize(name)), | |
cssName = hyphenate(name), | |
theName = asStylePrefix ? | |
styleName : | |
cssName, | |
thePrefix = prefixInfo_1.style ? | |
asStylePrefix ? | |
prefixInfo_1.style : | |
prefixInfo_1.css : | |
''; | |
if (styleName in docStyle$1) { | |
return config.asString ? | |
theName : [theName] | |
} | |
//not a valid style name, so we'll return the value with a prefix | |
var upperCased = theName, | |
prefixProperty = prefixProperties[cssName], | |
result = []; | |
if (asStylePrefix) { | |
upperCased = toUpperFirst(theName); | |
} | |
if (typeof prefixProperty == 'function') { | |
var prefixedCss = prefixProperty(theName, thePrefix) || []; | |
if (prefixedCss && !Array.isArray(prefixedCss)) { | |
prefixedCss = [prefixedCss]; | |
} | |
if (prefixedCss.length) { | |
prefixedCss = prefixedCss.map(function (property) { | |
return asStylePrefix ? | |
toLowerFirst(camelize(property)) : | |
hyphenate(property) | |
}); | |
} | |
result = result.concat(prefixedCss); | |
} | |
if (thePrefix) { | |
result.push(thePrefix + upperCased); | |
} | |
result.push(theName); | |
if (config.asString || result.length == 1) { | |
return result[0] | |
} | |
return result | |
} | |
}; | |
var cssPrefix = prefixer(); | |
var objectHasOwn = Object.prototype.hasOwnProperty; | |
var hasOwn = function (object, propertyName) { | |
return objectHasOwn.call(object, propertyName) | |
}; | |
var objectToString = Object.prototype.toString; | |
var isObject = function (v) { | |
return !!v && objectToString.call(v) === '[object Object]' | |
}; | |
var objectToString$1 = Object.prototype.toString; | |
var isFunction = function (v) { | |
return objectToString$1.apply(v) === '[object Function]' | |
}; | |
var applyPrefix = function (target, property, value, normalizeFn) { | |
cssPrefix(property).forEach(function (p) { | |
target[normalizeFn ? normalizeFn(p) : p] = value; | |
}); | |
}; | |
var toObject = function (str) { | |
str = (str || '').split(';'); | |
var result = {}; | |
str.forEach(function (item) { | |
var split = item.split(':'); | |
if (split.length == 2) { | |
result[split[0].trim()] = split[1].trim(); | |
} | |
}); | |
return result | |
}; | |
var CONFIG = { | |
cssUnitless: cssUnitless | |
}; | |
/** | |
* @ignore | |
* @method toStyleObject | |
* | |
* @param {Object} styles The object to convert to a style object. | |
* @param {Object} [config] | |
* @param {Boolean} [config.addUnits=true] True if you want to add units when numerical values are encountered. | |
* @param {Object} config.cssUnitless An object whose keys represent css numerical property names that will not be appended with units. | |
* @param {Object} config.prefixProperties An object whose keys represent css property names that should be prefixed | |
* @param {String} config.cssUnit='px' The css unit to append to numerical values. Defaults to 'px' | |
* @param {String} config.normalizeName A function that normalizes a name to a valid css property name | |
* @param {String} config.scope | |
* | |
* @return {Object} The object, normalized with css style names | |
*/ | |
var TO_STYLE_OBJECT = function (styles, config, prepend, result) { | |
if (typeof styles == 'string') { | |
styles = toObject(styles); | |
} | |
config = config || CONFIG; | |
config.cssUnitless = config.cssUnitless || CONFIG.cssUnitless; | |
result = result || {}; | |
var scope = config.scope || {}, | |
//configs | |
addUnits = config.addUnits != null ? | |
config.addUnits : | |
scope && scope.addUnits != null ? | |
scope.addUnits : | |
true, | |
cssUnitless$$1 = (config.cssUnitless != null ? | |
config.cssUnitless : | |
scope ? | |
scope.cssUnitless : | |
null) || {}, | |
cssUnit = (config.cssUnit || scope ? scope.cssUnit : null) || 'px', | |
prefixProperties = (config.prefixProperties || (scope ? scope.prefixProperties : null)) || {}, | |
camelize$$1 = config.camelize, | |
normalizeFn = camelize$$1 ? camelize : hyphenate; | |
// Object.keys(cssUnitless).forEach(function(key){ | |
// cssUnitless[normalizeFn(key)] = 1 | |
// }) | |
var processed, | |
styleName, | |
propName, | |
propValue, | |
propCssUnit, | |
propType, | |
propIsNumber, | |
fnPropValue, | |
prefix; | |
for (propName in styles) | |
if (hasOwn(styles, propName)) { | |
propValue = styles[propName]; | |
//the hyphenated style name (css property name) | |
styleName = hyphenate(prepend ? prepend + propName : propName); | |
processed = false; | |
prefix = false; | |
if (isFunction(propValue)) { | |
//a function can either return a css value | |
//or an object with { value, prefix, name } | |
fnPropValue = propValue.call(scope || styles, propValue, propName, styleName, styles); | |
if (isObject(fnPropValue) && fnPropValue.value != null) { | |
propValue = fnPropValue.value; | |
prefix = fnPropValue.prefix; | |
styleName = fnPropValue.name ? | |
hyphenate(fnPropValue.name) : | |
styleName; | |
} else { | |
propValue = fnPropValue; | |
} | |
} | |
propType = typeof propValue; | |
propIsNumber = propType == 'number' || (propType == 'string' && propValue != '' && propValue * 1 == propValue); | |
if (propValue == null || styleName == null || styleName === '') { | |
continue | |
} | |
if (propIsNumber || propType == 'string') { | |
processed = true; | |
} | |
if (!processed && propValue.value != null && propValue.prefix) { | |
processed = true; | |
prefix = propValue.prefix; | |
propValue = propValue.value; | |
} | |
// hyphenStyleName = camelize? HYPHENATE(styleName): styleName | |
if (processed) { | |
prefix = prefix || !!prefixProperties[styleName]; | |
if (propIsNumber) { | |
propValue = addUnits && !(styleName in cssUnitless$$1) ? | |
propValue + cssUnit : | |
propValue + ''; //change it to a string, so that jquery does not append px or other units | |
} | |
//special border treatment | |
if ( | |
( | |
styleName == 'border' || | |
(!styleName.indexOf('border') && | |
!~styleName.indexOf('radius') && | |
!~styleName.indexOf('width')) | |
) && | |
propIsNumber | |
) { | |
styleName = styleName + '-width'; | |
} | |
//special border radius treatment | |
if (!styleName.indexOf('border-radius-')) { | |
styleName.replace(/border(-radius)(-(.*))/, function (str, radius, theRest) { | |
var positions = { | |
'-top': ['-top-left', '-top-right'], | |
'-left': ['-top-left', '-bottom-left'], | |
'-right': ['-top-right', '-bottom-right'], | |
'-bottom': ['-bottom-left', '-bottom-right'] | |
}; | |
if (theRest in positions) { | |
styleName = []; | |
positions[theRest].forEach(function (pos) { | |
styleName.push('border' + pos + radius); | |
}); | |
} else { | |
styleName = 'border' + theRest + radius; | |
} | |
}); | |
if (Array.isArray(styleName)) { | |
styleName.forEach(function (styleName) { | |
if (prefix) { | |
applyPrefix(result, styleName, propValue, normalizeFn); | |
} else { | |
result[normalizeFn(styleName)] = propValue; | |
} | |
}); | |
continue | |
} | |
} | |
if (prefix) { | |
applyPrefix(result, styleName, propValue, normalizeFn); | |
} else { | |
result[normalizeFn(styleName)] = propValue; | |
} | |
} else { | |
//the propValue must be an object, so go down the hierarchy | |
TO_STYLE_OBJECT(propValue, config, styleName + '-', result); | |
} | |
} | |
return result | |
}; | |
var toStyleObject = TO_STYLE_OBJECT; | |
/** | |
* @ignore | |
* @method toStyleString | |
* | |
* @param {Object} styles The object to convert to a style string. | |
* @param {Object} config | |
* @param {Boolean} config.addUnits=true True if you want to add units when numerical values are encountered. Defaults to true | |
* @param {Object} config.cssUnitless An object whose keys represent css numerical property names that will not be appended with units. | |
* @param {Object} config.prefixProperties An object whose keys represent css property names that should be prefixed | |
* @param {String} config.cssUnit='px' The css unit to append to numerical values. Defaults to 'px' | |
* @param {String} config.scope | |
* | |
* @return {Object} The object, normalized with css style names | |
*/ | |
var toStyleString = function (styles, config) { | |
styles = toStyleObject(styles, config); | |
var result = []; | |
var prop; | |
for (prop in styles) | |
if (hasOwn(styles, prop)) { | |
result.push(prop + ': ' + styles[prop]); | |
} | |
return result.join('; ') | |
}; | |
var _toStyle_1_3_3_toStyle = { | |
prefixProperties: prefixProperties, | |
cssUnitless: cssUnitless, | |
object: toStyleObject, | |
string: toStyleString | |
}; | |
function getBlob(svg) { | |
var blob = null; | |
try { | |
blob = new Blob([svg], { | |
type: 'image/svg+xml' | |
}); | |
} catch (err) { | |
if (window.BlobBuilder) { | |
var bb = new window.BlobBuilder(); | |
bb.append([svg]); | |
blob = bb.getBlob('image/svg+xml'); | |
} | |
} | |
return blob; | |
} | |
function svgToImageUrl(svg) { | |
var blob = getBlob(svg); | |
var url = URL.createObjectURL(blob); | |
return url; | |
} | |
/** | |
* 获取带#的大写的颜色值 | |
* @param {String} color 颜色值 | |
*/ | |
function getNormalizeColor(color) { | |
color = color.toUpperCase(); | |
if (color[0] !== '#') { | |
color = '#' + color; | |
} | |
return color; | |
} | |
var lineColor = 'rgba(0,0,0,0.45)'; | |
function getNormalSvg(bgColor) { | |
return '\n <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n <path d="M11,1.5 C6.85786438,1.5 3.5,4.85786438 3.5,9 L3.5,28 C3.5,29.9329966 5.06700338,31.5 7,31.5 L25,31.5 C26.9329966,31.5 28.5,29.9329966 28.5,28 L28.5,9 C28.5,4.85786438 25.1421356,1.5 21,1.5 L11,1.5 Z" stroke="' + lineColor + '" fill="' + bgColor + '"></path>\n <path d="M31.5,15 C31.5,13.3431458 30.1568542,12 28.5,12 C26.8431458,12 25.5,13.3431458 25.5,15 L25.5,23 C25.5,24.3807119 24.3807119,25.5 23,25.5 L9,25.5 C7.61928813,25.5 6.5,24.3807119 6.5,23 L6.5,15 C6.5,13.3431458 5.15685425,12 3.5,12 C1.84314575,12 0.5,13.3431458 0.5,15 L0.5,26 C0.5,29.0375661 2.96243388,31.5 6,31.5 L26,31.5 C29.0375661,31.5 31.5,29.0375661 31.5,26 L31.5,15 Z" stroke="' + lineColor + '" fill="' + bgColor + '"></path>\n </g>\n </svg>\n '; | |
} | |
function getNormalCircleSvg(bgColor) { | |
return '\n <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n <circle stroke="' + lineColor + '" fill="' + bgColor + '" cx="16" cy="16" r="14.5"></circle>\n </g>\n </svg>\n '; | |
} | |
/** | |
* 沙发选中状态 | |
* @param {number} checkAngle 对勾角度 | |
*/ | |
function getSelectedSvg(checkAngle, color) { | |
return '\n <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n <path d="M11,1.5 C6.85786438,1.5 3.5,4.85786438 3.5,9 L3.5,28 C3.5,29.9329966 5.06700338,31.5 7,31.5 L25,31.5 C26.9329966,31.5 28.5,29.9329966 28.5,28 L28.5,9 C28.5,4.85786438 25.1421356,1.5 21,1.5 L11,1.5 Z" id="Rectangle-Copy-2" stroke="' + lineColor + '" fill="' + color + '"></path>\n <path d="M31.5,15 C31.5,13.3431458 30.1568542,12 28.5,12 C26.8431458,12 25.5,13.3431458 25.5,15 L25.5,23 C25.5,24.3807119 24.3807119,25.5 23,25.5 L9,25.5 C7.61928813,25.5 6.5,24.3807119 6.5,23 L6.5,15 C6.5,13.3431458 5.15685425,12 3.5,12 C1.84314575,12 0.5,13.3431458 0.5,15 L0.5,26 C0.5,29.0375661 2.96243388,31.5 6,31.5 L26,31.5 C29.0375661,31.5 31.5,29.0375661 31.5,26 L31.5,15 Z" stroke="r' + lineColor + '" fill="' + color + '"></path>\n <path d="M28.9292012,12.0304066 L28.5,11.9690142 L28.5,9 C28.5,4.85786438 25.1421356,1.5 21,1.5 L11,1.5 C6.85786438,1.5 3.5,4.85786438 3.5,9 L3.5,11.9690142 L3.07079879,12.0304066 C1.60371045,12.2402571 0.5,13.5028128 0.5,15 L0.5,26 C0.5,29.0375661 2.96243388,31.5 6,31.5 L26,31.5 C29.0375661,31.5 31.5,29.0375661 31.5,26 L31.5,15 C31.5,13.5028128 30.3962896,12.2402571 28.9292012,12.0304066 Z" stroke="#000000" fill="#000000" opacity="0.6"></path>\n <path style="transform: rotate(' + (checkAngle > 0 ? '-' + checkAngle : -checkAngle) + 'deg);transform-origin: 50% 50%;" d="M22.5688538,12.889892 L14.4449928,20.8889925 C14.2487772,21.0795102 13.9322232,21.0795102 13.7386256,20.8889925 L12.6716388,19.8387476 L9.14732667,16.3660028 C8.95089111,16.1752211 8.95089111,15.863551 9.14732667,15.6694254 L10.2114974,14.6214905 C10.408219,14.4283989 10.7216711,14.4283989 10.9181066,14.6214905 L14.0905552,17.7451876 L20.7952578,11.1430697 C20.9917154,10.9523101 21.3082474,10.9523101 21.504705,11.1430697 L22.5688758,12.1930727 C22.7627594,12.3838543 22.7627594,12.6955244 22.5688538,12.889892 Z" fill="#FFFFFF"></path>\n </g>\n </svg>\n '; | |
} | |
function getSelectedCircleSvg(color) { | |
return '\n <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n <circle stroke="rgba(0,0,0,0.25)" fill="' + color + '" cx="16" cy="16" r="14.5"></circle>\n <circle stroke="#000000" fill="#000000" opacity="0.6" cx="16" cy="16" r="14.5"></circle>\n <path d="M22.5688538,12.889892 L14.4449928,20.8889925 C14.2487772,21.0795102 13.9322232,21.0795102 13.7386256,20.8889925 L12.6716388,19.8387476 L9.14732667,16.3660028 C8.95089111,16.1752211 8.95089111,15.863551 9.14732667,15.6694254 L10.2114974,14.6214905 C10.408219,14.4283989 10.7216711,14.4283989 10.9181066,14.6214905 L14.0905552,17.7451876 L20.7952578,11.1430697 C20.9917154,10.9523101 21.3082474,10.9523101 21.504705,11.1430697 L22.5688758,12.1930727 C22.7627594,12.3838543 22.7627594,12.6955244 22.5688538,12.889892 Z" fill="#FFFFFF"></path>\n </g>\n </svg>\n '; | |
} | |
function getCannotSelectSvg() { | |
return '\n <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n <path d="M11.5,2.5 C7.63400675,2.5 4.5,5.63400675 4.5,9.5 L4.5,27.25 C4.5,29.0449254 5.95507456,30.5 7.75,30.5 L24.25,30.5 C26.0449254,30.5 27.5,29.0449254 27.5,27.25 L27.5,9.5 C27.5,5.63400675 24.3659932,2.5 20.5,2.5 L11.5,2.5 Z" stroke="#D3D3D3" fill="#F5F5F5"></path>\n <path d="M30.5,15.2439024 C30.5,13.7297763 29.2560651,12.5 27.71875,12.5 C26.1814349,12.5 24.9375,13.7297763 24.9375,15.2439024 L24.9375,22.6371951 C24.9375,23.9488714 23.8741763,25.0121951 22.5625,25.0121951 L9.4375,25.0121951 C8.12582372,25.0121951 7.0625,23.9488714 7.0625,22.6371951 L7.0625,15.2439024 C7.0625,13.7297763 5.81856508,12.5 4.28125,12.5 C2.74393492,12.5 1.5,13.7297763 1.5,15.2439024 L1.5,25.375 C1.5,28.2054593 3.79454066,30.5 6.625,30.5 L25.375,30.5 C28.2054593,30.5 30.5,28.2054593 30.5,25.375 L30.5,15.2439024 Z" stroke="#D3D3D3" fill="#F5F5F5"></path>\n </g>\n </svg>\n '; | |
} | |
function getThumbnailSvg(color) { | |
return '\n <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n <defs></defs>\n <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n <rect id="Rectangle" fill="' + color + '" x="0" y="0" width="32" height="32"></rect>\n </g>\n </svg>\n '; | |
} | |
function getPackageSvg(color) { | |
return '\n <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n <path d="M11.5,2.5 C7.63400675,2.5 4.5,5.63400675 4.5,9.5 L4.5,27.25 C4.5,29.0449254 5.95507456,30.5 7.75,30.5 L24.25,30.5 C26.0449254,30.5 27.5,29.0449254 27.5,27.25 L27.5,9.5 C27.5,5.63400675 24.3659932,2.5 20.5,2.5 L11.5,2.5 Z" stroke="' + lineColor + '" fill="' + color + '"></path>\n <path d="M30.5,15.2439024 C30.5,13.7297763 29.2560651,12.5 27.71875,12.5 C26.1814349,12.5 24.9375,13.7297763 24.9375,15.2439024 L24.9375,22.6371951 C24.9375,23.9488714 23.8741763,25.0121951 22.5625,25.0121951 L9.4375,25.0121951 C8.12582372,25.0121951 7.0625,23.9488714 7.0625,22.6371951 L7.0625,15.2439024 C7.0625,13.7297763 5.81856508,12.5 4.28125,12.5 C2.74393492,12.5 1.5,13.7297763 1.5,15.2439024 L1.5,25.375 C1.5,28.2054593 3.79454066,30.5 6.625,30.5 L25.375,30.5 C28.2054593,30.5 30.5,28.2054593 30.5,25.375 L30.5,15.2439024 Z" stroke="' + lineColor + '" fill="' + color + '"></path>\n <path d="M18.244,12.28 C17.656,11.872 17.188,11.44 16.828,10.984 L15.472,10.984 C15.064,11.464 14.584,11.896 14.032,12.28 L18.244,12.28 Z M17.764,10.984 C18.58,11.776 19.816,12.4 21.472,12.856 L21.088,13.66 C20.212,13.348 19.456,13.012 18.82,12.64 L18.82,13 L13.852,13 L13.852,13.732 L19.42,13.732 L19.42,14.428 L13.852,14.428 L13.852,15.148 L19.42,15.148 L19.42,15.844 L13.852,15.844 L13.852,16.6 L21.148,16.6 L21.148,17.38 L14.896,17.38 C14.416,18.172 13.96,18.784 13.528,19.216 C15.328,19.12 17.068,18.94 18.724,18.676 C18.496,18.34 18.268,18.028 18.028,17.74 L18.772,17.488 C19.408,18.232 19.96,19.024 20.428,19.876 L19.648,20.224 C19.492,19.924 19.336,19.648 19.18,19.384 C16.96,19.708 14.632,19.912 12.208,20.008 L11.992,19.288 C12.58,19.24 13.216,18.604 13.888,17.38 L10.828,17.38 L10.828,16.6 L13.012,16.6 L13.012,12.892 C12.388,13.204 11.716,13.48 10.984,13.708 L10.576,12.976 C12.244,12.472 13.516,11.8 14.392,10.984 L10.996,10.984 L10.996,10.192 L15.088,10.192 C15.316,9.88 15.496,9.544 15.64,9.196 L16.48,9.292 C16.36,9.604 16.204,9.904 16.036,10.192 L20.992,10.192 L20.992,10.984 L17.764,10.984 Z" fill="#000000" opacity="0.45"></path>\n </g>\n </svg>\n '; | |
} | |
function getPackageCircleSvg(color) { | |
return '\n <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n <circle stroke="rgba(0,0,0,0.25)" fill="' + color + '" cx="16" cy="16" r="14.5"></circle>\n <path d="M18.168,13.484 C17.58,13.076 17.112,12.644 16.752,12.188 L15.396,12.188 C14.988,12.668 14.508,13.1 13.956,13.484 L18.168,13.484 Z M17.688,12.188 C18.504,12.98 19.74,13.604 21.396,14.06 L21.012,14.864 C20.136,14.552 19.38,14.216 18.744,13.844 L18.744,14.204 L13.776,14.204 L13.776,14.936 L19.344,14.936 L19.344,15.632 L13.776,15.632 L13.776,16.352 L19.344,16.352 L19.344,17.048 L13.776,17.048 L13.776,17.804 L21.072,17.804 L21.072,18.584 L14.82,18.584 C14.34,19.376 13.884,19.988 13.452,20.42 C15.252,20.324 16.992,20.144 18.648,19.88 C18.42,19.544 18.192,19.232 17.952,18.944 L18.696,18.692 C19.332,19.436 19.884,20.228 20.352,21.08 L19.572,21.428 C19.416,21.128 19.26,20.852 19.104,20.588 C16.884,20.912 14.556,21.116 12.132,21.212 L11.916,20.492 C12.504,20.444 13.14,19.808 13.812,18.584 L10.752,18.584 L10.752,17.804 L12.936,17.804 L12.936,14.096 C12.312,14.408 11.64,14.684 10.908,14.912 L10.5,14.18 C12.168,13.676 13.44,13.004 14.316,12.188 L10.92,12.188 L10.92,11.396 L15.012,11.396 C15.24,11.084 15.42,10.748 15.564,10.4 L16.404,10.496 C16.284,10.808 16.128,11.108 15.96,11.396 L20.916,11.396 L20.916,12.188 L17.688,12.188 Z" fill="#000000" opacity="0.45"></path>\n </g>\n </svg>\n '; | |
} | |
function getLockSvg() { | |
return '\n <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n <g transform="translate(0.000000, 0.500000)" stroke="#AAAAAA" fill="#F5F5F5">\n <path d="M11,0.5 C6.85786438,0.5 3.5,3.85786438 3.5,8 L3.5,27 C3.5,28.9329966 5.06700338,30.5 7,30.5 L25,30.5 C26.9329966,30.5 28.5,28.9329966 28.5,27 L28.5,8 C28.5,3.85786438 25.1421356,0.5 21,0.5 L11,0.5 Z"></path>\n <path d="M31.5,14.5 C31.5,12.8431458 30.1568542,11.5 28.5,11.5 C26.8431458,11.5 25.5,12.8431458 25.5,14.5 L25.5,22.5 C25.5,23.8807119 24.3807119,25 23,25 L9,25 C7.61928813,25 6.5,23.8807119 6.5,22.5 L6.5,14.5 C6.5,12.8431458 5.15685425,11.5 3.5,11.5 C1.84314575,11.5 0.5,12.8431458 0.5,14.5 L0.5,25.5 C0.5,28.5375661 2.96243388,31 6,31 L26,31 C29.0375661,31 31.5,28.5375661 31.5,25.5 L31.5,14.5 Z"></path>\n </g>\n <g transform="translate(12.000000, 8.000000)" fill="#C1C1C1" fill-rule="nonzero">\n <path d="M8.56915897,4.5132396 L7.67246708,4.5132396 L7.67246708,3.14516385 C7.67246708,1.41038737 6.24914661,0 4.49846244,0 C2.74777827,0 1.32445781,1.41038737 1.32445781,3.14516385 L1.32445781,4.5132396 L0.427765919,4.5132396 C0.18580144,4.5132396 0.000769779727,4.69658996 0.000769779727,4.93635581 L0.000769779727,11.5651765 C-0.0134634249,11.7908385 0.171568235,11.9741888 0.399299509,11.9882927 L8.56915897,11.9882927 C8.79689024,12.0023966 8.9819219,11.8190462 8.99615511,11.5933842 L8.99615511,4.93635581 C8.99615511,4.69658996 8.81112345,4.5132396 8.56915897,4.5132396 Z M4.92545858,8.94185595 L4.92545858,10.0419581 L4.0714663,10.0419581 L4.0714663,8.94185595 C3.68716978,8.77260947 3.4452053,8.40590875 3.4452053,7.99689641 C3.4452053,7.41863759 3.91490105,6.95320976 4.49846244,6.95320976 C5.08202383,6.95320976 5.55171959,7.41863759 5.55171959,7.99689641 C5.55171959,8.40590875 5.30975511,8.77260947 4.92545858,8.94185595 Z M6.8184748,4.5132396 L2.17845009,4.5132396 L2.17845009,3.14516385 C2.17845009,1.87581521 3.21747403,0.846232425 4.49846244,0.846232425 C5.77945086,0.846232425 6.8184748,1.87581521 6.8184748,3.14516385 L6.8184748,4.5132396 Z"></path>\n </g>\n </g>\n </svg>\n '; | |
} | |
function getSecureSvg() { | |
return '\n <svg width="32px" height="30px" viewBox="0 0 32 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n <image xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAADhUExURUxpccPDw8TExP///8TExMTExMPDw8TExMXFxcTExMPDw8TExP///8TExMbGxszMzMPDw8nJycTExMTExMrKysTExMPDw8fHx8TExMnJycTExMXFxcTExMPDw8PDw8TExMPDw8PDw////8PDw8bGxsTExMPDw8XFxcTExMPDw8TExMXFxcTExMXFxcTExMbGxsTExMjIyMTExMXFxdXV1cTExMTExMbGxsTExMPDw8TExMbGxsTExN/f38PDw8XFxcbGxsbGxsPDw8XFxcPDw8TExMfHx8nJycTExMPDw8PDw/7sGWMAAABKdFJOUwDzzgH9eRH1av6JwQLhEgrrJtzbGPbRINIhwp2c52uf5iIEjSih4zXoza4jJ2DGNukONIwMW6hQSWLPWakIojlHOupGwMs7EzjMxvAyzQAAAKpJREFUKM9jYKAr4NNSVsIizGytxuKlp48ubGvO5GWlbmrAaWbEjCxuw+7Fa8nDwGBozO4lII8koclrwQNhmegqMCFJyGgg2LLSSBIcXtowpqIXB5KEuJccQo0ksu1iUjAWtwSKc1k5VSAMHU5WFAk2RjsIQ5WRDdWHXCxuIMqRhQvN6/zCQu7A4BIW4kcPFA9RTxERV1F7zFB0ZhdwYnfAFuyCLtyC9I1oAHSrDej+LAQzAAAAAElFTkSuQmCC" width="32" height="32" />\n </g>\n </svg>\n '; | |
} | |
function getBufferSvg() { | |
return '\n <svg width="32px" height="30px" viewBox="0 0 32 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n <image xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAABIUExURUxpccTExMfHx8XFxdLS0sTExMTExMXFxcTExP///8nJycXFxcXFxcTExMXFxcTExMXFxcTExP///////8TExMXFxcXFxcTExFe9T8MAAAAXdFJOUwDZRJURu+5q+wQm/v38+vT58wIB9/L2u3b/GAAAAFBJREFUKM9jYBgCgJkTu7iwOCsLVgkhcXFGLiQ+Nw8vn4CIGL+gqLi4OBsTQkIcBXCw08L17ByotiBkmNhwSDBwMaJwkQALKw4JBk7mQRRlAGLZBbOp4lJJAAAAAElFTkSuQmCC" width="32" height="32" />\n </g>\n </svg>\n '; | |
} | |
function getLockCircleSvg() { | |
return '\n <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n <circle stroke="#D3D3D3" fill="#F5F5F5" cx="16" cy="16" r="14.5"></circle>\n <g transform="translate(11.500000, 10.000000)" fill="#C1C1C1" fill-rule="nonzero">\n <path d="M8.56915897,4.5132396 L7.67246708,4.5132396 L7.67246708,3.14516385 C7.67246708,1.41038737 6.24914661,0 4.49846244,0 C2.74777827,0 1.32445781,1.41038737 1.32445781,3.14516385 L1.32445781,4.5132396 L0.427765919,4.5132396 C0.18580144,4.5132396 0.000769779727,4.69658996 0.000769779727,4.93635581 L0.000769779727,11.5651765 C-0.0134634249,11.7908385 0.171568235,11.9741888 0.399299509,11.9882927 L8.56915897,11.9882927 C8.79689024,12.0023966 8.9819219,11.8190462 8.99615511,11.5933842 L8.99615511,4.93635581 C8.99615511,4.69658996 8.81112345,4.5132396 8.56915897,4.5132396 Z M4.92545858,8.94185595 L4.92545858,10.0419581 L4.0714663,10.0419581 L4.0714663,8.94185595 C3.68716978,8.77260947 3.4452053,8.40590875 3.4452053,7.99689641 C3.4452053,7.41863759 3.91490105,6.95320976 4.49846244,6.95320976 C5.08202383,6.95320976 5.55171959,7.41863759 5.55171959,7.99689641 C5.55171959,8.40590875 5.30975511,8.77260947 4.92545858,8.94185595 Z M6.8184748,4.5132396 L2.17845009,4.5132396 L2.17845009,3.14516385 C2.17845009,1.87581521 3.21747403,0.846232425 4.49846244,0.846232425 C5.77945086,0.846232425 6.8184748,1.87581521 6.8184748,3.14516385 L6.8184748,4.5132396 Z"></path>\n </g>\n </g>\n </svg>\n '; | |
} | |
function getSecureCircleSvg() { | |
return '\n <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n <g>\n <circle id="Oval" fill="#FFFFFF" fill-rule="nonzero" cx="16" cy="16" r="15"></circle>\n <path d="M16,31.5 C7.43958638,31.5 0.5,24.5604136 0.5,16 C0.5,7.43958638 7.43958638,0.5 16,0.5 C24.5604136,0.5 31.5,7.43958638 31.5,16 C31.5,24.5604136 24.5604136,31.5 16,31.5 Z M16,30.5 C24.0081289,30.5 30.5,24.0081289 30.5,16 C30.5,7.99187113 24.0081289,1.5 16,1.5 C7.99187113,1.5 1.5,7.99187113 1.5,16 C1.5,24.0081289 7.99187113,30.5 16,30.5 Z" id="Shape" fill="#666666" fill-rule="nonzero"></path>\n <image xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAADhUExURUxpccPDw8TExP///8TExMTExMPDw8TExMXFxcTExMPDw8TExP///8TExMbGxszMzMPDw8nJycTExMTExMrKysTExMPDw8fHx8TExMnJycTExMXFxcTExMPDw8PDw8TExMPDw8PDw////8PDw8bGxsTExMPDw8XFxcTExMPDw8TExMXFxcTExMXFxcTExMbGxsTExMjIyMTExMXFxdXV1cTExMTExMbGxsTExMPDw8TExMbGxsTExN/f38PDw8XFxcbGxsbGxsPDw8XFxcPDw8TExMfHx8nJycTExMPDw8PDw/7sGWMAAABKdFJOUwDzzgH9eRH1av6JwQLhEgrrJtzbGPbRINIhwp2c52uf5iIEjSih4zXoza4jJ2DGNukONIwMW6hQSWLPWakIojlHOupGwMs7EzjMxvAyzQAAAKpJREFUKM9jYKAr4NNSVsIizGytxuKlp48ubGvO5GWlbmrAaWbEjCxuw+7Fa8nDwGBozO4lII8koclrwQNhmegqMCFJyGgg2LLSSBIcXtowpqIXB5KEuJccQo0ksu1iUjAWtwSKc1k5VSAMHU5WFAk2RjsIQ5WRDdWHXCxuIMqRhQvN6/zCQu7A4BIW4kcPFA9RTxERV1F7zFB0ZhdwYnfAFuyCLtyC9I1oAHSrDej+LAQzAAAAAElFTkSuQmCC" width="32" height="32" />\n </g>\n </g>\n </svg>\n '; | |
} | |
function getBufferCircleSvg() { | |
return '\n <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">\n <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n <g>\n <circle id="Oval" fill="#FFFFFF" fill-rule="nonzero" cx="16" cy="16" r="15"></circle>\n <path d="M16,31.5 C7.43958638,31.5 0.5,24.5604136 0.5,16 C0.5,7.43958638 7.43958638,0.5 16,0.5 C24.5604136,0.5 31.5,7.43958638 31.5,16 C31.5,24.5604136 24.5604136,31.5 16,31.5 Z M16,30.5 C24.0081289,30.5 30.5,24.0081289 30.5,16 C30.5,7.99187113 24.0081289,1.5 16,1.5 C7.99187113,1.5 1.5,7.99187113 1.5,16 C1.5,24.0081289 7.99187113,30.5 16,30.5 Z" id="Shape" fill="#666666" fill-rule="nonzero"></path>\n <image xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAABIUExURUxpccTExMfHx8XFxdLS0sTExMTExMXFxcTExP///8nJycXFxcXFxcTExMXFxcTExMXFxcTExP///////8TExMXFxcXFxcTExFe9T8MAAAAXdFJOUwDZRJURu+5q+wQm/v38+vT58wIB9/L2u3b/GAAAAFBJREFUKM9jYBgCgJkTu7iwOCsLVgkhcXFGLiQ+Nw8vn4CIGL+gqLi4OBsTQkIcBXCw08L17ByotiBkmNhwSDBwMaJwkQALKw4JBk7mQRRlAGLZBbOp4lJJAAAAAElFTkSuQmCC" width="32" height="32" />\n </g>\n </g>\n </svg>\n '; | |
} | |
window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; | |
// 座位类型 | |
var Type = { | |
Normal: 'normal', | |
Selected: 'selected', | |
CannotSelect: 'cannot-select', | |
CannotSelectPackage: 'cannot-select-package', | |
Thumbnail: 'thumbnail', | |
Package: 'package', | |
Lock: 'lock', | |
Secure: 'secure', | |
Buffer: 'buffer', | |
NormalCircle: 'normal-circle', | |
SelectedCircle: 'selected-circle', | |
CannotSelectCircle: 'cannot-select-circle', | |
CannotSelectPackageCircle: 'cannot-select-package-circle', | |
PackageCircle: 'package-circle', | |
LockCircle: 'lock-circle', | |
SecureCircle: 'secure-circle', | |
BufferCircle: 'buffer-circle' | |
}; | |
var imageCache = {}; | |
var CannotSelectSeatColor = '#f5f5f5'; | |
/** | |
* 生成指定颜色的座位图, 返回座位图地址 | |
* @param {String} type 座位状态(Normal:普通座位 Selected:选中座位 CannotSelect:不可选座位 Thumbnail:缩略图 Package:套票) | |
* @param {Color} color 座位颜色, 十六进制颜色值, #可省略 | |
*/ | |
function generateSeatImage() { | |
var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Type.Normal; | |
var color = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '#F190DF'; | |
var checkAngle = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; | |
color = getNormalizeColor(color); | |
var key = type + color + checkAngle; | |
// Util.UA.isBadPhone: 不能使用cache的机器, 使用cache会导致部分座位变小 | |
if (!UA.isBadPhone && imageCache[key]) { | |
return imageCache[key]; | |
} | |
var svg = ''; | |
switch (type) { | |
case Type.Normal: { | |
svg = getNormalSvg(color); | |
break; | |
} | |
case Type.Selected: { | |
svg = getSelectedSvg(checkAngle, color); | |
break; | |
} | |
case Type.CannotSelect: { | |
svg = getCannotSelectSvg(); | |
break; | |
} | |
case Type.CannotSelectPackage: { | |
svg = getPackageSvg(CannotSelectSeatColor); | |
break; | |
} | |
case Type.Thumbnail: { | |
svg = getThumbnailSvg(color); | |
break; | |
} | |
case Type.Package: { | |
svg = getPackageSvg(color); | |
break; | |
} | |
case Type.Lock: { | |
svg = getLockSvg(); | |
break; | |
} | |
case Type.Secure: { | |
svg = getSecureSvg(); | |
break; | |
} | |
case Type.Buffer: { | |
svg = getBufferSvg(); | |
break; | |
} | |
case Type.NormalCircle: { | |
svg = getNormalCircleSvg(color); | |
break; | |
} | |
case Type.SelectedCircle: { | |
svg = getSelectedCircleSvg(color); | |
break; | |
} | |
case Type.CannotSelectCircle: { | |
svg = getNormalCircleSvg('#e9e9e9'); | |
break; | |
} | |
case Type.CannotSelectPackageCircle: { | |
svg = getPackageCircleSvg('#e9e9e9'); | |
break; | |
} | |
case Type.PackageCircle: { | |
svg = getPackageCircleSvg(color); | |
break; | |
} | |
case Type.LockCircle: { | |
svg = getLockCircleSvg(); | |
break; | |
} | |
case Type.SecureCircle: { | |
svg = getSecureCircleSvg(); | |
break; | |
} | |
case Type.BufferCircle: { | |
svg = getBufferCircleSvg(); | |
break; | |
} | |
default: { | |
break; | |
} | |
} | |
var url = svgToImageUrl(svg); | |
imageCache[key] = url; | |
return url; | |
} | |
generateSeatImage.Type = Type; | |
var ShareData = { | |
// 选座绘制容器尺寸, 中网bbc使用了<keep-alive>, 导致后续获取容器尺寸为0, 需要在初次绘制时保存值 | |
ContainerWidth: 0, | |
ContainerHeight: 0, | |
// 中网BBC座位偏移 | |
BBCSeatOffsetX: 0, | |
BBCSeatOffsetY: 0, | |
// 默认视口大小与container的距离 | |
DefaultViewportMargin: 15, | |
// svg绘制缩放倍数 | |
SVGRenderScale: 1 | |
}; | |
/** | |
* 中网BBC鹰眼图额外边距 | |
*/ | |
var BBCThumbnailMargin = 6; | |
var SvgTypeMap = { | |
rect: ['x', 'y', 'width', 'height', 'stroke-width', 'stroke', 'rx', 'ry', 'transform'], | |
path: ['d', 'stroke-width', 'stroke'], | |
circle: ['cx', 'cy', 'r'], | |
ellipse: ['cx', 'cy', 'rx', 'ry'], | |
polygon: ['points'] | |
}; | |
/** | |
* 场馆选区 遮罩的状态Map | |
*/ | |
var standMaskStatusMap = { | |
INVISIBLE: Symbol('stand mask invisible'), // 正常状态(遮罩不可见) | |
HIGHLIGHT: Symbol('stand mask highlight'), // 高亮状态 | |
ACTIVE: Symbol('stand mask active'), // 选中状态 | |
TRANSLUCENT: Symbol('stand mask translucent') // 半透明状态 | |
}; | |
var ImageCache = {}; | |
var userAgent = window.navigator.userAgent; | |
var UA = { | |
isVivo: /vivo/i.test(userAgent) && !/VivoBrowser/i.test(userAgent), | |
isOPPO: /OPPO/i.test(userAgent), | |
isHuaWei: /HUAWEI/i.test(userAgent), | |
isMi5: /MI 5/i.test(userAgent), | |
isBadPhone: /iPhone OS (8|9)[_0-9]*/i.test(userAgent), | |
isUC: /UCBrowser/i.test(userAgent), | |
isAlipay: /Alipay/i.test(userAgent), | |
isiOS: /i(Phone|pad|touch)/i.test(userAgent), | |
isAndroid: /android/i.test(userAgent), | |
isIE: document.documentMode || +(navigator.userAgent.match(/MSIE (\d+)/) && RegExp.$1), | |
isPC: null | |
}; | |
UA.isPC = !(UA.isiOS || UA.isAndroid); | |
var Util = { | |
generateSeatImage: generateSeatImage, | |
getNormalizeColor: getNormalizeColor, | |
standMaskStatusMap: standMaskStatusMap, | |
svgToImageUrl: svgToImageUrl, | |
ShareData: ShareData, | |
SvgTypeMap: SvgTypeMap, | |
UA: UA, | |
shouldResizeSvgWidthHeight: UA.isVivo && !UA.isUC || UA.isMi5 || UA.isOPPO && UA.isUC || UA.isHuaWei && UA.isUC && !UA.isAlipay, | |
DoubleRenderBoundary: 7000 * 7000, | |
throttle: throttle, | |
addStyle: addStyle, | |
/** | |
* 获取dpr | |
*/ | |
getDpr: function getDpr() { | |
return window.dpr || window.devicePixelRatio; | |
}, | |
createCanvas: createCanvas, | |
fetchImage: fetchImage, | |
/** | |
* 获取字符串hash值 | |
* @param {String} str 要获取hash的字符串 | |
*/ | |
getHash: function getHash(str) { | |
var hash = 5381; | |
var i = str.length; | |
while (i) { | |
hash = hash * 33 ^ str.charCodeAt(--i); | |
} | |
return hash >>> 0; | |
}, | |
/** | |
* 获取手势事件点坐标 | |
* @param {Touches} eventTouches touch事件e.touches对象 | |
*/ | |
getTouchEventPoints: function getTouchEventPoints(eventTouches) { | |
return Array.prototype.map.call(eventTouches, function (touch) { | |
return { | |
x: touch.pageX, | |
y: touch.pageY | |
}; | |
}); | |
}, | |
getEventPoints: getEventPoints, | |
/** | |
* 判断两矩形是否相交 | |
* @param {Object} rect1 矩形1, 包含left top right bottom属性 | |
* @param {Object} rect2 矩形2 | |
*/ | |
isIntersect: function isIntersect(rect1, rect2) { | |
return !(rect1.right < rect2.left || rect1.bottom < rect2.top || rect1.left > rect2.right || rect1.top > rect2.bottom); | |
}, | |
getPoints: getPoints, | |
getBoundingRect: getBoundingRect, | |
getOffset: getOffset, | |
getPosition: getPosition, | |
getScroll: getScroll | |
}; | |
// iPhone6用2000px会容易闪退 | |
var SingleCanvasSize = UA.isBadPhone ? 1000 : 2000; | |
/** | |
* 不可售颜色 | |
*/ | |
var NotSaleColor = '#EEEEEE'; | |
var ThumbnailStateBase64Image = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAV4AAAAkBAMAAAAzy086AAAAKlBMVEVHcEzZ2dnZ2dnb29vg4ODc3NzZ2dna2trY2Nj////u7u7m5ubd3d329vYTZU6tAAAACHRSTlMAyutXEy+qg3jeFasAAALOSURBVFjD1Zg/b9NAGMZfiQA7iipWVEVijFjo2H4DxAArDEiMlRASa6iU2r7zHtvxHjtlT3LpHlN3j9Pku3D/7HOIS6I7S8SPJediS6df3rz3PGfDD6tJuoYnjeLtArxpEO4pADx93Rjcn+8oL7xvDG+H4ULrZUNwe+ecFy7MprmflL+RhRrjkRqjG2PeNkh9NZom2+L1SrxOoMb20hS3n+PCc5NpfntSHNsNyvc2ajgdmfJeFrxgEBoo80jGjjEvbDSSDYJTqumcnuh1esrYMF2YRIWSQWigdWTxg6OgkJ6SAatnXnbPt1AxNihyt8QLZwb/U5l3umalZdCzOI78mGlMf0UsFOnzXpVxDULDKWq3ZOUVTSFWoDvI/4O8qRNtXhEVStqhgeJMHiMLR2srvSOzaCh4l/XxdrZxTUJD9YPtbUSpwx1ezBebNm8eFUoXNfC6m80qJiSV5mWvpSVQXrb8An3eNuxIMzSikg8UEi6cFG1NeVdxrM/b38WFZ3pTzeJc41IQ8/BNVswSJO/Ewvq8nyp4tUNjyt3ggZuFRB+pG3YNvNdVuNqh4RFCPSEkE7bghISRZQtpCaa83UpezdBwKV8sG1WssPSe8/LYqIP3qhpXLzRwdpNG8zn2S5swERTCdXPeMSGavH9HhVloJAHBIRpW8CaDMq++n3Uew9UKDbTIfg3dYRoyo93iFfviZMJ57wghcy3e3agwDA3Hm/B1FhS8DuN1/MIkjPK4/TgutDRCA0eBhQgJafks+4Ew3TLeSLBnhvuH/j/KqxMaKPOZbcn+VX7msK0aJreB4iVk+9FJPyoMQsPluDmv8jOb7YSR2KFL3qkXLuqJCoPQwBKBpzES9WMf4rp4AMJzflnncai7h/fIXk+d7sM9rrcnvfO9vGYP9zXrEg7Qh6PB/QLQJOADcQE+HkMP977DwWq9/fziv8K+OvlWvdT+AGKH3jtCaIWxAAAAAElFTkSuQmCC'; | |
/** | |
* 获取目标元素包围矩形, 考虑transform属性影响 | |
* @param {HTMLElement} $el 目标元素 | |
*/ | |
function getBBox($el) { | |
var bBox = $el.getBBox(); | |
var x = bBox.x, | |
y = bBox.y; | |
var width = bBox.width, | |
height = bBox.height; | |
var transform = $el.getAttribute('transform'); | |
if (transform) { | |
var parseTranslateResult = /translate\(([+-]?\d+(?:\.\d+)?)[, ]([+-]?\d+(?:\.\d+)?)\)/i.exec(transform); | |
if (parseTranslateResult) { | |
x += parseInt(parseTranslateResult[1] || 0, 10); | |
y += parseInt(parseTranslateResult[2] || 0, 10); | |
} | |
} | |
return { | |
x: x, | |
y: y, | |
width: width, | |
height: height | |
}; | |
} | |
/** | |
* 场景 enum | |
*/ | |
var Scene = { | |
SelectArea: 'SelectArea', | |
SelectSeat: 'SelectSeat' | |
}; | |
/** | |
* 获取图片 | |
* @param {String} imgUrl | |
* @return {Image} img | |
*/ | |
function fetchImage(imgUrl) { | |
if (!imgUrl) { | |
return Promise.reject('不合法的图片地址'); | |
} | |
var cacheKey = Util.getHash(imgUrl); | |
if (ImageCache[cacheKey]) { | |
return Promise.resolve(ImageCache[cacheKey]); | |
} | |
ImageCache[cacheKey] = new Promise(function (resolve, reject) { | |
var img = new Image(); | |
img.onload = function () { | |
ImageCache[cacheKey] = img; | |
resolve(img); | |
}; | |
img.onerror = function () { | |
reject(new Error('请求图片失败')); | |
}; | |
img.src = imgUrl; | |
}); | |
return ImageCache[cacheKey]; | |
} | |
/** | |
* 给dom添加样式, 已存在属性会被新值覆盖 | |
* @param {DomElement} $dom dom节点 | |
* @param {Object} styleObject 样式对象, 与jsx样式类似 | |
*/ | |
function addStyle($dom) { | |
var styleObject = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | |
if (styleObject.transform) { | |
styleObject['-webkit-transform'] = styleObject.transform; | |
} | |
$dom.style.cssText += _toStyle_1_3_3_toStyle.string(styleObject); | |
} | |
/** | |
* 创建canvas dom节点 | |
* @param {Number} width 宽度 | |
* @param {Number} height 长度 | |
*/ | |
function createCanvas(width, height) { | |
var $canvas = document.createElement('canvas'); | |
$canvas.width = width; | |
$canvas.height = height; | |
$canvas.style.width = width + 'px'; | |
$canvas.style.height = height + 'px'; | |
return $canvas; | |
} | |
/** | |
* 函数节流, 在指定延时或者指定时间间隔后执行 | |
* @param {Function} func 要节流的函数 | |
* @param {Number} delay 延时执行时间 | |
* @param {Number} interval 间隔执行时间 | |
*/ | |
function throttle(func) { | |
var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 300; | |
var interval = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 30; | |
var lastTime = 0; | |
var timer = null; | |
return function () { | |
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | |
args[_key] = arguments[_key]; | |
} | |
if (!lastTime) { | |
func.apply(undefined, args); | |
lastTime = Date.now(); | |
} else { | |
var now = Date.now(); | |
if (now - lastTime >= interval) { | |
func.apply(undefined, args); | |
lastTime = now; | |
} else { | |
clearTimeout(timer); | |
timer = setTimeout(func.bind.apply(func, [null].concat(args)), delay); | |
} | |
} | |
}; | |
} | |
/** | |
* 获取事件的点击坐标或者手势坐标 | |
* @param {Event} event 事件对象 | |
*/ | |
function getEventPoints(event) { | |
var touches = event.touches, | |
changedTouches = event.changedTouches; | |
if (touches && touches.length > 0) { | |
return Util.getTouchEventPoints(event.touches); | |
} else if (changedTouches && changedTouches.length > 0) { | |
return Util.getTouchEventPoints(event.changedTouches); | |
} | |
return [{ | |
x: event.pageX, | |
y: event.pageY | |
}]; | |
} | |
/** | |
* 获取元素相对网页左上角的距离 | |
* http://www.ruanyifeng.com/blog/2009/09/find_element_s_position_using_javascript.html | |
* @param {Dom} element 元素 | |
*/ | |
function getOffset(element) { | |
var top = 0; | |
var left = 0; | |
do { | |
top += element.offsetTop; | |
left += element.offsetLeft; | |
element = element.offsetParent; | |
} while (element !== null); | |
return { | |
top: top, | |
left: left | |
}; | |
} | |
/** | |
* 获取元素滚动距离 | |
* @param {Dom} element 元素 | |
*/ | |
function getScroll(element) { | |
var top = 0; | |
var left = 0; | |
do { | |
top += element.scrollTop; | |
left += element.scrollLeft; | |
element = element.parentElement; | |
} while (element !== null); | |
return { | |
top: top, | |
left: left | |
}; | |
} | |
/** | |
* 获取元素位置 | |
* @param {Dom} element 元素 | |
*/ | |
function getPosition(element) { | |
var bounding = element.getBoundingClientRect(); | |
var scroll = Util.getScroll(element); | |
return { | |
left: bounding.left + scroll.left, | |
top: bounding.top + scroll.top | |
}; | |
} | |
/** | |
* 获取一系列点坐标构成的多边形的包围矩形 | |
* @param {Array} points 点坐标列表 | |
*/ | |
function getBoundingRect(points) { | |
return points.reduce(function (result, point, index) { | |
if (index === 0) { | |
return { | |
left: point.x, | |
right: point.x, | |
top: point.y, | |
bottom: point.y | |
}; | |
} | |
if (point.x < result.left) { | |
result.left = point.x; | |
} else if (point.x > result.right) { | |
result.right = point.x; | |
} | |
if (point.y < result.top) { | |
result.top = point.y; | |
} else if (point.y > result.bottom) { | |
result.bottom = point.y; | |
} | |
return result; | |
}, {}); | |
} | |
/** | |
* 将接口返回的字符串点坐标转为坐标数组 | |
* @param {String} pis 点坐标字符串(|,分隔) | |
*/ | |
function getPoints(pis) { | |
var points = pis.split(/,|\|/).map(function (v) { | |
return parseInt(v, 10); | |
}).reduce(function (result, number, index) { | |
if (index % 2 === 0) { | |
result[index / 2] = { | |
x: number | |
}; | |
} else { | |
result[(index - 1) / 2].y = number; | |
} | |
return result; | |
}, []); | |
return points; | |
} | |
/** | |
* 获取ios版本 | |
*/ | |
function getiOSVersion() { | |
var regResult = /iPhone OS (\d+_\d)/.exec(userAgent); | |
if (regResult) { | |
var version = regResult[1].replace('_', '.'); | |
return parseFloat(version); | |
} | |
return null; | |
} | |
/** | |
* 限制 canvas memory 使用量的情况 | |
* 已知在ios12系统中, iPhone7 限制 256MB, iPhone XS 限制 288MB, 其他情况均为 2151MB | |
* https://github.com/WebKit/webkit/commit/5d5b478917c685e50d1032ccf761ca53fc8f1b74#diff-b411cd4839e4bbc17b00570536abfa8f | |
*/ | |
var CanvasMemoryLimit = UA.isiOS && getiOSVersion() >= 12; | |
/** | |
* 错误码, 与业务相关, 标识不同错误场景, 可能对于不同的处理逻辑 | |
*/ | |
var ErrorCode = { | |
// 一般错误, 仅toast提示, 无额外业务逻辑 | |
Normal: 0, | |
// 超过区域限购次数 | |
ExceedLimitNumber: 100, | |
// 当前看台没有可售座位 | |
StandNoAvaliableSeat: 101, | |
/** | |
* 解压座位静态压缩数据失败 | |
*/ | |
DecompressSeatStaticFail: 102, | |
// 获取场馆图失败 | |
VenueImgNotFound: 400, | |
// 渲染场馆区域失败 | |
VenueRenderStandFail: 206 | |
}; | |
/** | |
* 错误消息 + 对应的key | |
* key用于国际化使用 | |
*/ | |
var ErrorMessage = { | |
seat_sold_out: '该票价座位已经卖光啦~', | |
load_venue_image_fail: '加载场馆底图失败', | |
exceeded_stand_purchase_limit: '超出限购数量了哦~', | |
render_stand_data_fail: '渲染区域数据失败', | |
stand_no_chooseable_seat: function stand_no_chooseable_seat(standName) { | |
return standName + '\u5DF2\u7ECF\u6CA1\u6709\u53EF\u552E\u5EA7\u4F4D\uFF0C\u8BF7\u9009\u62E9\u5176\u4ED6\u770B\u53F0'; | |
}, // 前面会拼上看台名称 | |
enter_select_seat: function enter_select_seat(standName) { | |
return '\u60A8\u5DF2\u8FDB\u5165' + standName; | |
}, // 后面拼上看台名称 | |
decompress_seat_static_fail: '座位静态压缩数据解压失败' | |
}; | |
var asyncToGenerator = function (fn) { | |
return function () { | |
var gen = fn.apply(this, arguments); | |
return new Promise(function (resolve, reject) { | |
function step(key, arg) { | |
try { | |
var info = gen[key](arg); | |
var value = info.value; | |
} catch (error) { | |
reject(error); | |
return; | |
} | |
if (info.done) { | |
resolve(value); | |
} else { | |
return Promise.resolve(value).then(function (value) { | |
step("next", value); | |
}, function (err) { | |
step("throw", err); | |
}); | |
} | |
} | |
return step("next"); | |
}); | |
}; | |
}; | |
var classCallCheck = function (instance, Constructor) { | |
if (!(instance instanceof Constructor)) { | |
throw new TypeError("Cannot call a class as a function"); | |
} | |
}; | |
var createClass = 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); | |
} | |
} | |
return function (Constructor, protoProps, staticProps) { | |
if (protoProps) defineProperties(Constructor.prototype, protoProps); | |
if (staticProps) defineProperties(Constructor, staticProps); | |
return Constructor; | |
}; | |
}(); | |
var defineProperty = function (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 _extends = Object.assign || function (target) { | |
for (var i = 1; i < arguments.length; i++) { | |
var source = arguments[i]; | |
for (var key in source) { | |
if (Object.prototype.hasOwnProperty.call(source, key)) { | |
target[key] = source[key]; | |
} | |
} | |
} | |
return target; | |
}; | |
var get = function get(object, property, receiver) { | |
if (object === null) object = Function.prototype; | |
var desc = Object.getOwnPropertyDescriptor(object, property); | |
if (desc === undefined) { | |
var parent = Object.getPrototypeOf(object); | |
if (parent === null) { | |
return undefined; | |
} else { | |
return get(parent, property, receiver); | |
} | |
} else if ("value" in desc) { | |
return desc.value; | |
} else { | |
var getter = desc.get; | |
if (getter === undefined) { | |
return undefined; | |
} | |
return getter.call(receiver); | |
} | |
}; | |
var inherits = function (subClass, superClass) { | |
if (typeof superClass !== "function" && superClass !== null) { | |
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); | |
} | |
subClass.prototype = Object.create(superClass && superClass.prototype, { | |
constructor: { | |
value: subClass, | |
enumerable: false, | |
writable: true, | |
configurable: true | |
} | |
}); | |
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; | |
}; | |
var possibleConstructorReturn = function (self, call) { | |
if (!self) { | |
throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); | |
} | |
return call && (typeof call === "object" || typeof call === "function") ? call : self; | |
}; | |
var slicedToArray = function () { | |
function sliceIterator(arr, i) { | |
var _arr = []; | |
var _n = true; | |
var _d = false; | |
var _e = undefined; | |
try { | |
for (var _i = arr[Symbol.iterator](), _s; !(_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"]) _i["return"](); | |
} finally { | |
if (_d) throw _e; | |
} | |
} | |
return _arr; | |
} | |
return function (arr, i) { | |
if (Array.isArray(arr)) { | |
return arr; | |
} else if (Symbol.iterator in Object(arr)) { | |
return sliceIterator(arr, i); | |
} else { | |
throw new TypeError("Invalid attempt to destructure non-iterable instance"); | |
} | |
}; | |
}(); | |
var toConsumableArray = function (arr) { | |
if (Array.isArray(arr)) { | |
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; | |
return arr2; | |
} else { | |
return Array.from(arr); | |
} | |
}; | |
var _class$1; | |
var _class2; | |
var _temp; | |
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { | |
var desc = {}; | |
Object['ke' + 'ys'](descriptor).forEach(function (key) { | |
desc[key] = descriptor[key]; | |
}); | |
desc.enumerable = !!desc.enumerable; | |
desc.configurable = !!desc.configurable; | |
if ('value' in desc || desc.initializer) { | |
desc.writable = true; | |
} | |
desc = decorators.slice().reverse().reduce(function (desc, decorator) { | |
return decorator(target, property, desc) || desc; | |
}, desc); | |
if (context && desc.initializer !== void 0) { | |
desc.value = desc.initializer ? desc.initializer.call(context) : void 0; | |
desc.initializer = undefined; | |
} | |
if (desc.initializer === void 0) { | |
Object['define' + 'Property'](target, property, desc); | |
desc = null; | |
} | |
return desc; | |
} | |
var StandRender = (_class$1 = (_temp = _class2 = function () { | |
createClass(StandRender, null, [{ | |
key: 'indexOfFirstExceedSeat', | |
/** | |
* 获取超过座位限购数的最小索引 | |
* 固定套票计算逻辑: Matrix、其他BBC项目算多张, 中网BBC项目算一张 | |
* @param {Array} seats 座位数组 | |
* @param {Number} maxPickNumber 最大可选座位数量 | |
* @param {Boolean} isPackageLinkOne 是否将固定套票当成一张票计数 | |
*/ | |
value: function indexOfFirstExceedSeat(seats, maxPickNumber) { | |
var isPackageLinkOne = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; | |
// 座位总数小于等于最大个数 | |
if (seats.length <= maxPickNumber) { | |
return -1; | |
} | |
var count = 0; | |
for (var i = 0; i < seats.length; i++) { | |
if (count === +maxPickNumber) { | |
return i; | |
} | |
if (seats[i].getInfo().isPackage) { | |
// 套票逻辑 | |
var packageCombinedId = seats[i].getInfo().packageCombinedId; | |
if (isPackageLinkOne) { | |
while (i + 1 < seats.length && seats[i + 1].getInfo().isPackage && seats[i + 1].getInfo().packageCombinedId === packageCombinedId) { | |
i++; | |
} | |
count++; | |
} else { | |
// 计算该套票组票的个数 | |
var groupCount = 1; | |
var j = i; | |
while (j + 1 < seats.length && seats[j + 1].getInfo().isPackage && seats[j + 1].getInfo().packageCombinedId === packageCombinedId) { | |
groupCount++; | |
j++; | |
} | |
// 如果已有个数加上该套票组票个数超过了限购数量, 返回该套票组第一个套票座位下标 | |
if (count + groupCount > maxPickNumber) { | |
return i; | |
} | |
// 如果没超过, 更新i到下一个非当前套票组座位, 更新计数 | |
i = j; | |
count += groupCount; | |
} | |
} else { | |
// 非套票 | |
count++; | |
} | |
} | |
return -1; | |
} | |
// 绘制座位context | |
// 鹰眼图最大高度(单位px) | |
// 当前最大可选座位数量 | |
// Area实例 | |
// Viewport实例 | |
// Thumbnail实例 | |
// 自定义Canvas类实例 | |
// 鹰眼图容器 | |
// 隐藏鹰眼图定时器 | |
// 绘制座位定时器 | |
// 上一次渲染座位时间 | |
// 鼠标点按类型 1-左键 2-右键 4-中键 | |
// 选框 | |
// 座位选中态变化事件 | |
// 错误事件 | |
}]); | |
/** | |
* 看台渲染器 | |
* @param {Dom} $container 容器div | |
*/ | |
function StandRender($container) { | |
var _this = this; | |
classCallCheck(this, StandRender); | |
this._ctx = null; | |
this._maxPickNumber = Number.MAX_VALUE; | |
this._area = null; | |
this._viewport = null; | |
this._thumbnail = null; | |
this._$seatCanvas = null; | |
this._$thumbnailContainer = null; | |
this._thumbnailHideTimer = null; | |
this._drawSeatTimer = null; | |
this._prevTime = Date.now(); | |
this._mouseType = null; | |
this._selectBox = null; | |
this.onSelectSeat = null; | |
this.onError = null; | |
this.onTouchStart = function (e) { | |
e.preventDefault(); | |
_this._touchStatus = 'start'; | |
_this._prevTouchPoints = getEventPoints(e); | |
_this._prevTime = Date.now(); | |
_this._mouseType = e.buttons || 1; // 移动端手势事件, buttons是undefined, 置为1 | |
if (_this._thumbnailHideTimer) { | |
clearTimeout(_this._thumbnailHideTimer); | |
} | |
if (e.buttons === 2) { | |
// 按下的是鼠标右键 | |
if (!_this._selectBox) { | |
_this._selectBox = document.createElement('div'); | |
_this._selectBox.style.cssText = 'position:absolute;width:0;height:0;border:1px dashed #eee;background-color:#aaa;opacity:0.6;display:none;'; | |
_this._selectBox.style.left = _this._prevTouchPoints[0].x + 'px'; | |
_this._selectBox.style.top = _this._prevTouchPoints[0].y + 'px'; | |
_this._$container.appendChild(_this._selectBox); | |
} | |
} | |
}; | |
this.onMouseLeave = function () { | |
_this._prevTouchPoints = null; | |
}; | |
this.cancelSelectSeat = function (seatId) { | |
_this._area.cancelSelectSeat(seatId); | |
}; | |
this._$container = $container; | |
} | |
/** | |
* 初始化Area | |
* @param {Area} Area Area类或者子类 | |
* @param {Number} row 行数 | |
* @param {Column} column 列数 | |
*/ | |
createClass(StandRender, [{ | |
key: 'initArea', | |
value: function initArea(Area, row, column) { | |
this._area = new Area(row, column); | |
this._area.onSelectSeat = this.handleSelectSeat.bind(this); | |
this._area.onError = this.handleError.bind(this); | |
} | |
/** | |
* 更新视图 | |
*/ | |
}, { | |
key: 'updateView', | |
value: function updateView() { | |
// 更新位置 | |
var centerViewportPoint = this._viewport.getCenterPoint(); | |
var currentViewportPoint = this._viewport.getPoint(); | |
var areaSize = this._area.getSize(); | |
var scale = this._viewport.getScale(); | |
// 如果是中网BBC项目, 在updateViewportFocusStand()里调用的updateView() | |
// 会因为<keep-alive>导致clientWidth和clientHeight为0, 需要用Util.ShareData里存的原始width和height | |
var containerWidth = this._$container.clientWidth || Util.ShareData.ContainerWidth; | |
var containerHeight = this._$container.clientHeight || Util.ShareData.ContainerHeight; | |
this._ctx.setScale(scale); | |
this._ctx.setPosition({ | |
x: -(areaSize.width * scale - containerWidth) / 2 + (centerViewportPoint.x - currentViewportPoint.x), | |
y: -(areaSize.height * scale - containerHeight) / 2 + (centerViewportPoint.y - currentViewportPoint.y) | |
}); | |
// 每300ms进行一次绘制 | |
if (Date.now() - this._prevTime > 300) { | |
this.drawSeat(); | |
this._prevTime = Date.now(); | |
} | |
// 更新鹰眼图 | |
this._thumbnail.update(); | |
if (!this._thumbnail.visible) { | |
this._thumbnail.show(); | |
} | |
} | |
/** | |
* 手势按下事件 或者 鼠标按下事件 | |
* @param {Event} e 事件对象 | |
*/ | |
}, { | |
key: 'onTouchMove', | |
/** | |
* 手势移动事件 或者 鼠标移动事件 | |
* @param {Number} scaleDivisor 缩放比例除数 | |
* @param {Event} e 事件对象 | |
*/ | |
value: function onTouchMove(scaleDivisor, e) { | |
e.preventDefault(); | |
if (!this._prevTouchPoints) { | |
return; | |
} | |
var currentTouchPoints = getEventPoints(e); | |
// 按下的是鼠标左键 | |
if (this._mouseType === 1) { | |
// 过滤横向和纵向同时低于1.5px的move事件 | |
// 三星浏览器和vivo浏览器会因为点击触发小距离move而不好点中座位, 这里可以缓解该情况 | |
if (Math.abs(currentTouchPoints[0].x - this._prevTouchPoints[0].x) <= 1.5 && Math.abs(currentTouchPoints[0].y - this._prevTouchPoints[0].y) <= 1.5) { | |
return; | |
} | |
this._touchStatus = 'move'; | |
if (currentTouchPoints.length === 1) { | |
// 单指拖动 | |
// 如果是二指缩放, 且手指离开时间不一致, 又触发了move事件, 将本次手指位置作为起始点 | |
if (this._prevTouchPoints.length === 2) { | |
this._prevTouchPoints = currentTouchPoints; | |
return; | |
} | |
// 移动视口位置 | |
this._viewport.move(this._prevTouchPoints[0].x - currentTouchPoints[0].x, this._prevTouchPoints[0].y - currentTouchPoints[0].y); | |
// 记录当前点 | |
this._prevTouchPoints = currentTouchPoints; | |
} else if (currentTouchPoints.length === 2) { | |
// 二指缩放 | |
if (this._prevTouchPoints.length === 1) { | |
return; | |
} | |
// 根据移动距离计算线性缩放倍率变化值, 缩放视口大小 | |
var sx = this._prevTouchPoints[0].x - this._prevTouchPoints[1].x; | |
var sy = this._prevTouchPoints[0].y - this._prevTouchPoints[1].y; | |
var ex = currentTouchPoints[0].x - currentTouchPoints[1].x; | |
var ey = currentTouchPoints[0].y - currentTouchPoints[1].y; | |
var d1 = Math.sqrt(sx * sx + sy * sy); | |
var d2 = Math.sqrt(ex * ex + ey * ey); | |
this._viewport.scale((d1 - d2) / scaleDivisor); | |
this._prevTouchPoints = currentTouchPoints; | |
// 设置Canvas缩放 | |
this._ctx.setScale(this._viewport.getScale()); | |
} | |
this.updateView(); | |
// 拖动完成后需要绘制一次座位, 但是发现一个奇怪的现象: onTouchEnd 比最后一次 onTouchMove 要慢上700ms左右 | |
// 因此在这里用timer控制, 最后一次 onTouchMove 60ms后绘制一次座位 | |
clearTimeout(this._drawSeatTimer); | |
this._drawSeatTimer = setTimeout(this.drawSeat.bind(this), 60); | |
clearTimeout(this._thumbnailHideTimer); | |
this._thumbnailHideTimer = setTimeout(this._thumbnail.hide.bind(this._thumbnail), 400); | |
} else if (this._mouseType === 2) { | |
this._touchStatus = 'move'; | |
this._selectBox.style.left = Math.min(currentTouchPoints[0].x, this._prevTouchPoints[0].x) + 'px'; | |
this._selectBox.style.top = Math.min(currentTouchPoints[0].y, this._prevTouchPoints[0].y) + 'px'; | |
this._selectBox.style.width = Math.abs(currentTouchPoints[0].x - this._prevTouchPoints[0].x) + 'px'; | |
this._selectBox.style.height = Math.abs(currentTouchPoints[0].y - this._prevTouchPoints[0].y) + 'px'; | |
this._selectBox.style.display = 'block'; | |
} | |
} | |
/** | |
* 手势松开事件 或者 鼠标按钮弹起事件 | |
* @param {Event} e 事件对象 | |
*/ | |
}, { | |
key: 'onTouchEnd', | |
value: function onTouchEnd(e) { | |
e.preventDefault(); | |
var position = getPosition(this._$seatCanvas); | |
var currentTouchPoints = getEventPoints(e); | |
// 如果status不是move, 说明是点击事件 | |
if (this._touchStatus === 'start') { | |
this._area.handleClick(this._ctx, { | |
x: (this._prevTouchPoints[0].x - position.left) / this._viewport.getScale(), | |
y: (this._prevTouchPoints[0].y - position.top) / this._viewport.getScale() | |
}); | |
} else if (this._mouseType === 2) { | |
this._area.selectRangeSeats((this._prevTouchPoints[0].x - position.left) / this._viewport.getScale(), (currentTouchPoints[0].x - position.left) / this._viewport.getScale(), (this._prevTouchPoints[0].y - position.top) / this._viewport.getScale(), (currentTouchPoints[0].y - position.top) / this._viewport.getScale()); | |
this._selectBox.style.display = 'none'; | |
} | |
this._prevTouchPoints = null; | |
this._isMouseLongTap = false; | |
} | |
/** | |
* 鼠标离开dom范围事件 | |
* @param {Event} e 事件对象 | |
*/ | |
}, { | |
key: 'onMouseWheel', | |
/** | |
* 鼠标滚轮事件 | |
* @param {Event} e 事件对象 | |
*/ | |
value: function onMouseWheel(e) { | |
e.preventDefault(); | |
this._viewport.scale((e.deltaY || e.wheelDelta) / 500); | |
this.updateView(); | |
if (this._thumbnailHideTimer) { | |
clearTimeout(this._thumbnailHideTimer); | |
} | |
this._thumbnailHideTimer = setTimeout(this._thumbnail.hide.bind(this._thumbnail), 500); | |
} | |
/** | |
* 绘制缩略图 | |
*/ | |
}, { | |
key: 'drawThumbnail', | |
value: function drawThumbnail() { | |
var _this2 = this; | |
// 延迟绘制, 保证座位优先显示 | |
setTimeout(function () { | |
_this2._thumbnail.draw(_this2._thumbnailCtx); | |
}, 300); | |
} | |
/** | |
* 处理选座事件 | |
* @param {Array} selectedSeats 已选中的座位 | |
* @param {Seat|[Seat]} changedSeat 本次变化的座位 | |
* @param {String} type 变化类型(选中/取消选中) | |
*/ | |
}, { | |
key: 'handleSelectSeat', | |
value: function handleSelectSeat(selectedSeats, changedSeat, type) { | |
var isPackageLinkOne = this.className === 'BBCStandRender'; // 固定套票计算逻辑: Matrix、其他BBC项目套票算多张, 中网BBC项目算一张 | |
var index = StandRender.indexOfFirstExceedSeat(selectedSeats, this._maxPickNumber, isPackageLinkOne); | |
if (index !== -1) { | |
for (var i = index; i < selectedSeats.length; i++) { | |
selectedSeats[i].cancelSelect(); | |
} | |
this._area.reserveNSelectSeats(index); | |
if (this.onError) { | |
this.onError({ | |
code: ErrorCode.ExceedLimitNumber, | |
message: ErrorMessage.exceeded_stand_purchase_limit, | |
messageKey: 'exceeded_stand_purchase_limit' | |
}); | |
} | |
return; | |
} | |
if (this.onSelectSeat) { | |
var selectedSeatsInfo = selectedSeats.map(function (seat) { | |
return seat.getInfo(); | |
}); | |
var changedSeatInfo = Array.isArray(changedSeat) ? changedSeat.map(function (seat) { | |
return seat.getInfo(); | |
}) : changedSeat.getInfo(); | |
this.onSelectSeat(selectedSeatsInfo, changedSeatInfo, type); | |
} | |
} | |
/** | |
* 处理错误 | |
* @param {Error} e 错误对象 | |
*/ | |
}, { | |
key: 'handleError', | |
value: function handleError(e) { | |
if (this.onError) { | |
this.onError(e); | |
} | |
} | |
/* ========== 对外暴露方法 start =========== */ | |
/** | |
* 取消座位选中 | |
* @param {Number} seatId 座位id | |
*/ | |
}, { | |
key: 'destroy', | |
/** | |
* 销毁组件, 释放内存 | |
*/ | |
value: function destroy() { | |
this._area = null; | |
this._thumbnail = null; | |
this._viewport = null; | |
this._ctx = null; | |
this._$seatCanvas = null; | |
this._$thumbnailContainer = null; | |
this._thumbnailHideTimer = null; | |
this._$container.removeEventListener('touchstart', this.onTouchStart); | |
this._$container.removeEventListener('touchmove', this.onTouchMove); | |
this._$container.removeEventListener('touchend', this.onTouchEnd); | |
this._$container.removeEventListener('mousedown', this.onTouchStart); | |
this._$container.removeEventListener('mousemove', this.onTouchMove); | |
this._$container.removeEventListener('mouseup', this.onTouchEnd); | |
this._$container.removeEventListener('mouseleave', this.onMouseLeave); | |
this._$container.removeEventListener('mousewheel', this.onMouseWheel); | |
} | |
/* ========== 对外暴露方法 end =========== */ | |
}]); | |
return StandRender; | |
}(), _class2.ThumbnailCanvasMaxHeight = 200, _temp), _applyDecoratedDescriptor(_class$1.prototype, 'onTouchEnd', [autobind], Object.getOwnPropertyDescriptor(_class$1.prototype, 'onTouchEnd'), _class$1.prototype), _class$1); | |
var _class$3; | |
var _temp$2; | |
// 座位点击事件 | |
var ClickSeatEvent = { | |
Select: 'Select', | |
CancelSelect: 'CancelSelect' | |
}; | |
var Area = (_temp$2 = _class$3 = function () { | |
/** | |
* 场馆区域 | |
* @param {Number} row 行数 | |
* @param {Number} column 列数 | |
*/ | |
// 按票价分组座位 | |
// 按套票逻辑分组 | |
function Area(row, column) { | |
classCallCheck(this, Area); | |
this._map = {}; | |
this._packages = {}; | |
this._selectedSeats = []; | |
this._prices = {}; | |
this._priceIndex = -1; | |
this.onSelectSeat = null; | |
this.onError = null; | |
this._row = row; | |
this._column = column; | |
} | |
/** | |
* 添加座位 | |
*/ | |
// 当前高亮的票价索引 | |
// 选中的座位 | |
// 座位数据, 二维矩阵 | |
createClass(Area, [{ | |
key: 'addSeat', | |
value: function addSeat() { | |
throw Error('请在子类实现addSeat()方法'); | |
} | |
/** | |
* 绘制区域内可见座位 | |
*/ | |
}, { | |
key: 'draw', | |
value: function draw() { | |
throw Error('请在子类实现draw()方法'); | |
} | |
/** | |
* 获取区域尺寸(px) | |
*/ | |
}, { | |
key: 'getSize', | |
value: function getSize() { | |
throw Error('请在子类实现getSize()方法'); | |
} | |
/** | |
* 按照对应规则选中某个范围内的座位 | |
*/ | |
}, { | |
key: 'selectRangeSeats', | |
value: function selectRangeSeats() { | |
throw Error('请在子类实现selectAreaSeats()方法'); | |
} | |
/** | |
* 取消座位选中态 | |
* @param {Number} seatId 座位id | |
*/ | |
}, { | |
key: 'cancelSelectSeat', | |
value: function cancelSelectSeat(seatId) { | |
var seatIterator = this.generateSeatsIterator(0, 0, this._row, this._column); | |
var _iteratorNormalCompletion = true; | |
var _didIteratorError = false; | |
var _iteratorError = undefined; | |
try { | |
for (var _iterator = seatIterator[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | |
var _ref = _step.value; | |
var seat = _ref.seat; | |
if (seat.id === seatId && seat.isSelect) { | |
seat.cancelSelect(); | |
this.emitSeatSelectEvent(seat); | |
} | |
} | |
} catch (err) { | |
_didIteratorError = true; | |
_iteratorError = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion && _iterator.return) { | |
_iterator.return(); | |
} | |
} finally { | |
if (_didIteratorError) { | |
throw _iteratorError; | |
} | |
} | |
} | |
} | |
/** | |
* 更新座位状态 | |
* @param {Object} seatsStatusData 座位状态数据 | |
*/ | |
}, { | |
key: 'updateSeatStatus', | |
value: function updateSeatStatus(seatsStatusData) { | |
this._selectedSeats = []; | |
var seatIterator = this.generateSeatsIterator(0, 0, this._row, this._column); | |
var _iteratorNormalCompletion2 = true; | |
var _didIteratorError2 = false; | |
var _iteratorError2 = undefined; | |
try { | |
for (var _iterator2 = seatIterator[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | |
var _ref2 = _step2.value; | |
var seat = _ref2.seat; | |
var seatInfo = seat.getInfo(); | |
var curStand = seatsStatusData[seatInfo.standId]; | |
if (seatInfo.status !== curStand[seatInfo.i]) { | |
seat.updateSeatStatus(curStand[seatInfo.i]); | |
} | |
if (seat.isSelect) { | |
this.emitSeatSelectEvent(seat); | |
} | |
} | |
} catch (err) { | |
_didIteratorError2 = true; | |
_iteratorError2 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion2 && _iterator2.return) { | |
_iterator2.return(); | |
} | |
} finally { | |
if (_didIteratorError2) { | |
throw _iteratorError2; | |
} | |
} | |
} | |
} | |
/** | |
* 锁定座位 | |
* @param {number[]} seatIds 要预锁的座位id列表 | |
*/ | |
}, { | |
key: 'preLockSelectSeat', | |
value: function preLockSelectSeat(seatIds) { | |
this._selectedSeats = []; | |
var set$$1 = new Set(seatIds); | |
var seatIterator = this.generateSeatsIterator(0, 0, this._row, this._column); | |
var _iteratorNormalCompletion3 = true; | |
var _didIteratorError3 = false; | |
var _iteratorError3 = undefined; | |
try { | |
for (var _iterator3 = seatIterator[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { | |
var _ref3 = _step3.value; | |
var seat = _ref3.seat; | |
if (set$$1.has(seat.id)) { | |
seat.preLockSelect(); | |
} | |
if (seat.isSelect) { | |
this.emitSeatSelectEvent(seat); | |
} | |
} | |
} catch (err) { | |
_didIteratorError3 = true; | |
_iteratorError3 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion3 && _iterator3.return) { | |
_iterator3.return(); | |
} | |
} finally { | |
if (_didIteratorError3) { | |
throw _iteratorError3; | |
} | |
} | |
} | |
} | |
/** | |
* 保留指定数量选中座位 | |
* @param {Number} n 数量 | |
*/ | |
}, { | |
key: 'reserveNSelectSeats', | |
value: function reserveNSelectSeats(n) { | |
this._selectedSeats = this._selectedSeats.slice(0, n); | |
} | |
/** | |
* 处理座位点击事件 | |
*/ | |
}, { | |
key: 'handleClick', | |
value: function handleClick() { | |
throw Error('请在子类实现handleClick()方法'); | |
} | |
/** | |
* 对外层触发选座事件 | |
* @param {BBCSeat} seat 座位实例 | |
*/ | |
}, { | |
key: 'emitSeatSelectEvent', | |
value: function emitSeatSelectEvent(seat) { | |
var _this = this; | |
var seatInfo = seat.getInfo(); | |
var packageSeats = []; | |
if (seat.isSelect) { | |
// 座位被选中 | |
if (seatInfo.isPackage) { | |
var _selectedSeats; | |
var _iteratorNormalCompletion4 = true; | |
var _didIteratorError4 = false; | |
var _iteratorError4 = undefined; | |
try { | |
for (var _iterator4 = this._packages[seatInfo.packageCombinedId][Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { | |
var packageSeat = _step4.value; | |
packageSeat.select(); | |
packageSeats.push(packageSeat); | |
} | |
} catch (err) { | |
_didIteratorError4 = true; | |
_iteratorError4 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion4 && _iterator4.return) { | |
_iterator4.return(); | |
} | |
} finally { | |
if (_didIteratorError4) { | |
throw _iteratorError4; | |
} | |
} | |
} | |
(_selectedSeats = this._selectedSeats).push.apply(_selectedSeats, toConsumableArray(packageSeats)); | |
} else { | |
this._selectedSeats.push(seat); | |
} | |
// 选中非高亮票价座位, 要高亮所有座位 | |
var priceGroup = this._prices[seat._info.priceIndex]; | |
if (priceGroup && !priceGroup.highlight) { | |
this.highlightPrice(-1); | |
} | |
} else if (seatInfo.isPackage) { | |
// 座位被取消且是套票 | |
packageSeats = this._packages[seatInfo.packageCombinedId]; | |
var _loop = function _loop(s) { | |
s.cancelSelect(); | |
_this._selectedSeats = _this._selectedSeats.filter(function (x) { | |
return x.id !== s.id; | |
}); | |
}; | |
var _iteratorNormalCompletion5 = true; | |
var _didIteratorError5 = false; | |
var _iteratorError5 = undefined; | |
try { | |
for (var _iterator5 = packageSeats[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { | |
var s = _step5.value; | |
_loop(s); | |
} | |
} catch (err) { | |
_didIteratorError5 = true; | |
_iteratorError5 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion5 && _iterator5.return) { | |
_iterator5.return(); | |
} | |
} finally { | |
if (_didIteratorError5) { | |
throw _iteratorError5; | |
} | |
} | |
} | |
} else { | |
// 座位被取消且是普通票 | |
this._selectedSeats = this._selectedSeats.filter(function (x) { | |
return x.id !== seat.id; | |
}); | |
} | |
// 向外部触发事件 | |
if (this.onSelectSeat) { | |
this.onSelectSeat(this._selectedSeats, packageSeats.length ? packageSeats : seat, seat.isSelect ? Area.ClickSeatEvent.Select : Area.ClickSeatEvent.CancelSelect); | |
} | |
} | |
/** | |
* 生成指定范围内座位迭代器 | |
* @param {Number} startRow 开始行 | |
* @param {Number} startColumn 开始列 | |
* @param {Number} endRow 结束行 | |
* @param {Number} endColumn 结束列 | |
*/ | |
}, { | |
key: 'generateSeatsIterator', | |
value: function generateSeatsIterator(startRow, startColumn, endRow, endColumn) { | |
var iterator = {}; | |
var map = this._map; | |
iterator[Symbol.iterator] = /*#__PURE__*/ regeneratorRuntime.mark(function _callee() { | |
var rowKey, row, columnKey, column; | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
_context.t0 = regeneratorRuntime.keys(map); | |
case 1: | |
if ((_context.t1 = _context.t0()).done) { | |
_context.next = 17; | |
break; | |
} | |
rowKey = _context.t1.value; | |
row = parseInt(rowKey, 10); | |
if (!(row >= startRow && row <= endRow)) { | |
_context.next = 15; | |
break; | |
} | |
_context.t2 = regeneratorRuntime.keys(map[rowKey]); | |
case 6: | |
if ((_context.t3 = _context.t2()).done) { | |
_context.next = 15; | |
break; | |
} | |
columnKey = _context.t3.value; | |
column = parseInt(columnKey, 10); | |
if (!(column >= startColumn && column <= endColumn)) { | |
_context.next = 13; | |
break; | |
} | |
if (!(map[row] && map[row][column])) { | |
_context.next = 13; | |
break; | |
} | |
_context.next = 13; | |
return { | |
row: row, | |
column: column, | |
seat: map[row][column] | |
}; | |
case 13: | |
_context.next = 6; | |
break; | |
case 15: | |
_context.next = 1; | |
break; | |
case 17: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, this); | |
}); | |
return iterator; | |
} | |
/** | |
* 高亮指定票价座位 | |
* @param {Number} priceIndex 票价索引, 传-1表示高亮所有 | |
*/ | |
}, { | |
key: 'highlightPrice', | |
value: function highlightPrice() { | |
var priceIndex = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : -1; | |
this._priceIndex = priceIndex; | |
var seats = this._prices[priceIndex] ? this._prices[priceIndex].seats : []; | |
if (priceIndex !== -1 && !seats.some(function (x) { | |
return x.canBuy; | |
}) && this instanceof MatrixArea) { | |
this.onError({ | |
code: ErrorCode.Normal, | |
message: ErrorMessage.seat_sold_out, | |
messageKey: 'seat_sold_out' | |
}); | |
return; | |
} | |
var priceIndexList = Object.keys(this._prices); | |
var _iteratorNormalCompletion6 = true; | |
var _didIteratorError6 = false; | |
var _iteratorError6 = undefined; | |
try { | |
for (var _iterator6 = priceIndexList[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { | |
var p = _step6.value; | |
p = +p; // string 转 number | |
if (priceIndex === -1) { | |
// 如果要高亮的组是-1, 表示全部高亮 | |
if (!this._prices[p].highlight) { | |
this._prices[p].highlight = true; | |
var _iteratorNormalCompletion7 = true; | |
var _didIteratorError7 = false; | |
var _iteratorError7 = undefined; | |
try { | |
for (var _iterator7 = this._prices[p].seats[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { | |
var seat = _step7.value; | |
seat.cancelOpacity(); | |
} | |
} catch (err) { | |
_didIteratorError7 = true; | |
_iteratorError7 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion7 && _iterator7.return) { | |
_iterator7.return(); | |
} | |
} finally { | |
if (_didIteratorError7) { | |
throw _iteratorError7; | |
} | |
} | |
} | |
} | |
} else if (p !== priceIndex && this._prices[p].highlight) { | |
// 如果当前票价组不等于要高亮的组, 且当前组是高亮态, 置为不高亮 | |
this._prices[p].highlight = false; | |
var _iteratorNormalCompletion8 = true; | |
var _didIteratorError8 = false; | |
var _iteratorError8 = undefined; | |
try { | |
for (var _iterator8 = this._prices[p].seats[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) { | |
var _seat = _step8.value; | |
_seat.opacity(); | |
} | |
} catch (err) { | |
_didIteratorError8 = true; | |
_iteratorError8 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion8 && _iterator8.return) { | |
_iterator8.return(); | |
} | |
} finally { | |
if (_didIteratorError8) { | |
throw _iteratorError8; | |
} | |
} | |
} | |
} else if (p === priceIndex && !this._prices[p].highlight) { | |
// 如果当前票价组等于要高亮的组, 且当前组不是高亮态, 置为高亮 | |
this._prices[p].highlight = true; | |
var _iteratorNormalCompletion9 = true; | |
var _didIteratorError9 = false; | |
var _iteratorError9 = undefined; | |
try { | |
for (var _iterator9 = this._prices[p].seats[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) { | |
var _seat2 = _step9.value; | |
_seat2.cancelOpacity(); | |
} | |
} catch (err) { | |
_didIteratorError9 = true; | |
_iteratorError9 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion9 && _iterator9.return) { | |
_iterator9.return(); | |
} | |
} finally { | |
if (_didIteratorError9) { | |
throw _iteratorError9; | |
} | |
} | |
} | |
} | |
} | |
} catch (err) { | |
_didIteratorError6 = true; | |
_iteratorError6 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion6 && _iterator6.return) { | |
_iterator6.return(); | |
} | |
} finally { | |
if (_didIteratorError6) { | |
throw _iteratorError6; | |
} | |
} | |
} | |
} | |
}]); | |
return Area; | |
}(), _class$3.ClickSeatEvent = ClickSeatEvent, _temp$2); | |
var SeatImage = { | |
Seat_Sofa_CannotSelect: Util.generateSeatImage(Util.generateSeatImage.Type.CannotSelect), | |
Seat_Sofa_Lock: Util.generateSeatImage(Util.generateSeatImage.Type.Lock, '#C3C3C3'), | |
Seat_Sofa_Secure: Util.generateSeatImage(Util.generateSeatImage.Type.Secure), | |
Seat_Sofa_Buffer: Util.generateSeatImage(Util.generateSeatImage.Type.Buffer), | |
Seat_Circle_CannotSelect: Util.generateSeatImage(Util.generateSeatImage.Type.CannotSelectCircle), | |
Seat_Circle_Lock: Util.generateSeatImage(Util.generateSeatImage.Type.LockCircle), | |
Seat_Circle_Secure: Util.generateSeatImage(Util.generateSeatImage.Type.SecureCircle), | |
Seat_Circle_Buffer: Util.generateSeatImage(Util.generateSeatImage.Type.BufferCircle), | |
Thumbnail_CannotSelect: Util.generateSeatImage(Util.generateSeatImage.Type.Thumbnail, '#E9E9E9'), | |
Thumbnail_Selected: Util.generateSeatImage(Util.generateSeatImage.Type.Thumbnail, '#63C54C'), | |
Thumbnail_Lock: Util.generateSeatImage(Util.generateSeatImage.Type.Thumbnail, '#E9E9E9') | |
}; | |
// 预存勾中状态的座位图 (不预存的话, cancelSelectSeat方法会因为异步问题出错, 先发起的绘制"勾中状态"完成时间晚于绘制"非勾中状态", 结果座位显示成了勾中态, 因此cancelSelectSeat方法调用后看到的座位仍是选中态) | |
fetchImage(SeatImage.Thumbnail_Selected); | |
var _class$5; | |
var _temp$3; | |
var SeatStyle = { | |
Circle: Symbol('circle'), | |
Sofa: Symbol('sofa') | |
}; | |
var Seat = (_temp$3 = _class$5 = function () { | |
createClass(Seat, null, [{ | |
key: 'getStyleString', | |
/** | |
* 获取座位样式字符串 | |
*/ | |
// 使用的座位样式 | |
// 透明态座位透明度值 | |
value: function getStyleString(style) { | |
switch (style) { | |
case SeatStyle.Sofa: | |
return 'Sofa'; | |
case SeatStyle.Circle: | |
return 'Circle'; | |
default: | |
return 'Sofa'; | |
} | |
} | |
// 座位是否锁定 | |
// 清空矩形padding | |
// 座位样式定义 | |
// 座位是否选中 | |
// 座位是否已绘制 | |
// 座位是否半透明 | |
// 座位画板 | |
}]); | |
/** | |
* 座位 | |
* @param {Number} x 座位位置, 横座位 | |
* @param {Number} y 座位位置, 纵座位 | |
* @param {Object} info 座位信息, 从接口获取 | |
*/ | |
function Seat(x, y, info) { | |
classCallCheck(this, Seat); | |
this._prelock = false; | |
this._select = false; | |
this._draw = false; | |
this._opacity = false; | |
this._ctx = null; | |
this._x = x; | |
this._y = y; | |
this._info = info; | |
} | |
// 是否可售 | |
createClass(Seat, [{ | |
key: 'setContext', | |
/** | |
* 设置座位canvas context | |
* @param {Context} ctx context | |
*/ | |
value: function setContext(ctx) { | |
this._ctx = ctx; | |
} | |
/** | |
* 绘制座位 | |
*/ | |
}, { | |
key: 'draw', | |
value: function () { | |
var _ref = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee(seatStyle, seatSize) { | |
var opacityValue, image, ClearPadding; | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
if (this._ctx) { | |
_context.next = 2; | |
break; | |
} | |
throw Error('ctx为空, 请先调用setContext'); | |
case 2: | |
opacityValue = this._opacity && !this._select ? Seat.Opacity : 1; | |
_context.next = 5; | |
return this.getSeatImageWithCache(seatStyle); | |
case 5: | |
image = _context.sent; | |
// 沙发座位且带有旋转角度, 则擦除范围要大于座位 | |
ClearPadding = seatStyle === SeatStyle.Sofa && this._info.angle !== 0 ? 4 : 0; | |
this._ctx.clearRect(this._x - ClearPadding, this._y - ClearPadding, seatSize + ClearPadding * 2, seatSize + ClearPadding * 2); | |
this._ctx.save(); | |
this._ctx.globalAlpha = opacityValue; | |
this._ctx.drawImage(image, this._x, this._y, seatSize, seatSize, seatStyle === SeatStyle.Sofa ? this._info.angle : 0); | |
this._ctx.restore(); | |
this._draw = true; | |
case 13: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, this); | |
})); | |
function draw(_x, _x2) { | |
return _ref.apply(this, arguments); | |
} | |
return draw; | |
}() | |
/** | |
* 选中座位 | |
*/ | |
}, { | |
key: 'select', | |
value: function () { | |
var _ref2 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee2() { | |
return regeneratorRuntime.wrap(function _callee2$(_context2) { | |
while (1) { | |
switch (_context2.prev = _context2.next) { | |
case 0: | |
if (this.canBuy) { | |
_context2.next = 2; | |
break; | |
} | |
return _context2.abrupt('return', false); | |
case 2: | |
this._select = true; | |
// 如果座位还未绘制过, 不可调用draw()重绘 | |
if (!this.isDraw) { | |
_context2.next = 6; | |
break; | |
} | |
_context2.next = 6; | |
return this.draw(); | |
case 6: | |
return _context2.abrupt('return', true); | |
case 7: | |
case 'end': | |
return _context2.stop(); | |
} | |
} | |
}, _callee2, this); | |
})); | |
function select() { | |
return _ref2.apply(this, arguments); | |
} | |
return select; | |
}() | |
/** | |
* 取消选中 | |
*/ | |
}, { | |
key: 'cancelSelect', | |
value: function () { | |
var _ref3 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee3() { | |
return regeneratorRuntime.wrap(function _callee3$(_context3) { | |
while (1) { | |
switch (_context3.prev = _context3.next) { | |
case 0: | |
this._select = false; | |
// 如果座位还未绘制过, 不可调用draw()重绘 | |
if (!this.isDraw) { | |
_context3.next = 4; | |
break; | |
} | |
_context3.next = 4; | |
return this.draw(); | |
case 4: | |
case 'end': | |
return _context3.stop(); | |
} | |
} | |
}, _callee3, this); | |
})); | |
function cancelSelect() { | |
return _ref3.apply(this, arguments); | |
} | |
return cancelSelect; | |
}() | |
/** | |
* 更新座位状态 | |
* @param {Object} seatStatusData 座位状态数据 | |
*/ | |
}, { | |
key: 'updateSeatStatus', | |
value: function () { | |
var _ref4 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee4(seatStatusData) { | |
return regeneratorRuntime.wrap(function _callee4$(_context4) { | |
while (1) { | |
switch (_context4.prev = _context4.next) { | |
case 0: | |
if (this._prelock) { | |
_context4.next = 8; | |
break; | |
} | |
this._info.s = seatStatusData; | |
this._info.status = seatStatusData; | |
// this._prelock = false; | |
delete this.notSelectedSeatImage; | |
delete this.selectdSeatImage; | |
delete this.preLockSelectedSeatImage; | |
_context4.next = 8; | |
return this.cancelSelect(); | |
case 8: | |
case 'end': | |
return _context4.stop(); | |
} | |
} | |
}, _callee4, this); | |
})); | |
function updateSeatStatus(_x3) { | |
return _ref4.apply(this, arguments); | |
} | |
return updateSeatStatus; | |
}() | |
/** | |
* 锁定座位 | |
*/ | |
}, { | |
key: 'preLockSelect', | |
value: function () { | |
var _ref5 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee5() { | |
return regeneratorRuntime.wrap(function _callee5$(_context5) { | |
while (1) { | |
switch (_context5.prev = _context5.next) { | |
case 0: | |
this._info.status = 0; | |
this._prelock = true; | |
_context5.next = 4; | |
return this.cancelSelect(); | |
case 4: | |
case 'end': | |
return _context5.stop(); | |
} | |
} | |
}, _callee5, this); | |
})); | |
function preLockSelect() { | |
return _ref5.apply(this, arguments); | |
} | |
return preLockSelect; | |
}() | |
/** | |
* 半透明座位, 已选中座位不需要重绘 | |
*/ | |
}, { | |
key: 'opacity', | |
value: function () { | |
var _ref6 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee6() { | |
return regeneratorRuntime.wrap(function _callee6$(_context6) { | |
while (1) { | |
switch (_context6.prev = _context6.next) { | |
case 0: | |
this._opacity = true; | |
if (!(this.isSelect || !this.isDraw)) { | |
_context6.next = 3; | |
break; | |
} | |
return _context6.abrupt('return'); | |
case 3: | |
_context6.next = 5; | |
return this.draw(); | |
case 5: | |
case 'end': | |
return _context6.stop(); | |
} | |
} | |
}, _callee6, this); | |
})); | |
function opacity() { | |
return _ref6.apply(this, arguments); | |
} | |
return opacity; | |
}() | |
/** | |
* 取消半透明, 已选中座位不需要重绘 | |
*/ | |
}, { | |
key: 'cancelOpacity', | |
value: function () { | |
var _ref7 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee7() { | |
return regeneratorRuntime.wrap(function _callee7$(_context7) { | |
while (1) { | |
switch (_context7.prev = _context7.next) { | |
case 0: | |
this._opacity = false; | |
if (!(this.isSelect || !this.isDraw)) { | |
_context7.next = 3; | |
break; | |
} | |
return _context7.abrupt('return'); | |
case 3: | |
_context7.next = 5; | |
return this.draw(); | |
case 5: | |
case 'end': | |
return _context7.stop(); | |
} | |
} | |
}, _callee7, this); | |
})); | |
function cancelOpacity() { | |
return _ref7.apply(this, arguments); | |
} | |
return cancelOpacity; | |
}() | |
/** | |
* 获取座位信息 | |
*/ | |
}, { | |
key: 'getInfo', | |
value: function getInfo() { | |
return this._info; | |
} | |
/** | |
* 根据座位状态获取座位图 | |
* @param {Symbol} useStyle 座位的样式 | |
*/ | |
}, { | |
key: 'getSeatImage', | |
value: function getSeatImage() { | |
var useStyle = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : SeatStyle.Sofa; | |
var src = ''; | |
var style = Seat.getStyleString(useStyle); | |
var status = this.getStatusString(); | |
var styleKey = style === 'Sofa' ? '' : style; | |
if (status === 'Normal' || status === 'Package' || status === 'CannotSelectPackage') { | |
src = Util.generateSeatImage(Util.generateSeatImage.Type['' + status + styleKey], this._info.color); | |
} else if (status === 'Selected') { | |
src = Util.generateSeatImage(Util.generateSeatImage.Type['Selected' + styleKey], this._info.color, this._info.angle); | |
} else { | |
src = SeatImage['Seat_' + style + '_' + status]; | |
} | |
return fetchImage(src); | |
} | |
/** | |
* 带缓存功能的获取座位图方法 | |
* 虽然座位有很多类型和状态, 但同一座位只会有选中态/非选中态变化, 可以把两种状态对应的图缓存下, 不再重复生成 | |
* @param {Symbol} useStyle 座位的样式 | |
*/ | |
}, { | |
key: 'getSeatImageWithCache', | |
value: function getSeatImageWithCache() { | |
var useStyle = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : SeatStyle.Sofa; | |
// 锁定状态 | |
if (this.isPreLock) { | |
if (!this.preLockSelectedSeatImage) { | |
this.preLockSelectedSeatImage = this.getSeatImage(useStyle); | |
} | |
return this.preLockSelectedSeatImage; | |
} | |
// 选中状态 | |
if (this.isSelect) { | |
if (!this.selectdSeatImage) { | |
this.selectdSeatImage = this.getSeatImage(useStyle); | |
} | |
return this.selectdSeatImage; | |
} | |
// 未选中状态 | |
if (!this.notSelectedSeatImage) { | |
this.notSelectedSeatImage = this.getSeatImage(useStyle); | |
} | |
return this.notSelectedSeatImage; | |
} | |
/** | |
* 获取座位状态字符串 | |
*/ | |
}, { | |
key: 'getStatusString', | |
value: function getStatusString() { | |
switch (this._info.status) { | |
case 0: { | |
if (this._info.isPackage) { | |
return 'CannotSelectPackage'; | |
} | |
return 'CannotSelect'; | |
} | |
case 2: { | |
if (this.isSelect) { | |
return 'Selected'; | |
} else if (this._info.isPackage) { | |
return 'Package'; | |
} else if (this._info.isSecure) { | |
return 'Secure'; | |
} else if (this._info.isBuffer) { | |
return 'Buffer'; | |
} | |
return 'Normal'; | |
} | |
case 4: | |
return 'Lock'; | |
// 特殊状态, @余浩 使用 | |
case 99: | |
return 'Selected'; | |
default: | |
return 'Normal'; | |
} | |
} | |
}, { | |
key: 'canBuy', | |
get: function get$$1() { | |
return this._info.status === 2; | |
} | |
// 是否锁定 | |
}, { | |
key: 'isPreLock', | |
get: function get$$1() { | |
return this._prelock; | |
} | |
// 是否已选中 | |
}, { | |
key: 'isSelect', | |
get: function get$$1() { | |
return this._select; | |
} | |
// 是否已绘制 | |
}, { | |
key: 'isDraw', | |
get: function get$$1() { | |
return this._draw; | |
}, | |
set: function set$$1(value) { | |
this._draw = value; | |
} | |
// 座位id | |
}, { | |
key: 'id', | |
get: function get$$1() { | |
return this._info.id; | |
} | |
}]); | |
return Seat; | |
}(), _class$5.Opacity = 0.2, _class$5.Style = SeatStyle, _class$5._useStyle = SeatStyle.Sofa, _class$5.ClearPadding = 4, _temp$3); | |
var _class$7; | |
var _temp$5; | |
var Thumbnail = (_temp$5 = _class$7 = function () { | |
/** | |
* 鹰眼图 | |
* @param {Viewport} viewport Viewport实例 | |
* @param {Dom} $container 鹰眼图容器div | |
*/ | |
// 鹰眼图缩放倍率 | |
function Thumbnail(viewport, $container) { | |
classCallCheck(this, Thumbnail); | |
this.ScaleRatio = 1; | |
this._$line = null; | |
this._viewport = viewport; | |
this._$container = $container; | |
this._$container.id = 'thumbnail'; | |
} | |
/** | |
* 获取鹰眼图可见状态 | |
*/ | |
// 红框div | |
// 鹰眼图最大高度 | |
createClass(Thumbnail, [{ | |
key: 'draw', | |
/** | |
* 绘制鹰眼图 | |
*/ | |
value: function draw() { | |
throw Error('请在子类实现draw()方法'); | |
} | |
/** | |
* 绘制红框 | |
*/ | |
}, { | |
key: 'drawLineBox', | |
value: function drawLineBox(scale) { | |
var LineBoxTopOffset = this._lineBoxTopOffset || 0; | |
var LineBoxLeftOffset = this._lineBoxLeftOffset || 0; | |
var viewportPosition = this._viewport.getLeftTopPoint(); | |
var viewportSize = this._viewport.getSize(); | |
this._$line = document.createElement('div'); | |
addStyle(this._$line, { | |
position: 'absolute', | |
left: viewportPosition.x * scale + LineBoxLeftOffset, | |
top: viewportPosition.y * scale + LineBoxTopOffset, | |
width: viewportSize.width * scale, | |
height: viewportSize.height * scale, | |
boxSizing: 'border-box', | |
border: '1px solid #FF2D79' | |
}); | |
this._$container.appendChild(this._$line); | |
} | |
/** | |
* 更新红框位置 | |
*/ | |
}, { | |
key: 'update', | |
value: function update(scale) { | |
if (!this._$line) { | |
return; | |
} | |
var LineBoxTopOffset = this._lineBoxTopOffset || 0; | |
var LineBoxLeftOffset = this._lineBoxLeftOffset || 0; | |
var viewportPosition = this._viewport.getLeftTopPoint(); | |
var viewportSize = this._viewport.getSize(); | |
addStyle(this._$line, { | |
left: viewportPosition.x * scale + LineBoxLeftOffset, | |
top: viewportPosition.y * scale + LineBoxTopOffset, | |
width: viewportSize.width * scale, | |
height: viewportSize.height * scale | |
}); | |
} | |
/** | |
* 隐藏鹰眼图 | |
*/ | |
}, { | |
key: 'show', | |
value: function show() { | |
this._$container.style.display = 'block'; | |
if (this._standRender.onThumbnailVisible) { | |
this._standRender.onThumbnailVisible(); | |
} | |
} | |
/** | |
* 显示鹰眼图 | |
*/ | |
}, { | |
key: 'hide', | |
value: function hide() { | |
this._$container.style.display = 'none'; | |
if (this._standRender.onThumbnailHidden) { | |
this._standRender.onThumbnailHidden(); | |
} | |
} | |
}, { | |
key: 'visible', | |
get: function get$$1() { | |
return this._$container.style.display === 'block'; | |
} | |
}]); | |
return Thumbnail; | |
}(), _class$7.ThumbnailCanvasMaxHeight = 200, _temp$5); | |
var _class$6; | |
var _temp$4; | |
var MatrixThumbnail = (_temp$4 = _class$6 = function (_Thumbnail) { | |
inherits(MatrixThumbnail, _Thumbnail); | |
/** | |
* Matrix鹰眼图 | |
* @param {Area} area Area实例 | |
* @param {Viewport} viewport Viewport实例 | |
* @param {Dom} $container 鹰眼图容器div | |
* @param {StandRender} StandRender实例 | |
*/ | |
function MatrixThumbnail(area, viewport, $container, standRender) { | |
var lineBoxTopOffset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0; | |
var lineBoxLeftOffset = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; | |
classCallCheck(this, MatrixThumbnail); | |
var _this = possibleConstructorReturn(this, (MatrixThumbnail.__proto__ || Object.getPrototypeOf(MatrixThumbnail)).call(this, viewport, $container)); | |
_this._area = area; | |
_this._standRender = standRender; | |
_this._lineBoxTopOffset = lineBoxTopOffset; | |
_this._lineBoxLeftOffset = lineBoxLeftOffset; | |
return _this; | |
} | |
/** | |
* 绘制鹰眼图 | |
* @param {Context} ctx canvas context | |
*/ | |
// 鹰眼图缩放倍率 | |
createClass(MatrixThumbnail, [{ | |
key: 'draw', | |
value: function draw(ctx) { | |
this._area.drawThumbnail(ctx); | |
this.drawLineBox(MatrixThumbnail.ScaleRatio); | |
} | |
}, { | |
key: 'update', | |
value: function update() { | |
get(MatrixThumbnail.prototype.__proto__ || Object.getPrototypeOf(MatrixThumbnail.prototype), 'update', this).call(this, MatrixThumbnail.ScaleRatio); | |
} | |
}]); | |
return MatrixThumbnail; | |
}(Thumbnail), _class$6.ScaleRatio = 1, _temp$4); | |
var _class$4; | |
var _temp2$1; | |
var MatrixSeat = (_temp2$1 = _class$4 = function (_Seat) { | |
inherits(MatrixSeat, _Seat); | |
function MatrixSeat() { | |
var _ref; | |
var _temp, _this, _ret; | |
classCallCheck(this, MatrixSeat); | |
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | |
args[_key] = arguments[_key]; | |
} | |
return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref = MatrixSeat.__proto__ || Object.getPrototypeOf(MatrixSeat)).call.apply(_ref, [this].concat(args))), _this), _this._thumbnailCtx = null, _temp), possibleConstructorReturn(_this, _ret); | |
} | |
// 使用的座位样式, matrix项目固定为沙发 | |
// 座位大小 | |
// 座位缩略图画板 | |
createClass(MatrixSeat, [{ | |
key: 'setThumbnailContext', | |
/** | |
* 设置座位缩略图canvas context | |
* @param {Context} thumbnailCtx context | |
*/ | |
value: function setThumbnailContext(thumbnailCtx) { | |
this._thumbnailCtx = thumbnailCtx; | |
} | |
/** | |
* 绘制座位 | |
*/ | |
}, { | |
key: 'draw', | |
value: function () { | |
var _ref2 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee() { | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
_context.next = 2; | |
return get(MatrixSeat.prototype.__proto__ || Object.getPrototypeOf(MatrixSeat.prototype), 'draw', this).call(this, MatrixSeat._useStyle, MatrixSeat.SeatSize); | |
case 2: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, this); | |
})); | |
function draw() { | |
return _ref2.apply(this, arguments); | |
} | |
return draw; | |
}() | |
/** | |
* 绘制座位在缩略图中的节点 | |
*/ | |
}, { | |
key: 'drawThumbnail', | |
value: function () { | |
var _ref3 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee2() { | |
var image, scale; | |
return regeneratorRuntime.wrap(function _callee2$(_context2) { | |
while (1) { | |
switch (_context2.prev = _context2.next) { | |
case 0: | |
if (this._thumbnailCtx) { | |
_context2.next = 2; | |
break; | |
} | |
throw Error('thumbnailCtx为空, 请先调用setThumbnailContext'); | |
case 2: | |
_context2.next = 4; | |
return this.getSeatThumbnailImage(); | |
case 4: | |
image = _context2.sent; | |
scale = MatrixThumbnail.ScaleRatio; | |
this._thumbnailCtx.drawImage(image, this._x * scale, this._y * scale, MatrixSeat.SeatSize * scale, MatrixSeat.SeatSize * scale); | |
case 7: | |
case 'end': | |
return _context2.stop(); | |
} | |
} | |
}, _callee2, this); | |
})); | |
function drawThumbnail() { | |
return _ref3.apply(this, arguments); | |
} | |
return drawThumbnail; | |
}() | |
/** | |
* 选中座位 | |
*/ | |
}, { | |
key: 'select', | |
value: function () { | |
var _ref4 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee3() { | |
return regeneratorRuntime.wrap(function _callee3$(_context3) { | |
while (1) { | |
switch (_context3.prev = _context3.next) { | |
case 0: | |
_context3.next = 2; | |
return get(MatrixSeat.prototype.__proto__ || Object.getPrototypeOf(MatrixSeat.prototype), 'select', this).call(this); | |
case 2: | |
if (_context3.sent) { | |
_context3.next = 4; | |
break; | |
} | |
return _context3.abrupt('return', false); | |
case 4: | |
if (this._thumbnailCtx) { | |
this.drawThumbnail(); | |
} | |
return _context3.abrupt('return', true); | |
case 6: | |
case 'end': | |
return _context3.stop(); | |
} | |
} | |
}, _callee3, this); | |
})); | |
function select() { | |
return _ref4.apply(this, arguments); | |
} | |
return select; | |
}() | |
/** | |
* 取消选中 | |
*/ | |
}, { | |
key: 'cancelSelect', | |
value: function () { | |
var _ref5 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee4() { | |
return regeneratorRuntime.wrap(function _callee4$(_context4) { | |
while (1) { | |
switch (_context4.prev = _context4.next) { | |
case 0: | |
_context4.next = 2; | |
return get(MatrixSeat.prototype.__proto__ || Object.getPrototypeOf(MatrixSeat.prototype), 'cancelSelect', this).call(this); | |
case 2: | |
this.drawThumbnail(); | |
case 3: | |
case 'end': | |
return _context4.stop(); | |
} | |
} | |
}, _callee4, this); | |
})); | |
function cancelSelect() { | |
return _ref5.apply(this, arguments); | |
} | |
return cancelSelect; | |
}() | |
/** | |
* 根据座位状态获取座位缩略图 | |
*/ | |
}, { | |
key: 'getSeatThumbnailImage', | |
value: function getSeatThumbnailImage() { | |
var src = ''; | |
var status = this.getStatusString(); | |
if (status === 'Normal' || status === 'Package') { | |
src = Util.generateSeatImage(Util.generateSeatImage.Type.Thumbnail, this._info.color); | |
} else { | |
src = SeatImage['Thumbnail_' + status]; | |
} | |
return fetchImage(src); | |
} | |
}]); | |
return MatrixSeat; | |
}(Seat), _class$4._useStyle = Seat.Style.Sofa, _class$4.SeatSize = 32, _temp2$1); | |
var _class$2; | |
var _temp$1; | |
var MatrixArea = (_temp$1 = _class$2 = function (_Area) { | |
inherits(MatrixArea, _Area); | |
function MatrixArea() { | |
classCallCheck(this, MatrixArea); | |
return possibleConstructorReturn(this, (MatrixArea.__proto__ || Object.getPrototypeOf(MatrixArea)).apply(this, arguments)); | |
} | |
createClass(MatrixArea, [{ | |
key: 'addSeat', | |
/** | |
* 添加座位 | |
* @param {Number} row 座位所在行数 | |
* @param {Number} column 座位所在列数 | |
* @param {Object} seatInfo 座位信息 | |
*/ | |
value: function addSeat(row, column, seatInfo) { | |
if (row < 0 || row >= this._row || column < 0 || column >= this._column) { | |
throw Error('超出场馆区域'); | |
} | |
var seat = new MatrixSeat(column * (MatrixSeat.SeatSize + MatrixArea.SeatMargin * 2) + MatrixArea.SeatMargin, row * (MatrixSeat.SeatSize + MatrixArea.SeatMargin * 2) + MatrixArea.SeatMargin, seatInfo); | |
this._map[row] = this._map[row] || {}; | |
this._map[row][column] = seat; | |
// 可售态 | |
if (seat.canBuy) { | |
// 如果该座位可售, 且票价索引不是高亮的, 则将座位置为半透明 | |
if (this._priceIndex !== -1 && this._priceIndex !== seatInfo.priceIndex) { | |
seat.opacity(); | |
} | |
this._prices[seatInfo.priceIndex] = this._prices[seatInfo.priceIndex] || { | |
seats: [], // 当前票价座位 | |
highlight: true // 当前票价座位是否显示为高亮(即非透明状) | |
}; | |
this._prices[seatInfo.priceIndex].seats.push(seat); | |
// 是套票 | |
if (seatInfo.isPackage) { | |
this._packages[seatInfo.packageCombinedId] = this._packages[seatInfo.packageCombinedId] || []; | |
this._packages[seatInfo.packageCombinedId].push(seat); | |
} | |
} | |
} | |
/** | |
* 绘制区域内可见座位 | |
* @param {Context} ctx canvas context | |
* @param {Number} startRow 显示区域起始行 | |
* @param {Number} startColumn 显示区域起始列 | |
* @param {Number} endRow 显示区域结束行 | |
* @param {Number} endColumn 显示区域结束列 | |
*/ | |
// 座位间距 | |
}, { | |
key: 'draw', | |
value: function () { | |
var _ref = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee(ctx, startRow, startColumn, endRow, endColumn) { | |
var seatIterator, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _ref2, seat; | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
seatIterator = this.generateSeatsIterator(startRow, startColumn, endRow, endColumn); | |
_iteratorNormalCompletion = true; | |
_didIteratorError = false; | |
_iteratorError = undefined; | |
_context.prev = 4; | |
_iterator = seatIterator[Symbol.iterator](); | |
case 6: | |
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { | |
_context.next = 16; | |
break; | |
} | |
_ref2 = _step.value; | |
seat = _ref2.seat; | |
if (!seat.isDraw) { | |
_context.next = 11; | |
break; | |
} | |
return _context.abrupt('continue', 13); | |
case 11: | |
seat.setContext(ctx); | |
seat.draw(); | |
case 13: | |
_iteratorNormalCompletion = true; | |
_context.next = 6; | |
break; | |
case 16: | |
_context.next = 22; | |
break; | |
case 18: | |
_context.prev = 18; | |
_context.t0 = _context['catch'](4); | |
_didIteratorError = true; | |
_iteratorError = _context.t0; | |
case 22: | |
_context.prev = 22; | |
_context.prev = 23; | |
if (!_iteratorNormalCompletion && _iterator.return) { | |
_iterator.return(); | |
} | |
case 25: | |
_context.prev = 25; | |
if (!_didIteratorError) { | |
_context.next = 28; | |
break; | |
} | |
throw _iteratorError; | |
case 28: | |
return _context.finish(25); | |
case 29: | |
return _context.finish(22); | |
case 30: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, this, [ | |
[4, 18, 22, 30], | |
[23, , 25, 29] | |
]); | |
})); | |
function draw(_x, _x2, _x3, _x4, _x5) { | |
return _ref.apply(this, arguments); | |
} | |
return draw; | |
}() | |
/** | |
* 绘制区域内所有座位 | |
* @param {Context} ctx canvas context | |
*/ | |
}, { | |
key: 'drawThumbnail', | |
value: function drawThumbnail(ctx) { | |
var seatIterator = this.generateSeatsIterator(0, 0, this._row, this._column); | |
var _iteratorNormalCompletion2 = true; | |
var _didIteratorError2 = false; | |
var _iteratorError2 = undefined; | |
try { | |
for (var _iterator2 = seatIterator[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | |
var _ref3 = _step2.value; | |
var seat = _ref3.seat; | |
seat.setThumbnailContext(ctx); | |
seat.drawThumbnail(); | |
} | |
} catch (err) { | |
_didIteratorError2 = true; | |
_iteratorError2 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion2 && _iterator2.return) { | |
_iterator2.return(); | |
} | |
} finally { | |
if (_didIteratorError2) { | |
throw _iteratorError2; | |
} | |
} | |
} | |
} | |
/** | |
* 获取区域尺寸(px) | |
*/ | |
}, { | |
key: 'getSize', | |
value: function getSize() { | |
var seatSize = this.getSeatSize(); | |
return { | |
width: seatSize.width * this._column, | |
height: seatSize.height * this._row | |
}; | |
} | |
/** | |
* 获取座位大小(包含margin) | |
*/ | |
}, { | |
key: 'getSeatSize', | |
value: function getSeatSize() { | |
return { | |
width: MatrixSeat.SeatSize + MatrixArea.SeatMargin * 2, | |
height: MatrixSeat.SeatSize + MatrixArea.SeatMargin * 2 | |
}; | |
} | |
/** | |
* 获取区域总行列数 | |
*/ | |
}, { | |
key: 'getRowColumn', | |
value: function getRowColumn() { | |
return { | |
row: this._row, | |
column: this._column | |
}; | |
} | |
/** | |
* 选中座位 | |
* @param {Number} seatId 座位id | |
*/ | |
}, { | |
key: 'selectSeat', | |
value: function selectSeat(seatId) { | |
var seatIterator = this.generateSeatsIterator(0, 0, this._row, this._column); | |
var _iteratorNormalCompletion3 = true; | |
var _didIteratorError3 = false; | |
var _iteratorError3 = undefined; | |
try { | |
for (var _iterator3 = seatIterator[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { | |
var _ref4 = _step3.value; | |
var seat = _ref4.seat; | |
if (seat.id === seatId && seat.canBuy) { | |
var selectSuccess = seat.select(); | |
if (selectSuccess) { | |
this.emitSeatSelectEvent(seat); | |
} | |
return selectSuccess; | |
} | |
} | |
} catch (err) { | |
_didIteratorError3 = true; | |
_iteratorError3 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion3 && _iterator3.return) { | |
_iterator3.return(); | |
} | |
} finally { | |
if (_didIteratorError3) { | |
throw _iteratorError3; | |
} | |
} | |
} | |
} | |
/** | |
* 获取指定行第一个座位, 无座返回null | |
* @param {Number} row 行数 | |
*/ | |
}, { | |
key: 'getFirstSeatByRow', | |
value: function getFirstSeatByRow(row) { | |
if (!this._map[row]) { | |
return null; | |
} | |
var _Object$keys = Object.keys(this._map[row]), | |
_Object$keys2 = slicedToArray(_Object$keys, 1), | |
column = _Object$keys2[0]; | |
return this._map[row][column]; | |
} | |
/** | |
* 该行是不是没有座位 | |
* @param {Number} row 行号 | |
*/ | |
}, { | |
key: 'isNoSeats', | |
value: function isNoSeats(row) { | |
return this.getFirstSeatByRow(row) === null; | |
} | |
/** | |
* 处理座位点击事件 | |
* @param {Context} ctx 绘图context | |
* @param {Object} point 点击位置 | |
*/ | |
}, { | |
key: 'handleClick', | |
value: function () { | |
var _ref5 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee2(ctx, point) { | |
var seatSize, row, column, seat; | |
return regeneratorRuntime.wrap(function _callee2$(_context2) { | |
while (1) { | |
switch (_context2.prev = _context2.next) { | |
case 0: | |
seatSize = this.getSeatSize(); | |
row = Math.floor(point.y / seatSize.height); | |
column = Math.floor(point.x / seatSize.width); | |
seat = this._map[row] && this._map[row][column]; | |
if (!(seat && seat.canBuy)) { | |
_context2.next = 13; | |
break; | |
} | |
if (!seat.isSelect) { | |
_context2.next = 10; | |
break; | |
} | |
_context2.next = 8; | |
return seat.cancelSelect(); | |
case 8: | |
_context2.next = 12; | |
break; | |
case 10: | |
_context2.next = 12; | |
return seat.select(); | |
case 12: | |
this.emitSeatSelectEvent(seat); | |
case 13: | |
case 'end': | |
return _context2.stop(); | |
} | |
} | |
}, _callee2, this); | |
})); | |
function handleClick(_x6, _x7) { | |
return _ref5.apply(this, arguments); | |
} | |
return handleClick; | |
}() | |
}]); | |
return MatrixArea; | |
}(Area), _class$2.SeatMargin = 4, _temp$1); | |
var Viewport = function () { | |
/** | |
* 视口 | |
* @param {Number} width 视口宽度 | |
* @param {Number} height 视口高度 | |
* @param {Number} maxWidth 区域宽度 | |
* @param {Number} maxHeight 区域高度 | |
* @param {Number} options.minScaleRatio 最小缩放倍率 | |
* @param {Number} options.maxScaleRatio 最大缩放倍率 | |
* @param {Number} options.x 视口初始位置横坐标 | |
* @param {Number} options.y 视口初始位置纵坐标 | |
* @param {Boolean} options.renderPadding 渲染额外边距 | |
* @param {Number} options.ratio 初始缩放倍率 | |
*/ | |
function Viewport(width, height, maxWidth, maxHeight) { | |
var _ref = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}, | |
_ref$minScaleRatio = _ref.minScaleRatio, | |
minScaleRatio = _ref$minScaleRatio === undefined ? 1 : _ref$minScaleRatio, | |
_ref$maxScaleRatio = _ref.maxScaleRatio, | |
maxScaleRatio = _ref$maxScaleRatio === undefined ? 3 : _ref$maxScaleRatio, | |
_ref$x = _ref.x, | |
x = _ref$x === undefined ? (maxWidth - width) / 2 : _ref$x, | |
_ref$y = _ref.y, | |
y = _ref$y === undefined ? (maxHeight - height) / 2 : _ref$y, | |
_ref$renderPadding = _ref.renderPadding, | |
renderPadding = _ref$renderPadding === undefined ? true : _ref$renderPadding, | |
_ref$ratio = _ref.ratio, | |
ratio = _ref$ratio === undefined ? 2 : _ref$ratio; | |
classCallCheck(this, Viewport); | |
this._width = width; | |
this._height = height; | |
this._maxWidth = maxWidth; | |
this._maxHeight = maxHeight; | |
this._minScaleRatio = minScaleRatio; | |
this._maxScaleRatio = maxScaleRatio; | |
this._x = x; | |
this._y = y; | |
this._renderPadding = renderPadding; | |
this._ratio = ratio; | |
if (this._ratio > this._maxScaleRatio) { | |
this._ratio = this._maxScaleRatio; | |
} else if (this._ratio < this._minScaleRatio) { | |
this._ratio = this._minScaleRatio; | |
} | |
} | |
/** | |
* 获取视口左上角坐标 | |
*/ | |
createClass(Viewport, [{ | |
key: "getLeftTopPoint", | |
value: function getLeftTopPoint() { | |
return { | |
x: this._x - this._width * (this._ratio - 1) / 2, | |
y: this._y - this._height * (this._ratio - 1) / 2 | |
}; | |
} | |
/** | |
* 获取视口右下角坐标 | |
*/ | |
}, { | |
key: "getRightBottomPoint", | |
value: function getRightBottomPoint() { | |
return { | |
x: this._x + this._width * (this._ratio + 1) / 2, | |
y: this._y + this._height * (this._ratio + 1) / 2 | |
}; | |
} | |
/** | |
* 获取当前视口位置下, 物体相对位置 | |
*/ | |
}, { | |
key: "getPoint", | |
value: function getPoint() { | |
return { | |
x: this._x / this._ratio, | |
y: this._y / this._ratio | |
}; | |
} | |
/** | |
* 获取视口处于中心位置时, 物体相对位置 | |
*/ | |
}, { | |
key: "getCenterPoint", | |
value: function getCenterPoint() { | |
return { | |
x: (this._maxWidth - this._width) / 2 / this._ratio, | |
y: (this._maxHeight - this._height) / 2 / this._ratio | |
}; | |
} | |
/** | |
* 获取物体相对缩放倍率 | |
*/ | |
}, { | |
key: "getScale", | |
value: function getScale() { | |
return 1 / this._ratio; | |
} | |
/** | |
* 获取当前视口大小 | |
*/ | |
}, { | |
key: "getSize", | |
value: function getSize() { | |
return { | |
width: this._width * this._ratio, | |
height: this._height * this._ratio | |
}; | |
} | |
/** | |
* 获取行号纵向偏移值 | |
*/ | |
}, { | |
key: "getLineNumberOffset", | |
value: function getLineNumberOffset() { | |
return -this.getLeftTopPoint().y / this._ratio; | |
} | |
/** | |
* 视口位移 | |
* @param {Number} x 横向变化距离 | |
* @param {Number} y 纵向变化距离 | |
*/ | |
}, { | |
key: "move", | |
value: function move() { | |
var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; | |
var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; | |
this._x += x * this._ratio; | |
this._y += y * this._ratio; | |
var leftTop = this.getLeftTopPoint(); | |
var rightBottom = this.getRightBottomPoint(); | |
// renderPadding为true(需要绘制额外边距) | |
// this._width * this._ratio > this._maxWidth 视口比区域最大值还大, 这种情况下拖动会抖动 | |
var leftRightExtraPx = this._renderPadding || this._width * this._ratio > this._maxWidth ? Math.max((this._width * this._ratio - this._maxWidth) / 2, 160) : 0; | |
var topBottomExtraPx = this._renderPadding || this._height * this._ratio > this._maxHeight ? Math.max((this._height * this._ratio - this._maxHeight) / 2, 200) : 0; | |
if (leftTop.x < -leftRightExtraPx) { | |
this._x = -leftRightExtraPx + this._width * (this._ratio - 1) / 2; | |
} | |
if (rightBottom.x > this._maxWidth + leftRightExtraPx) { | |
this._x = this._maxWidth + leftRightExtraPx - this._width * (this._ratio + 1) / 2; | |
} | |
if (leftTop.y < -topBottomExtraPx) { | |
this._y = -topBottomExtraPx + this._height * (this._ratio - 1) / 2; | |
} | |
if (rightBottom.y > this._maxHeight + topBottomExtraPx) { | |
this._y = this._maxHeight + topBottomExtraPx - this._height * (this._ratio + 1) / 2; | |
} | |
} | |
/** | |
* 视口缩放 | |
* @param {Number} ratio 缩放倍率变化值 | |
*/ | |
}, { | |
key: "scale", | |
value: function scale(ratio) { | |
this._ratio += ratio; | |
if (this._ratio > this._maxScaleRatio) { | |
this._ratio = this._maxScaleRatio; | |
} | |
if (this._ratio < this._minScaleRatio) { | |
this._ratio = this._minScaleRatio; | |
} | |
this.move(0, 0); | |
} | |
/** | |
* 视口缩放, 乘法变化 | |
* @param {number} ratio 缩放倍率变化倍数 | |
*/ | |
}, { | |
key: "scaleMultip", | |
value: function scaleMultip(ratio) { | |
this._ratio *= ratio; | |
this.scale(0); | |
} | |
/** | |
* 更新视口位置 | |
* @param {Number} x 横坐标 | |
* @param {Number} y 纵坐标 | |
*/ | |
}, { | |
key: "updatePosition", | |
value: function updatePosition(x, y) { | |
this._x = x; | |
this._y = y; | |
} | |
/** | |
* 更新缩放倍率 | |
* @param {Number} ratio 缩放倍率 | |
*/ | |
}, { | |
key: "updateRatio", | |
value: function updateRatio(ratio) { | |
this._ratio = ratio; | |
if (this._ratio > this._maxScaleRatio) { | |
this._ratio = this._maxScaleRatio; | |
} else if (this._ratio < this._minScaleRatio) { | |
this._ratio = this._minScaleRatio; | |
} | |
} | |
}]); | |
return Viewport; | |
}(); | |
/** | |
* 双端链表 | |
*/ | |
var DoubleLinkList = function () { | |
function DoubleLinkList() { | |
classCallCheck(this, DoubleLinkList); | |
this.head = null; | |
this.tail = null; | |
this.length = 0; | |
} | |
createClass(DoubleLinkList, [{ | |
key: "unshift", | |
value: function unshift(node) { | |
if (this.head && this.tail) { | |
node.prev = null; | |
node.next = this.head; | |
this.head.prev = node; | |
this.head = node; | |
} else { | |
node.prev = node.next = null; | |
this.head = this.tail = node; | |
} | |
this.length++; | |
return node; | |
} | |
}, { | |
key: "pop", | |
value: function pop() { | |
if (this.tail) { | |
var node = this.tail; | |
if (this.head === this.tail) { | |
this.head = this.tail = null; | |
} else { | |
this.tail.prev.next = null; | |
this.tail = this.tail.prev; | |
} | |
this.length--; | |
return node; | |
} | |
} | |
}, { | |
key: "remove", | |
value: function remove(node) { | |
if (node !== this.head && node !== this.tail) { | |
node.prev.next = node.next; | |
node.next.prev = node.prev; | |
} | |
if (node === this.head) { | |
this.head = this.head.next; | |
} | |
if (node === this.tail) { | |
this.tail = this.tail.prev; | |
} | |
this.length--; | |
} | |
}]); | |
return DoubleLinkList; | |
}(); | |
/** | |
* LRU缓存 | |
*/ | |
var LRUCache = function () { | |
/** | |
* 构造函数 | |
* @param {number} capacity 最大数量 | |
* @param {Function} dispose 释放资源回调 | |
*/ | |
function LRUCache(capacity, dispose) { | |
classCallCheck(this, LRUCache); | |
this.capacity = capacity; | |
this.list = new DoubleLinkList(); | |
this.map = new Map(); | |
this.dispose = dispose; | |
} | |
createClass(LRUCache, [{ | |
key: "get", | |
value: function get$$1(key) { | |
var node = this.map.get(key); | |
if (node) { | |
this.list.remove(node); | |
this.list.unshift(node); | |
return node.value; | |
} | |
return null; | |
} | |
}, { | |
key: "put", | |
value: function put(key, value) { | |
var node = this.map.get(key); | |
if (node) { | |
node.value = value; | |
this.list.remove(node); | |
this.list.unshift(node); | |
} else { | |
node = { | |
key: key, | |
value: value | |
}; | |
this.list.unshift(node); | |
this.map.set(key, node); | |
if (this.list.length > this.capacity) { | |
var tail = this.list.pop(); | |
this.map.delete(tail.key); | |
this.dispose(tail.value); | |
} | |
} | |
} | |
}, { | |
key: "getAll", | |
value: function getAll() { | |
return [].concat(toConsumableArray(this.map.values())).map(function (x) { | |
return x.value; | |
}); | |
} | |
}, { | |
key: "disposeAll", | |
value: function disposeAll() { | |
var _iteratorNormalCompletion = true; | |
var _didIteratorError = false; | |
var _iteratorError = undefined; | |
try { | |
for (var _iterator = this.getAll()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | |
var item = _step.value; | |
this.dispose(item); | |
} | |
} catch (err) { | |
_didIteratorError = true; | |
_iteratorError = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion && _iterator.return) { | |
_iterator.return(); | |
} | |
} finally { | |
if (_didIteratorError) { | |
throw _iteratorError; | |
} | |
} | |
} | |
this.list = new DoubleLinkList(); | |
this.map = new Map(); | |
} | |
}]); | |
return LRUCache; | |
}(); | |
var noop = function noop() {}; | |
var ctxCache = new LRUCache(14, noop); | |
/** | |
* 假context | |
*/ | |
var methods = ['translate', 'rotate', 'drawImage', 'beginPath', 'moveTo', 'lineTo', 'stroke', 'clearRect', 'save', 'restore']; | |
var FakerContext = methods.reduce(function (result, method) { | |
result[method] = noop; | |
return result; | |
}, {}); | |
var Canvas = function () { | |
createClass(Canvas, null, [{ | |
key: 'isOnBorder', | |
/** | |
* 绘制任务是否经过canvas边界 | |
* @param {Number} x 横坐标 | |
* @param {Number} y 纵坐标 | |
* @param {Number} width 宽度 | |
* @param {Number} height 高度 | |
*/ | |
value: function isOnBorder(x, y, width, height) { | |
return !((x + width) % SingleCanvasSize > width && (y + height) % SingleCanvasSize > height); | |
} | |
}]); | |
function Canvas($container) { | |
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, | |
width = _ref.width, | |
height = _ref.height, | |
_ref$scale = _ref.scale, | |
scale = _ref$scale === undefined ? 1 : _ref$scale, | |
standWidth = _ref.standWidth, | |
standHeight = _ref.standHeight; | |
classCallCheck(this, Canvas); | |
this.$container = $container; | |
this.width = width; | |
this.height = height; | |
this.scale = scale; | |
this.standWidth = standWidth; | |
this.standHeight = standHeight; | |
this.row = Math.ceil(this.height / SingleCanvasSize); | |
this.column = Math.ceil(this.width / SingleCanvasSize); | |
ctxCache.disposeAll(); | |
ctxCache.dispose = this.disposeCacheItem.bind(this); | |
window.addEventListener('beforeunload', function () { | |
ctxCache.disposeAll(); | |
}); | |
this.init(); | |
} | |
/** | |
* 设置透明度 | |
*/ | |
createClass(Canvas, [{ | |
key: 'init', | |
/** | |
* 初始化 | |
*/ | |
value: function init() { | |
addStyle(this.$container, { | |
width: this.width * this.scale, | |
height: this.height * this.scale, | |
overflow: 'hidden', | |
position: 'relative' | |
}); | |
} | |
}, { | |
key: 'getCacheKey', | |
value: function getCacheKey(row, column) { | |
return row + ',' + column; | |
} | |
/** | |
* 释放缓存资源 | |
* @param {Object} item 将被释放的资源 | |
*/ | |
}, { | |
key: 'disposeCacheItem', | |
value: function disposeCacheItem(item) { | |
item.$canvas.width = 0; | |
item.$canvas.height = 0; | |
item.$canvas.remove(); | |
item.$canvas = null; | |
item.ctx = null; | |
if (this.onDispose) { | |
this.onDispose(item); | |
} | |
} | |
/** | |
* 初始化指定位置canvas | |
* @param {Number} row 行 | |
* @param {Number} column 列 | |
*/ | |
}, { | |
key: 'initCanvas', | |
value: function initCanvas(row, column) { | |
var $canvas = createCanvas(SingleCanvasSize, SingleCanvasSize); | |
var size = Math.ceil(SingleCanvasSize * this.scale); | |
addStyle($canvas, { | |
position: 'absolute', | |
top: row * size, | |
left: column * size, | |
width: size, | |
height: size, | |
pointerEvents: 'none' | |
}); | |
this.$container.appendChild($canvas); | |
var item = { | |
$canvas: $canvas, | |
ctx: $canvas.getContext('2d') || FakerContext, // 如果获取ctx失败, 则使用假ctx避免后续报错 | |
row: row, | |
column: column | |
}; | |
ctxCache.put(this.getCacheKey(row, column), item); | |
return item; | |
} | |
/** | |
* 获取canvas context, 如果canvas不存在则创建一个 | |
* @param {Number} row 行 | |
* @param {Number} column 列 | |
*/ | |
}, { | |
key: 'getContext', | |
value: function getContext(row, column) { | |
var item = ctxCache.get(this.getCacheKey(row, column)); | |
if (!item) { | |
item = this.initCanvas(row, column); | |
} | |
return item.ctx; | |
} | |
/** | |
* 设置位置 | |
* @param {Object} point 位置 | |
*/ | |
}, { | |
key: 'setPosition', | |
value: function setPosition(point) { | |
addStyle(this.$container, { | |
left: point.x, | |
top: point.y | |
}); | |
} | |
/** | |
* 设置缩放 | |
* @param {Number} value 缩放值 | |
*/ | |
}, { | |
key: 'setScale', | |
value: function setScale(value) { | |
this.scale = value; | |
var size = Math.ceil(SingleCanvasSize * this.scale); | |
addStyle(this.$container, { | |
width: this.width * this.scale, | |
height: this.height * this.scale, | |
left: -(this.width * this.scale - this.standWidth) / 2, | |
top: -(this.height * this.scale - this.standHeight) / 2 | |
}); | |
var _iteratorNormalCompletion = true; | |
var _didIteratorError = false; | |
var _iteratorError = undefined; | |
try { | |
for (var _iterator = ctxCache.getAll()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | |
var _ref2 = _step.value; | |
var row = _ref2.row; | |
var column = _ref2.column; | |
var $canvas = _ref2.$canvas; | |
addStyle($canvas, { | |
top: row * size, | |
left: column * size, | |
width: size, | |
height: size | |
}); | |
} | |
} catch (err) { | |
_didIteratorError = true; | |
_iteratorError = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion && _iterator.return) { | |
_iterator.return(); | |
} | |
} finally { | |
if (_didIteratorError) { | |
throw _iteratorError; | |
} | |
} | |
} | |
} | |
/** | |
* 绘制图片 | |
* 如果绘制范围跨越了canvas边界, 则切分绘制 | |
* @param {Image} image 图片对象 | |
* @param {Number} x 横坐标 | |
* @param {Number} y 纵坐标 | |
* @param {Number} width 宽度 | |
* @param {Number} height 高度 | |
* @param {Number} range 角度, 0~360 | |
*/ | |
}, { | |
key: 'drawImage', | |
value: function drawImage(image, x, y, width, height) { | |
var angle = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; | |
angle *= Math.PI / 180; | |
// 没跨越canvas边界的座位, 直接绘制 | |
if (!Canvas.isOnBorder(x, y, width, height)) { | |
var ctx = this.getContext(Math.floor(y / SingleCanvasSize), Math.floor(x / SingleCanvasSize)); | |
ctx.translate(x % SingleCanvasSize + width / 2, y % SingleCanvasSize + height / 2); | |
ctx.rotate(angle); | |
ctx.drawImage(image, 0 - width / 2, 0 - height / 2, width, height); | |
return; | |
} | |
// 跨越边界的座位, 计算跨越范围 | |
var startRow = Math.floor(y / SingleCanvasSize); | |
var endRow = Math.ceil((y + height) / SingleCanvasSize); | |
var startColumn = Math.floor(x / SingleCanvasSize); | |
var endColumn = Math.ceil((x + width) / SingleCanvasSize); | |
// image高度/宽度写死固定值32px, 如果后面座位图更换大小了, 要注意 | |
var imageWidthScale = 32 / width; | |
var imageHeightScale = 32 / height; | |
var sx = 0; // 原图裁切起点横坐标 | |
var sy = 0; // 原图裁切起点纵坐标 | |
var dy = y; // 绘制起点纵坐标 | |
var remainWidth = width; | |
var remainHeight = height; | |
for (var i = startRow; i < endRow; i++) { | |
var dx = x; // 绘制起点横坐标 | |
var sWidth = 0; | |
var sHeight = 0; | |
var dWidth = remainWidth; // 绘制宽度 | |
var dHeight = remainHeight; // 绘制高度 | |
for (var j = startColumn; j < endColumn; j++) { | |
if (dx >= SingleCanvasSize) { | |
dx -= SingleCanvasSize * j; | |
} | |
if (dy >= SingleCanvasSize) { | |
dy -= SingleCanvasSize * i; | |
} | |
dWidth = remainWidth; | |
if (SingleCanvasSize - dx < dWidth) { | |
dWidth = SingleCanvasSize - dx; | |
} | |
if (SingleCanvasSize - dy < dHeight) { | |
dHeight = SingleCanvasSize - dy; | |
} | |
sWidth = dWidth * imageWidthScale; | |
sHeight = dHeight * imageHeightScale; | |
var _ctx = this.getContext(i, j); | |
var xOffset = sx !== 0 ? dWidth - width : 0; | |
var yOffset = sy !== 0 ? dHeight - height : 0; | |
_ctx.translate(dx + xOffset + width / 2, dy + yOffset + height / 2); | |
_ctx.rotate(angle); | |
_ctx.drawImage(image, 0 - width / 2, 0 - height / 2, width, height); | |
sx += sWidth; | |
dx = 0; | |
remainWidth -= dWidth; | |
} | |
sy += sHeight; | |
dy = 0; | |
sx = 0; | |
remainWidth = width; | |
remainHeight -= dHeight; | |
} | |
} | |
/** | |
* 绘制折线 | |
* 如果绘制范围跨越了canvas边界, 则切分绘制 | |
* @param {Array} points 关键点坐标 | |
* @param {Number} seatSize 座位尺寸 | |
*/ | |
}, { | |
key: 'drawLine', | |
value: function drawLine(points) { | |
var _this = this; | |
var seatSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; | |
if (!Array.isArray(points) || points.length < 2) return; | |
points.reduce(function (pre, cur) { | |
var x = pre.x + seatSize / 2; | |
var y = pre.y + seatSize / 2; | |
var width = cur.x - pre.x; | |
var height = cur.y - pre.y; | |
// 没跨越canvas边界的区域, 直接绘制 | |
if (!Canvas.isOnBorder(x, y, width, height)) { | |
// 没跨越canvas边界的座位, 直接绘制 | |
var ctx = _this.getContext(Math.floor(y / SingleCanvasSize), Math.floor(x / SingleCanvasSize)); | |
ctx.beginPath(); | |
ctx.strokeStyle = 'lightgray'; | |
ctx.lineWidth = 3; | |
ctx.moveTo(x % SingleCanvasSize, y % SingleCanvasSize); | |
ctx.lineTo((x + width) % SingleCanvasSize, (y + height) % SingleCanvasSize); | |
ctx.stroke(); | |
return cur; | |
} | |
// 跨越边界, 计算跨越范围 | |
var startRow = Math.floor(y / SingleCanvasSize); | |
var endRow = Math.ceil((y + height) / SingleCanvasSize); | |
var startColumn = Math.floor(x / SingleCanvasSize); | |
var endColumn = Math.ceil((x + width) / SingleCanvasSize); | |
var dy = y; // 绘制起点纵坐标 | |
for (var i = startRow; i < endRow; i++) { | |
var dx = x; // 绘制起点横坐标 | |
for (var j = startColumn; j < endColumn; j++) { | |
if (dx >= SingleCanvasSize) { | |
dx -= SingleCanvasSize * j; | |
} | |
if (dy >= SingleCanvasSize) { | |
dy -= SingleCanvasSize * i; | |
} | |
var _ctx2 = _this.getContext(i, j); | |
_ctx2.beginPath(); | |
_ctx2.strokeStyle = 'lightgray'; | |
_ctx2.lineWidth = 3; | |
_ctx2.moveTo(dx, dy); | |
_ctx2.lineTo(dx + width, dy + height); | |
_ctx2.stroke(); | |
dx -= SingleCanvasSize; | |
} | |
dy -= SingleCanvasSize; | |
} | |
return cur; | |
}); | |
} | |
/** | |
* 清空区域 | |
* 如果绘制范围跨越了canvas边界, 则切分后分别清空 | |
* @param {Number} x 横坐标 | |
* @param {Number} y 纵坐标 | |
* @param {Number} width 宽度 | |
* @param {Number} height 高度 | |
*/ | |
}, { | |
key: 'clearRect', | |
value: function clearRect(x, y, width, height) { | |
// 没跨越canvas边界的区域, 直接清除 | |
if (!Canvas.isOnBorder(x, y, width, height)) { | |
var ctx = this.getContext(Math.floor(y / SingleCanvasSize), Math.floor(x / SingleCanvasSize)); | |
ctx.clearRect(x % SingleCanvasSize, y % SingleCanvasSize, width, height); | |
return; | |
} | |
// 跨越边界, 计算跨越范围 | |
var startRow = Math.floor(y / SingleCanvasSize); | |
var endRow = Math.ceil((y + height) / SingleCanvasSize); | |
var startColumn = Math.floor(x / SingleCanvasSize); | |
var endColumn = Math.ceil((x + width) / SingleCanvasSize); | |
var dy = y; // 绘制起点纵坐标 | |
var remainWidth = width; | |
var remainHeight = height; | |
for (var i = startRow; i < endRow; i++) { | |
var dx = x; // 绘制起点横坐标 | |
var dWidth = remainWidth; // 绘制宽度 | |
var dHeight = remainHeight; // 绘制高度 | |
for (var j = startColumn; j < endColumn; j++) { | |
if (dx >= SingleCanvasSize) { | |
dx -= SingleCanvasSize * j; | |
} | |
if (dy >= SingleCanvasSize) { | |
dy -= SingleCanvasSize * i; | |
} | |
dWidth = remainWidth; | |
if (SingleCanvasSize - dx < dWidth) { | |
dWidth = SingleCanvasSize - dx; | |
} | |
dHeight = remainHeight; | |
if (SingleCanvasSize - dy < dHeight) { | |
dHeight = SingleCanvasSize - dy; | |
} | |
var _ctx3 = this.getContext(i, j); | |
_ctx3.clearRect(dx, dy, dWidth, dHeight); | |
dx = 0; | |
remainWidth -= dWidth; | |
} | |
dy = 0; | |
remainWidth = width; | |
remainHeight -= dHeight; | |
} | |
} | |
/** | |
* 保存上下文 | |
*/ | |
}, { | |
key: 'save', | |
value: function save() { | |
var _iteratorNormalCompletion2 = true; | |
var _didIteratorError2 = false; | |
var _iteratorError2 = undefined; | |
try { | |
for (var _iterator2 = ctxCache.getAll()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | |
var _ref3 = _step2.value; | |
var ctx = _ref3.ctx; | |
ctx.save(); | |
} | |
} catch (err) { | |
_didIteratorError2 = true; | |
_iteratorError2 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion2 && _iterator2.return) { | |
_iterator2.return(); | |
} | |
} finally { | |
if (_didIteratorError2) { | |
throw _iteratorError2; | |
} | |
} | |
} | |
} | |
/** | |
* 恢复上下文 | |
*/ | |
}, { | |
key: 'restore', | |
value: function restore() { | |
var _iteratorNormalCompletion3 = true; | |
var _didIteratorError3 = false; | |
var _iteratorError3 = undefined; | |
try { | |
for (var _iterator3 = ctxCache.getAll()[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { | |
var _ref4 = _step3.value; | |
var ctx = _ref4.ctx; | |
ctx.restore(); | |
} | |
} catch (err) { | |
_didIteratorError3 = true; | |
_iteratorError3 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion3 && _iterator3.return) { | |
_iterator3.return(); | |
} | |
} finally { | |
if (_didIteratorError3) { | |
throw _iteratorError3; | |
} | |
} | |
} | |
} | |
}, { | |
key: 'globalAlpha', | |
set: function set$$1(value) { | |
var _iteratorNormalCompletion4 = true; | |
var _didIteratorError4 = false; | |
var _iteratorError4 = undefined; | |
try { | |
for (var _iterator4 = ctxCache.getAll()[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { | |
var _ref5 = _step4.value; | |
var ctx = _ref5.ctx; | |
ctx.globalAlpha = value; | |
} | |
} catch (err) { | |
_didIteratorError4 = true; | |
_iteratorError4 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion4 && _iterator4.return) { | |
_iterator4.return(); | |
} | |
} finally { | |
if (_didIteratorError4) { | |
throw _iteratorError4; | |
} | |
} | |
} | |
} | |
}]); | |
return Canvas; | |
}(); | |
/** | |
* @module arraybuffer-to-string | |
*/ | |
var _arraybufferToString_1_0_2_arraybufferToString = function ArrayBufferToString(buffer, encoding) { | |
if (encoding == null) encoding = 'utf8'; | |
return Buffer.from(buffer).toString(encoding) | |
}; | |
var _class$8; | |
var _temp$6; | |
var _class2$1; | |
var _temp2$2; | |
/** | |
* zigzag压缩数据解码 | |
*/ | |
var Zigzag = function () { | |
function Zigzag() { | |
classCallCheck(this, Zigzag); | |
} | |
createClass(Zigzag, null, [{ | |
key: 'readInt', | |
/** | |
* 读取一个int数据 | |
* @param {Buffer} buf 数据 | |
* @param {number} pos 位置 | |
*/ | |
value: function readInt(buf, pos) { | |
var len = 1; | |
var b = buf[pos] & 0xff; | |
var n = b & 0x7f; | |
if (b > 0x7f) { | |
b = buf[pos + len++] & 0xff; | |
n ^= (b & 0x7f) << 7; | |
if (b > 0x7f) { | |
b = buf[pos + len++] & 0xff; | |
n ^= (b & 0x7f) << 14; | |
if (b > 0x7f) { | |
b = buf[pos + len++] & 0xff; | |
n ^= (b & 0x7f) << 21; | |
if (b > 0x7f) { | |
b = buf[pos + len++] & 0xff; | |
n ^= (b & 0x7f) << 28; | |
if (b > 0x7f) { | |
throw Error('zigzag解码失败'); | |
} | |
} | |
} | |
} | |
} | |
return { | |
value: n >>> 1 ^ -(n & 1), | |
nextPos: pos + len | |
}; | |
} | |
/** | |
* 读取一段数据 | |
* @param {Buffer} buf 数据 | |
* @param {number} pos 位置 | |
* @param {number} size 大小 | |
*/ | |
}, { | |
key: 'readValue', | |
value: function readValue(buf, pos, size) { | |
var result = []; | |
var i = 0; | |
while (i < size) { | |
var _Zigzag$readInt = Zigzag.readInt(buf, pos), | |
value = _Zigzag$readInt.value, | |
nextPos = _Zigzag$readInt.nextPos; | |
result.push(value); | |
i++; | |
pos = nextPos; | |
} | |
return result; | |
} | |
}]); | |
return Zigzag; | |
}(); | |
/** | |
* 二进制数据解析器 | |
* 基类, 抽象类 | |
*/ | |
var BinaryDataParser = function () { | |
function BinaryDataParser(data) { | |
classCallCheck(this, BinaryDataParser); | |
this.bytes = new Uint8Array(data); | |
this.i = 0; | |
} | |
/** | |
* 获取下8位, 1字节 | |
* @param {boolean} goForward 是否前移指针 | |
*/ | |
createClass(BinaryDataParser, [{ | |
key: 'getInt8', | |
value: function getInt8() { | |
var goForward = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; | |
var result = this.bytes[this.i]; | |
if (goForward) { | |
this.i++; | |
} | |
return result; | |
} | |
/** | |
* 获取下16位, 2字节 | |
* @param {boolean} goForward 是否前移指针 | |
*/ | |
}, { | |
key: 'getInt16', | |
value: function getInt16() { | |
var goForward = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; | |
var result = 0; | |
result |= this.bytes[this.i]; | |
result |= this.bytes[this.i + 1] << 8; | |
if (goForward) { | |
this.i += 2; | |
} | |
return result; | |
} | |
/** | |
* 获取下32位, 4字节 | |
* @param {boolean} goForward 是否前移指针 | |
*/ | |
}, { | |
key: 'getInt32', | |
value: function getInt32() { | |
var goForward = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; | |
var result = 0; | |
result |= this.bytes[this.i]; | |
result |= this.bytes[this.i + 1] << 8; | |
result |= this.bytes[this.i + 2] << 16; | |
result |= this.bytes[this.i + 3] << 24; | |
if (goForward) { | |
this.i += 4; | |
} | |
return result; | |
} | |
/** | |
* 获取下64位, 8字节 | |
* @param {boolean} goForward 是否前移指针 | |
*/ | |
}, { | |
key: 'getInt64', | |
value: function getInt64() { | |
var goForward = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; | |
var result = 0; | |
result |= this.bytes[this.i]; | |
result |= this.bytes[this.i + 1] << 8; | |
result |= this.bytes[this.i + 2] << 16; | |
result |= this.bytes[this.i + 3] << 24; | |
result |= this.bytes[this.i + 4] << 32; | |
result |= this.bytes[this.i + 5] << 40; | |
result |= this.bytes[this.i + 6] << 48; | |
result |= this.bytes[this.i + 7] << 56; | |
if (goForward) { | |
this.i += 8; | |
} | |
return result; | |
} | |
}, { | |
key: 'toString', | |
value: function toString(lineBreak) { | |
return this.formatData(0, this.bytes.byteLength, lineBreak); | |
} | |
}, { | |
key: 'formatData', | |
value: function formatData(index, length) { | |
var lineBreak = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 16; | |
var result = []; | |
for (var i = index; i < index + length; i++) { | |
var v = this.bytes[i].toString(16).toUpperCase(); | |
if (v.length === 1) { | |
v = '0' + v; | |
} | |
result.push(v); | |
if ((i - index) % lineBreak === lineBreak - 1) { | |
result.push('\n'); | |
} else { | |
result.push(' '); | |
} | |
} | |
return result.join(''); | |
} | |
}]); | |
return BinaryDataParser; | |
}(); | |
/** | |
* Matrix类型座位二进制数据解析器 | |
*/ | |
var MatrixSeatParser = (_temp$6 = _class$8 = function (_BinaryDataParser) { | |
inherits(MatrixSeatParser, _BinaryDataParser); | |
function MatrixSeatParser() { | |
classCallCheck(this, MatrixSeatParser); | |
return possibleConstructorReturn(this, (MatrixSeatParser.__proto__ || Object.getPrototypeOf(MatrixSeatParser)).apply(this, arguments)); | |
} | |
createClass(MatrixSeatParser, [{ | |
key: 'parse', | |
value: function parse(seatStatus) { | |
// 座位基数 | |
var base = this.getInt32(); | |
// 座位总数 | |
var seatCount = this.getInt16(); | |
var seats = {}; | |
var _row = 0; | |
var _column = 0; | |
var maxColumn = 0; | |
while (this.i < this.bytes.length) { | |
var flagValue = this.getInt8(); | |
var flag = flagValue & 0xC0; // 1100 0000 | |
switch (flag) { | |
case MatrixSeatParser.FLAG.DRAW_SEAT: { | |
// 行号 | |
var rowValue = this.getInt8(); | |
var rn = rowValue >> 1; | |
var offset = 0; | |
if ((rowValue & 1) === 1) { | |
offset = this.getInt32(); | |
} else { | |
offset = this.getInt16(); | |
} | |
var sid = base + offset; | |
var priceChineseValue = this.getInt8(); | |
// 价格等级索引 | |
var priceIndex = priceChineseValue & 0x7F; // 0111 1111 | |
// 排号是否有中文 | |
var isChinese = priceChineseValue >> 7 === 1; | |
var snPackagedValue = this.getInt8(); | |
// 座位号 | |
var sn = snPackagedValue >> 1; | |
// 是否系统套票 | |
var isPackage = (snPackagedValue & 1) === 1; | |
// 楼层索引 | |
var floor = this.getInt8(); | |
if (floor === 0xFF) { | |
floor = this.getInt16(); | |
} | |
var packagePriceIndex = -1; | |
var packageCombinedId = -1; | |
if (isPackage) { | |
packagePriceIndex = this.getInt8(); | |
packageCombinedId = this.getInt32(); | |
} | |
var seat = { | |
s: seatStatus[sid] || 0, // 座位状态 | |
rn: rn, // 排号 | |
sn: sn, // 座位号 | |
sid: sid, // 座位id | |
floor: floor, | |
priceIndex: priceIndex, // 价格索引 | |
isChinese: isChinese, | |
isPackage: isPackage, | |
packagePriceIndex: packagePriceIndex, | |
packageCombinedId: packageCombinedId | |
}; | |
if (seats[_row]) { | |
seats[_row][_column] = seat; | |
} else { | |
seats[_row] = defineProperty({}, _column, seat); | |
} | |
_column++; | |
break; | |
} | |
case MatrixSeatParser.FLAG.DRAW_SPACE: { | |
var spaces = 0; | |
if ((flagValue & 0x20) === 0) { | |
// 0010 0000 | |
spaces = flagValue & 0x1f; // 0001 1111 | |
} else { | |
spaces = this.getInt8(); | |
} | |
_column += spaces; | |
break; | |
} | |
case MatrixSeatParser.FLAG.DRAW_BR: { | |
var brs = flagValue & 0x3F; // 0011 1111 | |
_row += brs; | |
_column = 0; | |
break; | |
} | |
default: { | |
this.i = this.bytes.length; | |
break; | |
} | |
} | |
if (_column > maxColumn) { | |
maxColumn = _column; | |
} | |
} | |
var seatsInfo = {}; | |
seatsInfo.base = base; | |
seatsInfo.count = seatCount; | |
seatsInfo.seats = seats; | |
seatsInfo.row = _row + 1; | |
seatsInfo.column = maxColumn; | |
return seatsInfo; | |
} | |
}]); | |
return MatrixSeatParser; | |
}(BinaryDataParser), _class$8.FLAG = { | |
DRAW_SEAT: 192, | |
DRAW_SPACE: 128, | |
DRAW_BR: 64 | |
}, _temp$6); | |
/** | |
* 麒麟新座位压缩方法二进制数据解析器 | |
* 压缩方案: https://yuque.antfin-inc.com/damai/seat/bgkb7d | |
*/ | |
var KeylinSeatParser = (_temp2$2 = _class2$1 = function (_BinaryDataParser2) { | |
inherits(KeylinSeatParser, _BinaryDataParser2); | |
function KeylinSeatParser() { | |
classCallCheck(this, KeylinSeatParser); | |
return possibleConstructorReturn(this, (KeylinSeatParser.__proto__ || Object.getPrototypeOf(KeylinSeatParser)).apply(this, arguments)); | |
} | |
createClass(KeylinSeatParser, [{ | |
key: 'parseHeader', | |
value: function parseHeader() { | |
var flag = this.getInt32(); | |
var version = this.getInt16(); | |
var standId = this.getInt64(); | |
var offset = this.getInt32(); | |
var expandSize = this.getInt32(); // 拓展字段长度 | |
this.getInt32(); // 保留 | |
this.i += expandSize; | |
return { | |
flag: flag, | |
version: version, | |
standId: standId, | |
offset: offset | |
}; | |
} | |
/** | |
* 解析看台座位 | |
* @param {number} byteIndex 看台数据起始位置 | |
*/ | |
}, { | |
key: 'parseStandSeats', | |
value: function parseStandSeats(byteIndex) { | |
this.i = byteIndex; | |
this.getInt32(); // flag | |
var standId = this.getInt64(); // standId | |
var seatCount = this.getInt32(); | |
var blockSize = this.getInt32(); | |
var compressModeBytesSize = this.getInt32(); | |
var expandSize = this.getInt32(); // 拓展字段长度 | |
this.getInt32(); // 保留 | |
this.getInt32(); // 保留 | |
this.i += expandSize; | |
// 初始化座位对象, 注意不能 fill({}) !!! | |
var seats = new Array(seatCount); | |
for (var i = 0; i < seats.length; i++) { | |
seats[i] = {}; | |
} | |
var data = this.bytes.slice(this.i, this.i + blockSize); | |
var compressModeBytes = data.slice(0, compressModeBytesSize); | |
var compressModeString = _arraybufferToString_1_0_2_arraybufferToString(compressModeBytes, 'utf-8'); | |
/** | |
* 需要读取 zigzag 数据的字段数 | |
*/ | |
var zigzagFieldCount = 0; | |
// 解析各字段的数值模式、压缩模式, 获取基础值和字典 | |
var fields = compressModeString.split('|').map(function (field) { | |
var _field$split = field.split('&'), | |
_field$split2 = slicedToArray(_field$split, 5), | |
name = _field$split2[0], | |
valueType = _field$split2[1], | |
compressType = _field$split2[2], | |
value = _field$split2[3], | |
map = _field$split2[4]; | |
switch (compressType) { | |
case '1': | |
case '2': | |
case '3': { | |
zigzagFieldCount++; | |
break; | |
} | |
default: { | |
break; | |
} | |
} | |
/** | |
* 根据数值类型解码相应的值 | |
*/ | |
function parseValue(v) { | |
switch (valueType) { | |
case '1': { | |
// 整数 | |
return parseInt(v, 10); | |
} | |
case '2': { | |
// 小数 | |
return parseFloat(v / 10); | |
} | |
default: { | |
// 原值 | |
return v; | |
} | |
} | |
} | |
var parsedValue = null; | |
if (!map) { | |
// 值模式, 解析出原类型值 | |
parsedValue = parseValue(value); | |
} else { | |
// 字典模式, 解析成 key: value 对象 | |
parsedValue = map.split(',').reduce(function (result, kv) { | |
var _kv$split = kv.split(':'), | |
_kv$split2 = slicedToArray(_kv$split, 2), | |
k = _kv$split2[0], | |
v = _kv$split2[1]; | |
result[k] = parseValue(v); | |
return result; | |
}, {}); | |
} | |
return { | |
name: name, | |
compressType: compressType, | |
value: parsedValue | |
}; | |
}); | |
var zigzagBytes = data.slice(compressModeBytesSize); | |
var values = Zigzag.readValue(zigzagBytes, 0, zigzagFieldCount * seatCount); | |
var index = 0; | |
/** | |
* 抛异常 | |
* @param {string} msg 异常信息 | |
* @param {object} payload 额外负载信息 | |
*/ | |
function throwError() { | |
var msg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; | |
var payload = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | |
var error = Error(msg); | |
// 异常上报拓展信息 | |
error.expandInfo = JSON.stringify(Object.assign({ | |
standId: standId, | |
startIndex: byteIndex, | |
blockSize: blockSize, | |
zigzagValuesCount: values.length, | |
seatCount: seatCount | |
}, payload)); | |
throw error; | |
} | |
if (values.length % seatCount !== 0) { | |
throwError('zigzag数值个数异常'); | |
} | |
for (var _i = 0; _i < fields.length; _i++) { | |
if (index > values.length) { | |
throwError('zigzag读取的index超界', { | |
currentIndex: index | |
}); | |
} | |
var field = fields[_i]; | |
switch (field.compressType) { | |
case '1': { | |
// Number + BaseValue(String) | |
var _iteratorNormalCompletion = true; | |
var _didIteratorError = false; | |
var _iteratorError = undefined; | |
try { | |
for (var _iterator = seats[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | |
var seat = _step.value; | |
seat[field.name] = values[index] + field.value; | |
index++; | |
} | |
} catch (err) { | |
_didIteratorError = true; | |
_iteratorError = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion && _iterator.return) { | |
_iterator.return(); | |
} | |
} finally { | |
if (_didIteratorError) { | |
throw _iteratorError; | |
} | |
} | |
} | |
break; | |
} | |
case '2': { | |
// BaseValue(Number) + Number | |
var _iteratorNormalCompletion2 = true; | |
var _didIteratorError2 = false; | |
var _iteratorError2 = undefined; | |
try { | |
for (var _iterator2 = seats[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | |
var _seat = _step2.value; | |
_seat[field.name] = field.value + values[index]; | |
index++; | |
} | |
} catch (err) { | |
_didIteratorError2 = true; | |
_iteratorError2 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion2 && _iterator2.return) { | |
_iterator2.return(); | |
} | |
} finally { | |
if (_didIteratorError2) { | |
throw _iteratorError2; | |
} | |
} | |
} | |
break; | |
} | |
case '3': { | |
// 字典映射 | |
var _iteratorNormalCompletion3 = true; | |
var _didIteratorError3 = false; | |
var _iteratorError3 = undefined; | |
try { | |
for (var _iterator3 = seats[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { | |
var _seat2 = _step3.value; | |
_seat2[field.name] = field.value[values[index]]; | |
index++; | |
} | |
} catch (err) { | |
_didIteratorError3 = true; | |
_iteratorError3 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion3 && _iterator3.return) { | |
_iterator3.return(); | |
} | |
} finally { | |
if (_didIteratorError3) { | |
throw _iteratorError3; | |
} | |
} | |
} | |
break; | |
} | |
case '4': { | |
// 空值, null | |
var _iteratorNormalCompletion4 = true; | |
var _didIteratorError4 = false; | |
var _iteratorError4 = undefined; | |
try { | |
for (var _iterator4 = seats[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { | |
var _seat3 = _step4.value; | |
_seat3[field.name] = null; | |
} | |
} catch (err) { | |
_didIteratorError4 = true; | |
_iteratorError4 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion4 && _iterator4.return) { | |
_iterator4.return(); | |
} | |
} finally { | |
if (_didIteratorError4) { | |
throw _iteratorError4; | |
} | |
} | |
} | |
break; | |
} | |
case '5': { | |
// 相同值 | |
var _iteratorNormalCompletion5 = true; | |
var _didIteratorError5 = false; | |
var _iteratorError5 = undefined; | |
try { | |
for (var _iterator5 = seats[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { | |
var _seat4 = _step5.value; | |
_seat4[field.name] = field.value; | |
} | |
} catch (err) { | |
_didIteratorError5 = true; | |
_iteratorError5 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion5 && _iterator5.return) { | |
_iterator5.return(); | |
} | |
} finally { | |
if (_didIteratorError5) { | |
throw _iteratorError5; | |
} | |
} | |
} | |
break; | |
} | |
case '6': { | |
// 关联模式, 在关联字段上追加上一个值 | |
var _iteratorNormalCompletion6 = true; | |
var _didIteratorError6 = false; | |
var _iteratorError6 = undefined; | |
try { | |
for (var _iterator6 = seats[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { | |
var _seat5 = _step6.value; | |
var _field$value$split = field.value.split(','), | |
_field$value$split2 = slicedToArray(_field$value$split, 2), | |
key = _field$value$split2[0], | |
_field$value$split2$ = _field$value$split2[1], | |
str = _field$value$split2$ === undefined ? '' : _field$value$split2$; | |
if (Object.prototype.hasOwnProperty.call(_seat5, key)) { | |
_seat5[field.name] = _seat5[key] + str; | |
} | |
} | |
} catch (err) { | |
_didIteratorError6 = true; | |
_iteratorError6 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion6 && _iterator6.return) { | |
_iterator6.return(); | |
} | |
} finally { | |
if (_didIteratorError6) { | |
throw _iteratorError6; | |
} | |
} | |
} | |
break; | |
} | |
default: { | |
break; | |
} | |
} | |
} | |
return seats; | |
} | |
/** | |
* 解码全量数据 | |
* 不推荐一次解码全量, 除非有相应需求 | |
*/ | |
/* | |
parse() { | |
console.time('parse time:'); | |
const headers = []; | |
while (this.isHeader()) { | |
headers.push(this.parseHeader()); | |
} | |
const seats = {}; | |
for (const header of headers) { | |
seats[header.standId] = this.parseStandSeats(header.offset); | |
} | |
console.timeEnd('parse time:'); | |
return seats; | |
} | |
*/ | |
/** | |
* 解压所有看台headers, 备用 | |
*/ | |
}, { | |
key: 'parseHeaders', | |
value: function parseHeaders() { | |
this.headers = []; | |
var loop = true; | |
while (loop) { | |
switch (this.getInt32(false)) { | |
case KeylinSeatParser.Flag.HeaderFlag: { | |
this.headers.push(this.parseHeader()); | |
break; | |
} | |
case KeylinSeatParser.Flag.StandHeaderFlag: { | |
loop = false; | |
break; | |
} | |
default: { | |
var err = Error('parseHeaders异常'); | |
err.expandInfo = { | |
index: this.i, | |
bytes: this.formatData(this.i, 80) | |
}; | |
throw err; | |
} | |
} | |
} | |
} | |
/** | |
* 根据看台id解压对应看台座位数据 | |
* @param {number} standId 看台id | |
*/ | |
}, { | |
key: 'getStandSeats', | |
value: function getStandSeats(standId) { | |
var header = this.headers.find(function (h) { | |
return h.standId === +standId; | |
}); | |
if (header) { | |
return this.parseStandSeats(header.offset); | |
} | |
return []; | |
} | |
}]); | |
return KeylinSeatParser; | |
}(BinaryDataParser), _class2$1.Flag = { | |
HeaderFlag: 0x01034b50, | |
StandHeaderFlag: 0x01034b20 | |
}, _temp2$2); | |
var _class; | |
var _temp2; | |
var MatrixStandRender = (_temp2 = _class = function (_StandRender) { | |
inherits(MatrixStandRender, _StandRender); | |
function MatrixStandRender() { | |
var _ref; | |
var _temp, _this, _ret; | |
classCallCheck(this, MatrixStandRender); | |
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | |
args[_key] = arguments[_key]; | |
} | |
return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref = MatrixStandRender.__proto__ || Object.getPrototypeOf(MatrixStandRender)).call.apply(_ref, [this].concat(args))), _this), _this.className = 'MatrixStandRender', _this._thumbnailCtx = null, _this._$seatCanvasContainer = null, _this._$thumbnailCanvas = null, _this._$lineNumberContainer = null, _this._$lineNumbers = null, _this.onTouchMove = function (e) { | |
get(MatrixStandRender.prototype.__proto__ || Object.getPrototypeOf(MatrixStandRender.prototype), 'onTouchMove', _this).call(_this, 100, e); | |
_this.updateLineNumber(_this._viewport.getLineNumberOffset(), e.touches === undefined /* 鼠标事件 */ || e.touches.length === 1 /* 手势单指 */ ? 0 : _this._viewport.getScale()); | |
}, _this.onMouseWheel = function (e) { | |
get(MatrixStandRender.prototype.__proto__ || Object.getPrototypeOf(MatrixStandRender.prototype), 'onMouseWheel', _this).call(_this, e); | |
_this.updateLineNumber(_this._viewport.getLineNumberOffset(), _this._viewport.getScale()); | |
}, _this.highlightPrice = function (priceIndex) { | |
_this._area.highlightPrice(priceIndex); | |
}, _this.selectSeat = function (seatId) { | |
_this._area.selectSeat(seatId); | |
}, _this.updateMaxPickNumber = function (newValue) { | |
_this._maxPickNumber = newValue; | |
}, _temp), possibleConstructorReturn(_this, _ret); | |
} | |
// 行号div距离父容器上下margin值 | |
// 行号纵轴偏移值 | |
// 舞台方向图片尺寸 | |
// 绘制座位缩略图context | |
// 座位canvas容器 | |
// 鹰眼图canvas | |
// 行号容器 | |
// 行号 | |
createClass(MatrixStandRender, [{ | |
key: 'init', | |
/** | |
* 初始化 | |
* @param {Number} row 行数 | |
* @param {Number} column 列数 | |
*/ | |
value: function init(row, column) { | |
addStyle(this._$container, { | |
position: 'relative', | |
textAlign: 'center' | |
}); | |
this.initStageImage(); | |
get(MatrixStandRender.prototype.__proto__ || Object.getPrototypeOf(MatrixStandRender.prototype), 'initArea', this).call(this, MatrixArea, row, column); | |
this.initViewport(); | |
this.initSeatCanvas(); | |
this.initThumbnail(); | |
// 移动端事件 | |
this._$seatCanvasContainer.addEventListener('touchstart', this.onTouchStart); | |
this._$seatCanvasContainer.addEventListener('touchmove', this.onTouchMove); | |
this._$seatCanvasContainer.addEventListener('touchend', this.onTouchEnd); | |
// pc端事件 | |
this._$container.addEventListener('mousedown', this.onTouchStart); | |
this._$container.addEventListener('mousemove', this.onTouchMove); | |
this._$container.addEventListener('mouseup', this.onTouchEnd); | |
this._$container.addEventListener('mouseleave', this.onMouseLeave); | |
this._$container.addEventListener('mousewheel', this.onMouseWheel); | |
} | |
/** | |
* 初始化舞台方向图 | |
*/ | |
}, { | |
key: 'initStageImage', | |
value: function initStageImage() { | |
var $stageImage = new Image(); | |
$stageImage.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAg0AAAA2CAMAAABz5FrhAAABAlBMVEUAAADn6Ovp6+7n6ezn6ezn6evn6ezo6u3////////n6ezn6ezr6/Dq7e/n6ezn6Ozn6ezn6ezn6uzn6ezn6ezn6u3n6u7p6e/t8/Pu7u7n6ezn6ezn6Ovn6ezo6u3m7Ozm6OtmZma9vsCztLbY293j5ei2t7nc3eB7fHzS1NdtbW3Nz9Goqqt1dXXHycuZmpuKiotnZ2e9v8Fvb2+ur7HX2NuTk5SXmJl/gIB3d3hycnONjo7e4OOGh4eam5xqamqxsrTDxce6u72kpaegoaJoaGjl5+qmp6l5eXrh4+XW19qjpKXJy83BwsSrrK6Sk5SEhIWVlpednp/Q0dSqq616e3tD6toqAAAAIHRSTlMA9jX768+8RAcD3IMlG+PUrJaLd2tbTS4UDvHGtaNiKUidV58AAAWgSURBVHja7d1pV9pqFIbh1wFBcdZW26rdDxCGIAhEJMEgg4Ayo7b//6+cgFhDEgmKR/Nirg+btVzLfOFGwwYC2yOX69EeY9+WyOUiWvrGNN4FcrkWvGxocZlcX93yIhtZXyPX17a2zv7Z8JDrK/NsMJ0fK+T6ulZ+sDG+bXJ9Vds+ZrC6Q66vaWeVme0Rv4Szaoem0o7TFJph+wOVyirNgz1m6WSJeFUFwjSNkAQlRHZuANu4LoEs8W/phL3g+wLxKQP0aRr1AnBDtppF3Ao0kVpDgfi38J1Z4HoPVRbxgob5QZ+iKbRs/9YEgTBxT9s5TfB7k7jTuAKmrCGZhqLSSLY84Zh5RGmiAooq8W7zN5toY4s4k1SAvxLuk8mkhKo2b5HTpoyUNuukF0qg+EAj1VqtTc/UyJguUIno0YAQe9JOIxUbx18cWxvMxuEv4ksY6Zag4JyIEihpU8aNNgvIkYEaBSr0pJxGIkL/9DCR+JgTJggSZ34dMguc76Fu4kTT1CCkgCo9OwUK9S9cw7aPWeB/DzVVDfU74J70LvV1lINP+qgFTcJPNVwELHX5qMG8c7LnJ44EEpoaJG2mh7MGUZvF4ZTpSWN03+uoClAhkx4kekEIOCVLcd5q8LOp7RM/wpggTyMRGbgmg7iWTNNiraTMfw37zAr/e6hsRpNHTpsSrrSpoKfNKAra7NBQPZx4uh+FSDNerpSur3qFaD4NFMiogOg812DeOdnz/iRe2J83CFEA0mVBVvJFGJXIQEZ/zmv46WWvdLBJnLCvgRQY1PJ/+5e56p9SEWKWxkWRsquhcqZT4q2GzQNmg+c9lH0NOUXup3q5+9bpeThQbusWRV3z/woRqewY1VTDFXQuOanBfufE/x5KEgfSKGoTw5kezZqokWgyIWq8GyMwureoIX07UuOhBvudkz3fETlfDRPVyEYbuDP8wKhqUYNEI1HOajjysTdaPSbHCzy6qQSskZ3gA42pAK3As8p81XC8yt5ul/jQgdQZj6T1h/Tq4RfUyeAaiNAzFWjNTw27zBb/eyg1AalBejnkSU/ACwQykBE1nEbczE0N+2wmnHxMMwf0z4ea5dRQAsWU5vTVNTSBK8OTyu6c1LD0jdnjfw9VwT+ZIPR6uhouQiYX5hq6QIZ0skCJtxpm3znx+/a4eguQUgMyUI5fD8kQBzcVXQ1nZHJmrkFGQiCdGBCeixqWF9lM+PiYppoC8jEa6EEm6p7GTecN09eQBLqk9wAELGoono/kOalhbZ29k0MPOVZTARKxSoeIykCHGkUEZqhBRlE15lGeg12k55DNhJOPaQp9XEZOkS5RM48CUQe1xttr+GN63bsDPPBfw8oP9o58x+RU2SBR4w64v4UUI7pHNKlJQUoOhF5VQ7IGWTC9fSLC/WuYxz5mYX73UFUAYpyIbjGm9JoamnmIMdOBReK9hl327vbIwdRqGmKbiLLpRwCGt8FX1BBSgDAZRNHnvYY9ZmF+91BCVwKicZtdpHJhouhriESBC4tVxvk0NZRnqME5Oyf+3x4nZO5EoHgqzLiZjilA7/kgakhtNEKlIsTI5Bra7fhDLFkAMuQU9m96m9c91IMITSpGZFeDGDURn2uI54FcXf9gH6nQ5BpkPKplyUHsd06zW98kx+kj3zK08JZnmKG/uB/7BQkDSoZsamhhKN0lB9pcZ+/O0ZcLi1cEMqsmZMNna+7CZBK+u6vTSOScxsSS5UwmVic9tdVKmi/8MRBokgN5Nti7cy8XxiXzzml27vWhuLWzyv5/++6FqXmwtM8+xOIWuZxua5F9EN8uuZxt18c+zoF7MulkKwfsY3ndS1M7lcfLPp73iFzOc+Rln2Pd736VgbOs+dfZJzrwr7hffeMMCyv+A/bpVhdP/NuetWW3is+xsLzm2fafLK6ymf0HG+uQI8Z5wW0AAAAASUVORK5CYII='; | |
addStyle($stageImage, { | |
width: MatrixStandRender.StageImageSize.width, | |
height: MatrixStandRender.StageImageSize.height, | |
margin: 'auto' | |
}); | |
this._$container.appendChild($stageImage); | |
} | |
/** | |
* 初始化Viewport | |
*/ | |
}, { | |
key: 'initViewport', | |
value: function initViewport() { | |
var areaSize = this._area.getSize(); | |
var ratio = areaSize.width / this._$container.clientWidth; | |
if (areaSize.height / this._$container.clientHeight > ratio) { | |
ratio = areaSize.height / this._$container.clientHeight; | |
} | |
this._viewport = new Viewport(this._$container.clientWidth, this._$container.clientHeight - MatrixStandRender.StageImageSize.height, areaSize.width, areaSize.height, { | |
ratio: ratio, | |
maxScaleRatio: ratio | |
}); | |
} | |
/** | |
* 初始化座位绘制canvas | |
*/ | |
}, { | |
key: 'initSeatCanvas', | |
value: function initSeatCanvas() { | |
var areaSize = this._area.getSize(); | |
// 创建座位canvas容器 | |
this._$seatCanvasContainer = document.createElement('div'); | |
addStyle(this._$seatCanvasContainer, { | |
width: this._$container.clientWidth, | |
height: this._$container.clientHeight - 20, | |
position: 'relative', | |
overflow: 'hidden' | |
}); | |
this._$container.appendChild(this._$seatCanvasContainer); | |
// 创建自定义Canvas类容器 | |
this._$seatCanvas = document.createElement('div'); | |
var scale = this._viewport.getScale(); | |
addStyle(this._$seatCanvas, { | |
position: 'relative', | |
left: -(areaSize.width * scale - this._$container.clientWidth) / 2, | |
top: -(areaSize.height * scale - this._$container.clientHeight) / 2 | |
}); | |
this._$seatCanvasContainer.appendChild(this._$seatCanvas); | |
// 初始化context绘图实例 | |
this._ctx = new Canvas(this._$seatCanvas, { | |
width: areaSize.width, | |
height: areaSize.height, | |
scale: scale, | |
standWidth: this._$container.clientWidth, | |
standHeight: this._$container.clientHeight | |
}); | |
} | |
/** | |
* 初始化Thumbnail | |
*/ | |
}, { | |
key: 'initThumbnail', | |
value: function initThumbnail() { | |
var areaSize = this._area.getSize(); | |
// 计算鹰眼图缩放 | |
var thumbnailScaleRatio = this._$container.clientWidth * 0.46 / areaSize.width; | |
if (areaSize.height * thumbnailScaleRatio > Thumbnail.ThumbnailCanvasMaxHeight) { | |
thumbnailScaleRatio = Thumbnail.ThumbnailCanvasMaxHeight / areaSize.height; | |
} | |
MatrixThumbnail.ScaleRatio = thumbnailScaleRatio; | |
// 创建鹰眼图容器div | |
this._$thumbnailContainer = document.createElement('div'); | |
this._$thumbnailContainer.className = 'select-seat-thumbnail'; | |
var LeftRightPadding = 16; | |
var width = areaSize.width * thumbnailScaleRatio + LeftRightPadding; | |
var stageImageHeight = width * 0.4 * 54 / 525; | |
var TopBottomPadding = 24 + stageImageHeight; | |
var height = areaSize.height * thumbnailScaleRatio + TopBottomPadding; | |
addStyle(this._$thumbnailContainer, { | |
display: 'none', | |
position: 'absolute', | |
top: 6, | |
right: 6, | |
borderRadius: 2, | |
backgroundColor: 'rgba(0, 0, 0, 0.6)', | |
pointerEvents: 'none', | |
overflow: 'hidden', | |
width: width, | |
height: height, | |
textAlign: 'center' | |
}); | |
this._$container.appendChild(this._$thumbnailContainer); | |
// 创建鹰眼图舞台方向图 | |
var $thumbnailStageImage = document.createElement('img'); | |
$thumbnailStageImage.src = ThumbnailStateBase64Image; | |
addStyle($thumbnailStageImage, { | |
width: '40%', | |
height: stageImageHeight, | |
position: 'absolute', | |
top: 0, | |
left: 0, | |
right: 0, | |
margin: 'auto' | |
}); | |
this._$thumbnailContainer.appendChild($thumbnailStageImage); | |
// 创建鹰眼图canvas | |
this._$thumbnailCanvas = createCanvas(areaSize.width * thumbnailScaleRatio, areaSize.height * thumbnailScaleRatio); | |
addStyle(this._$thumbnailCanvas, { | |
position: 'absolute', | |
top: (TopBottomPadding + stageImageHeight) / 2, | |
left: LeftRightPadding / 2 | |
}); | |
this._$thumbnailContainer.appendChild(this._$thumbnailCanvas); | |
this._thumbnail = new MatrixThumbnail(this._area, this._viewport, this._$thumbnailContainer, this, TopBottomPadding / 2 + 2, LeftRightPadding / 2); | |
this._thumbnailCtx = this._$thumbnailCanvas.getContext('2d'); | |
} | |
}, { | |
key: 'drawSeat', | |
/** | |
* 绘制座位 | |
*/ | |
value: function () { | |
var _ref2 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee() { | |
var viewportLeftTop, viewportRightBottom, seatSize; | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
viewportLeftTop = this._viewport.getLeftTopPoint(); | |
viewportRightBottom = this._viewport.getRightBottomPoint(); | |
seatSize = this._area.getSeatSize(); | |
_context.next = 5; | |
return this._area.draw(this._ctx, Math.floor(viewportLeftTop.y / seatSize.height), Math.floor(viewportLeftTop.x / seatSize.width), Math.ceil(viewportRightBottom.y / seatSize.height), Math.ceil(viewportRightBottom.x / seatSize.width)); | |
case 5: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, this); | |
})); | |
function drawSeat() { | |
return _ref2.apply(this, arguments); | |
} | |
return drawSeat; | |
}() | |
/** | |
* 绘制行号 | |
*/ | |
}, { | |
key: 'drawLineNumber', | |
value: function drawLineNumber() { | |
var scale = this._viewport.getScale(); | |
var seatHeight = this._area.getSeatSize().height * scale; | |
this._$lineNumberContainer = document.createElement('div'); | |
addStyle(this._$lineNumberContainer, { | |
width: 18, | |
height: this._$seatCanvasContainer.clientHeight - MatrixStandRender.LineNumberMargin * 2, | |
backgroundColor: 'rgba(0, 0, 0, 0.3)', | |
position: 'absolute', | |
left: 15, | |
top: MatrixStandRender.LineNumberMargin, | |
borderRadius: 9, | |
textAlign: 'center', | |
overflow: 'hidden', | |
pointerEvents: 'none', | |
display: seatHeight < 9 ? 'none' : 'block' | |
}); | |
var $numbers = document.createElement('div'); | |
addStyle($numbers, { | |
position: 'relative', | |
transform: 'translateY(' + (this._viewport.getLineNumberOffset() - MatrixStandRender.LineNumberMargin + MatrixStandRender.LineNumberOffset) + 'px)' | |
}); | |
var _area$getRowColumn = this._area.getRowColumn(), | |
row = _area$getRowColumn.row; | |
var hasNumber = false; | |
for (var i = 0; i < row; i++) { | |
var $line = document.createElement('div'); | |
addStyle($line, { | |
height: seatHeight, | |
color: 'rgba(255, 255, 255, 0.8)', | |
fontSize: 12, | |
lineHeight: seatHeight | |
}); | |
var rowSeat = this._area.getFirstSeatByRow(i); | |
if (rowSeat) { | |
var seatInfo = rowSeat.getInfo(); | |
// 座位排号可能不是纯数字, 取其中的数字部分 | |
var rowNumber = seatInfo.row.toString().replace(/[^0-9]/g, ''); | |
if (rowNumber) { | |
hasNumber = true; | |
} | |
$line.innerText = rowNumber; | |
} | |
$numbers.appendChild($line); | |
} | |
this._$lineNumbers = $numbers; | |
// 任一行行号不为空, 则显示行号 | |
if (hasNumber) { | |
this._$lineNumberContainer.appendChild($numbers); | |
this._$seatCanvasContainer.appendChild(this._$lineNumberContainer); | |
} | |
} | |
/** | |
* 更新行号 | |
* 仅在发生缩放时遍历dom节点修改 | |
* @param {Number} offset 纵向偏移值 | |
* @param {Number} scale 行高缩放值 | |
*/ | |
}, { | |
key: 'updateLineNumber', | |
value: function updateLineNumber(offset, scale) { | |
if (this._area.getSeatSize().height * this._viewport.getScale() < 9) { | |
addStyle(this._$lineNumberContainer, { | |
display: 'none' | |
}); | |
return; | |
} | |
addStyle(this._$lineNumberContainer, { | |
display: 'block' | |
}); | |
if (scale) { | |
var newHeight = this._area.getSeatSize().height * scale; | |
var _iteratorNormalCompletion = true; | |
var _didIteratorError = false; | |
var _iteratorError = undefined; | |
try { | |
for (var _iterator = this._$lineNumbers.children[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | |
var $line = _step.value; | |
addStyle($line, { | |
height: newHeight, | |
lineHeight: newHeight | |
}); | |
} | |
} catch (err) { | |
_didIteratorError = true; | |
_iteratorError = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion && _iterator.return) { | |
_iterator.return(); | |
} | |
} finally { | |
if (_didIteratorError) { | |
throw _iteratorError; | |
} | |
} | |
} | |
} | |
addStyle(this._$lineNumbers, { | |
transform: 'translateY(' + (offset - MatrixStandRender.LineNumberMargin + MatrixStandRender.LineNumberOffset) + 'px)' | |
}); | |
} | |
/** | |
* 渲染普通选座 | |
* @param {Array} seatData 座位静态数据 | |
* @param {Array} seatStatus 座位动态数据 | |
* @param {Object} seatChineseName 座位中文排号 | |
* @param {Array} priceList 票价列表 | |
* @param {Number} maxPickNumber 座位最大可选个数 | |
*/ | |
}, { | |
key: 'render', | |
value: function render(seatData, seatStatus, seatChineseName, priceList, maxPickNumber) { | |
this._maxPickNumber = maxPickNumber; | |
var seatStatusMap = {}; | |
var _iteratorNormalCompletion2 = true; | |
var _didIteratorError2 = false; | |
var _iteratorError2 = undefined; | |
try { | |
for (var _iterator2 = seatStatus.seat[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | |
var seat = _step2.value; | |
seatStatusMap[seat.sid] = seat.s; | |
} | |
} catch (err) { | |
_didIteratorError2 = true; | |
_iteratorError2 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion2 && _iterator2.return) { | |
_iterator2.return(); | |
} | |
} finally { | |
if (_didIteratorError2) { | |
throw _iteratorError2; | |
} | |
} | |
} | |
var Parser = new MatrixSeatParser(seatData); | |
var seatsInfo = Parser.parse(seatStatusMap); | |
this.init(seatsInfo.row, seatsInfo.column); | |
for (var i = 0; i < seatsInfo.row; i++) { | |
for (var j = 0; j < seatsInfo.column; j++) { | |
if (seatsInfo.seats[i] && seatsInfo.seats[i][j]) { | |
var _seat = seatsInfo.seats[i][j]; | |
this._area.addSeat(i, j, { | |
id: _seat.sid, | |
status: _seat.s, | |
row: _seat.rn, | |
column: _seat.sn, | |
color: priceList[_seat.priceIndex] && priceList[_seat.priceIndex].c, | |
floor: _seat.floor, | |
priceIndex: _seat.priceIndex, | |
chinese: _seat.isChinese ? seatChineseName[_seat.sid] : '', | |
isPackage: _seat.isPackage, | |
packagePriceIndex: _seat.packagePriceIndex, | |
packageCombinedId: _seat.packageCombinedId | |
}); | |
} | |
} | |
} | |
this.drawSeat(); | |
this.drawLineNumber(); | |
this.drawThumbnail(); | |
} | |
/* ========== 对外暴露方法 start =========== */ | |
/** | |
* 高亮指定票价 | |
* @param {Number} priceIndex 票价索引 | |
*/ | |
/** | |
* 选中座位 | |
* @param {Number} seatId 座位id | |
*/ | |
/** | |
* 更新当前看台最大可选座位数量 | |
* @param {Number} newValue 新数量 | |
*/ | |
}, { | |
key: 'destroy', | |
value: function destroy() { | |
get(MatrixStandRender.prototype.__proto__ || Object.getPrototypeOf(MatrixStandRender.prototype), 'destroy', this).call(this); | |
this._$seatCanvasContainer.removeEventListener('touchstart', this.onTouchStart); | |
this._$seatCanvasContainer.removeEventListener('touchmove', this.onTouchMove); | |
this._$seatCanvasContainer.removeEventListener('touchend', this.onTouchEnd); | |
this._thumbnailCtx = null; | |
this._$lineNumbers = null; | |
this._$lineNumberContainer = null; | |
this._$seatCanvasContainer = null; | |
this._$thumbnailCanvas = null; | |
this._$container.innerHTML = ''; | |
} | |
/* ========== 对外暴露方法 end =========== */ | |
}]); | |
return MatrixStandRender; | |
}(StandRender), _class.LineNumberMargin = 15, _class.LineNumberOffset = 9, _class.StageImageSize = { | |
width: 175, | |
height: 18 | |
}, _temp2); | |
/* eslint-disable */ | |
// iconfont仓库: http://iconfont.cn/manage/index?manage_type=myprojects&projectId=879101 | |
if (Util.isPC) { | |
(function (window) { | |
var svgSprite = '<svg><symbol id="icon-reset" viewBox="0 0 1024 1024"><path d="M947.346286 274.139429c-3.291429 14.116571-14.848 23.04-30.793143 23.04H725.284571c-19.163429 0-31.890286-12.726857-31.890285-31.817143 0-19.163429 12.726857-31.890286 31.890285-31.890286h130.340572a444.854857 444.854857 0 0 0-82.578286-79.725714C616.886857 32.768 390.656 35.84 234.496 157.037714 5.046857 335.433143 5.046857 679.643429 231.277714 867.620571c153.014857 121.124571 376.100571 127.488 535.405715 12.8a456.923429 456.923429 0 0 0 114.761142-121.124571c3.145143-9.508571 15.945143-15.945143 25.453715-15.945143 25.526857 0 41.472 25.526857 28.672 47.835429a467.968 467.968 0 0 1-114.688 124.269714c-181.686857 140.214857-442.953143 140.214857-624.64-3.218286-270.921143-210.285714-261.339429-624.64 28.672-825.344 168.96-117.979429 401.554286-114.761143 573.659428 3.145143 32.768 22.893714 61.293714 48.347429 86.016 75.483429v-91.428572c0-15.945143 12.8-31.817143 31.890286-31.817143s31.890286 12.726857 31.890286 31.817143v179.565715a30.72 30.72 0 0 1-1.024 20.48z" fill="#4A4A4A" ></path></symbol><symbol id="icon-zoom-out" viewBox="0 0 1024 1024"><path d="M475.428571 475.428571v-438.857142a36.571429 36.571429 0 0 1 73.142858 0v438.857142h438.857142a36.571429 36.571429 0 1 1 0 73.142858h-438.857142v438.857142a36.571429 36.571429 0 1 1-73.142858 0v-438.857142h-438.857142a36.571429 36.571429 0 0 1 0-73.142858h438.857142z" fill="#4A4A4A" ></path></symbol><symbol id="icon-toggle" viewBox="0 0 1024 1024"><path d="M520.557714 122.221714L170.422857 533.796571l348.598857 363.593143-50.102857 52.297143L73.142857 536.868571 467.529143 73.142857l53.028571 49.078857z m430.299429 0L600.795429 533.796571l348.598857 363.593143-50.102857 52.297143L503.442286 536.868571 897.828571 73.142857l53.028572 49.078857z" fill="#515151" ></path></symbol><symbol id="icon-zoom-in" viewBox="0 0 1024 1024"><path d="M0 475.428571m36.571429 0l950.857142 0q36.571429 0 36.571429 36.571429l0 0q0 36.571429-36.571429 36.571429l-950.857142 0q-36.571429 0-36.571429-36.571429l0 0q0-36.571429 36.571429-36.571429Z" fill="#4A4A4A" ></path></symbol></svg>'; | |
var script = function () { | |
var scripts = document.getElementsByTagName("script"); | |
return scripts[scripts.length - 1]; | |
}(); | |
var shouldInjectCss = script.getAttribute("data-injectcss"); | |
var ready = function ready(fn) { | |
if (document.addEventListener) { | |
if (~["complete", "loaded", "interactive"].indexOf(document.readyState)) { | |
setTimeout(fn, 0); | |
} else { | |
var loadFn = function loadFn() { | |
document.removeEventListener("DOMContentLoaded", loadFn, false); | |
fn(); | |
}; | |
document.addEventListener("DOMContentLoaded", loadFn, false); | |
} | |
} else if (document.attachEvent) { | |
IEContentLoaded(window, fn); | |
} | |
function IEContentLoaded(w, fn) { | |
var d = w.document, | |
done = false, | |
init = function init() { | |
if (!done) { | |
done = true; | |
fn(); | |
} | |
}; | |
var polling = function polling() { | |
try { | |
d.documentElement.doScroll("left"); | |
} catch (e) { | |
setTimeout(polling, 50); | |
return; | |
} | |
init(); | |
}; | |
polling(); | |
d.onreadystatechange = function () { | |
if (d.readyState == "complete") { | |
d.onreadystatechange = null; | |
init(); | |
} | |
}; | |
} | |
}; | |
var before = function before(el, target) { | |
target.parentNode.insertBefore(el, target); | |
}; | |
var prepend = function prepend(el, target) { | |
if (target.firstChild) { | |
before(el, target.firstChild); | |
} else { | |
target.appendChild(el); | |
} | |
}; | |
function appendSvg() { | |
var div, svg; | |
div = document.createElement("div"); | |
div.innerHTML = svgSprite; | |
svgSprite = null; | |
svg = div.getElementsByTagName("svg")[0]; | |
if (svg) { | |
svg.setAttribute("aria-hidden", "true"); | |
svg.style.position = "absolute"; | |
svg.style.width = 0; | |
svg.style.height = 0; | |
svg.style.overflow = "hidden"; | |
prepend(svg, document.body); | |
} | |
} | |
if (shouldInjectCss && !window.__iconfont__svg__cssinject__) { | |
window.__iconfont__svg__cssinject__ = true; | |
try { | |
document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>"); | |
} catch (e) { | |
} | |
} | |
ready(appendSvg); | |
})(window); | |
} | |
var _class$11; | |
var _temp$7; | |
var BBCThumbnail = (_temp$7 = _class$11 = function (_Thumbnail) { | |
inherits(BBCThumbnail, _Thumbnail); | |
createClass(BBCThumbnail, null, [{ | |
key: 'createButton', | |
/** | |
* 创建按钮dom | |
* @param {String} iconName css类名 | |
* @param {Function} onClick 点击回调 | |
*/ | |
// 鹰眼图缩放倍率 | |
value: function createButton(iconName, onClick) { | |
var $button = document.createElement('div'); | |
$button.className = 'thumbnail-button ' + iconName; | |
$button.innerHTML = '\n <svg class="dmss-icon" aria-hidden="true">\n <use xlink:href="#icon-' + iconName + '"></use>\n </svg>\n '; | |
addStyle($button, { | |
width: 30, | |
height: 30, | |
textAlign: 'center', | |
lineHeight: '30', | |
cursor: 'pointer', | |
borderBottom: '1px solid #DFDFDF', | |
borderLeft: '1px solid #DFDFDF', | |
userSelect: 'none' | |
}); | |
var stopPropagation = function stopPropagation(e) { | |
return e.stopPropagation(); | |
}; | |
var handleClick = function handleClick(e) { | |
e.stopPropagation(); | |
onClick(); | |
}; | |
if (UA.isPC) { | |
$button.onmousedown = handleClick; | |
$button.onmousemove = stopPropagation; | |
$button.onmouseup = stopPropagation; | |
} else { | |
$button.ontouchstart = handleClick; | |
$button.ontouchmove = stopPropagation; | |
$button.ontouchend = stopPropagation; | |
} | |
return $button; | |
} | |
// StandRender实例 | |
// Area实例 | |
// 鹰眼图按钮容器div | |
}]); | |
/** | |
* 构造函数 | |
* @param {StandRender} standRender StandRender实例 | |
* @param {Dom} $container 鹰眼图容器div | |
* @param {Dom} $buttonContainer 按钮容器div | |
*/ | |
function BBCThumbnail(standRender, $container, $buttonContainer) { | |
classCallCheck(this, BBCThumbnail); | |
var _this = possibleConstructorReturn(this, (BBCThumbnail.__proto__ || Object.getPrototypeOf(BBCThumbnail)).call(this, standRender._viewport, $container)); | |
_this._area = null; | |
_this._standRender = null; | |
_this._$buttonContainer = null; | |
_this._standRender = standRender; | |
_this._$buttonContainer = $buttonContainer; | |
_this._lineBoxTopOffset = BBCThumbnailMargin; | |
_this._lineBoxLeftOffset = BBCThumbnailMargin; | |
return _this; | |
} | |
/** | |
* 绘制鹰眼图 | |
* @param {Context} ctx canvas context | |
*/ | |
createClass(BBCThumbnail, [{ | |
key: 'draw', | |
value: function draw(ctx) { | |
// renderMode, 接口返回, 3: 鹰眼图绘制座位 其他: 不处理 | |
if (this._standRender._renderMode === 3) { | |
this._standRender._area.drawThumbnail(ctx); | |
} | |
this.drawLineBox(BBCThumbnail.ScaleRatio); | |
if (UA.isPC) { | |
this.drawButtonList(); | |
} | |
} | |
/** | |
* 绘制功能按钮列表 | |
*/ | |
}, { | |
key: 'drawButtonList', | |
value: function drawButtonList() { | |
var _this2 = this; | |
var $style = document.createElement('style'); | |
$style.setAttribute('type', 'text/css'); | |
$style.innerHTML = '\n .dmss-icon {\n width: 16px; height: 16px;\n vertical-align: -0.15em;\n fill: currentColor;\n overflow: hidden;\n }\n '; | |
document.body.appendChild($style); | |
// 重置视口 | |
var $resetViewport = BBCThumbnail.createButton('reset', function () { | |
return _this2._standRender.gotoInitialView(); | |
}); | |
this._$buttonContainer.appendChild($resetViewport); | |
// 放大 | |
var $zoomOut = BBCThumbnail.createButton('zoom-out', function () { | |
_this2._standRender._viewport.scale(-0.4); | |
_this2._standRender._ctx.setScale(_this2._viewport.getScale); | |
_this2._standRender.updateView(true); | |
}); | |
this._$buttonContainer.appendChild($zoomOut); | |
// 缩小 | |
var $zoomIn = BBCThumbnail.createButton('zoom-in', function () { | |
_this2._standRender._viewport.scale(0.4); | |
_this2._standRender._ctx.setScale(_this2._viewport.getScale); | |
_this2._standRender.updateView(true); | |
}); | |
this._$buttonContainer.appendChild($zoomIn); | |
// 打开/收起鹰眼图 | |
var $toggle = BBCThumbnail.createButton('toggle', function () { | |
var translate = _this2._$container.style.transform.match(/translateX\(([0-9]+)px\)/); | |
translate = parseInt(translate && translate[1], 10) || 0; | |
var newTranslate = translate === 0 ? parseInt(_this2._$container.style.width, 10) + 30 : 0; | |
addStyle(_this2._$container, { | |
transform: 'translateX(' + newTranslate + 'px)' | |
}); | |
var $svg = $toggle.childNodes[1]; | |
$svg.style.transform = translate === 0 ? 'rotate(0deg)' : 'rotate(180deg)'; | |
}); | |
var $svg = $toggle.childNodes[1]; | |
$svg.style.transform = 'rotate(180deg)'; | |
$svg.style.transition = 'all 0.2s'; | |
this._$buttonContainer.appendChild($toggle); | |
} | |
}, { | |
key: 'update', | |
value: function update() { | |
get(BBCThumbnail.prototype.__proto__ || Object.getPrototypeOf(BBCThumbnail.prototype), 'update', this).call(this, BBCThumbnail.ScaleRatio); | |
} | |
// 中网BBC PC选座, 不需要自动关闭鹰眼图的逻辑 | |
}, { | |
key: 'show', | |
value: function show() { | |
if (!UA.isPC) { | |
get(BBCThumbnail.prototype.__proto__ || Object.getPrototypeOf(BBCThumbnail.prototype), 'show', this).call(this); | |
} | |
} | |
}, { | |
key: 'hide', | |
value: function hide() { | |
if (!UA.isPC) { | |
get(BBCThumbnail.prototype.__proto__ || Object.getPrototypeOf(BBCThumbnail.prototype), 'hide', this).call(this); | |
} | |
} | |
}]); | |
return BBCThumbnail; | |
}(Thumbnail), _class$11.ScaleRatio = 1, _temp$7); | |
var _class$10; | |
var _temp2$3; | |
var BBCSeat = (_temp2$3 = _class$10 = function (_Seat) { | |
inherits(BBCSeat, _Seat); | |
function BBCSeat() { | |
var _ref; | |
var _temp, _this, _ret; | |
classCallCheck(this, BBCSeat); | |
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | |
args[_key] = arguments[_key]; | |
} | |
return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref = BBCSeat.__proto__ || Object.getPrototypeOf(BBCSeat)).call.apply(_ref, [this].concat(args))), _this), _this._thumbnailCtx = null, _temp), possibleConstructorReturn(_this, _ret); | |
} | |
// 座位样式, 中网BBC项目默认用圆形 | |
createClass(BBCSeat, [{ | |
key: 'setThumbnailContext', | |
value: function setThumbnailContext(thumbnailCtx) { | |
this._thumbnailCtx = thumbnailCtx; | |
} | |
/** | |
* 绘制座位 | |
*/ | |
}, { | |
key: 'draw', | |
value: function () { | |
var _ref2 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee() { | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
_context.next = 2; | |
return get(BBCSeat.prototype.__proto__ || Object.getPrototypeOf(BBCSeat.prototype), 'draw', this).call(this, BBCSeat._useStyle, BBCSeat.SeatSize * Util.ShareData.SVGRenderScale); | |
case 2: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, this); | |
})); | |
function draw() { | |
return _ref2.apply(this, arguments); | |
} | |
return draw; | |
}() | |
/** | |
* 绘制鹰眼图座位 | |
*/ | |
}, { | |
key: 'drawThumbnail', | |
value: function () { | |
var _ref3 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee2() { | |
var image, scale, seatSize; | |
return regeneratorRuntime.wrap(function _callee2$(_context2) { | |
while (1) { | |
switch (_context2.prev = _context2.next) { | |
case 0: | |
if (this._thumbnailCtx) { | |
_context2.next = 2; | |
break; | |
} | |
throw Error('thumbnailCtx为空, 请先调用setThumbnailContext'); | |
case 2: | |
_context2.next = 4; | |
return this.getSeatImage(); | |
case 4: | |
image = _context2.sent; | |
scale = BBCThumbnail.ScaleRatio; | |
seatSize = (Math.round(BBCSeat.SeatSize * scale) || 1) * 2; // 放大一倍绘制, 不然看不清 | |
this._thumbnailCtx.drawImage(image, this._x * scale, this._y * scale, seatSize, seatSize); | |
case 8: | |
case 'end': | |
return _context2.stop(); | |
} | |
} | |
}, _callee2, this); | |
})); | |
function drawThumbnail() { | |
return _ref3.apply(this, arguments); | |
} | |
return drawThumbnail; | |
}() | |
}], [{ | |
key: 'setStyle', | |
// 设置要使用的座位样式 | |
value: function setStyle(style) { | |
BBCSeat._useStyle = style; | |
} | |
// 座位大小, 固定值24是由后端数据决定的 | |
// 之前是18px | |
// 座位缩略图画板 | |
}]); | |
return BBCSeat; | |
}(Seat), _class$10._useStyle = Seat.Style.Circle, _class$10.SeatSize = 24, _temp2$3); | |
var BBCArea = function (_Area) { | |
inherits(BBCArea, _Area); | |
function BBCArea() { | |
var _ref; | |
var _temp, _this, _ret; | |
classCallCheck(this, BBCArea); | |
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | |
args[_key] = arguments[_key]; | |
} | |
return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref = BBCArea.__proto__ || Object.getPrototypeOf(BBCArea)).call.apply(_ref, [this].concat(args))), _this), _this._drewLinkPackageSet = new Set(), _temp), possibleConstructorReturn(_this, _ret); | |
} | |
// 已经画过连线的套票组id集合 | |
createClass(BBCArea, [{ | |
key: 'addSeat', | |
/** | |
* 添加座位 | |
* @param {Number} row 座位所在行数 | |
* @param {Number} column 座位所在列数 | |
* @param {Object} seatInfo 座位信息 | |
* @param {Number} seatStyle 座位样式(3:沙发, 其它:圆) | |
*/ | |
value: function addSeat(row, column, seatInfo, seatStyle) { | |
if (row < 0 || row >= this._row || column < 0 || column >= this._column) { | |
// console.warn('超出场馆区域', '座位位置', row, column, '场馆大小', this._row, this._column); | |
return; | |
} | |
var seat = new BBCSeat(row, column, seatInfo); | |
// 如果接口返回3, 则座位显示为沙发. TODO:该方法应该只调用一次, 放这里不合适 | |
if (seatStyle === 3) { | |
BBCSeat.setStyle(Seat.Style.Sofa); | |
} | |
// 如果该座位可售, 且票价索引不是高亮的, 则将座位置为半透明 | |
if (seatInfo.status === 2 && this._priceIndex !== -1 && this._priceIndex !== seatInfo.priceIndex) { | |
seat.opacity(); | |
} | |
this._map[row] = this._map[row] || {}; | |
this._map[row][column] = seat; | |
if (seat.canBuy) { | |
// 按票价索引分组 | |
this._prices[seatInfo.priceIndex] = this._prices[seatInfo.priceIndex] || { | |
seats: [], | |
highlight: this._priceIndex === -1 || this._priceIndex === seatInfo.priceIndex // 判断当前组是否要高亮 | |
}; | |
this._prices[seatInfo.priceIndex].seats.push(seat); | |
} | |
// 按套票ID分组 | |
if (seatInfo.isPackage) { | |
var packageCombinedId = seatInfo.packageCombinedId; | |
this._packages[packageCombinedId] = this._packages[packageCombinedId] || []; | |
this._packages[packageCombinedId].push(seat); | |
} | |
} | |
/** | |
* 绘制区域内可见座位 | |
* @param {Context} ctx canvas context | |
* @param {Number} startRow 显示区域起始行 | |
* @param {Number} startColumn 显示区域起始列 | |
* @param {Number} endRow 显示区域结束行 | |
* @param {Number} endColumn 显示区域结束列 | |
*/ | |
}, { | |
key: 'draw', | |
value: function draw(ctx, startRow, startColumn, endRow, endColumn) { | |
var _this2 = this; | |
var SeatSize = BBCSeat.SeatSize; | |
var seatIterator = this.generateSeatsIterator(Math.ceil(startRow - SeatSize), Math.ceil(startColumn - SeatSize), Math.ceil(endRow), Math.ceil(endColumn)); | |
var groupId = 0; | |
var renderGroup = defineProperty({}, groupId, []); | |
var allSeats = []; | |
var _iteratorNormalCompletion = true; | |
var _didIteratorError = false; | |
var _iteratorError = undefined; | |
try { | |
for (var _iterator = seatIterator[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | |
var _ref2 = _step.value; | |
var seat = _ref2.seat; | |
if (seat.isDraw) { | |
continue; | |
} | |
seat.setContext(ctx); | |
// 如果直接同步绘制座位的话, 会将cpu线程占满, 导致无法响应dom事件, 因此拖动时感觉就很卡 | |
// 将座位每15个分一组, 按组异步绘制 | |
renderGroup[groupId].push(seat); | |
if (renderGroup[groupId].length >= 15) { | |
groupId++; | |
renderGroup[groupId] = []; | |
} | |
allSeats.push(seat); | |
} | |
// 在座位绘制之前,优先绘制套票座位连线 | |
} catch (err) { | |
_didIteratorError = true; | |
_iteratorError = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion && _iterator.return) { | |
_iterator.return(); | |
} | |
} finally { | |
if (_didIteratorError) { | |
throw _iteratorError; | |
} | |
} | |
} | |
var packageSeats = allSeats.filter(function (seat) { | |
var _seat$getInfo = seat.getInfo(), | |
isPackage = _seat$getInfo.isPackage; | |
return isPackage; | |
}); | |
var packageSeatGroup = {}; | |
packageSeats.forEach(function (seat) { | |
var _seat$getInfo2 = seat.getInfo(), | |
groupid = _seat$getInfo2.groupid; | |
if (!_this2._drewLinkPackageSet.has(groupid) // 没画过线的套票才绘制 | |
&& | |
packageSeatGroup[groupid] === undefined // 已经处理过的组不用再次处理 | |
) { | |
_this2._drewLinkPackageSet.add(groupid); | |
packageSeatGroup[groupid] = _this2._packages[groupid].map(function (_ref3) { | |
var isPackage = _ref3.isPackage, | |
x = _ref3._x, | |
y = _ref3._y; | |
return { | |
isPackage: isPackage, | |
groupid: groupid, | |
x: x, | |
y: y | |
}; | |
}); | |
// 按x y座位排序 | |
packageSeatGroup[groupid].sort(function (a, b) { | |
if (a.x < b.x) { | |
return -1; | |
} else if (a.x > b.x) { | |
return 1; | |
} else if (a.y < b.y) { | |
return -1; | |
} else if (a.y > b.y) { | |
return 1; | |
} | |
return -1; | |
}); | |
} | |
}); | |
Object.values(packageSeatGroup).forEach(function (seatGroup) { | |
return ctx.drawLine(seatGroup, BBCSeat.SeatSize * Util.ShareData.SVGRenderScale); | |
}); | |
// 绘制每一组, 每组均setTimeout 0转异步, 来尽量使dom事件可以被响应 | |
var _loop = function _loop(seats) { | |
setTimeout(function () { | |
for (var i = 0; i < seats.length; i++) { | |
seats[i].draw(); | |
} | |
}, 0); | |
}; | |
var _iteratorNormalCompletion2 = true; | |
var _didIteratorError2 = false; | |
var _iteratorError2 = undefined; | |
try { | |
for (var _iterator2 = Object.values(renderGroup)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | |
var seats = _step2.value; | |
_loop(seats); | |
} | |
} catch (err) { | |
_didIteratorError2 = true; | |
_iteratorError2 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion2 && _iterator2.return) { | |
_iterator2.return(); | |
} | |
} finally { | |
if (_didIteratorError2) { | |
throw _iteratorError2; | |
} | |
} | |
} | |
if (window.onTrcker && window.selectSeatTiming.clickStandTime) { | |
window.onTrcker({ | |
type: 'clickStandRenderTime', | |
c1: Date.now() - window.selectSeatTiming.clickStandTime | |
}); | |
} | |
} | |
/** | |
* 绘制区域内所有座位 | |
* @param {Context} ctx canvas context | |
*/ | |
}, { | |
key: 'drawThumbnail', | |
value: function drawThumbnail(ctx) { | |
var seatIterator = this.generateSeatsIterator(0, 0, this._row, this._column); | |
var _iteratorNormalCompletion3 = true; | |
var _didIteratorError3 = false; | |
var _iteratorError3 = undefined; | |
try { | |
for (var _iterator3 = seatIterator[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { | |
var _ref4 = _step3.value; | |
var seat = _ref4.seat; | |
seat.setThumbnailContext(ctx); | |
seat.drawThumbnail(); | |
} | |
} catch (err) { | |
_didIteratorError3 = true; | |
_iteratorError3 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion3 && _iterator3.return) { | |
_iterator3.return(); | |
} | |
} finally { | |
if (_didIteratorError3) { | |
throw _iteratorError3; | |
} | |
} | |
} | |
} | |
/** | |
* 获取区域尺寸(px) | |
*/ | |
}, { | |
key: 'getSize', | |
value: function getSize() { | |
return { | |
width: this._row, | |
height: this._column | |
}; | |
} | |
/** | |
* 处理座位点击事件 | |
* @param {Context} ctx 绘图context | |
* @param {Object} point 点击位置 | |
*/ | |
}, { | |
key: 'handleClick', | |
value: function () { | |
var _ref5 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee(ctx, point) { | |
var x, y, SeatSize, seatIterator, _iteratorNormalCompletion4, _didIteratorError4, _iteratorError4, _iterator4, _step4, _ref6, seat; | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
x = Math.ceil(point.x); | |
y = Math.ceil(point.y); | |
SeatSize = BBCSeat.SeatSize * Util.ShareData.SVGRenderScale; | |
seatIterator = this.generateSeatsIterator(x - SeatSize, y - SeatSize, x, y); | |
_iteratorNormalCompletion4 = true; | |
_didIteratorError4 = false; | |
_iteratorError4 = undefined; | |
_context.prev = 7; | |
_iterator4 = seatIterator[Symbol.iterator](); | |
case 9: | |
if (_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done) { | |
_context.next = 25; | |
break; | |
} | |
_ref6 = _step4.value; | |
seat = _ref6.seat; | |
if (!seat.canBuy) { | |
_context.next = 21; | |
break; | |
} | |
if (!seat.isSelect) { | |
_context.next = 18; | |
break; | |
} | |
_context.next = 16; | |
return seat.cancelSelect(); | |
case 16: | |
_context.next = 20; | |
break; | |
case 18: | |
_context.next = 20; | |
return seat.select(); | |
case 20: | |
this.emitSeatSelectEvent(seat); | |
case 21: | |
return _context.abrupt('return'); | |
case 22: | |
_iteratorNormalCompletion4 = true; | |
_context.next = 9; | |
break; | |
case 25: | |
_context.next = 31; | |
break; | |
case 27: | |
_context.prev = 27; | |
_context.t0 = _context['catch'](7); | |
_didIteratorError4 = true; | |
_iteratorError4 = _context.t0; | |
case 31: | |
_context.prev = 31; | |
_context.prev = 32; | |
if (!_iteratorNormalCompletion4 && _iterator4.return) { | |
_iterator4.return(); | |
} | |
case 34: | |
_context.prev = 34; | |
if (!_didIteratorError4) { | |
_context.next = 37; | |
break; | |
} | |
throw _iteratorError4; | |
case 37: | |
return _context.finish(34); | |
case 38: | |
return _context.finish(31); | |
case 39: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, this, [ | |
[7, 27, 31, 39], | |
[32, , 34, 38] | |
]); | |
})); | |
function handleClick(_x, _x2) { | |
return _ref5.apply(this, arguments); | |
} | |
return handleClick; | |
}() | |
/** | |
* 按照对应规则选中某个范围内的座位 | |
* @param {Number} rangeLeftX 范围左侧的横坐标 | |
* @param {Number} rangeRightX 范围右侧的横坐标 | |
* @param {Number} rangeTopY 范围顶部的纵坐标 | |
* @param {Number} rangeBottomY 范围底部的纵坐标 | |
*/ | |
// selectRangeSeats(rangeLeftX, rangeRightX, rangeTopY, rangeBottomY) { | |
// rangeLeftX = Math.ceil(rangeLeftX); | |
// rangeRightX = Math.ceil(rangeRightX); | |
// rangeTopY = Math.ceil(rangeTopY); | |
// rangeBottomY = Math.ceil(rangeBottomY); | |
// const seatIterator = this.generateSeatsIterator(Math.min(rangeLeftX, rangeRightX), Math.min(rangeTopY, rangeBottomY), Math.max(rangeLeftX, rangeRightX), Math.max(rangeTopY, rangeBottomY)); | |
// // 范围内的座位为全部选中则取消选中范围内的座位 | |
// // 范围内的座位如有未选中座位,则选中未选中座位,已选中座位依然为选中状态 | |
// const rangedSeats = []; | |
// let hasUnselectedSeat = true; | |
// for (const { seat } of seatIterator) { | |
// if (seat.canBuy) { | |
// rangedSeats.push(seat); | |
// hasUnselectedSeat = hasUnselectedSeat && !seat.isSelect; | |
// } | |
// } | |
// rangedSeats.forEach(seat => { | |
// if (hasUnselectedSeat) { | |
// if (seat.isSelect) { | |
// seat.cancelSelect(); | |
// } else { | |
// seat.select(); | |
// } | |
// } else { | |
// seat.cancelSelect(); | |
// } | |
// this.emitSeatSelectEvent(seat); | |
// }); | |
// } | |
/** | |
* 获取指定位置座位, 没有返回null | |
* @param {Object} point 坐标 | |
*/ | |
}, { | |
key: 'getSeat', | |
value: function getSeat(point) { | |
var x = Math.ceil(point.x); | |
var y = Math.ceil(point.y); | |
var SeatSize = BBCSeat.SeatSize * Util.ShareData.SVGRenderScale; | |
var seatIterator = this.generateSeatsIterator(x - SeatSize, y - SeatSize, x, y); | |
var _iteratorNormalCompletion5 = true; | |
var _didIteratorError5 = false; | |
var _iteratorError5 = undefined; | |
try { | |
for (var _iterator5 = seatIterator[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { | |
var _ref7 = _step5.value; | |
var seat = _ref7.seat; | |
return seat; | |
} | |
} catch (err) { | |
_didIteratorError5 = true; | |
_iteratorError5 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion5 && _iterator5.return) { | |
_iterator5.return(); | |
} | |
} finally { | |
if (_didIteratorError5) { | |
throw _iteratorError5; | |
} | |
} | |
} | |
return null; | |
} | |
/** | |
* 获取指定票价的可售座位包围矩形 | |
* @param {number} priceIndex 票价索引 | |
*/ | |
}, { | |
key: 'getAvaliableSeatBoundingRectByPrice', | |
value: function getAvaliableSeatBoundingRectByPrice(priceIndex) { | |
var _ref8 = [this._column, 0, 0, this._row], | |
top = _ref8[0], | |
right = _ref8[1], | |
bottom = _ref8[2], | |
left = _ref8[3]; | |
var seats = this._prices[priceIndex] && this._prices[priceIndex].seats; | |
// 可售座位大于等于10个, 回全局视口 | |
if (seats && seats.filter(function (s) { | |
return s.canBuy; | |
}).length > 10) { | |
return null; | |
} | |
if (seats && seats.length > 0) { | |
var _iteratorNormalCompletion6 = true; | |
var _didIteratorError6 = false; | |
var _iteratorError6 = undefined; | |
try { | |
for (var _iterator6 = seats[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { | |
var seat = _step6.value; | |
if (!seat.canBuy) { | |
continue; | |
} | |
if (seat._x > right) { | |
right = seat._x; | |
} | |
if (seat._x < left) { | |
left = seat._x; | |
} | |
if (seat._y > bottom) { | |
bottom = seat._y; | |
} | |
if (seat._y < top) { | |
top = seat._y; | |
} | |
} | |
} catch (err) { | |
_didIteratorError6 = true; | |
_iteratorError6 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion6 && _iterator6.return) { | |
_iterator6.return(); | |
} | |
} finally { | |
if (_didIteratorError6) { | |
throw _iteratorError6; | |
} | |
} | |
} | |
return { | |
top: top, | |
right: right, | |
bottom: bottom, | |
left: left | |
}; | |
} | |
return null; | |
} | |
}, { | |
key: 'handleCanvasDispose', | |
value: function handleCanvasDispose(_ref9) { | |
var row = _ref9.row, | |
column = _ref9.column; | |
var seatIterator = this.generateSeatsIterator(column * SingleCanvasSize - BBCSeat.SeatSize, row * SingleCanvasSize - BBCSeat.SeatSize, (column + 1) * SingleCanvasSize, (row + 1) * SingleCanvasSize); | |
var _iteratorNormalCompletion7 = true; | |
var _didIteratorError7 = false; | |
var _iteratorError7 = undefined; | |
try { | |
for (var _iterator7 = seatIterator[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { | |
var _ref10 = _step7.value; | |
var seat = _ref10.seat; | |
if (seat.isDraw) { | |
seat.isDraw = false; | |
} | |
} | |
} catch (err) { | |
_didIteratorError7 = true; | |
_iteratorError7 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion7 && _iterator7.return) { | |
_iterator7.return(); | |
} | |
} finally { | |
if (_didIteratorError7) { | |
throw _iteratorError7; | |
} | |
} | |
} | |
} | |
}]); | |
return BBCArea; | |
}(Area); | |
var _class$9; | |
function _applyDecoratedDescriptor$1(target, property, decorators, descriptor, context) { | |
var desc = {}; | |
Object['ke' + 'ys'](descriptor).forEach(function (key) { | |
desc[key] = descriptor[key]; | |
}); | |
desc.enumerable = !!desc.enumerable; | |
desc.configurable = !!desc.configurable; | |
if ('value' in desc || desc.initializer) { | |
desc.writable = true; | |
} | |
desc = decorators.slice().reverse().reduce(function (desc, decorator) { | |
return decorator(target, property, desc) || desc; | |
}, desc); | |
if (context && desc.initializer !== void 0) { | |
desc.value = desc.initializer ? desc.initializer.call(context) : void 0; | |
desc.initializer = undefined; | |
} | |
if (desc.initializer === void 0) { | |
Object['define' + 'Property'](target, property, desc); | |
desc = null; | |
} | |
return desc; | |
} | |
var BBCStandRender = (_class$9 = function (_StandRender) { | |
inherits(BBCStandRender, _StandRender); | |
function BBCStandRender() { | |
var _ref; | |
var _temp, _this, _ret; | |
classCallCheck(this, BBCStandRender); | |
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | |
args[_key] = arguments[_key]; | |
} | |
return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref = BBCStandRender.__proto__ || Object.getPrototypeOf(BBCStandRender)).call.apply(_ref, [this].concat(args))), _this), _this.minScaleRatio = 18 / 28, _this.maxScaleRatio = UA.isPC ? 18 / 3 : 18 / 6, _this.className = 'BBCStandRender', _this._standFetchRecord = {}, _this._seatStyle = 1, _this._priceList = [], _this._packagePriceList = [], _this._stands = [], _this._lastFocusStandId = 0, _this._standGroup = [], _this.fetchStandSeats = function () { | |
return []; | |
}, _this.onTouchMove = function (e) { | |
get(BBCStandRender.prototype.__proto__ || Object.getPrototypeOf(BBCStandRender.prototype), 'onTouchMove', _this).call(_this, 200, e); | |
if (UA.isPC) { | |
var points = getEventPoints(e); | |
var position = getPosition(_this._$seatCanvas); | |
var scale = _this._viewport.getScale(); | |
var point = { | |
x: (points[0].x - position.left) / scale, | |
y: (points[0].y - position.top) / scale | |
}; | |
var seat = _this._area.getSeat(point); | |
if (_this.onHoverSeat) { | |
var offset = getOffset(e.currentTarget); | |
_this.onHoverSeat({ | |
x: points[0].x - offset.left, | |
y: points[0].y - offset.top, | |
seat: seat && seat.getInfo() | |
}); | |
} | |
} | |
}, _this.updateViewportFocusStand = function (standId) { | |
_this._lastFocusStandId = standId; | |
var focusStand = _this._stands.find(function (stand) { | |
return stand.standId === +standId; | |
}); | |
if (focusStand) { | |
var _this$calculateViewpo = _this.calculateViewport(focusStand), | |
x = _this$calculateViewpo.x, | |
y = _this$calculateViewpo.y, | |
ratio = _this$calculateViewpo.ratio; | |
// 更新视口位置和缩放 | |
_this._viewport.updatePosition(x, y); | |
_this._viewport.updateRatio(ratio); | |
// 调整座位canvas位置和缩放 | |
_this.updateView(); | |
} | |
}, _temp), possibleConstructorReturn(_this, _ret); | |
} | |
createClass(BBCStandRender, [{ | |
key: 'init', | |
/** | |
* 初始化 | |
* @param {Number} row 行数 | |
* @param {Number} column 列数 | |
* @param {String} imageSrc 底图地址 | |
* @param {Object} focusStand 聚焦看台 | |
* @param {String} thumbnailBgImage 鹰眼图底图地址 | |
*/ | |
value: function init(row, column, imageSrc, focusStand, thumbnailBgImage) { | |
row *= Util.ShareData.SVGRenderScale; | |
column *= Util.ShareData.SVGRenderScale; | |
// 保存容器宽度/高度, <keep-alive>重新激活时拿到的宽度/高度为0 | |
Util.ShareData.ContainerWidth = this._$container.clientWidth; | |
Util.ShareData.ContainerHeight = this._$container.clientHeight; | |
addStyle(this._$container, { | |
position: 'relative' | |
}); | |
get(BBCStandRender.prototype.__proto__ || Object.getPrototypeOf(BBCStandRender.prototype), 'initArea', this).call(this, BBCArea, row, column); | |
this.initViewport(focusStand); | |
this.initSeatCanvas(focusStand, imageSrc); | |
this.initThumbnail(imageSrc, thumbnailBgImage); | |
if (UA.isPC) { | |
// pc端事件 | |
document.oncontextmenu = function () { | |
event.returnValue = false; | |
}; // 禁用右键菜单 | |
this._$container.addEventListener('mousedown', this.onTouchStart); | |
this._$container.addEventListener('mousemove', this.onTouchMove); | |
this._$container.addEventListener('mouseup', this.onTouchEnd); | |
this._$container.addEventListener('mouseleave', this.onMouseLeave); | |
} else { | |
// 移动端事件 | |
this._$container.addEventListener('touchstart', this.onTouchStart); | |
this._$container.addEventListener('touchmove', this.onTouchMove); | |
this._$container.addEventListener('touchend', this.onTouchEnd); | |
} | |
// pc和移动端都注册滚轮事件, 移动端方便用触摸板缩放 | |
this._$container.addEventListener('mousewheel', this.onMouseWheel.bind(this)); | |
} | |
/** | |
* 初始化Viewport | |
* @param {Object} focusStand 聚焦看台 | |
*/ | |
}, { | |
key: 'initViewport', | |
value: function initViewport(focusStand) { | |
var areaSize = this._area.getSize(); | |
var viewportDefaultX = void 0; | |
var viewportDefaultY = void 0; | |
var ratio = 1 * Util.ShareData.SVGRenderScale; | |
if (focusStand) { | |
var viewportValue = this.calculateViewport(focusStand); | |
viewportDefaultX = viewportValue.x; | |
viewportDefaultY = viewportValue.y; | |
ratio = viewportValue.ratio; | |
} else { | |
ratio *= 2; | |
} | |
this._viewport = new Viewport(this._$container.clientWidth, this._$container.clientHeight, areaSize.width, areaSize.height, { | |
minScaleRatio: this.minScaleRatio, | |
maxScaleRatio: this.maxScaleRatio, | |
x: viewportDefaultX, | |
y: viewportDefaultY, | |
renderPadding: true, | |
ratio: ratio | |
}); | |
} | |
/** | |
* 初始化座位绘制canvas | |
* @param {Object} focusStand 聚焦看台 | |
* @param {String} imageSrc 底图地址 | |
*/ | |
}, { | |
key: 'initSeatCanvas', | |
value: function initSeatCanvas(focusStand, imageSrc) { | |
var areaSize = this._area.getSize(); | |
var centerViewportPoint = this._viewport.getCenterPoint(); | |
var currentViewportPoint = this._viewport.getPoint(); | |
var scale = this._viewport.getScale(); | |
this._$seatCanvas = document.createElement('div'); | |
addStyle(this._$seatCanvas, { | |
position: 'relative', | |
left: -(areaSize.width * scale - this._$container.clientWidth) / 2 + (focusStand ? centerViewportPoint.x - currentViewportPoint.x : 0), | |
top: -(areaSize.height * scale - this._$container.clientHeight) / 2 + (focusStand ? centerViewportPoint.y - currentViewportPoint.y : 0), | |
backgroundImage: 'url(' + imageSrc + ')', | |
backgroundSize: 'cover' | |
}); | |
this._$container.appendChild(this._$seatCanvas); | |
this._ctx = new Canvas(this._$seatCanvas, { | |
width: areaSize.width, | |
height: areaSize.height, | |
scale: scale, | |
standWidth: this._$container.clientWidth, | |
standHeight: this._$container.clientHeight | |
}); | |
} | |
/** | |
* 初始化鹰眼图 | |
* @param {String} imageSrc 底图地址 | |
* @param {String} thumbnailBgImage 鹰眼图底图地址 | |
*/ | |
}, { | |
key: 'initThumbnail', | |
value: function () { | |
var _ref2 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee(imageSrc, thumbnailBgImage) { | |
var isJpgImage, image, thumbnailCanvasWidth, thumbnailCanvasHeight, ThumbnailScaleRatio, $thumbnailDiv, $thumbnailCanvas, $buttonListDiv; | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
isJpgImage = thumbnailBgImage.endsWith('.jpg'); | |
_context.next = 3; | |
return fetchImage(thumbnailBgImage); | |
case 3: | |
image = _context.sent; | |
// 计算鹰眼图尺寸 | |
thumbnailCanvasWidth = image.width; | |
thumbnailCanvasHeight = image.height; | |
ThumbnailScaleRatio = this._$container.clientWidth * 0.5 / thumbnailCanvasWidth; | |
if (thumbnailCanvasHeight * ThumbnailScaleRatio > Thumbnail.ThumbnailCanvasMaxHeight) { | |
ThumbnailScaleRatio = Thumbnail.ThumbnailCanvasMaxHeight / thumbnailCanvasHeight; | |
} | |
// 鹰眼图缩放 | |
thumbnailCanvasWidth *= ThumbnailScaleRatio; | |
thumbnailCanvasHeight *= ThumbnailScaleRatio; | |
BBCThumbnail.ScaleRatio = ThumbnailScaleRatio / Util.ShareData.SVGRenderScale; | |
if (isJpgImage) { | |
BBCThumbnail.ScaleRatio /= 2; | |
} | |
// 鹰眼图整体div | |
this._$thumbnailContainer = document.createElement('div'); | |
this._$thumbnailContainer.className = 'select-seat-thumbnail'; | |
addStyle(this._$thumbnailContainer, { | |
position: 'absolute', | |
top: 6, | |
right: 6, | |
width: thumbnailCanvasWidth + (UA.isPC ? 30 : 0) + BBCThumbnailMargin * 2, // PC 30px 是按钮区域 | |
height: thumbnailCanvasHeight + BBCThumbnailMargin * 2 | |
}); | |
this._$container.appendChild(this._$thumbnailContainer); | |
// 鹰眼图区域 | |
$thumbnailDiv = document.createElement('div'); | |
addStyle($thumbnailDiv, { | |
position: 'absolute', | |
top: 0, | |
left: 0, | |
borderRadius: 2, | |
overflow: 'hidden', | |
width: thumbnailCanvasWidth + BBCThumbnailMargin * 2, | |
height: thumbnailCanvasHeight + BBCThumbnailMargin * 2, | |
backgroundImage: 'url(' + thumbnailBgImage + ')', | |
backgroundColor: 'rgba(0, 0, 0, 0.6)', | |
backgroundSize: thumbnailCanvasWidth + 'px ' + thumbnailCanvasHeight + 'px', | |
backgroundPosition: BBCThumbnailMargin + 'px ' + BBCThumbnailMargin + 'px', | |
backgroundRepeat: 'no-repeat', | |
transform: 'translateX(0)', | |
transition: 'all 0.4s', | |
display: UA.isPC ? 'block' : 'none' | |
}); | |
this._$thumbnailContainer.appendChild($thumbnailDiv); | |
// 接口返回字段, 3表示需要鹰眼图展示座位 | |
if (this._renderMode === 3 && !isJpgImage) { | |
// 鹰眼图canvas | |
$thumbnailCanvas = createCanvas(thumbnailCanvasWidth, thumbnailCanvasHeight); | |
addStyle($thumbnailCanvas, { | |
position: 'absolute', | |
top: BBCThumbnailMargin, | |
left: BBCThumbnailMargin | |
}); | |
this._thumbnailCtx = $thumbnailCanvas.getContext('2d'); | |
$thumbnailDiv.appendChild($thumbnailCanvas); | |
} | |
// 仅PC显示鹰眼图按钮 | |
if (UA.isPC) { | |
// 按钮区域 | |
$buttonListDiv = document.createElement('div'); | |
addStyle($buttonListDiv, { | |
width: 30, | |
height: thumbnailCanvasHeight, | |
position: 'absolute', | |
top: 0, | |
right: 0, | |
backgroundColor: 'white' | |
}); | |
this._$thumbnailContainer.appendChild($buttonListDiv); | |
this._thumbnail = new BBCThumbnail(this, $thumbnailDiv, $buttonListDiv); | |
} else { | |
this._thumbnail = new BBCThumbnail(this, $thumbnailDiv, null); | |
} | |
case 21: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, this); | |
})); | |
function initThumbnail(_x, _x2) { | |
return _ref2.apply(this, arguments); | |
} | |
return initThumbnail; | |
}() | |
}, { | |
key: 'onTouchEnd', | |
value: function onTouchEnd(e) { | |
get(BBCStandRender.prototype.__proto__ || Object.getPrototypeOf(BBCStandRender.prototype), 'onTouchEnd', this).call(this, e); | |
if (this._touchStatus === 'start') { | |
var offset = getOffset(e.currentTarget); | |
// 获取点击位置 | |
var points = getEventPoints(e); | |
var touchPoint = { | |
x: points[0].x - offset.left, | |
y: points[0].y - offset.top | |
}; | |
// 获取当前缩放倍数 | |
var scale = this._viewport.getScale(); | |
var maxScale = 1 / Util.ShareData.SVGRenderScale; | |
// 判断是否小于1倍(18px座位), 注意浮点数比较 | |
if (scale > maxScale || Math.abs(scale - maxScale) < 0.0001) { | |
return; | |
} | |
// 计算点击位置与div容器中心点的距离, 基于当前缩放倍率下 | |
var moveX = touchPoint.x - this._$container.clientWidth / 2; | |
var moveY = touchPoint.y - this._$container.clientHeight / 2; | |
// 放大+居中的过渡效果在PC火狐上非常不流畅, 在该问题解决前先不加过渡 | |
this._viewport.scale(1 / maxScale - 1 / scale); | |
var moveScale = maxScale === scale ? 1 : this._viewport.getScale() / scale; | |
this._viewport.move(moveX * moveScale, moveY * moveScale); | |
this.updateView(); | |
return; | |
// if (false) { | |
// // 过渡实现 | |
// const duration = 320; | |
// const interval = 20; | |
// let count = 0; | |
// const total = duration / interval; | |
// const timer = setInterval(() => { | |
// // 更新视口, 必须先更新缩放, 再更新位置, 因为更新位置会计算是否超出边界, 如果超界了会导致缩放原点不对 | |
// this._viewport.scale((1 / newScale - 1 / scale) / total); | |
// // 计算视口移动距离需要缩放的倍数 | |
// const moveScale = (newScale === scale ? 1 : this._viewport.getScale() / scale); | |
// this._viewport.move(moveX * moveScale / total, moveY * moveScale / total); | |
// this.updateView(true); | |
// count++; | |
// if (count >= total) { | |
// this.updateView(); | |
// clearInterval(timer); | |
// } | |
// }, interval); | |
// // requestAnimationFrame实现 | |
// // let start = null; | |
// // let prev = null; | |
// // const total = 300; | |
// // const step = timestamp => { | |
// // if (!start) { | |
// // start = timestamp; | |
// // prev = timestamp; | |
// // return requestAnimationFrame(step); | |
// // } | |
// // const duration = timestamp - prev; | |
// // prev = timestamp; | |
// // // 更新视口, 必须先更新缩放, 再更新位置, 因为更新位置会计算是否超出边界, 如果超界了会导致缩放原点不对 | |
// // this._viewport.scale((1 / newScale - 1 / scale) * duration / total); | |
// // // 计算视口移动距离需要缩放的倍数 | |
// // const moveScale = (newScale === scale ? 1 : this._viewport.getScale() / scale); | |
// // this._viewport.move(moveX * moveScale * duration / total, moveY * moveScale * duration / total); | |
// // this.updateView(true); | |
// // if (timestamp - start < total) { | |
// // requestAnimationFrame(step); | |
// // } | |
// // }; | |
// // requestAnimationFrame(step); | |
// } | |
} | |
} | |
/** | |
* 根据要聚焦的看台位置和容器大小, 计算出视口的位置和缩放值 | |
* @param {Object} focusStand 要聚焦的看台 | |
*/ | |
}, { | |
key: 'calculateViewport', | |
value: function calculateViewport(focusStand) { | |
var _focusStand$boundingR = focusStand.boundingRect, | |
left = _focusStand$boundingR.left, | |
right = _focusStand$boundingR.right, | |
top = _focusStand$boundingR.top, | |
bottom = _focusStand$boundingR.bottom; | |
var _Util$ShareData = Util.ShareData, | |
ContainerWidth = _Util$ShareData.ContainerWidth, | |
ContainerHeight = _Util$ShareData.ContainerHeight, | |
DefaultViewportMargin = _Util$ShareData.DefaultViewportMargin; | |
var maxWidth = ContainerWidth - DefaultViewportMargin * 2; | |
var maxHeight = ContainerHeight - DefaultViewportMargin * 2; | |
var standWidth = right - left; | |
var standHeight = bottom - top; | |
// 计算视口缩放值 | |
// 保证 standWidth * ratio <= maxWidth 并且 standHeight * ratio <= maxHeight | |
var ratio = standWidth / maxWidth; | |
if (ratio * maxHeight < standHeight) { | |
ratio = standHeight / maxHeight; | |
} | |
// 不能超过最大/最小缩放倍数限制 | |
if (ratio < this.minScaleRatio) { | |
ratio = this.minScaleRatio; | |
} else if (ratio > this.maxScaleRatio) { | |
ratio = this.maxScaleRatio; | |
} | |
// 原始位置 + 居中差值 + margin边距 | |
return { | |
x: left + (standWidth - maxWidth) / 2 - DefaultViewportMargin, | |
y: top + (standHeight - maxHeight) / 2 - DefaultViewportMargin, | |
ratio: ratio | |
}; | |
} | |
/** | |
* 绘制座位 | |
*/ | |
}, { | |
key: 'drawSeat', | |
value: function () { | |
var _ref3 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee2() { | |
var _this2 = this; | |
var viewportLeftTop, viewportRightBottom, viewportRect, existStandIds, intersectStandIds, _loop, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, stand, _ret2, setStatus, seats, fetchTasks, groupSeats, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, seat, offset, isPackage, price, packagePriceIndex; | |
return regeneratorRuntime.wrap(function _callee2$(_context2) { | |
while (1) { | |
switch (_context2.prev = _context2.next) { | |
case 0: | |
if (!(UA.isBadPhone && this.prevDrawTime && Date.now() - this.prevDrawTime < 1000)) { | |
_context2.next = 2; | |
break; | |
} | |
return _context2.abrupt('return'); | |
case 2: | |
this.prevDrawTime = Date.now(); | |
// 获取视口矩形 | |
viewportLeftTop = this._viewport.getLeftTopPoint(); | |
viewportRightBottom = this._viewport.getRightBottomPoint(); | |
viewportRect = { | |
left: viewportLeftTop.x, | |
top: viewportLeftTop.y, | |
right: viewportRightBottom.x, | |
bottom: viewportRightBottom.y | |
}; | |
// 接口返回的看台分组可能包含没数据的看台, 需要与接口返回的看台列表对比, 将不存在的过滤掉 | |
existStandIds = this._stands.reduce(function (result, cur) { | |
result[cur.standId] = true; | |
return result; | |
}, {}); | |
// 判断相交看台 | |
intersectStandIds = []; | |
// 该模式下, 初次请求直接获取所有座位数据 | |
if (!(this._renderMode === 3 && this.initial === undefined)) { | |
_context2.next = 13; | |
break; | |
} | |
if (this._standGroup.length === 0) { | |
intersectStandIds = this._stands.map(function (x) { | |
return x.standId; | |
}); | |
} else { | |
intersectStandIds = this._standGroup.map(function (ids) { | |
return ids.split(',').filter(function (id) { | |
return existStandIds[id]; | |
}); | |
}); | |
} | |
this.initial = false; | |
_context2.next = 41; | |
break; | |
case 13: | |
_loop = function _loop(stand) { | |
if (Util.isIntersect(viewportRect, stand.boundingRect)) { | |
// 忽略已加载过的看台 | |
if (_this2._standFetchRecord[stand.standId] !== undefined) { | |
return 'continue'; | |
} | |
if (_this2._standGroup.length === 0) { | |
_this2._standFetchRecord[stand.standId] = 'fetch'; // 状态: "获取中" | |
intersectStandIds.push(stand.standId); | |
} else { | |
// 查找该看台所在组 | |
var group = _this2._standGroup.find(function (x) { | |
return x.indexOf(stand.standId) !== -1; | |
}); | |
var standIds = []; | |
if (!group) { | |
standIds = [stand.standId]; | |
} else { | |
standIds = group.split(',').filter(function (id) { | |
return existStandIds[id]; | |
}); | |
} | |
standIds.forEach(function (id) { | |
_this2._standFetchRecord[id] = 'fetch'; // 状态: "获取中" | |
}); | |
intersectStandIds.push(standIds); | |
} | |
} | |
}; | |
_iteratorNormalCompletion = true; | |
_didIteratorError = false; | |
_iteratorError = undefined; | |
_context2.prev = 17; | |
_iterator = this._stands[Symbol.iterator](); | |
case 19: | |
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) { | |
_context2.next = 27; | |
break; | |
} | |
stand = _step.value; | |
_ret2 = _loop(stand); | |
if (!(_ret2 === 'continue')) { | |
_context2.next = 24; | |
break; | |
} | |
return _context2.abrupt('continue', 24); | |
case 24: | |
_iteratorNormalCompletion = true; | |
_context2.next = 19; | |
break; | |
case 27: | |
_context2.next = 33; | |
break; | |
case 29: | |
_context2.prev = 29; | |
_context2.t0 = _context2['catch'](17); | |
_didIteratorError = true; | |
_iteratorError = _context2.t0; | |
case 33: | |
_context2.prev = 33; | |
_context2.prev = 34; | |
if (!_iteratorNormalCompletion && _iterator.return) { | |
_iterator.return(); | |
} | |
case 36: | |
_context2.prev = 36; | |
if (!_didIteratorError) { | |
_context2.next = 39; | |
break; | |
} | |
throw _iteratorError; | |
case 39: | |
return _context2.finish(36); | |
case 40: | |
return _context2.finish(33); | |
case 41: | |
if (!(intersectStandIds.length !== 0)) { | |
_context2.next = 82; | |
break; | |
} | |
/** | |
* 设置各看台状态 | |
* @param {undefined | String} status 状态 | |
*/ | |
setStatus = function setStatus(status) { | |
// eslint-disable-line no-inner-declarations | |
if (_this2._standGroup.length === 0) { | |
intersectStandIds.forEach(function (id) { | |
_this2._standFetchRecord[id] = status; | |
}); | |
} else { | |
intersectStandIds.forEach(function (ids) { | |
ids.forEach(function (id) { | |
_this2._standFetchRecord[id] = status; | |
}); | |
}); | |
} | |
}; | |
seats = void 0; | |
_context2.prev = 44; | |
if (!(this._standGroup.length === 0)) { | |
_context2.next = 51; | |
break; | |
} | |
_context2.next = 48; | |
return this.fetchStandSeats(intersectStandIds); | |
case 48: | |
seats = _context2.sent; | |
_context2.next = 56; | |
break; | |
case 51: | |
// 如果不为0, 则按组并行请求 | |
fetchTasks = intersectStandIds.map(function (ids) { | |
return _this2.fetchStandSeats(ids); | |
}); | |
_context2.next = 54; | |
return Promise.all(fetchTasks); | |
case 54: | |
groupSeats = _context2.sent; | |
seats = groupSeats.filter(function (x) { | |
return Array.isArray(x); | |
}).reduce(function (result, cur) { | |
result.push.apply(result, toConsumableArray(cur)); | |
return result; | |
}, []); | |
case 56: | |
_context2.next = 62; | |
break; | |
case 58: | |
_context2.prev = 58; | |
_context2.t1 = _context2['catch'](44); | |
setStatus(undefined); // 重置状态 | |
return _context2.abrupt('return'); | |
case 62: | |
setStatus('end'); // 状态: "获取成功" | |
_iteratorNormalCompletion2 = true; | |
_didIteratorError2 = false; | |
_iteratorError2 = undefined; | |
_context2.prev = 66; | |
for (_iterator2 = seats[Symbol.iterator](); !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | |
seat = _step2.value; | |
offset = this._seatStyle === 3 ? 0 : BBCSeat.SeatSize / 2; | |
isPackage = seat.groupid != '0'; // eslint-disable-line eqeqeq | |
price = this._priceList[seat.plid]; | |
// 如果是固定套票, 则设置为相应的套票颜色 | |
// 非候鸟的中网BBC逻辑不变, 不会把套票list转换到票价list | |
if (isPackage && this._priceList[seat.groupPriceid]) { | |
price = this._priceList[seat.groupPriceid]; | |
} | |
// 票价不存在, 设置默认颜色 | |
if (!price) { | |
price = { | |
c: '#000000', | |
index: -1 | |
}; | |
seat.s = 0; | |
} | |
packagePriceIndex = -1; | |
// 可售的固定套票, 设置套票票价index | |
if (isPackage && seat.s === 2) { | |
if (this._packagePriceList[seat.groupPriceid]) { | |
packagePriceIndex = this._packagePriceList[seat.groupPriceid].index; | |
} else { | |
seat.s = 0; // 强制转为不可售 | |
} | |
} | |
this._area.addSeat( | |
// 座位坐标要取整 | |
((+seat.x >> 0) - offset + Util.ShareData.BBCSeatOffsetX) * Util.ShareData.SVGRenderScale, ((+seat.y >> 0) - offset + Util.ShareData.BBCSeatOffsetY) * Util.ShareData.SVGRenderScale, Object.assign({}, { | |
id: seat.sid, | |
status: seat.s, | |
row: seat.rhint, | |
column: seat.chint, | |
color: price.c, | |
floor: seat.fn, | |
priceIndex: price.index, | |
chinese: false, | |
isPackage: isPackage, | |
packagePriceIndex: packagePriceIndex, | |
packageCombinedId: isPackage ? seat.groupid : -1 | |
}, seat), this._seatStyle); | |
} | |
_context2.next = 74; | |
break; | |
case 70: | |
_context2.prev = 70; | |
_context2.t2 = _context2['catch'](66); | |
_didIteratorError2 = true; | |
_iteratorError2 = _context2.t2; | |
case 74: | |
_context2.prev = 74; | |
_context2.prev = 75; | |
if (!_iteratorNormalCompletion2 && _iterator2.return) { | |
_iterator2.return(); | |
} | |
case 77: | |
_context2.prev = 77; | |
if (!_didIteratorError2) { | |
_context2.next = 80; | |
break; | |
} | |
throw _iteratorError2; | |
case 80: | |
return _context2.finish(77); | |
case 81: | |
return _context2.finish(74); | |
case 82: | |
this._area.draw(this._ctx, viewportLeftTop.x, viewportLeftTop.y, viewportRightBottom.x, viewportRightBottom.y); | |
case 83: | |
case 'end': | |
return _context2.stop(); | |
} | |
} | |
}, _callee2, this, [ | |
[17, 29, 33, 41], | |
[34, , 36, 40], | |
[44, 58], | |
[66, 70, 74, 82], | |
[75, , 77, 81] | |
]); | |
})); | |
function drawSeat() { | |
return _ref3.apply(this, arguments); | |
} | |
return drawSeat; | |
}() | |
/** | |
* 从svg底图内容解析看台包围矩形, 并修改svg缩放为1倍大小 | |
* @param {String} svg svg图片文本内容 | |
* @param {Array} stands 接口返回的看台列表 | |
*/ | |
}, { | |
key: 'getSvgData', | |
value: function getSvgData(svg, stands) { | |
var standIdMap = stands.reduce(function (result, stand) { | |
result[stand.vid] = stand.i; | |
return result; | |
}, {}); | |
var $div = document.createElement('div'); | |
$div.innerHTML = svg; | |
var $svg = $div.children[0]; | |
var svgScale = BBCStandRender.handleSvgAttribute($svg); | |
var _$svg$getAttribute$sp = $svg.getAttribute('viewBox').split(' '), | |
_$svg$getAttribute$sp2 = slicedToArray(_$svg$getAttribute$sp, 4), | |
svgWidth = _$svg$getAttribute$sp2[2], | |
svgHeight = _$svg$getAttribute$sp2[3]; | |
// 如果是小于指定大小的场馆, 放大一倍绘制来保证清晰度 | |
if (svgWidth * svgHeight * svgScale * svgScale <= Util.DoubleRenderBoundary) { | |
Util.ShareData.SVGRenderScale = 2; | |
this.minScaleRatio *= Util.ShareData.SVGRenderScale; | |
this.maxScaleRatio *= Util.ShareData.SVGRenderScale; | |
} | |
function getStands(root) { | |
var newStands = []; | |
function dfs(element) { | |
if (element.nodeType !== 1) { | |
return; | |
} | |
// floorName对选座业务无用, 部分底图存在floorName乱码的情况, 导致svg生成的blob图片加载时走到onerror回调 | |
element.removeAttribute('floorname'); | |
if (element.tagName === 'text') { | |
addStyle(element, { | |
fill: '#E0E0E0' | |
}); | |
} | |
var floorId = element.getAttribute('floorid'); | |
if (floorId && standIdMap[floorId]) { | |
var _getBBox = getBBox(element), | |
x = _getBBox.x, | |
y = _getBBox.y, | |
width = _getBBox.width, | |
height = _getBBox.height; | |
newStands.push({ | |
standId: standIdMap[floorId], | |
boundingRect: { | |
left: x * svgScale * Util.ShareData.SVGRenderScale, | |
top: y * svgScale * Util.ShareData.SVGRenderScale, | |
right: (x + width) * svgScale * Util.ShareData.SVGRenderScale, | |
bottom: (y + height) * svgScale * Util.ShareData.SVGRenderScale | |
} | |
}); | |
} else if (element.childNodes && element.childNodes.length > 0) { | |
for (var i = 0; i < element.childNodes.length; i++) { | |
dfs(element.childNodes[i]); | |
} | |
} | |
} | |
dfs(root); | |
return newStands; | |
} | |
$div.style.visibility = 'hidden'; | |
document.body.appendChild($div); | |
var newStands = getStands($div); | |
svg = $div.innerHTML; | |
$div.remove(); | |
return { | |
stands: newStands, | |
svg: svg, | |
scale: svgScale, | |
width: svgWidth, | |
height: svgHeight | |
}; | |
} | |
/** | |
* 从接口返回的看台列表解析看台包围矩形 | |
* @param {Array} stands 接口返回的看台列表 | |
*/ | |
}, { | |
key: 'getStands', | |
value: function getStands(stands) { | |
return stands.reduce(function (result, stand) { | |
var points = getPoints(stand.pis); | |
var boundingRect = getBoundingRect(points); | |
result.push({ | |
standId: stand.i, | |
boundingRect: boundingRect | |
}); | |
return result; | |
}, []); | |
} | |
/** | |
* 生成带颜色的svg底图 | |
* @param {String} svg svg文本内容 | |
* @param {Array} stands 看台列表 | |
*/ | |
}, { | |
key: 'generateColorfulSvg', | |
value: function generateColorfulSvg(svg, stands) { | |
// 不可售颜色 | |
var notSaleColor = '#BCC3C8'; | |
// 从看台列表解析颜色值 | |
var colorMap = stands.reduce(function (result, stand) { | |
if (stand.rainbow) { | |
result[stand.vid] = stand.rainbow.split('|').reduce(function (result2, item) { | |
var idAndColor = item.split('='); | |
if (idAndColor[0]) { | |
result2[idAndColor[0]] = stand.s === 1 ? idAndColor[1] : notSaleColor; | |
} | |
return result2; | |
}, {}); | |
} else { | |
result[stand.vid] = stand.s === 1 ? getNormalizeColor(stand.c) : notSaleColor; | |
} | |
return result; | |
}, {}); | |
var $div = document.createElement('div'); | |
$div.innerHTML = svg; | |
$div.style.visibility = 'hidden'; | |
document.body.appendChild($div); | |
var $svg = $div.children[0]; | |
BBCStandRender.handleSvgAttribute($svg); | |
// 遍历修改座位颜色 | |
function dfs(element) { | |
if (element.nodeType !== 1) { | |
return; | |
} | |
// floorName对选座业务无用, 部分底图存在floorName乱码的情况, 导致svg生成的blob图片加载时走到onerror回调 | |
element.removeAttribute('floorname'); | |
var floorId = element.getAttribute('floorid'); | |
if (floorId && colorMap[floorId]) { | |
var colors = colorMap[floorId]; | |
if (element.tagName === 'g') { | |
for (var i = 0; i < element.childNodes.length; i++) { | |
var $child = element.childNodes[i]; | |
var rowId = $child.getAttribute('row_id'); | |
if (colors[rowId]) { | |
addStyle($child, { | |
fill: colors[rowId] | |
}); | |
} | |
} | |
} else { | |
addStyle(element, { | |
fill: colors | |
}); | |
} | |
} else if (element.childNodes && element.childNodes.length > 0) { | |
for (var _i = 0; _i < element.childNodes.length; _i++) { | |
dfs(element.childNodes[_i]); | |
} | |
} | |
} | |
dfs($svg); | |
// svg转url | |
var colorfulSvgHtml = $div.innerHTML; | |
var url = Util.svgToImageUrl(colorfulSvgHtml); | |
$div.remove(); | |
return url; | |
} | |
/** | |
* 生成透明色的svg底图 | |
* @param {String} svg svg文本内容 | |
*/ | |
}, { | |
key: 'generateTransparentSvg', | |
value: function generateTransparentSvg(svg) { | |
var $div = document.createElement('div'); | |
$div.innerHTML = svg; | |
$div.style.visibility = 'hidden'; | |
document.body.appendChild($div); | |
var $svg = $div.children[0]; | |
BBCStandRender.handleSvgAttribute($svg); | |
// 遍历修改座位颜色 | |
function dfs(element) { | |
if (element.nodeType !== 1) { | |
return; | |
} | |
// floorName对选座业务无用, 部分底图存在floorName乱码的情况, 导致svg生成的blob图片加载时走到onerror回调 | |
element.removeAttribute('floorname'); | |
var floorId = element.getAttribute('floorid'); | |
if (floorId) { | |
addStyle(element, { | |
fill: 'rgba(0,0,0,0.2)' | |
}); | |
} else if (element.childNodes && element.childNodes.length > 0) { | |
for (var i = 0; i < element.childNodes.length; i++) { | |
dfs(element.childNodes[i]); | |
} | |
} | |
} | |
dfs($svg); | |
// svg转url | |
var transparentSvgHtml = $div.innerHTML; | |
var url = Util.svgToImageUrl(transparentSvgHtml); | |
$div.remove(); | |
return url; | |
} | |
/** | |
* 渲染中网BBC选座 | |
* @param {String} backgroundImage 底图地址 | |
* @param {String} svgImageBody svg底图内容, 没有传空 | |
* @param {String} rainbowImageBody svg彩虹图内容, 没有传空 | |
* @param {Array} stands 看台列表 | |
* @param {Number} focusStandId 默认聚焦的看台id | |
* @param {Array} priceList 票价列表 | |
* @param {Array} packagePriceList 套票票价列表 | |
* @param {Function} fetchStandSeats 请求看台座位数据的方法 | |
* @param {Number} maxPickNumber 最大可选座位数量 | |
* @param {Number} seatStyle 座位样式(3:沙发, 其他:圆) | |
* @param {String} standGroup 看台分组信息, 组间竖线|分隔, 组内看台id逗号,分隔 | |
* @param {Number} renderMode 接口返回字段, 渲染模式, 3: 鹰眼图展示座位, 其他: 无需处理 | |
*/ | |
}, { | |
key: 'render', | |
value: function () { | |
var _ref4 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee3(backgroundImage, svgImageBody, rainbowImageBody, stands, focusStandId, priceList, packagePriceList, fetchStandSeats, maxPickNumber, seatStyle, standGroup, renderMode) { | |
var _this3 = this; | |
var svgData, focusStand, url, thumbnailBackgroundImage, _focusStand, $image; | |
return regeneratorRuntime.wrap(function _callee3$(_context3) { | |
while (1) { | |
switch (_context3.prev = _context3.next) { | |
case 0: | |
this.fetchStandSeats = fetchStandSeats; | |
this._maxPickNumber = maxPickNumber; | |
this._seatStyle = seatStyle; | |
this._priceList = priceList.reduce(function (result, price, index) { | |
result[price.damaiPriceId] = Object.assign({ | |
index: index | |
}, price); | |
return result; | |
}, {}); | |
this._packagePriceList = packagePriceList.reduce(function (result, price, index) { | |
result[price.tpId] = Object.assign({ | |
index: index | |
}, price); | |
return result; | |
}, {}); | |
this._lastFocusStandId = focusStandId; | |
if (standGroup) { | |
this._standGroup = standGroup.split('|'); | |
} | |
this._renderMode = renderMode; | |
if (!/\.svg/.test(backgroundImage)) { | |
_context3.next = 18; | |
break; | |
} | |
svgData = this.getSvgData(svgImageBody, stands); | |
this._stands = svgData.stands; | |
focusStand = this._stands.find(function (stand) { | |
return stand.standId == focusStandId; | |
}); // eslint-disable-line eqeqeq | |
url = Util.svgToImageUrl(svgData.svg); | |
// 生成鹰眼图底图, 3: 透明底图, 其他: 带看台颜色底图 | |
thumbnailBackgroundImage = null; | |
if (this._renderMode === 3) { | |
thumbnailBackgroundImage = this.generateTransparentSvg(svgImageBody); | |
} else { | |
thumbnailBackgroundImage = this.generateColorfulSvg(rainbowImageBody || svgImageBody, stands); | |
} | |
this.init(svgData.width * svgData.scale, svgData.height * svgData.scale, url, focusStand, thumbnailBackgroundImage); | |
_context3.next = 32; | |
break; | |
case 18: | |
this._stands = this.getStands(stands); | |
_focusStand = this._stands.find(function (stand) { | |
return stand.standId == focusStandId; | |
}); // eslint-disable-line eqeqeq | |
$image = null; | |
_context3.prev = 21; | |
_context3.next = 24; | |
return fetchImage(backgroundImage); | |
case 24: | |
$image = _context3.sent; | |
_context3.next = 31; | |
break; | |
case 27: | |
_context3.prev = 27; | |
_context3.t0 = _context3['catch'](21); | |
this.onError({ | |
code: ErrorCode.Normal, | |
message: ErrorMessage.load_venue_image_fail, | |
messageKey: 'load_venue_image_fail' | |
}); | |
return _context3.abrupt('return'); | |
case 31: | |
this.init($image.width * 2, $image.height * 2, backgroundImage, _focusStand, backgroundImage); | |
case 32: | |
_context3.next = 34; | |
return this.drawSeat(); | |
case 34: | |
// drawSeat里会请求座位数据, 必须等待执行完, 才能drawThumbnail | |
// 延时绘制鹰眼图, 节约资源优先绘座 | |
// PC不用 | |
setTimeout(function () { | |
_this3.drawThumbnail(); | |
}, UA.isPC ? 0 : 500); | |
case 35: | |
case 'end': | |
return _context3.stop(); | |
} | |
} | |
}, _callee3, this, [ | |
[21, 27] | |
]); | |
})); | |
function render(_x3, _x4, _x5, _x6, _x7, _x8, _x9, _x10, _x11, _x12, _x13, _x14) { | |
return _ref4.apply(this, arguments); | |
} | |
return render; | |
}() | |
/* ======= 对外暴露方法 ======= */ | |
/** | |
* 更新视口聚焦的看台 | |
* @param {Number} standId 看台id | |
*/ | |
}, { | |
key: 'highlightPrice', | |
/** | |
* 高亮指定票价座位 | |
* @param {Number} priceIndex 票价索引 | |
*/ | |
value: function highlightPrice(priceIndex) { | |
this._area.highlightPrice(priceIndex); | |
} | |
}, { | |
key: 'destroy', | |
value: function destroy() { | |
get(BBCStandRender.prototype.__proto__ || Object.getPrototypeOf(BBCStandRender.prototype), 'destroy', this).call(this); | |
this._standFetchRecord = null; | |
this._priceList = null; | |
this._packagePriceList = null; | |
this._stands = null; | |
this.fetchStandSeats = null; | |
} | |
/* ======= 对外暴露方法 ======= */ | |
}], [{ | |
key: 'handleSvgAttribute', | |
value: function handleSvgAttribute($svg) { | |
var scale = 1; | |
// 处理viewBox属性 | |
var viewboxAttribute = $svg.getAttribute('viewBox'); | |
if (viewboxAttribute) { | |
var viewbox = viewboxAttribute.split(' '); | |
$svg.setAttribute('width', viewbox[2]); | |
$svg.setAttribute('height', viewbox[3]); | |
} | |
// 处理transform属性 | |
var transformAttribute = $svg.getAttribute('transform'); | |
if (transformAttribute) { | |
var regexResult = transformAttribute.match(/scale\(([0-9.]+)\)/); | |
var svgScale = parseFloat(regexResult && regexResult[1] || 1); | |
scale = svgScale; | |
var svgWidth = parseInt($svg.getAttribute('width'), 10); | |
var svgHeight = parseInt($svg.getAttribute('height'), 10); | |
$svg.setAttribute('viewBox', '0 0 ' + svgWidth + ' ' + svgHeight); | |
$svg.setAttribute('width', svgWidth * scale); | |
$svg.setAttribute('height', svgHeight * scale); | |
$svg.removeAttribute('transform'); | |
} | |
return scale; | |
} // 视口最小缩放, 座位最大28px | |
// 视口最大缩放, PC上座位最小3px, 移动端最小6px | |
// 看台座位请求记录 | |
// 座位样式(3:沙发, 其他:圆) | |
// 票价列表 | |
// 套票票价列表 | |
// 看台列表 | |
// 最后一次聚焦的看台id | |
// 后端看台分组数据 | |
// 请求座位数据的方法 | |
}]); | |
return BBCStandRender; | |
}(StandRender), _applyDecoratedDescriptor$1(_class$9.prototype, 'onTouchEnd', [autobind], Object.getOwnPropertyDescriptor(_class$9.prototype, 'onTouchEnd'), _class$9.prototype), _class$9); | |
var OtherBBCStandRender = function (_MatrixStandRender) { | |
inherits(OtherBBCStandRender, _MatrixStandRender); | |
function OtherBBCStandRender() { | |
var _ref; | |
var _temp, _this, _ret; | |
classCallCheck(this, OtherBBCStandRender); | |
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | |
args[_key] = arguments[_key]; | |
} | |
return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref = OtherBBCStandRender.__proto__ || Object.getPrototypeOf(OtherBBCStandRender)).call.apply(_ref, [this].concat(args))), _this), _this.className = 'OtherBBCStandRender', _temp), possibleConstructorReturn(_this, _ret); | |
} | |
createClass(OtherBBCStandRender, [{ | |
key: 'render', | |
/** | |
* 渲染其它bbc选座 | |
* @param {Array} seatList 座位列表 | |
* @param {Array} priceList 票价列表 | |
* @param {Number} maxPickNumber 座位最大可选个数 | |
*/ | |
value: function render(seatList, priceList, maxPickNumber) { | |
this._maxPickNumber = maxPickNumber; | |
var maxRow = 0; | |
var maxColumn = 0; | |
var priceListMap = {}; | |
for (var i = 0; i < priceList.length; i++) { | |
priceList[i].priceIndex = i; | |
priceListMap[priceList[i].damaiPriceId] = priceList[i]; | |
} | |
var _iteratorNormalCompletion = true; | |
var _didIteratorError = false; | |
var _iteratorError = undefined; | |
try { | |
for (var _iterator = priceList[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | |
var price = _step.value; | |
priceListMap[price.damaiPriceId] = price; | |
} | |
} catch (err) { | |
_didIteratorError = true; | |
_iteratorError = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion && _iterator.return) { | |
_iterator.return(); | |
} | |
} finally { | |
if (_didIteratorError) { | |
throw _iteratorError; | |
} | |
} | |
} | |
var seats = []; | |
var _iteratorNormalCompletion2 = true; | |
var _didIteratorError2 = false; | |
var _iteratorError2 = undefined; | |
try { | |
for (var _iterator2 = seatList[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | |
var seat = _step2.value; | |
if (seat.type === 1) { | |
// 状态为1但是dmPriceId为0的座位, 当成不可售座位 | |
if (seat.seatInfo.dmPriceId === 0) { | |
seats.push({ | |
x: seat.seatInfo.x - 1, | |
y: seat.seatInfo.y - 1, | |
info: { | |
id: seat.seatInfo.seatId, | |
status: 0, | |
row: seat.seatInfo.rowNo, | |
column: seat.seatInfo.seatNo, | |
color: '', | |
priceIndex: -1, | |
packagePriceIndex: seat.seatInfo.tId | |
} | |
}); | |
} else { | |
seats.push({ | |
x: seat.seatInfo.x - 1, | |
y: seat.seatInfo.y - 1, | |
info: { | |
id: seat.seatInfo.seatId, | |
status: seat.seatInfo.state, | |
row: seat.seatInfo.rowNo, | |
column: seat.seatInfo.seatNo, | |
color: priceListMap[seat.seatInfo.dmPriceId].c, | |
priceIndex: priceListMap[seat.seatInfo.dmPriceId].priceIndex, | |
packagePriceIndex: seat.seatInfo.tId | |
} | |
}); | |
} | |
if (seat.seatInfo.x > maxRow) { | |
maxRow = seat.seatInfo.x; | |
} | |
if (seat.seatInfo.y > maxColumn) { | |
maxColumn = seat.seatInfo.y; | |
} | |
} | |
} | |
} catch (err) { | |
_didIteratorError2 = true; | |
_iteratorError2 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion2 && _iterator2.return) { | |
_iterator2.return(); | |
} | |
} finally { | |
if (_didIteratorError2) { | |
throw _iteratorError2; | |
} | |
} | |
} | |
this.init(maxRow, maxColumn); | |
var _iteratorNormalCompletion3 = true; | |
var _didIteratorError3 = false; | |
var _iteratorError3 = undefined; | |
try { | |
for (var _iterator3 = seats[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { | |
var _seat = _step3.value; | |
this._area.addSeat(_seat.x, _seat.y, _seat.info); | |
} | |
} catch (err) { | |
_didIteratorError3 = true; | |
_iteratorError3 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion3 && _iterator3.return) { | |
_iterator3.return(); | |
} | |
} finally { | |
if (_didIteratorError3) { | |
throw _iteratorError3; | |
} | |
} | |
} | |
this.drawSeat(); | |
this.drawLineNumber(); | |
this.drawThumbnail(); | |
} | |
}]); | |
return OtherBBCStandRender; | |
}(MatrixStandRender); | |
var Polygon = function () { | |
/** | |
* @param {context} canvas context | |
* @param {opt} options | |
*/ | |
function Polygon(_ref) { | |
var ctx = _ref.ctx, | |
_ref$points = _ref.points, | |
points = _ref$points === undefined ? [] : _ref$points, | |
_ref$fillStyle = _ref.fillStyle, | |
fillStyle = _ref$fillStyle === undefined ? '#000' : _ref$fillStyle, | |
_ref$strokeStyle = _ref.strokeStyle, | |
strokeStyle = _ref$strokeStyle === undefined ? '#F00' : _ref$strokeStyle, | |
_ref$lineWidth = _ref.lineWidth, | |
lineWidth = _ref$lineWidth === undefined ? 1 : _ref$lineWidth, | |
_ref$globalAlpha = _ref.globalAlpha, | |
globalAlpha = _ref$globalAlpha === undefined ? 1 : _ref$globalAlpha; | |
classCallCheck(this, Polygon); | |
if (!ctx) { | |
throw new Error('ctx is illegal'); | |
} | |
this.ctx = ctx; | |
this.points = points; | |
this.fillStyle = fillStyle; | |
this.strokeStyle = strokeStyle; | |
this.lineWidth = lineWidth; | |
this.globalAlpha = globalAlpha; | |
this.boundingRect = null; | |
this.init(); | |
} | |
/** | |
* 初始方法 | |
*/ | |
createClass(Polygon, [{ | |
key: 'init', | |
value: function init() { | |
if (!Array.isArray(this.points) && this.points.length < 2) { | |
throw new Error('illegal points'); | |
} | |
this._render(); | |
} | |
/** | |
* 重绘方法 | |
*/ | |
}, { | |
key: 'redraw', | |
value: function redraw() { | |
this.ctx.save(); | |
this._render(); | |
this.ctx.restore(); | |
} | |
/** | |
* 改变图形的样式 | |
* @param {Object} styles | |
*/ | |
}, { | |
key: 'setAttr', | |
value: function setAttr(_ref2) { | |
var _ref2$lineWidth = _ref2.lineWidth, | |
lineWidth = _ref2$lineWidth === undefined ? this.lineWidth : _ref2$lineWidth, | |
_ref2$fillStyle = _ref2.fillStyle, | |
fillStyle = _ref2$fillStyle === undefined ? this.fillStyle : _ref2$fillStyle, | |
_ref2$strokeStyle = _ref2.strokeStyle, | |
strokeStyle = _ref2$strokeStyle === undefined ? this.strokeStyle : _ref2$strokeStyle, | |
_ref2$globalAlpha = _ref2.globalAlpha, | |
globalAlpha = _ref2$globalAlpha === undefined ? this.globalAlpha : _ref2$globalAlpha; | |
var ctx = this.ctx; | |
ctx.save(); | |
this._updateStyle({ | |
lineWidth: lineWidth, | |
fillStyle: fillStyle, | |
strokeStyle: strokeStyle, | |
globalAlpha: globalAlpha | |
}); | |
this._drawPath(true, true); | |
ctx.restore(); | |
} | |
/** | |
* 测试传入点是否在该图形内 | |
* @param {Number} x | |
* @param {Number} y | |
* @return {Boolean} result | |
*/ | |
}, { | |
key: 'isContainPoint', | |
value: function isContainPoint(x, y) { | |
this._drawPath(); | |
return this.ctx.isPointInPath(x, y); | |
} | |
/** | |
* 获取外层包围矩形 | |
* points在传入时就已经做了ratio的缩放处理 | |
*/ | |
}, { | |
key: 'getBoundingRect', | |
value: function getBoundingRect() { | |
// Lazy | |
if (!this.boundingRect) { | |
// 算出点序列中最小的x,y 最大的x,y | |
var xArr = this.points.map(function (arr) { | |
return arr[0]; | |
}); | |
var yArr = this.points.map(function (arr) { | |
return arr[1]; | |
}); | |
var minX = Math.min.apply(Math, toConsumableArray(xArr)); | |
var minY = Math.min.apply(Math, toConsumableArray(yArr)); | |
var maxX = Math.max.apply(Math, toConsumableArray(xArr)); | |
var maxY = Math.max.apply(Math, toConsumableArray(yArr)); | |
this.boundingRect = { | |
left: minX, | |
top: minY, | |
right: maxX, | |
bottom: maxY | |
}; | |
} | |
return this.boundingRect; | |
} | |
}, { | |
key: 'clearBoundingRect', | |
value: function clearBoundingRect() { | |
this.ctx.save(); | |
var boundingRect = this.getBoundingRect(); | |
this.ctx.clearRect(boundingRect.left - this.lineWidth, boundingRect.top - this.lineWidth, boundingRect.right - boundingRect.left + this.lineWidth, boundingRect.bottom - boundingRect.top + this.lineWidth); | |
this.ctx.restore(); | |
} | |
/** | |
* 绘制图形 | |
*/ | |
}, { | |
key: '_render', | |
value: function _render() { | |
this.ctx.save(); | |
this._drawPath(true, true); | |
this.ctx.restore(); | |
} | |
/** | |
* 绘制Path | |
* @param {Boolean} isFill 是否渲染 | |
* @param {Boolean} isStroke 是否描线 | |
*/ | |
}, { | |
key: '_drawPath', | |
value: function _drawPath() { | |
var isFill = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; | |
var isStroke = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; | |
var _ref3 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { | |
lineWidth: this.lineWidth, | |
fillStyle: this.fillStyle, | |
strokeStyle: this.strokeStyle, | |
globalAlpha: this.globalAlpha | |
}, | |
lineWidth = _ref3.lineWidth, | |
fillStyle = _ref3.fillStyle, | |
strokeStyle = _ref3.strokeStyle, | |
globalAlpha = _ref3.globalAlpha; | |
var ctx = this.ctx; | |
ctx.save(); | |
if (isFill) { | |
ctx.fillStyle = fillStyle || this.fillStyle; | |
ctx.globalAlpha = globalAlpha || this.globalAlpha; | |
} | |
if (isStroke) { | |
ctx.strokeStyle = strokeStyle || this.strokeStyle; | |
ctx.lineWidth = lineWidth || this.lineWidth; | |
} | |
ctx.beginPath(); | |
ctx.moveTo(this.points[0][0], this.points[0][1]); | |
this.points.slice(1).forEach(function (point) { | |
ctx.lineTo(point[0], point[1]); | |
}); | |
ctx.closePath(); | |
isFill && ctx.fill(); | |
isStroke && ctx.stroke(); | |
ctx.restore(); | |
} | |
}, { | |
key: '_updateStyle', | |
value: function _updateStyle(styles) { | |
Object.assign(this, styles); | |
} | |
}]); | |
return Polygon; | |
}(); | |
var Stand = function () { | |
function Stand(_ref) { | |
var _this = this; | |
var _ref$ctx = _ref.ctx, | |
ctx = _ref$ctx === undefined ? null : _ref$ctx, | |
_ref$redrawAllFn = _ref.redrawAllFn, | |
redrawAllFn = _ref$redrawAllFn === undefined ? null : _ref$redrawAllFn, | |
_ref$i = _ref.i, | |
i = _ref$i === undefined ? -1 : _ref$i, | |
_ref$n = _ref.n, | |
n = _ref$n === undefined ? '' : _ref$n, | |
_ref$c = _ref.c, | |
c = _ref$c === undefined ? '000' : _ref$c, | |
_ref$s = _ref.s, | |
s = _ref$s === undefined ? 0 : _ref$s, | |
_ref$pis = _ref.pis, | |
pis = _ref$pis === undefined ? '' : _ref$pis, | |
_ref$j = _ref.j, | |
j = _ref$j === undefined ? '' : _ref$j, | |
_ref$zh = _ref.zh, | |
zh = _ref$zh === undefined ? 0 : _ref$zh, | |
_ref$vid = _ref.vid, | |
vid = _ref$vid === undefined ? 0 : _ref$vid; | |
classCallCheck(this, Stand); | |
this.onMouseEnter = function () { | |
if (_this.status !== 0) { | |
_this.standMaskState = Util.standMaskStatusMap.ACTIVE; | |
_this.isMouseEnter = true; | |
} | |
}; | |
this.onMouseLeave = function () { | |
if (_this.status !== 0) { | |
_this.standMaskState = _this.lastStandMaskState; // 应该是恢复Enter前的状态 (enter前保存一下) | |
_this.isMouseEnter = false; | |
} | |
}; | |
this.ctx = ctx; | |
this.id = i; | |
this.name = n; | |
this.color = c; | |
this.status = s; | |
this.areaPriceList = j ? j.split(',').map(function (v) { | |
return +v; | |
}) : ''; | |
this.zh = zh; | |
this.vid = vid; | |
this.pointsArea = this._parsePointsData(pis); // 解析坐标点数据 | |
this._standMaskState = Util.standMaskStatusMap.INVISIBLE; // 默认不显示 | |
this.polygon = null; | |
this.isMouseEnter = false; | |
this.lastStandMaskState = Util.standMaskStatusMap.INVISIBLE; | |
this.redrawAll = redrawAllFn; | |
this.renderStandPolygon(MaitixVenueRender.ratio); | |
} | |
createClass(Stand, [{ | |
key: '_parsePointsData', | |
/** | |
* 解析区域点数据 | |
* @param {String} pointsStr | |
*/ | |
value: function _parsePointsData(pis) { | |
var pointsArr = pis.split(/,|\|/).map(function (v) { | |
return parseInt(v, 10); | |
}); // 将区域点字符串转换为坐标数组 | |
var result = []; // 再组织数组 | |
for (var i = 1; i < pointsArr.length; i += 2) { | |
var tmpArr = [pointsArr[i - 1], pointsArr[i]]; | |
result.push(tmpArr); | |
} | |
return result; | |
} | |
/** | |
* 测试传入点是否在该图形内 | |
* @param {Number} x | |
* @param {Number} y | |
* @return {Boolean} result | |
*/ | |
}, { | |
key: 'isContainPoint', | |
value: function isContainPoint(x, y) { | |
return this.polygon.isContainPoint(x, y); | |
} | |
/** | |
* 重绘方法 | |
*/ | |
}, { | |
key: 'redraw', | |
value: function redraw() { | |
this.polygon.redraw(); | |
} | |
}, { | |
key: 'renderStandPolygon', | |
value: function renderStandPolygon(ratio) { | |
if (!this.pointsArea) { | |
throw new Error('pointsArea is empty!'); | |
} | |
var color = this.status ? '#' + this.color : '#D8D8D8'; | |
var stroke = this.status ? '#FF1268' : '#D8D8D8'; | |
var points = this.pointsArea.map(function (item) { | |
var x = Math.round(item[0] * ratio); | |
var y = Math.round(item[1] * ratio); | |
return [x, y]; | |
}); | |
var polygon = new Polygon({ | |
ctx: this.ctx, | |
points: points, | |
fillStyle: color, | |
strokeStyle: stroke, | |
lineWidth: 1, | |
globalAlpha: 0.9 | |
}); | |
this.polygon = polygon; | |
return polygon; | |
} | |
}, { | |
key: '_updateStandMask', | |
value: function _updateStandMask() { | |
switch (this._standMaskState) { | |
case Util.standMaskStatusMap.INVISIBLE: | |
this.polygon.setAttr({ | |
fillStyle: 'transparent', | |
strokeStyle: '#D8D8D8' | |
}); | |
break; | |
case Util.standMaskStatusMap.HIGHLIGHT: | |
this.polygon.setAttr({ | |
fillStyle: 'rgba(255,18,104,.3)', | |
strokeStyle: '#FF1268', | |
globalAlpha: 0.9 | |
}); | |
break; | |
case Util.standMaskStatusMap.ACTIVE: | |
this.polygon.setAttr({ | |
fillStyle: '#' + this.color, | |
globalAlpha: 0.9 | |
}); | |
break; | |
default: | |
} | |
this.redrawAll && this.redrawAll(); | |
} | |
}, { | |
key: 'standMaskState', | |
set: function set$$1(nextState) { | |
if (this.status !== 0) { | |
this._standMaskState = nextState; | |
this._updateStandMask(); | |
} | |
} | |
}]); | |
return Stand; | |
}(); | |
/* | |
* @Author: minxu | |
* @Date: 2018-07-16 17:26:07 | |
* @Last Modified by: mikey.zhaopeng | |
* @Last Modified time: 2018-08-29 17:34:14 | |
* @Description: 选区模块的舞台类 | |
*/ | |
var Stage = function () { | |
function Stage() { | |
var $dom = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; | |
var spacePadding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 120; | |
classCallCheck(this, Stage); | |
this.$container = $dom; // 舞台对应的DOM元素 | |
this.zoomRatio = 1; // 舞台的缩放比 | |
this.offsetX = 0; // 舞台的水平偏移 | |
this.offsetY = 0; // 舞台的垂直偏移 | |
this.spacePadding = spacePadding; // 视口拖动距离边界的padding | |
addStyle(this.$container, { | |
position: 'relative', | |
width: '100%', | |
height: '100%', | |
display: 'flex', | |
justifyContent: 'center', | |
alignItems: 'center' | |
}); | |
} | |
/** | |
* 对舞台进行移动 | |
* @param {Number} offsetX | |
* @param {Number} offsetY | |
*/ | |
createClass(Stage, [{ | |
key: 'venueMove', | |
value: function venueMove(offsetX, offsetY) { | |
var positionX = this.offsetX - offsetX * this.zoomRatio; | |
var positionY = this.offsetY - offsetY * this.zoomRatio; | |
addStyle(this.$container, { | |
willChange: 'transform', | |
transform: 'translate3d(' + positionX + 'px, ' + positionY + 'px, 0) scale(' + this.zoomRatio + ')' | |
}); | |
var $parent = this.$container.parentNode; | |
var limitBoundRect = $parent.getBoundingClientRect(); | |
var currentBoundRect = this.$container.firstChild.getBoundingClientRect(); | |
var dirty = false; | |
var maxX = limitBoundRect.right - this.spacePadding * this.zoomRatio; | |
var minX = limitBoundRect.left + this.spacePadding * this.zoomRatio; | |
var maxY = limitBoundRect.bottom - this.spacePadding * this.zoomRatio; | |
var minY = limitBoundRect.top + this.spacePadding * this.zoomRatio; | |
if (currentBoundRect.left > maxX) { | |
positionX += maxX - currentBoundRect.left; | |
dirty = true; | |
} else if (currentBoundRect.right < minX) { | |
positionX += minX - currentBoundRect.right; | |
dirty = true; | |
} | |
if (currentBoundRect.top > maxY) { | |
positionY += maxY - currentBoundRect.top; | |
dirty = true; | |
} else if (currentBoundRect.bottom < minY) { | |
positionY += minY - currentBoundRect.bottom; | |
dirty = true; | |
} | |
if (dirty) { | |
addStyle(this.$container, { | |
willChange: 'transform', | |
transform: 'translate3d(' + positionX + 'px, ' + positionY + 'px, 0) scale(' + this.zoomRatio + ')' | |
}); | |
} | |
this.offsetX = positionX; | |
this.offsetY = positionY; | |
} | |
/** | |
* 对舞台进行缩放 | |
* @param {Number} ratio | |
*/ | |
}, { | |
key: 'venueZoomRatio', | |
value: function venueZoomRatio(ratio) { | |
this.zoomRatio += ratio; | |
if (this.zoomRatio > 3) { | |
this.zoomRatio = 3; | |
} | |
if (this.zoomRatio < 1) { | |
this.zoomRatio = 1; | |
} | |
addStyle(this.$container, { | |
willChange: 'transform', | |
transform: 'translate3d(' + this.offsetX + 'px, ' + this.offsetY + 'px, 0) scale(' + this.zoomRatio + ')' | |
}); | |
} | |
/** | |
* 重置舞台属性 | |
*/ | |
}, { | |
key: 'reset', | |
value: function reset() { | |
addStyle(this.$container, { | |
willChange: 'transform', | |
transform: 'translate3d(0,0,0) scale(1)', | |
transition: 'transform .3s' | |
}); | |
this.offsetX = 0; | |
this.offsetY = 0; | |
this.zoomRatio = 1; | |
} | |
/** | |
* | |
*/ | |
}, { | |
key: 'cancelTransition', | |
value: function cancelTransition() { | |
addStyle(this.$container, { | |
transition: 'none' | |
}); | |
} | |
/** | |
* 销毁实例方法 | |
*/ | |
}, { | |
key: 'destroy', | |
value: function destroy() { | |
this.$container = null; | |
} | |
}]); | |
return Stage; | |
}(); | |
var _class$13; | |
function _applyDecoratedDescriptor$3(target, property, decorators, descriptor, context) { | |
var desc = {}; | |
Object['ke' + 'ys'](descriptor).forEach(function (key) { | |
desc[key] = descriptor[key]; | |
}); | |
desc.enumerable = !!desc.enumerable; | |
desc.configurable = !!desc.configurable; | |
if ('value' in desc || desc.initializer) { | |
desc.writable = true; | |
} | |
desc = decorators.slice().reverse().reduce(function (desc, decorator) { | |
return decorator(target, property, desc) || desc; | |
}, desc); | |
if (context && desc.initializer !== void 0) { | |
desc.value = desc.initializer ? desc.initializer.call(context) : void 0; | |
desc.initializer = undefined; | |
} | |
if (desc.initializer === void 0) { | |
Object['define' + 'Property'](target, property, desc); | |
desc = null; | |
} | |
return desc; | |
} | |
var VenueRender = (_class$13 = function () { | |
function VenueRender($container) { | |
var _this = this; | |
classCallCheck(this, VenueRender); | |
this.handleVenueSelectStand = function (selectedStand) { | |
if (_this.onSelectStand) { | |
_this.onSelectStand(selectedStand); | |
} | |
}; | |
this.handleVenueError = function (e) { | |
if (_this.onError) { | |
_this.onError(e); | |
} | |
}; | |
var $newContainer = document.createElement('div'); | |
$container.appendChild($newContainer); | |
this.stage = new Stage($newContainer); | |
this.$container = $newContainer; | |
this.containerWidth = $container.clientWidth; | |
this.containerHeight = $container.clientHeight; | |
this.avaibleStandsArr = []; | |
this.priceList = []; | |
this.onSelectStand = null; // 对外暴露的点击事件 | |
this.onError = null; | |
this.currentSelectedStand = null; | |
this.allStandsArr = []; | |
this._setup(); | |
} | |
createClass(VenueRender, [{ | |
key: '_setup', | |
value: function _setup() { | |
this.$container.parentNode.addEventListener('touchstart', this.onTouchStart); | |
this.$container.parentNode.addEventListener('touchmove', this.onTouchMove); | |
this.$container.parentNode.addEventListener('touchend', this.onTouchEnd); | |
this.$container.parentNode.addEventListener('mousedown', this.onTouchStart); | |
this.$container.parentNode.addEventListener('mousemove', this.onTouchMove); | |
this.$container.parentNode.addEventListener('mouseup', this.onTouchEnd); | |
this.$container.parentNode.addEventListener('mouseleave', this.onMouseLeave); | |
this.$container.parentNode.addEventListener('mousewheel', this.onMouseWheel); | |
} | |
/** | |
* 对外暴露的onClick | |
*/ | |
/** | |
* 对外暴露的onError | |
*/ | |
}, { | |
key: 'onTouchStart', | |
value: function onTouchStart(e) { | |
var _this2 = this; | |
e.preventDefault(); | |
// 清空动画 | |
window.requestAnimationFrame(function () { | |
_this2.stage.cancelTransition(); | |
}); | |
this.touchStatus = 'start'; | |
this.prevTouchPoints = getEventPoints(e); | |
} | |
}, { | |
key: 'onTouchMove', | |
value: function onTouchMove(e) { | |
var _this3 = this; | |
e.preventDefault(); | |
if (!this.prevTouchPoints) { | |
return; | |
} | |
// vivo手机极度敏感容易触发touchmove的解决问题 | |
var currentTouchPoints = getEventPoints(e); | |
if (Math.abs(currentTouchPoints[0].x - this.prevTouchPoints[0].x) <= 1.5 && Math.abs(currentTouchPoints[0].y - this.prevTouchPoints[0].y) <= 1.5) { | |
return; | |
} | |
this.touchStatus = 'move'; // 考虑到两指缩放离开屏幕时可能会有先后,故不在这里判断 | |
if (this.currentSelectedStand && this.avaibleStandsArr.some(function (stand) { | |
return _this3.currentSelectedStand.vid === stand.vid; | |
})) { | |
this.currentSelectedStand.onMouseLeave(); | |
} | |
if (currentTouchPoints.length === 1) { | |
// 如果是二指缩放, 且手指离开时间不一致, 又触发了move事件 | |
if (this.prevTouchPoints.length === 2) { | |
this.prevTouchPoints = currentTouchPoints; | |
return; | |
} | |
// 单指拖动 | |
var offsetX = this.prevTouchPoints[0].x - currentTouchPoints[0].x; | |
var offsetY = this.prevTouchPoints[0].y - currentTouchPoints[0].y; | |
this.stage.venueMove(offsetX, offsetY); | |
this.prevTouchPoints = currentTouchPoints; | |
} else if (currentTouchPoints.length === 2) { | |
// 双指缩放 | |
// 当单指滑动过程中又多一根手指 | |
if (this.prevTouchPoints.length === 1) { | |
return; | |
} | |
var sx = this.prevTouchPoints[0].x - this.prevTouchPoints[1].x; | |
var sy = this.prevTouchPoints[0].y - this.prevTouchPoints[1].y; | |
var ex = currentTouchPoints[0].x - currentTouchPoints[1].x; | |
var ey = currentTouchPoints[0].y - currentTouchPoints[1].y; | |
var d1 = Math.sqrt(sx * sx + sy * sy); | |
var d2 = Math.sqrt(ex * ex + ey * ey); | |
var ratio = (d2 - d1) / 400; | |
this.stage.venueZoomRatio(ratio); | |
this.prevTouchPoints = currentTouchPoints; | |
} | |
// 判断坐标点是否已经移出界 | |
var posX = e.clientX || e.touches[0].clientX; | |
var posY = e.clientY || e.touches[0].clientY; | |
if (posX < 0 || posX > document.documentElement.clientWidth || posY > document.documentElement.clientHeight || posY < 0) { | |
this.onTouchEnd(e); | |
} | |
} | |
}, { | |
key: 'onTouchEnd', | |
value: function onTouchEnd(e) { | |
e.preventDefault(); | |
// 如果status不是move,说明是点击事件 | |
if (this.touchStatus === 'start' && this.currentSelectedStand) { | |
var selectedStand = this.currentSelectedStand; | |
if (selectedStand.status === 0) { | |
this.handleVenueError({ | |
code: ErrorCode.StandNoAvaliableSeat, | |
message: ErrorMessage.stand_no_chooseable_seat(selectedStand.name), | |
messageKey: 'stand_no_chooseable_seat' | |
}); | |
} else { | |
this.handleVenueSelectStand(this.currentSelectedStand); | |
} | |
this.currentSelectedStand.onMouseLeave(); | |
} else if (this.touchStatus === 'move') { | |
// move结束,归位 | |
if (this.stage.zoomRatio < 1.1) { | |
this.stage.reset(); | |
} | |
} | |
this.currentSelectedStand = null; | |
this.prevTouchPoints = null; | |
} | |
}, { | |
key: 'onMouseLeave', | |
value: function onMouseLeave(e) { | |
e.preventDefault(); | |
this.prevTouchPoints = null; | |
if (this.stage.zoomRatio < 1.1) { | |
this.stage.reset(); | |
} | |
} | |
}, { | |
key: 'onMouseWheel', | |
value: function onMouseWheel(e) { | |
e.preventDefault(); | |
this.stage.venueZoomRatio((e.deltaY || e.wheelDelta) / 500); | |
} | |
/** | |
* 回收实例 | |
*/ | |
}, { | |
key: 'destroy', | |
value: function destroy() { | |
try { | |
this.avaibleStandsArr = null; | |
this.priceList = null; | |
this.onSelectStand = null; // 对外暴露的点击事件 | |
this.onError = null; | |
this.currentSelectedStand = null; | |
this.allStandsArr = null; | |
this.$container.parentNode.removeEventListener('touchstart', this.onTouchStart); | |
this.$container.parentNode.removeEventListener('touchmove', this.onTouchMove); | |
this.$container.parentNode.removeEventListener('touchend', this.onTouchEnd); | |
this.$container.parentNode.removeEventListener('mousedown', this.onTouchStart); | |
this.$container.parentNode.removeEventListener('mousemove', this.onTouchMove); | |
this.$container.parentNode.removeEventListener('mouseup', this.onTouchEnd); | |
this.$container.parentNode.removeEventListener('mouseleave', this.onMouseLeave); | |
this.$container.parentNode.removeEventListener('mousewheel', this.onMouseWheel); | |
this.handleVenueSelectStand = null; | |
this.handleVenueError = null; | |
this.onTouchStart = null; | |
this.onTouchMove = null; | |
this.onTouchEnd = null; | |
this.prevTouchPoints = null; | |
this.$container = null; | |
} catch (error) {} | |
} | |
}]); | |
return VenueRender; | |
}(), _applyDecoratedDescriptor$3(_class$13.prototype, 'onTouchStart', [autobind], Object.getOwnPropertyDescriptor(_class$13.prototype, 'onTouchStart'), _class$13.prototype), _applyDecoratedDescriptor$3(_class$13.prototype, 'onTouchMove', [autobind], Object.getOwnPropertyDescriptor(_class$13.prototype, 'onTouchMove'), _class$13.prototype), _applyDecoratedDescriptor$3(_class$13.prototype, 'onTouchEnd', [autobind], Object.getOwnPropertyDescriptor(_class$13.prototype, 'onTouchEnd'), _class$13.prototype), _applyDecoratedDescriptor$3(_class$13.prototype, 'onMouseLeave', [autobind], Object.getOwnPropertyDescriptor(_class$13.prototype, 'onMouseLeave'), _class$13.prototype), _applyDecoratedDescriptor$3(_class$13.prototype, 'onMouseWheel', [autobind], Object.getOwnPropertyDescriptor(_class$13.prototype, 'onMouseWheel'), _class$13.prototype), _class$13); | |
var _class$12; | |
var _class2$2; | |
var _temp$8; | |
function _applyDecoratedDescriptor$2(target, property, decorators, descriptor, context) { | |
var desc = {}; | |
Object['ke' + 'ys'](descriptor).forEach(function (key) { | |
desc[key] = descriptor[key]; | |
}); | |
desc.enumerable = !!desc.enumerable; | |
desc.configurable = !!desc.configurable; | |
if ('value' in desc || desc.initializer) { | |
desc.writable = true; | |
} | |
desc = decorators.slice().reverse().reduce(function (desc, decorator) { | |
return decorator(target, property, desc) || desc; | |
}, desc); | |
if (context && desc.initializer !== void 0) { | |
desc.value = desc.initializer ? desc.initializer.call(context) : void 0; | |
desc.initializer = undefined; | |
} | |
if (desc.initializer === void 0) { | |
Object['define' + 'Property'](target, property, desc); | |
desc = null; | |
} | |
return desc; | |
} | |
var MaitixVenueRender = (_class$12 = (_temp$8 = _class2$2 = function (_VenueRender) { | |
inherits(MaitixVenueRender, _VenueRender); | |
// 背景图的原始尺寸 | |
function MaitixVenueRender($container) { | |
classCallCheck(this, MaitixVenueRender); | |
var _this = possibleConstructorReturn(this, (MaitixVenueRender.__proto__ || Object.getPrototypeOf(MaitixVenueRender)).call(this, $container)); | |
_this.redrawAll = function () { | |
_this.clearCanvas(); | |
_this.allStandsArr.forEach(function (stand) { | |
return stand.redraw(); | |
}); | |
}; | |
_this.clearCanvas = function () { | |
var ctx = _this.$canvas.getContext('2d'); | |
ctx.save(); | |
ctx.clearRect(0, 0, _this.containerWidth, MaitixVenueRender.ratio * MaitixVenueRender.imgSize.height); | |
ctx.restore(); | |
}; | |
_this.$canvas = null; | |
_this.$background = null; | |
_this.initDOM(); | |
_this.updateAllCanvasStyle({ | |
position: 'absolute', | |
top: 0, | |
left: 0 | |
}); | |
return _this; | |
} // 获取到的图片显示在Canvas元素时的缩放比 | |
createClass(MaitixVenueRender, [{ | |
key: 'initDOM', | |
value: function initDOM() { | |
var $canvas = createCanvas(this.containerWidth, this.containerHeight); | |
var $background = document.createElement('div'); | |
this.$canvas = $canvas; | |
this.$background = $background; | |
var $contentContainer = document.createElement('div'); | |
addStyle($contentContainer, { | |
position: 'relative', | |
width: '100%' | |
}); | |
$contentContainer.appendChild($background); | |
$contentContainer.appendChild($canvas); | |
this.$container.appendChild($contentContainer); | |
} | |
/** | |
* 对外暴露的场馆区域渲染接口 | |
* @param {String} backgroundImageUrl | |
* @param {Array} standsData | |
* @param {Array} priceList | |
*/ | |
}, { | |
key: 'render', | |
value: function () { | |
var _ref = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee(backgroundImageUrl, standsData) { | |
var img, ratio, imgWidth, imgHeight, originY, contentHeight; | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
// 一个很典型的 使用promise不如async/await好的区别,(try/catch) | |
// 可是img要定义在外面好蛋疼 | |
img = null; | |
_context.prev = 1; | |
_context.next = 4; | |
return fetchImage(backgroundImageUrl); | |
case 4: | |
img = _context.sent; | |
_context.next = 10; | |
break; | |
case 7: | |
_context.prev = 7; | |
_context.t0 = _context['catch'](1); | |
this.handleVenueError({ | |
code: ErrorCode.VenueImgNotFound, | |
message: ErrorMessage.load_venue_image_fail, | |
messageKey: 'load_venue_image_fail' | |
}); | |
case 10: | |
// 渲染底图 | |
addStyle(this.$background, { | |
width: this.containerWidth, | |
height: this.containerHeight, | |
backgroundImage: 'url(' + backgroundImageUrl + ')', | |
backgroundSize: 'contain', | |
backgroundRepeat: 'no-repeat' | |
}); | |
ratio = this.containerWidth / img.naturalWidth; | |
imgWidth = img.naturalWidth; | |
imgHeight = img.naturalHeight; | |
if (imgHeight * ratio > this.containerHeight) { | |
ratio *= this.containerHeight / (imgHeight * ratio); | |
// 底图按比例缩放之后,绘制在div上 高度仍超出div高度,则需要根据高度超出部分再进行缩放 | |
} | |
// 如果长度比containerHeight短,需要按比例移动 | |
if (imgHeight * ratio < this.containerHeight) { | |
originY = Math.ceil(imgHeight * ratio / 2) / this.containerHeight; | |
this.updateAllCanvasStyle({ | |
transformOrigin: '50% ' + originY.toFixed(2) * 100 + '%' | |
}); | |
} | |
MaitixVenueRender.ratio = ratio; | |
MaitixVenueRender.imgSize.width = imgWidth; | |
MaitixVenueRender.imgSize.height = imgHeight; | |
// 重新调整canvas样式的高度,以实际渲染的大小为准,因为宽度就是containerWidth,所以只需调整高度 | |
contentHeight = imgHeight * ratio; | |
this.updateAllCanvasStyle({ | |
height: contentHeight | |
}); | |
this.$canvas.height = imgHeight * ratio; | |
addStyle(this.$canvas.parentNode, { | |
height: contentHeight | |
}); | |
this._renderStands(standsData); // 其实在传数据之前应该包一层Adapter | |
case 24: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, this, [ | |
[1, 7] | |
]); | |
})); | |
function render(_x, _x2) { | |
return _ref.apply(this, arguments); | |
} | |
return render; | |
}() | |
}, { | |
key: 'highlightStands', | |
value: function highlightStands(priceIndex) { | |
var priceId = this.priceList[priceIndex] ? this.priceList[priceIndex].maitixPriceId : undefined; | |
var isNoAvaibleStands = true; | |
this.avaibleStandsArr.forEach(function (stand) { | |
if (Array.isArray(stand.areaPriceList) && stand.areaPriceList.some(function (val) { | |
return val === priceId; | |
})) { | |
isNoAvaibleStands = false; | |
stand.standMaskState = Util.standMaskStatusMap.HIGHLIGHT; | |
} else { | |
stand.standMaskState = Util.standMaskStatusMap.INVISIBLE; | |
} | |
}); | |
if (isNoAvaibleStands && priceIndex !== -1) { | |
this.handleVenueError({ | |
code: ErrorCode.Normal, | |
message: ErrorMessage.seat_sold_out, | |
messageKey: 'seat_sold_out' | |
}); | |
} | |
} | |
/** | |
* 回收实例 | |
*/ | |
}, { | |
key: 'destroy', | |
value: function destroy() { | |
try { | |
get(MaitixVenueRender.prototype.__proto__ || Object.getPrototypeOf(MaitixVenueRender.prototype), 'destroy', this).call(this); | |
this.$canvas.parentNode.removeChild(this.$canvas); | |
this.$background.parentNode.removeChild(this.$background); | |
this.$canvas = null; | |
this.$background = null; | |
this.redrawAll = null; | |
this.clearCanvas = null; | |
} catch (error) {} | |
} | |
}, { | |
key: '_renderStands', | |
value: function _renderStands(standsData) { | |
var _this2 = this; | |
try { | |
standsData.forEach(function (item) { | |
// Stand实例化时会绘制区域(生成polygon,会用到VenueRender.ratio); | |
var stand = new Stand(_extends({ | |
ctx: _this2.$canvas.getContext('2d'), | |
redrawAllFn: _this2.redrawAll | |
}, item)); | |
if (!stand.areaPriceList) { | |
stand.status = 0; | |
item.s = 0; | |
} | |
_this2.allStandsArr.push(stand); | |
if (item.s !== 0) { | |
_this2.avaibleStandsArr.push(stand); | |
stand.standMaskState = Util.standMaskStatusMap.INVISIBLE; | |
} | |
}); | |
} catch (error) { | |
this.handleVenueError({ | |
code: ErrorCode.VenueRenderStandFail, | |
message: ErrorMessage.render_stand_data_fail, | |
messageKey: 'render_stand_data_fail' | |
}); | |
} | |
} | |
}, { | |
key: 'onTouchStart', | |
value: function onTouchStart(e) { | |
get(MaitixVenueRender.prototype.__proto__ || Object.getPrototypeOf(MaitixVenueRender.prototype), 'onTouchStart', this).call(this, e); | |
var position = this.$canvas.getBoundingClientRect(); | |
var x = Math.floor((this.prevTouchPoints[0].x - position.left) / this.stage.zoomRatio); | |
var y = Math.floor((this.prevTouchPoints[0].y - position.top) / this.stage.zoomRatio); | |
var selectedStand = this.getStandByPoint(x, y); | |
if (selectedStand) { | |
this.currentSelectedStand = selectedStand; | |
selectedStand.lastStandMaskState = selectedStand._standMaskState; | |
selectedStand.onMouseEnter(); | |
} | |
} | |
/** | |
* 同时对于背景图canvas与区域canvas两个DOM元素进行样式改变 | |
* @param {Obj} style | |
*/ | |
}, { | |
key: 'updateAllCanvasStyle', | |
value: function updateAllCanvasStyle(style) { | |
addStyle(this.$canvas, style); | |
addStyle(this.$background, style); | |
} | |
/** | |
* 根据点坐标返回所对应的stand | |
* @param {Number} x | |
* @param {Number} y | |
*/ | |
}, { | |
key: 'getStandByPoint', | |
value: function getStandByPoint(x, y) { | |
var selectedStand = null; | |
this.allStandsArr.some(function (stand) { | |
if (stand.isContainPoint(x, y)) { | |
selectedStand = stand; | |
return true; | |
} | |
return false; | |
}); | |
return selectedStand; | |
} | |
/** | |
* 重绘所有区域 | |
*/ | |
/** | |
* 清除画布方法 | |
*/ | |
}]); | |
return MaitixVenueRender; | |
}(VenueRender), _class2$2.ratio = 1, _class2$2.imgSize = { | |
width: 0, | |
height: 0 | |
}, _temp$8), _applyDecoratedDescriptor$2(_class$12.prototype, 'onTouchStart', [autobind], Object.getOwnPropertyDescriptor(_class$12.prototype, 'onTouchStart'), _class$12.prototype), _class$12); | |
var _class$14; | |
var _temp$9; | |
var BBCVenueRender = (_temp$9 = _class$14 = function (_MaitixVenueRender) { | |
inherits(BBCVenueRender, _MaitixVenueRender); | |
function BBCVenueRender() { | |
classCallCheck(this, BBCVenueRender); | |
return possibleConstructorReturn(this, (BBCVenueRender.__proto__ || Object.getPrototypeOf(BBCVenueRender)).apply(this, arguments)); | |
} | |
createClass(BBCVenueRender, [{ | |
key: 'render', | |
// 背景图的原始尺寸 | |
/** | |
* 对外暴露的场馆区域渲染接口 | |
* @param {String} backgroundImageUrl | |
* @param {Array} standsData | |
* @param {Array} priceList | |
*/ | |
value: function () { | |
var _ref = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee(backgroundImageUrl, standsData) { | |
var img, ratio, imgWidth, imgHeight, originY, contentHeight; | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
// 一个很典型的 使用promise不如async/await好的区别,(try/catch) | |
// 可是img要定义在外面好蛋疼 | |
img = null; | |
_context.prev = 1; | |
_context.next = 4; | |
return fetchImage(backgroundImageUrl); | |
case 4: | |
img = _context.sent; | |
_context.next = 10; | |
break; | |
case 7: | |
_context.prev = 7; | |
_context.t0 = _context['catch'](1); | |
this.handleVenueError({ | |
code: ErrorCode.VenueImgNotFound, | |
message: ErrorMessage.load_venue_image_fail, | |
messageKey: 'load_venue_image_fail' | |
}); | |
case 10: | |
// 渲染底图 | |
addStyle(this.$background, { | |
width: this.containerWidth, | |
height: this.containerHeight, | |
backgroundImage: 'url(' + backgroundImageUrl + ')', | |
backgroundSize: 'contain', | |
backgroundRepeat: 'no-repeat' | |
}); | |
ratio = this.containerWidth / img.naturalWidth; | |
imgWidth = img.naturalWidth; | |
imgHeight = img.naturalHeight; | |
if (imgHeight * ratio > this.containerHeight) { | |
ratio *= this.containerHeight / (imgHeight * ratio); | |
// 底图按比例缩放之后,绘制在div上 高度仍超出div高度,则需要根据高度超出部分再进行缩放 | |
} | |
// 如果长度比containerHeight短,需要按比例移动 | |
if (imgHeight * ratio < this.containerHeight) { | |
originY = Math.ceil(imgHeight * ratio / 2) / this.containerHeight; | |
this.updateAllCanvasStyle({ | |
transformOrigin: '50% ' + originY.toFixed(2) * 100 + '%' | |
}); | |
} | |
// BBC获取的jpg底图需要 宽高*2 | |
BBCVenueRender.ratio = this.containerWidth / (img.naturalWidth * 2); | |
BBCVenueRender.imgSize.width = imgWidth * 2; | |
BBCVenueRender.imgSize.height = imgHeight * 2; | |
// 重新调整canvas样式的高度,以实际渲染的大小为准,因为宽度就是containerWidth,所以只需调整高度 | |
contentHeight = BBCVenueRender.imgSize.height * BBCVenueRender.ratio; | |
this.updateAllCanvasStyle({ | |
height: contentHeight | |
}); | |
this.$canvas.height = BBCVenueRender.imgSize.height * BBCVenueRender.ratio; | |
addStyle(this.$canvas.parentNode, { | |
height: contentHeight | |
}); | |
this._renderStands(standsData); // 其实在传数据之前应该包一层Adapter | |
case 24: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, this, [ | |
[1, 7] | |
]); | |
})); | |
function render(_x, _x2) { | |
return _ref.apply(this, arguments); | |
} | |
return render; | |
}() // 获取到的图片显示在Canvas元素时的缩放比 | |
}]); | |
return BBCVenueRender; | |
}(MaitixVenueRender), _class$14.ratio = 1, _class$14.imgSize = { | |
width: 0, | |
height: 0 | |
}, _temp$9); | |
var BBCSVGStand = function () { | |
function BBCSVGStand(_ref) { | |
var _this = this; | |
var _ref$element = _ref.element, | |
element = _ref$element === undefined ? null : _ref$element, | |
_ref$i = _ref.i, | |
i = _ref$i === undefined ? -1 : _ref$i, | |
_ref$n = _ref.n, | |
n = _ref$n === undefined ? '' : _ref$n, | |
_ref$c = _ref.c, | |
c = _ref$c === undefined ? '000' : _ref$c, | |
_ref$s = _ref.s, | |
s = _ref$s === undefined ? 0 : _ref$s, | |
_ref$j = _ref.j, | |
j = _ref$j === undefined ? '' : _ref$j, | |
_ref$zh = _ref.zh, | |
zh = _ref$zh === undefined ? 0 : _ref$zh, | |
_ref$vid = _ref.vid, | |
vid = _ref$vid === undefined ? 0 : _ref$vid, | |
_ref$lineWidth = _ref.lineWidth, | |
lineWidth = _ref$lineWidth === undefined ? null : _ref$lineWidth, | |
_ref$rainbow = _ref.rainbow, | |
rainbow = _ref$rainbow === undefined ? '' : _ref$rainbow; | |
classCallCheck(this, BBCSVGStand); | |
this.onMouseEnter = function () { | |
if (_this.status !== 0) { | |
_this.standMaskState = Util.standMaskStatusMap.ACTIVE; | |
_this.isMouseEnter = true; | |
} | |
}; | |
this.onMouseLeave = function () { | |
if (_this.status !== 0) { | |
_this.standMaskState = _this.lastStandMaskState; // 应该是恢复Enter前的状态 (enter前保存一下) | |
_this.isMouseEnter = false; | |
} | |
}; | |
this.$el = element; | |
this.id = i; | |
this.name = n; | |
this.color = c; | |
this.status = s; | |
this.areaPriceList = j ? j.split(',').map(function (v) { | |
return +v; | |
}) : ''; | |
this.zh = zh; | |
this.vid = vid; | |
// 票务云项目彩虹图 | |
this.rainbow = {}; | |
if (rainbow) { | |
rainbow.split('|').forEach(function (item) { | |
var idAndColor = item.split('='); | |
if (idAndColor[0]) { | |
_this.rainbow[idAndColor[0]] = idAndColor[1]; | |
} | |
}); | |
} | |
this.lineWidth = lineWidth; | |
this._standMaskState = Util.standMaskStatusMap.INVISIBLE; // 默认不显示 | |
this.isMouseEnter = false; | |
this.lastStandMaskState = Util.standMaskStatusMap.INVISIBLE; | |
this.initStyle(); | |
} | |
createClass(BBCSVGStand, [{ | |
key: 'initStyle', | |
value: function initStyle() { | |
var disableColor = '#BCC3C8'; | |
var isAvaible = this.status === 1; | |
if (this.$el.tagName === 'g') { | |
for (var i = 0; i < this.$el.childNodes.length; i++) { | |
var $path = this.$el.childNodes[i]; | |
var rowId = $path.getAttribute('row_id'); | |
addStyle($path, { | |
fill: isAvaible ? this.rainbow[rowId] : disableColor | |
}); | |
} | |
} else { | |
addStyle(this.$el, { | |
fill: isAvaible ? getNormalizeColor(this.color) : disableColor | |
}); | |
} | |
} | |
}, { | |
key: '_updateStandMask', | |
value: function _updateStandMask() { | |
var $dom = this.$el; | |
// 如果是<g>标签(彩虹图), 则给第一个zi'yuan | |
if ($dom.tagName === 'g' && $dom.childNodes && $dom.childNodes.length > 1) { | |
$dom = $dom.childNodes[0]; | |
} | |
switch (this._standMaskState) { | |
case Util.standMaskStatusMap.INVISIBLE: | |
addStyle($dom, { | |
strokeWidth: 5, | |
stroke: 'transparent', | |
opacity: 1 | |
}); | |
break; | |
case Util.standMaskStatusMap.HIGHLIGHT: | |
addStyle($dom, { | |
stroke: '#111111', | |
strokeWidth: BBCSVGRender.highlightStrokeWidth, | |
opacity: 1 | |
}); | |
break; | |
case Util.standMaskStatusMap.ACTIVE: | |
addStyle($dom, { | |
opacity: 0.7 | |
}); | |
break; | |
case Util.standMaskStatusMap.TRANSLUCENT: | |
addStyle($dom, { | |
opacity: 0.2, | |
strokeWidth: 5, | |
stroke: 'transparent' | |
}); | |
break; | |
default: | |
} | |
} | |
}, { | |
key: 'standMaskState', | |
set: function set$$1(nextState) { | |
if (this.status !== 0) { | |
this._standMaskState = nextState; | |
this._updateStandMask(); | |
} | |
} | |
}]); | |
return BBCSVGStand; | |
}(); | |
var _class$15; | |
var _class2$3; | |
var _temp$10; | |
function _applyDecoratedDescriptor$4(target, property, decorators, descriptor, context) { | |
var desc = {}; | |
Object['ke' + 'ys'](descriptor).forEach(function (key) { | |
desc[key] = descriptor[key]; | |
}); | |
desc.enumerable = !!desc.enumerable; | |
desc.configurable = !!desc.configurable; | |
if ('value' in desc || desc.initializer) { | |
desc.writable = true; | |
} | |
desc = decorators.slice().reverse().reduce(function (desc, decorator) { | |
return decorator(target, property, desc) || desc; | |
}, desc); | |
if (context && desc.initializer !== void 0) { | |
desc.value = desc.initializer ? desc.initializer.call(context) : void 0; | |
desc.initializer = undefined; | |
} | |
if (desc.initializer === void 0) { | |
Object['define' + 'Property'](target, property, desc); | |
desc = null; | |
} | |
return desc; | |
} | |
var BBCSVGRender = (_class$15 = (_temp$10 = _class2$3 = function (_VenueRender) { | |
inherits(BBCSVGRender, _VenueRender); | |
function BBCSVGRender($container) { | |
classCallCheck(this, BBCSVGRender); | |
var _this = possibleConstructorReturn(this, (BBCSVGRender.__proto__ || Object.getPrototypeOf(BBCSVGRender)).call(this, $container)); | |
_this.onHoverStand = null; // 对外暴露的看台hover事件 | |
return _this; | |
} | |
/** | |
* 对外暴露的场馆区域渲染接口 | |
* @param {String} backgroundImageUrl | |
* @param {Array} standsData | |
* @param {Array} priceList | |
* @param {String} svgImageBody | |
*/ | |
createClass(BBCSVGRender, [{ | |
key: 'render', | |
value: function () { | |
var _ref = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee(backgroundImageUrl, standsData, svgImageBody, isRainbow) { | |
var svgData; | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
BBCSVGRender.isRainbow = isRainbow; | |
svgData = this.getSvgData(svgImageBody, standsData); | |
// 加入DOM树 | |
this.$container.appendChild(svgData.$svgObj); | |
// 处理stands | |
standsData = svgData.stands.map(function (item) { | |
return _extends({ | |
element: item.element, | |
standId: item.standId | |
}, item.stand); | |
}); | |
this._renderStands(standsData); // 其实在传数据之前应该包一层Adapter | |
case 5: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, this); | |
})); | |
function render(_x, _x2, _x3, _x4) { | |
return _ref.apply(this, arguments); | |
} | |
return render; | |
}() | |
}, { | |
key: 'highlightStands', | |
value: function highlightStands(priceIndex) { | |
if (BBCSVGRender.isRainbow) { | |
return; | |
} | |
var priceId = this.priceList[priceIndex] ? this.priceList[priceIndex].maitixPriceId : undefined; | |
var isNoAvaibleStands = true; | |
/** | |
* 如果是-1 则是取消选中 | |
* 如果不是 则为切换选中票价,非选中部分变为半透明状态 | |
*/ | |
this.avaibleStandsArr.forEach(function (stand) { | |
if (Array.isArray(stand.areaPriceList) && stand.areaPriceList.some(function (val) { | |
return val === priceId; | |
})) { | |
isNoAvaibleStands = false; | |
stand.standMaskState = Util.standMaskStatusMap.HIGHLIGHT; | |
} else { | |
stand.standMaskState = +priceIndex === -1 ? Util.standMaskStatusMap.INVISIBLE : Util.standMaskStatusMap.TRANSLUCENT; | |
} | |
}); | |
if (isNoAvaibleStands && priceIndex !== -1) { | |
this.handleVenueError({ | |
code: ErrorCode.Normal, | |
message: ErrorMessage.seat_sold_out, | |
messageKey: 'seat_sold_out' | |
}); | |
} | |
} | |
/** | |
* 回收实例 | |
*/ | |
}, { | |
key: 'destroy', | |
value: function destroy() { | |
try { | |
get(BBCSVGRender.prototype.__proto__ || Object.getPrototypeOf(BBCSVGRender.prototype), 'destroy', this).call(this); | |
this.onHoverStand = null; | |
} catch (error) {} | |
} | |
}, { | |
key: '_renderStands', | |
value: function _renderStands(standsData) { | |
var _this2 = this; | |
try { | |
standsData.forEach(function (item) { | |
// console.log('item', item); | |
var stand = new BBCSVGStand(_extends({}, item)); | |
if (!stand.areaPriceList) { | |
stand.status = 0; | |
item.s = 0; | |
} | |
_this2.allStandsArr.push(stand); | |
if (item.s !== 0) { | |
_this2.avaibleStandsArr.push(stand); | |
stand.standMaskState = Util.standMaskStatusMap.INVISIBLE; | |
} | |
}); | |
} catch (error) { | |
this.handleVenueError({ | |
code: ErrorCode.VenueRenderStandFail, | |
message: ErrorMessage.render_stand_data_fail, | |
messageKey: 'render_stand_data_fail' | |
}); | |
} | |
} | |
}, { | |
key: 'onTouchStart', | |
value: function onTouchStart(e) { | |
get(BBCSVGRender.prototype.__proto__ || Object.getPrototypeOf(BBCSVGRender.prototype), 'onTouchStart', this).call(this, e); | |
var floorid = e.target.getAttribute('floorid'); | |
// 注意floorid是String类型, 普通svg项目vid是String类型, 彩虹图项目vid是Number类型 | |
if (floorid && this.allStandsArr.some(function (stand) { | |
return stand.vid.toString() === floorid; | |
})) { | |
var selectedStand = this.allStandsArr.find(function (stand) { | |
return stand.vid.toString() === floorid; | |
}); | |
this.currentSelectedStand = selectedStand; | |
selectedStand.lastStandMaskState = selectedStand._standMaskState; | |
selectedStand.onMouseEnter(); | |
} | |
} | |
}, { | |
key: 'onTouchMove', | |
value: function onTouchMove(e) { | |
get(BBCSVGRender.prototype.__proto__ || Object.getPrototypeOf(BBCSVGRender.prototype), 'onTouchMove', this).call(this, e); | |
if (UA.isPC && this.onHoverStand) { | |
var point = getEventPoints(e)[0]; | |
var floorid = e.target.getAttribute('floorid'); | |
// 注意floorid是String类型, 普通svg项目vid是String类型, 彩虹图项目vid是Number类型 | |
var selectedStand = null; | |
if (floorid && this.allStandsArr.some(function (stand) { | |
return stand.vid.toString() === floorid; | |
})) { | |
var standRes = this.allStandsArr.find(function (stand) { | |
return stand.vid.toString() === floorid; | |
}); | |
selectedStand = { | |
i: standRes.id, | |
n: standRes.name, | |
c: standRes.color, | |
s: standRes.status, | |
zh: standRes.zh, | |
vid: standRes.vid | |
}; | |
} | |
var offset = getOffset(e.currentTarget); | |
this.onHoverStand({ | |
x: point.x - offset.left, | |
y: point.y - offset.top, | |
stand: selectedStand | |
}); | |
} | |
} | |
/** | |
* 从svg底图内容解析看台包围矩形, 并修改svg缩放为1倍大小 | |
* @param {String} svg svg图片文本内容 | |
* @param {Array} stands 接口返回的看台列表 | |
*/ | |
}, { | |
key: 'getSvgData', | |
value: function getSvgData(svg, stands) { | |
var standIdMap = stands.reduce(function (result, stand) { | |
result[stand.vid] = stand; | |
return result; | |
}, {}); | |
// 1. 转换为DOM | |
var $svgContainer = document.createElement('div'); | |
// const $svgContainer = this.$container; 切勿过早将svg添加到DOM树中,因为后面还有一系列操作,会产生卡帧 | |
// 好吧,卡帧是由于svg 100%, 100% 有问题, 要保证svg的同比例,所以只设置了宽度100%, | |
var styleObj = UA.isPC ? { | |
width: '100%', | |
height: '100%' | |
} : { | |
width: '100%' | |
}; // PC不会有这个问题,需要加100% | |
addStyle($svgContainer, styleObj); | |
$svgContainer.innerHTML = svg; | |
var $svg = $svgContainer.children[0]; | |
// 2. 取transform,修改width, height | |
var svgScale = 1; | |
var svgTransform = $svg.getAttribute('transform'); | |
if (svgTransform) { | |
var regexResult = svgTransform.match(/scale\(([0-9.]+)\)/); | |
svgScale = parseFloat(regexResult && regexResult[1] || 1); | |
var svgWidth = $svg.getAttribute('width'); | |
var svgHeight = $svg.getAttribute('height'); | |
if (svgWidth * svgHeight < 1000 * 1000) { | |
BBCSVGRender.highlightStrokeWidth = 3; | |
} | |
$svg.setAttribute('transform', 'translate(0,0) rotate(0,0,0) scale(1)'); | |
$svg.setAttribute('viewBox', '0 0 ' + svgWidth + ' ' + svgHeight); | |
} | |
addStyle($svg, { | |
width: '100%', | |
height: '100%' | |
}); | |
// 3. 取点坐标 | |
function getStands(root) { | |
var newStands = []; | |
function dfs(element) { | |
if (element.nodeType !== 1) { | |
return; | |
} | |
var floorId = element.getAttribute('floorid'); | |
if (floorId && standIdMap[floorId]) { | |
newStands.push({ | |
element: element, | |
stand: standIdMap[floorId] | |
}); | |
} | |
if (element.tagName !== 'g' && element.childNodes && element.childNodes.length > 0) { | |
for (var i = 0; i < element.childNodes.length; i++) { | |
dfs(element.childNodes[i]); | |
} | |
} | |
} | |
dfs(root); | |
return newStands; | |
} | |
var newStands = getStands($svg); | |
return { | |
stands: newStands, | |
$svgObj: $svgContainer | |
}; | |
} | |
}]); | |
return BBCSVGRender; | |
}(VenueRender), _class2$3.isRainbow = false, _class2$3.highlightStrokeWidth = 10, _temp$10), _applyDecoratedDescriptor$4(_class$15.prototype, 'onTouchStart', [autobind], Object.getOwnPropertyDescriptor(_class$15.prototype, 'onTouchStart'), _class$15.prototype), _applyDecoratedDescriptor$4(_class$15.prototype, 'onTouchMove', [autobind], Object.getOwnPropertyDescriptor(_class$15.prototype, 'onTouchMove'), _class$15.prototype), _class$15); | |
var noop$1 = function noop() {}; | |
/** | |
* 不可售颜色 | |
*/ | |
var NotSaleColor$1 = '#EEEEEE'; | |
var SVGRender = function () { | |
createClass(SVGRender, [{ | |
key: 'onlyShowSelectSeatScene', | |
/** | |
* 只展示选座场景 | |
*/ | |
get: function get$$1() { | |
var _Util$ShareData = Util.ShareData, | |
SVGRenderScale = _Util$ShareData.SVGRenderScale, | |
DoubleRenderBoundary = _Util$ShareData.DoubleRenderBoundary; | |
if (CanvasMemoryLimit && this._svgWidth * this._svgHeight * SVGRenderScale * SVGRenderScale > DoubleRenderBoundary) { | |
return false; | |
} | |
return this._venueScale === 1 || Object.keys(this._standsMap).length <= 1; | |
} | |
/** | |
* 构造函数 | |
* @param {HTMLElement} $container 渲染容器div | |
*/ | |
}], [{ | |
key: 'normalizeSvg', | |
/** | |
* 标准化svg, 并获取原始scale值 | |
* @param {SvgDom} $svg 要处理的svg dom对象 | |
* @return {number} 原始scale值 | |
*/ | |
value: function normalizeSvg($svg) { | |
var scale = 1; | |
// 处理viewBox属性 | |
var viewboxAttribute = $svg.getAttribute('viewBox'); | |
if (viewboxAttribute) { | |
var viewbox = viewboxAttribute.split(' '); | |
$svg.setAttribute('width', viewbox[2]); | |
$svg.setAttribute('height', viewbox[3]); | |
} | |
// 处理transform属性 | |
var transformAttribute = $svg.getAttribute('transform'); | |
if (transformAttribute) { | |
var regexResult = transformAttribute.match(/scale\(([0-9.]+)\)/); | |
var svgScale = parseFloat(regexResult && regexResult[1] || 1); | |
scale = svgScale; | |
var svgWidth = parseInt($svg.getAttribute('width'), 10); | |
var svgHeight = parseInt($svg.getAttribute('height'), 10); | |
$svg.setAttribute('viewBox', '0 0 ' + svgWidth + ' ' + svgHeight); | |
$svg.setAttribute('width', svgWidth * scale); | |
$svg.setAttribute('height', svgHeight * scale); | |
$svg.removeAttribute('transform'); | |
} | |
return scale; | |
} // 缩放倍数, 座位24px级别 | |
// 缩放倍数, 座位6px级别 | |
// 视口最大缩放, 初始值, initViewport里会计算一个最大值 | |
/** | |
* 当前场景, 选区or选座 | |
*/ | |
/** | |
* 看台svg元素 | |
*/ | |
/** | |
* 座位svg元素 | |
*/ | |
/** | |
* 看台数据, Map结构存储, key: 看台id | |
*/ | |
// svg信息 | |
/** | |
* 聚焦看台 {Object} | |
*/ | |
/** | |
* 看台座位请求记录 | |
*/ | |
}]); | |
function SVGRender($container) { | |
var _this = this; | |
classCallCheck(this, SVGRender); | |
this.ScaleRatio24px = BBCSeat.SeatSize / 24; | |
this.ScaleRatio6px = BBCSeat.SeatSize / 9; | |
this.MaxScaleRatio = 99; | |
this._$container = null; | |
this._scene = Scene.SelectArea; | |
this._$venueSvg = null; | |
this._$standSvg = null; | |
this._standsMap = null; | |
this._svgScale = 1; | |
this._svgWidth = 0; | |
this._svgHeight = 0; | |
this._focusStand = null; | |
this._standFetchRecord = {}; | |
this.drawSeat = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee() { | |
var viewportLeftTop, viewportRightBottom, viewportRect, intersectStandIds, allStandStatus, _loop, standVid, _ret, setStatus, seats, fetchTasks, groupSeats, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, seat, offset, isPackage, price; | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
if (!(UA.isBadPhone && _this.prevDrawTime && Date.now() - _this.prevDrawTime < 1000)) { | |
_context.next = 2; | |
break; | |
} | |
return _context.abrupt('return'); | |
case 2: | |
_this.prevDrawTime = Date.now(); | |
// 获取视口矩形 | |
viewportLeftTop = _this._viewport.getLeftTopPoint(); | |
viewportRightBottom = _this._viewport.getRightBottomPoint(); | |
viewportRect = { | |
left: viewportLeftTop.x, | |
top: viewportLeftTop.y, | |
right: viewportRightBottom.x, | |
bottom: viewportRightBottom.y | |
}; | |
// 判断相交看台 | |
intersectStandIds = []; | |
allStandStatus = Object.values(_this._standsMap).map(function (stand) { | |
return stand.fetchStatus; | |
}); | |
if (!allStandStatus.some(function (status) { | |
return status === undefined; | |
})) { | |
_context.next = 23; | |
break; | |
} | |
if (!(_this._venueScale === 1 && _this.initial === undefined)) { | |
_context.next = 14; | |
break; | |
} | |
// 该情况下, 初次请求直接获取所有座位数据 | |
if (_this._standGroup.length === 0) { | |
intersectStandIds = Object.keys(_this._standsMap); | |
} else { | |
// 接口返回的看台分组可能包含没数据的看台, 需要与接口返回的看台列表对比, 将不存在的过滤掉 | |
intersectStandIds = _this._standGroup.map(function (ids) { | |
return ids.split(',').filter(function (id) { | |
return _this._standsMap[id]; | |
}); | |
}); | |
} | |
_this.initial = false; | |
_context.next = 23; | |
break; | |
case 14: | |
_loop = function _loop(standVid) { | |
var stand = _this._standsMap[standVid]; | |
var standId = '' + stand.i; | |
if (Util.isIntersect(viewportRect, stand.boundingRect)) { | |
// 忽略已加载过的看台 | |
if (_this._standsMap[standVid].fetchStatus !== undefined) { | |
return 'continue'; | |
} | |
if (_this._standGroup.length === 0) { | |
_this._standsMap[standVid].fetchStatus = 'fetch'; // 状态: "获取中" | |
intersectStandIds.push(standId); | |
} else { | |
// 查找该看台所在组 | |
var group = _this._standGroup.find(function (x) { | |
return x.indexOf(standId) !== -1; | |
}); | |
var standIds = []; | |
if (!group) { | |
standIds = [standId]; | |
} else { | |
standIds = group.split(',').filter(function (id) { | |
return _this._standsMap[_this._standIdToVidMap[id]]; | |
}); | |
} | |
standIds.forEach(function (id) { | |
_this._standsMap[_this._standIdToVidMap[id]].fetchStatus = 'fetch'; // 状态: "获取中" | |
}); | |
intersectStandIds.push(standIds); | |
} | |
} | |
}; | |
_context.t0 = regeneratorRuntime.keys(_this._standsMap); | |
case 16: | |
if ((_context.t1 = _context.t0()).done) { | |
_context.next = 23; | |
break; | |
} | |
standVid = _context.t1.value; | |
_ret = _loop(standVid); | |
if (!(_ret === 'continue')) { | |
_context.next = 21; | |
break; | |
} | |
return _context.abrupt('continue', 16); | |
case 21: | |
_context.next = 16; | |
break; | |
case 23: | |
if (!(intersectStandIds.length !== 0)) { | |
_context.next = 64; | |
break; | |
} | |
/** | |
* 设置各看台状态 | |
* @param {undefined | String} status 状态 | |
*/ | |
setStatus = function setStatus(status) { | |
// eslint-disable-line no-inner-declarations | |
if (_this._standGroup.length === 0) { | |
intersectStandIds.forEach(function (id) { | |
_this._standsMap[_this._standIdToVidMap[id]].fetchStatus = status; | |
}); | |
} else { | |
intersectStandIds.forEach(function (ids) { | |
ids.forEach(function (id) { | |
_this._standsMap[_this._standIdToVidMap[id]].fetchStatus = status; | |
}); | |
}); | |
} | |
}; | |
seats = []; | |
_context.prev = 26; | |
if (!(_this._standGroup.length === 0)) { | |
_context.next = 33; | |
break; | |
} | |
_context.next = 30; | |
return _this.fetchStandSeats(intersectStandIds); | |
case 30: | |
seats = _context.sent; | |
_context.next = 38; | |
break; | |
case 33: | |
// 如果不为0, 则按组并行请求 | |
fetchTasks = intersectStandIds.map(function (ids) { | |
return _this.fetchStandSeats(ids); | |
}); | |
_context.next = 36; | |
return Promise.all(fetchTasks); | |
case 36: | |
groupSeats = _context.sent; | |
seats = groupSeats.filter(function (x) { | |
return Array.isArray(x); | |
}).reduce(function (result, cur) { | |
result.push.apply(result, toConsumableArray(cur)); | |
return result; | |
}, []); | |
case 38: | |
_context.next = 44; | |
break; | |
case 40: | |
_context.prev = 40; | |
_context.t2 = _context['catch'](26); | |
setStatus(undefined); // 重置状态 | |
return _context.abrupt('return'); | |
case 44: | |
setStatus('end'); // 状态: "获取成功" | |
_iteratorNormalCompletion = true; | |
_didIteratorError = false; | |
_iteratorError = undefined; | |
_context.prev = 48; | |
for (_iterator = seats[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | |
seat = _step.value; | |
offset = _this._seatStyle === 3 ? 0 : BBCSeat.SeatSize / 2; | |
isPackage = seat.groupid != '0'; // eslint-disable-line eqeqeq | |
price = _this._priceList[seat.plid]; | |
// 如果是固定套票, 则设置为相应的套票颜色 | |
// 非候鸟的中网BBC逻辑不变, 不会把套票list转换到票价list | |
if (isPackage) { | |
price = _this._priceList[seat.groupPriceid]; | |
} | |
if (!price) { | |
// 票价不存在, 设置默认颜色 | |
price = { | |
color: '#000000', | |
index: -1 | |
}; | |
seat.s = 0; | |
} else if (price.salable === false) { | |
// 票价不可售, 认为座位也是不可售的, 特权选座场景 | |
seat.s = 0; | |
} | |
_this._area.addSeat( | |
// 座位坐标要取整 | |
((+seat.x >> 0) - offset + Util.ShareData.BBCSeatOffsetX) * Util.ShareData.SVGRenderScale, ((+seat.y >> 0) - offset + Util.ShareData.BBCSeatOffsetY) * Util.ShareData.SVGRenderScale, Object.assign({}, { | |
id: seat.sid, | |
status: seat.s, | |
row: seat.rhint, | |
column: seat.chint, | |
color: price.color, | |
floor: seat.fn, | |
priceIndex: price.index, | |
chinese: false, | |
isPackage: isPackage, | |
packageCombinedId: isPackage ? seat.groupid : -1 | |
}, seat), _this._seatStyle); | |
} | |
_context.next = 56; | |
break; | |
case 52: | |
_context.prev = 52; | |
_context.t3 = _context['catch'](48); | |
_didIteratorError = true; | |
_iteratorError = _context.t3; | |
case 56: | |
_context.prev = 56; | |
_context.prev = 57; | |
if (!_iteratorNormalCompletion && _iterator.return) { | |
_iterator.return(); | |
} | |
case 59: | |
_context.prev = 59; | |
if (!_didIteratorError) { | |
_context.next = 62; | |
break; | |
} | |
throw _iteratorError; | |
case 62: | |
return _context.finish(59); | |
case 63: | |
return _context.finish(56); | |
case 64: | |
_this._area.draw(_this._ctx, viewportLeftTop.x, viewportLeftTop.y, viewportRightBottom.x, viewportRightBottom.y); | |
if (_this._venueScale === 1 && !_this.alreadyDrawn) { | |
_this.alreadyDrawn = true; // 保证鹰眼图仅绘制一次 | |
_this._area.drawThumbnail(_this._thumbnailCtx); | |
} | |
case 66: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, _this, [ | |
[26, 40], | |
[48, 52, 56, 64], | |
[57, , 59, 63] | |
]); | |
})); | |
this.onTouchStart = function (e) { | |
e.preventDefault(); | |
_this._touchStatus = 'start'; | |
_this._prevTouchPoints = getEventPoints(e); | |
_this._prevTime = Date.now(); | |
_this._mouseType = e.buttons || 1; | |
if (_this._thumbnailHideTimer) { | |
clearTimeout(_this._thumbnailHideTimer); | |
} | |
}; | |
this.onTouchMove = function (e) { | |
e.preventDefault(); | |
if (_this._prevTouchPoints) { | |
var currentTouchPoints = getEventPoints(e); | |
// 按下的是鼠标左键 | |
if (_this._mouseType === 1) { | |
// 过滤横向和纵向同时低于1.5px的move事件 | |
// 三星浏览器和vivo浏览器会因为点击触发小距离move而不好点中座位, 这里可以缓解该情况 | |
if (Math.abs(currentTouchPoints[0].x - _this._prevTouchPoints[0].x) <= 1.5 && Math.abs(currentTouchPoints[0].y - _this._prevTouchPoints[0].y) <= 1.5) { | |
return; | |
} | |
_this._touchStatus = 'move'; | |
if (currentTouchPoints.length === 1) { | |
// 单指拖动 | |
// 如果是二指缩放, 且手指离开时间不一致, 又触发了move事件, 将本次手指位置作为起始点 | |
if (_this._prevTouchPoints.length === 2) { | |
_this._prevTouchPoints = currentTouchPoints; | |
return; | |
} | |
// 移动视口位置 | |
_this._viewport.move(_this._prevTouchPoints[0].x - currentTouchPoints[0].x, _this._prevTouchPoints[0].y - currentTouchPoints[0].y); | |
// 记录当前点 | |
_this._prevTouchPoints = currentTouchPoints; | |
} else if (currentTouchPoints.length === 2) { | |
// 二指缩放 | |
if (_this._prevTouchPoints.length === 1) { | |
return; | |
} | |
// 根据移动距离计算线性缩放倍率变化值, 缩放视口大小 | |
var sx = _this._prevTouchPoints[0].x - _this._prevTouchPoints[1].x; | |
var sy = _this._prevTouchPoints[0].y - _this._prevTouchPoints[1].y; | |
var ex = currentTouchPoints[0].x - currentTouchPoints[1].x; | |
var ey = currentTouchPoints[0].y - currentTouchPoints[1].y; | |
var d1 = Math.sqrt(sx * sx + sy * sy); | |
var d2 = Math.sqrt(ex * ex + ey * ey); | |
_this._viewport.scaleMultip(d1 / d2); | |
_this._prevTouchPoints = currentTouchPoints; | |
// 设置Canvas缩放 | |
_this._ctx.setScale(_this._viewport.getScale()); | |
} | |
_this.updateView(true); | |
if (_this._scene === Scene.SelectSeat) { | |
// 拖动完成后需要绘制一次座位, 但是发现一个奇怪的现象: onTouchEnd 比最后一次 onTouchMove 要慢上700ms左右 | |
// 因此在这里用timer控制, 最后一次 onTouchMove 60ms后绘制一次座位 | |
clearTimeout(_this._drawSeatTimer); | |
_this._drawSeatTimer = setTimeout(_this.drawSeat, 60); | |
} | |
clearTimeout(_this._thumbnailHideTimer); | |
_this._thumbnailHideTimer = setTimeout(_this._thumbnail.hide.bind(_this._thumbnail), 400); | |
} | |
} | |
if (UA.isPC && _this.onHoverSeat) { | |
var _currentTouchPoints = getEventPoints(e); | |
var position = getPosition(_this._$seatCanvas); | |
var scale = _this._viewport.getScale(); | |
var point = { | |
x: (_currentTouchPoints[0].x - position.left) / scale, | |
y: (_currentTouchPoints[0].y - position.top) / scale | |
}; | |
var seat = _this._area.getSeat(point); | |
// 使用 throttle 后, 最后一次触发事件时 e.currentTarget 为空, 需要排除这种情况 | |
if (e.currentTarget) { | |
var offset = getOffset(e.currentTarget); | |
_this.onHoverSeat({ | |
x: _currentTouchPoints[0].x - offset.left, | |
y: _currentTouchPoints[0].y - offset.top, | |
seat: seat && seat.getInfo() | |
}); | |
} | |
} | |
}; | |
this.onTouchEnd = function (e) { | |
e.preventDefault(); | |
// 如果status不是move, 说明是点击事件 | |
if (_this._touchStatus === 'start') { | |
if (_this._scene === Scene.SelectSeat) { | |
var position = getPosition(_this._$seatCanvas); | |
_this._area.handleClick(_this._ctx, { | |
x: (_this._prevTouchPoints[0].x - position.left) / _this._viewport.getScale(), | |
y: (_this._prevTouchPoints[0].y - position.top) / _this._viewport.getScale() | |
}); | |
} else { | |
var floorId = ''; | |
if (e.target) { | |
floorId = e.target.getAttribute('floorid'); | |
} | |
if (floorId) { | |
_this.onClickStand(floorId); | |
return; | |
} | |
} | |
} | |
_this._prevTouchPoints = null; | |
_this._isMouseLongTap = false; | |
// 视口移动, 根据点击位置, 居中+放大 | |
// 这里的逻辑和 onClickStand 里的逻辑一模一样, 唯一区别就是这里的缩放有两个级别 | |
if (_this._scene === Scene.SelectSeat && _this._touchStatus === 'start') { | |
var offset = getOffset(e.currentTarget); | |
// 获取点击位置 | |
var points = getEventPoints(e); | |
var touchPoint = { | |
x: points[0].x - offset.left, | |
y: points[0].y - offset.top | |
}; | |
// 计算目标缩放值 | |
var scale = _this._viewport.getScale(); | |
var px24 = 1 / Util.ShareData.SVGRenderScale; | |
var targetScale = px24; | |
if (scale > px24 || Math.abs(scale - px24) < 0.0001) { | |
// 大于等于24px不用缩放, 注意浮点数比较 | |
_this.showThumbnail(); | |
return; | |
} | |
// 计算点击位置与div容器中心点的距离, 基于当前缩放倍率下 | |
var moveX = touchPoint.x - _this._$container.clientWidth / 2; | |
var moveY = touchPoint.y - _this._$container.clientHeight / 2; | |
// 修改缩放和移动视口 | |
_this._viewport.updateRatio(1 / targetScale); | |
var moveScale = targetScale === scale ? 1 : _this._viewport.getScale() / scale; | |
_this._viewport.move(moveX * moveScale, moveY * moveScale); | |
// 更新视图 | |
_this.updateView(undefined, true); | |
} | |
}; | |
this.onMouseWheel = function (e) { | |
e.preventDefault(); | |
_this._viewport.scale((e.deltaY || e.wheelDelta) / 500); // IE没有 | |
_this.updateView(true); | |
if (_this._thumbnailHideTimer) { | |
clearTimeout(_this._thumbnailHideTimer); | |
} | |
_this._thumbnailHideTimer = setTimeout(_this._thumbnail.hide.bind(_this._thumbnail), 500); | |
}; | |
this.onMouseLeave = function () { | |
_this._prevTouchPoints = null; | |
}; | |
this.onClickStand = function (floorId) { | |
window.selectSeatTiming.clickStandTime = Date.now(); | |
if (_this._standsMap[floorId].s === 0) { | |
return; | |
} | |
_this._prevTouchPoints = null; | |
_this._focusStand = _this._standsMap[floorId]; | |
var _calculateViewport = _this.calculateViewport(), | |
x = _calculateViewport.x, | |
y = _calculateViewport.y, | |
ratio = _calculateViewport.ratio; | |
_this._viewport.updatePosition(x, y); | |
_this._viewport.updateRatio(ratio); | |
// 切换到选座场景, 并强制绘座一次 | |
_this.showSelectSeatScene(); | |
_this.drawSeat(); | |
_this._thumbnail.show(); | |
}; | |
this.updateViewportFocusStand = function (standId) { | |
_this.focusStand = _this._standsMap[standId]; | |
if (_this.focusStand) { | |
var _calculateViewport2 = _this.calculateViewport(_this.focusStand), | |
x = _calculateViewport2.x, | |
y = _calculateViewport2.y, | |
ratio = _calculateViewport2.ratio; | |
// 更新视口位置和缩放 | |
_this._viewport.updatePosition(x, y); | |
_this._viewport.updateRatio(ratio); | |
// 调整座位canvas位置和缩放 | |
_this.updateView(); | |
} | |
}; | |
this.highlightPrice = function (priceIndex) { | |
var boundingRect = _this._area.getAvaliableSeatBoundingRectByPrice(priceIndex); | |
// 小场馆 | |
// 如果能找到座位包围矩形(可售座位小于等于10个), 并且不需要强制回初始视图, 则定位视口到可售座位并高亮座位 | |
// 反之, 回到初始视图, 并高亮座位 | |
if (_this.onlyShowSelectSeatScene) { | |
if (boundingRect) { | |
var targetViewport = _this.calculateViewport(boundingRect, false); | |
_this._viewport.updatePosition(targetViewport.x, targetViewport.y); | |
_this._viewport.updateRatio(targetViewport.ratio); | |
_this.updateView(true); | |
} else { | |
_this.gotoInitialView(); | |
} | |
_this._area.highlightPrice(priceIndex); | |
return; | |
} | |
// 大场馆, 直接回选区页并高亮看台 | |
_this.gotoInitialView(); | |
_this.highlightStand(priceIndex); | |
}; | |
this.gotoInitialView = function () { | |
_this.resetViewport(); | |
if (_this.onlyShowSelectSeatScene) { | |
_this.showSelectSeatScene(); | |
} else { | |
_this.showSelectAreaScene(); | |
} | |
}; | |
this.updateSeatStatus = function (seatsStatusData) { | |
_this.standSeatsStatus = seatsStatusData; | |
_this._area.updateSeatStatus(seatsStatusData); | |
}; | |
this.cancelSelectSeat = function (seatId) { | |
_this._area.cancelSelectSeat(seatId); | |
}; | |
this.preLockSelectSeat = function (seatIds) { | |
_this._area.preLockSelectSeat(seatIds); | |
}; | |
this._$container = $container; | |
} | |
/** | |
* 创建svg元素 | |
* @param {string} rainbowSvgText 彩虹图svg文本 | |
* @param {string} svgText svg文本 | |
*/ | |
createClass(SVGRender, [{ | |
key: 'createSvgElement', | |
value: function createSvgElement(rainbowSvgText, svgText) { | |
var _this2 = this; | |
// 选座svg | |
var $tempDiv = document.createElement('div'); | |
addStyle($tempDiv, { | |
visibility: 'hidden' | |
}); | |
document.body.appendChild($tempDiv); | |
$tempDiv.innerHTML = svgText; | |
this._$standSvg = $tempDiv.children[0]; | |
this._svgScale = SVGRender.normalizeSvg(this._$standSvg); | |
var _$standSvg$getAttribu = this._$standSvg.getAttribute('viewBox').split(' '), | |
_$standSvg$getAttribu2 = slicedToArray(_$standSvg$getAttribu, 4), | |
svgWidth = _$standSvg$getAttribu2[2], | |
svgHeight = _$standSvg$getAttribu2[3]; | |
this._svgWidth = svgWidth * this._svgScale; | |
this._svgHeight = svgHeight * this._svgScale; | |
// 选座页底图, 修改<text>样式 | |
this.walkSvgTextElement(this._$standSvg, function ($text) { | |
addStyle($text, { | |
fill: '#E0E0E0', | |
pointerEvents: 'none' | |
}); | |
}); | |
this._normalizeSvgText = this._$standSvg.parentNode.innerHTML; | |
// 选区svg | |
if (rainbowSvgText) { | |
var $div = document.createElement('div'); | |
$div.innerHTML = rainbowSvgText; | |
this._$venueSvg = $div.children[0]; | |
SVGRender.normalizeSvg(this._$venueSvg); | |
} else { | |
this._$venueSvg = this._$standSvg; | |
// 选区页底图, 还原<text>样式 | |
this.walkSvgTextElement(this._$venueSvg, function ($text) { | |
addStyle($text, { | |
fill: '#000000' | |
}); | |
}); | |
} | |
this._$container.appendChild(this._$venueSvg); | |
// 如果是小于指定大小的场馆, 放大一倍绘制来保证清晰度 | |
if (svgWidth * svgHeight * this._svgScale * this._svgScale <= Util.DoubleRenderBoundary) { | |
Util.ShareData.SVGRenderScale = 2; | |
this.ScaleRatio24px *= Util.ShareData.SVGRenderScale; | |
this.ScaleRatio6px *= Util.ShareData.SVGRenderScale; | |
this.MaxScaleRatio *= Util.ShareData.SVGRenderScale; | |
} | |
// 选区页看台上色 | |
this.walkSvgStandsElement(this._$venueSvg, function ($stand, floorId) { | |
var standInfo = _this2._standsMap[floorId]; | |
if (_this2.isRainbow && standInfo.rainbow) { | |
for (var i = 0; i < $stand.childNodes.length; i++) { | |
var $child = $stand.childNodes[i]; | |
var rowId = $child.getAttribute('row_id'); | |
var color = standInfo.rainbow[rowId]; | |
var colorAvailable = !standInfo.availableRainbowColors || standInfo.availableRainbowColors[color]; | |
if (color) { | |
addStyle($child, { | |
fill: standInfo.s === 1 && colorAvailable ? color : NotSaleColor$1 | |
}); | |
} | |
} | |
} else { | |
addStyle($stand, { | |
fill: standInfo.s === 1 ? standInfo.c : NotSaleColor$1 | |
}); | |
} | |
_this2._standsMap[floorId].$el = $stand; | |
}); | |
this.getStandsBoundingRect(); | |
$tempDiv.remove(); | |
} | |
/** | |
* 遍历svg看台节点 | |
* @param {Function} callback 处理看台的回调 | |
*/ | |
}, { | |
key: 'walkSvgStandsElement', | |
value: function walkSvgStandsElement($svg) { | |
var _this3 = this; | |
var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop$1; | |
var dfs = function dfs(element) { | |
if (element.nodeType !== 1) { | |
return; | |
} | |
// floorName对选座业务无用, 部分底图存在floorName乱码的情况, 导致svg生成的blob图片加载时走到onerror回调 | |
element.removeAttribute('floorname'); | |
var floorId = element.getAttribute('floorid'); | |
if (floorId && _this3._standsMap[floorId]) { | |
callback(element, floorId); | |
} else if (element.childNodes && element.childNodes.length > 0) { | |
for (var i = 0; i < element.childNodes.length; i++) { | |
dfs(element.childNodes[i]); | |
} | |
} | |
}; | |
dfs($svg); | |
} | |
/** | |
* 遍历svg <text>节点 | |
* @param {Function} callback 回调函数 | |
*/ | |
}, { | |
key: 'walkSvgTextElement', | |
value: function walkSvgTextElement($svg) { | |
var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop$1; | |
var dfs = function dfs(element) { | |
if (element.nodeType !== 1) { | |
return; | |
} | |
if (element.tagName === 'text') { | |
callback(element); | |
} else if (element.childNodes && element.childNodes.length > 0) { | |
for (var i = 0; i < element.childNodes.length; i++) { | |
dfs(element.childNodes[i]); | |
} | |
} | |
}; | |
dfs($svg); | |
} | |
/** | |
* 获取Map结构的看台数据, key: 看台id | |
* @param {Array} stands 看台列表 | |
*/ | |
}, { | |
key: 'getStandsMap', | |
value: function getStandsMap(stands) { | |
var _this4 = this; | |
this._standsMap = {}; | |
this._standIdToVidMap = {}; | |
stands.forEach(function (stand) { | |
// 颜色标准化 | |
stand.c = Util.getNormalizeColor(stand.c); | |
// 彩虹图数据解析 | |
if (stand.rainbow) { | |
stand.rainbow = stand.rainbow.split('|').reduce(function (rainbowMap, item) { | |
if (item) { | |
var _item$split = item.split('='), | |
_item$split2 = slicedToArray(_item$split, 2), | |
rowId = _item$split2[0], | |
color = _item$split2[1]; | |
rainbowMap[rowId] = stand.s === 1 ? Util.getNormalizeColor(color) : NotSaleColor$1; | |
} | |
return rainbowMap; | |
}, {}); | |
} | |
_this4._standsMap[stand.vid] = stand; | |
_this4._standIdToVidMap[stand.i] = stand.vid; | |
}); | |
} | |
/** | |
* 获取各看台包围矩形 | |
*/ | |
}, { | |
key: 'getStandsBoundingRect', | |
value: function getStandsBoundingRect() { | |
var _this5 = this; | |
this.walkSvgStandsElement(this._$standSvg, function ($stand, floorId) { | |
var _getBBox = getBBox($stand), | |
x = _getBBox.x, | |
y = _getBBox.y, | |
width = _getBBox.width, | |
height = _getBBox.height; | |
_this5._standsMap[floorId].boundingRect = { | |
left: x * _this5._svgScale * Util.ShareData.SVGRenderScale, | |
top: y * _this5._svgScale * Util.ShareData.SVGRenderScale, | |
right: (x + width) * _this5._svgScale * Util.ShareData.SVGRenderScale, | |
bottom: (y + height) * _this5._svgScale * Util.ShareData.SVGRenderScale | |
}; | |
}); | |
} | |
/** | |
* 初始化必要内容 | |
*/ | |
}, { | |
key: 'init', | |
value: function init(thumbnailBackgroundImage) { | |
this._svgWidth *= Util.ShareData.SVGRenderScale; | |
this._svgHeight *= Util.ShareData.SVGRenderScale; | |
addStyle(this._$container, { | |
position: 'relative' | |
}); | |
this.initArea(); | |
this.initViewport(); | |
this.initSvg(); | |
this.initCanvas(); | |
this.initThumbnail(thumbnailBackgroundImage); | |
if (UA.isPC) { | |
// pc端事件 | |
document.oncontextmenu = function () { | |
event.returnValue = false; | |
}; // 禁用右键菜单 | |
this._$container.addEventListener('mousedown', this.onTouchStart); | |
this._$container.addEventListener('mousemove', throttle(this.onTouchMove, 100, 50)); | |
this._$container.addEventListener('mouseup', this.onTouchEnd); | |
this._$container.addEventListener('mouseleave', this.onMouseLeave); | |
} else { | |
// 移动端事件 | |
this._$container.addEventListener('touchstart', this.onTouchStart); | |
this._$container.addEventListener('touchmove', throttle(this.onTouchMove, 100, 50)); | |
this._$container.addEventListener('touchend', this.onTouchEnd); | |
} | |
// pc和移动端都注册滚轮事件, 移动端方便用触摸板缩放 | |
this._$container.addEventListener('mousewheel', this.onMouseWheel); | |
} | |
/** | |
* 初始化Area | |
*/ | |
}, { | |
key: 'initArea', | |
value: function initArea() { | |
this._area = new BBCArea(this._svgWidth, this._svgHeight); | |
this._area.onSelectSeat = this.handleSelectSeat.bind(this); | |
this._area.onError = this.handleError.bind(this); | |
} | |
/** | |
* 初始化Viewport | |
*/ | |
}, { | |
key: 'initViewport', | |
value: function initViewport() { | |
var areaSize = this._area.getSize(); | |
var containerWidth = this._$container.clientWidth - Util.ShareData.DefaultViewportMargin * 2; | |
var containerHeight = this._$container.clientHeight - Util.ShareData.DefaultViewportMargin * 2; | |
var ratio = this._svgWidth / containerWidth; | |
if (this._svgHeight / ratio > containerHeight) { | |
ratio = this._svgHeight / containerHeight; | |
} | |
this.MaxScaleRatio = ratio; | |
this._viewport = new Viewport(this._$container.clientWidth, this._$container.clientHeight, areaSize.width, areaSize.height, { | |
minScaleRatio: this.ScaleRatio24px, | |
maxScaleRatio: this.MaxScaleRatio, | |
x: undefined, | |
y: undefined, | |
renderPadding: true, | |
ratio: ratio | |
}); | |
} | |
/** | |
* 重置视口到初始状态 | |
*/ | |
}, { | |
key: 'resetViewport', | |
value: function resetViewport() { | |
var areaSize = this._area.getSize(); | |
var containerWidth = this._$container.clientWidth - Util.ShareData.DefaultViewportMargin * 2; | |
var containerHeight = this._$container.clientHeight - Util.ShareData.DefaultViewportMargin * 2; | |
var ratio = this._svgWidth / containerWidth; | |
if (this._svgHeight / ratio > containerHeight) { | |
ratio = this._svgHeight / containerHeight; | |
} | |
this._viewport.updatePosition((areaSize.width - this._$container.clientWidth) / 2, (areaSize.height - this._$container.clientHeight) / 2); | |
this._viewport.updateRatio(ratio); | |
} | |
/** | |
* 初始化svg元素 | |
*/ | |
}, { | |
key: 'initSvg', | |
value: function initSvg() { | |
var areaSize = this._area.getSize(); | |
var centerViewportPoint = this._viewport.getCenterPoint(); | |
var currentViewportPoint = this._viewport.getPoint(); | |
var scale = this._viewport.getScale(); | |
addStyle(this._$venueSvg, { | |
position: 'relative', | |
width: this._svgWidth * scale, | |
height: this._svgHeight * scale, | |
left: -(areaSize.width * scale - this._$container.clientWidth) / 2 + (centerViewportPoint.x - currentViewportPoint.x), | |
top: -(areaSize.height * scale - this._$container.clientHeight) / 2 + (centerViewportPoint.y - currentViewportPoint.y) | |
}); | |
} | |
/** | |
* 初始化canvas | |
*/ | |
}, { | |
key: 'initCanvas', | |
value: function initCanvas() { | |
var areaSize = this._area.getSize(); | |
var centerViewportPoint = this._viewport.getCenterPoint(); | |
var currentViewportPoint = this._viewport.getPoint(); | |
var scale = this._viewport.getScale(); | |
var imageSrc = Util.svgToImageUrl(this._normalizeSvgText); | |
this._$seatCanvas = document.createElement('div'); | |
addStyle(this._$seatCanvas, { | |
position: 'relative', | |
left: -(areaSize.width * scale - this._$container.clientWidth) / 2 + (this._focusStand ? centerViewportPoint.x - currentViewportPoint.x : 0), | |
top: -(areaSize.height * scale - this._$container.clientHeight) / 2 + (this._focusStand ? centerViewportPoint.y - currentViewportPoint.y : 0) | |
}); | |
this._$container.appendChild(this._$seatCanvas); | |
// 背景图如果使用 background-image, 在chrome上会闪烁, 并且network中重复获取blob对象 | |
// 改为 <img> 可解 | |
var $bgImage = document.createElement('img'); | |
$bgImage.src = imageSrc; | |
addStyle($bgImage, { | |
position: 'absolute', | |
top: 0, | |
left: 0, | |
width: '100%', | |
height: '100%' | |
}); | |
this._$seatCanvas.appendChild($bgImage); | |
this._ctx = new Canvas(this._$seatCanvas, { | |
width: areaSize.width, | |
height: areaSize.height, | |
scale: scale, | |
standWidth: this._$container.clientWidth, | |
standHeight: this._$container.clientHeight | |
}); | |
this._ctx.onDispose = this._area.handleCanvasDispose.bind(this._area); | |
} | |
/** | |
* 初始化鹰眼图 | |
* @param {String} thumbnailBgImage 鹰眼图底图地址 | |
*/ | |
}, { | |
key: 'initThumbnail', | |
value: function () { | |
var _ref2 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee2(thumbnailBgImage) { | |
var isJpgImage, size, thumbnailCanvasWidth, thumbnailCanvasHeight, ThumbnailScaleRatio, $thumbnailDiv, $thumbnailCanvas, $buttonListDiv; | |
return regeneratorRuntime.wrap(function _callee2$(_context2) { | |
while (1) { | |
switch (_context2.prev = _context2.next) { | |
case 0: | |
isJpgImage = thumbnailBgImage.endsWith('.jpg'); | |
size = this._area.getSize(); | |
// 计算鹰眼图尺寸 | |
thumbnailCanvasWidth = size.width / Util.ShareData.SVGRenderScale; | |
thumbnailCanvasHeight = size.height / Util.ShareData.SVGRenderScale; | |
ThumbnailScaleRatio = this._$container.clientWidth * 0.4 / thumbnailCanvasWidth; | |
if (thumbnailCanvasHeight * ThumbnailScaleRatio > Thumbnail.ThumbnailCanvasMaxHeight) { | |
ThumbnailScaleRatio = Thumbnail.ThumbnailCanvasMaxHeight / thumbnailCanvasHeight; | |
} | |
// 鹰眼图缩放 | |
thumbnailCanvasWidth *= ThumbnailScaleRatio; | |
thumbnailCanvasHeight *= ThumbnailScaleRatio; | |
BBCThumbnail.ScaleRatio = ThumbnailScaleRatio / Util.ShareData.SVGRenderScale; | |
if (isJpgImage) { | |
BBCThumbnail.ScaleRatio /= 2; | |
} | |
// 鹰眼图整体div | |
this._$thumbnailContainer = document.createElement('div'); | |
this._$thumbnailContainer.className = 'select-seat-thumbnail'; | |
addStyle(this._$thumbnailContainer, { | |
position: 'absolute', | |
top: 6, | |
right: 6, | |
width: thumbnailCanvasWidth + (UA.isPC ? 30 : 0) + BBCThumbnailMargin * 2, // PC 30px 是按钮区域 | |
height: thumbnailCanvasHeight + BBCThumbnailMargin * 2, | |
pointerEvents: UA.isPC ? 'all' : 'none' | |
}); | |
this._$container.appendChild(this._$thumbnailContainer); | |
// 鹰眼图区域 | |
$thumbnailDiv = document.createElement('div'); | |
addStyle($thumbnailDiv, { | |
position: 'absolute', | |
top: 0, | |
left: 0, | |
borderRadius: 2, | |
overflow: 'hidden', | |
width: thumbnailCanvasWidth + BBCThumbnailMargin * 2, | |
height: thumbnailCanvasHeight + BBCThumbnailMargin * 2, | |
backgroundImage: 'url(' + thumbnailBgImage + ')', | |
backgroundColor: 'rgba(0, 0, 0, 0.6)', | |
backgroundSize: thumbnailCanvasWidth + 'px ' + thumbnailCanvasHeight + 'px', | |
backgroundPosition: BBCThumbnailMargin + 'px ' + BBCThumbnailMargin + 'px', | |
backgroundRepeat: 'no-repeat', | |
transform: 'translateX(0)', | |
transition: 'all 0.4s', | |
display: UA.isPC ? 'block' : 'none' | |
}); | |
this._$thumbnailContainer.appendChild($thumbnailDiv); | |
// 接口返回字段, 3表示需要鹰眼图展示座位 | |
if (this._venueScale === 1 && !isJpgImage) { | |
// 鹰眼图canvas | |
$thumbnailCanvas = createCanvas(thumbnailCanvasWidth, thumbnailCanvasHeight); | |
addStyle($thumbnailCanvas, { | |
position: 'absolute', | |
top: BBCThumbnailMargin, | |
left: BBCThumbnailMargin | |
}); | |
this._thumbnailCtx = $thumbnailCanvas.getContext('2d'); | |
$thumbnailDiv.appendChild($thumbnailCanvas); | |
} | |
// 仅PC显示鹰眼图按钮 | |
if (UA.isPC) { | |
// 按钮区域 | |
$buttonListDiv = document.createElement('div'); | |
addStyle($buttonListDiv, { | |
width: 30, | |
height: thumbnailCanvasHeight, | |
position: 'absolute', | |
top: 0, | |
right: 0, | |
backgroundColor: 'white' | |
}); | |
this._$thumbnailContainer.appendChild($buttonListDiv); | |
this._thumbnail = new BBCThumbnail(this, $thumbnailDiv, $buttonListDiv); | |
} else { | |
this._thumbnail = new BBCThumbnail(this, $thumbnailDiv, null); | |
} | |
case 19: | |
case 'end': | |
return _context2.stop(); | |
} | |
} | |
}, _callee2, this); | |
})); | |
function initThumbnail(_x3) { | |
return _ref2.apply(this, arguments); | |
} | |
return initThumbnail; | |
}() | |
/** | |
* 将鹰眼图置为可见状态 | |
*/ | |
}, { | |
key: 'showThumbnail', | |
value: function showThumbnail() { | |
if (this._thumbnail && !this._thumbnail.visible) { | |
this._thumbnail.show(); | |
} | |
} | |
/** | |
* 根据要聚焦的看台位置和容器大小, 计算出视口的位置和缩放值 | |
* @param {Object} boundingRect 包围矩形, 不传则用 this._focusStand 的包围矩形 | |
* @param {boolean} maxScaleRatioLimit 是否限制最大缩放倍率 | |
*/ | |
}, { | |
key: 'calculateViewport', | |
value: function calculateViewport(boundingRect) { | |
var maxScaleRatioLimit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; | |
var _ref3 = boundingRect || this._focusStand.boundingRect, | |
left = _ref3.left, | |
right = _ref3.right, | |
top = _ref3.top, | |
bottom = _ref3.bottom; | |
var DefaultViewportMargin = Util.ShareData.DefaultViewportMargin; | |
var maxWidth = this._$container.clientWidth - DefaultViewportMargin * 2; | |
var maxHeight = this._$container.clientHeight - DefaultViewportMargin * 2; | |
var standWidth = right - left; | |
var standHeight = bottom - top; | |
// 计算视口缩放值 | |
// 保证 standWidth * ratio <= maxWidth 并且 standHeight * ratio <= maxHeight | |
var ratio = standWidth / maxWidth; | |
if (ratio * maxHeight < standHeight) { | |
ratio = standHeight / maxHeight; | |
} | |
// 不能超过最大/最小缩放倍数限制 | |
if (ratio < this.ScaleRatio24px) { | |
ratio = this.ScaleRatio24px; | |
} else if (maxScaleRatioLimit && ratio > this.ScaleRatio6px) { | |
ratio = this.ScaleRatio6px; | |
} | |
// 原始位置 + 居中差值 + margin边距 | |
return { | |
x: left + (standWidth - maxWidth) / 2 - DefaultViewportMargin, | |
y: top + (standHeight - maxHeight) / 2 - DefaultViewportMargin, | |
ratio: ratio | |
}; | |
} | |
/** | |
* 生成透明色的svg底图 | |
* @param {String} svg svg文本内容 | |
*/ | |
}, { | |
key: 'generateTransparentSvg', | |
value: function generateTransparentSvg(svg) { | |
var $div = document.createElement('div'); | |
$div.innerHTML = svg; | |
$div.style.visibility = 'hidden'; | |
document.body.appendChild($div); | |
var $svg = $div.children[0]; | |
SVGRender.normalizeSvg($svg); | |
this.walkSvgStandsElement($svg, function ($stand) { | |
addStyle($stand, { | |
fill: 'rgba(0,0,0,0.2)' | |
}); | |
}); | |
// svg转url | |
var transparentSvgHtml = $div.innerHTML; | |
var url = Util.svgToImageUrl(transparentSvgHtml); | |
$div.remove(); | |
return url; | |
} | |
}, { | |
key: 'updateView', | |
/** | |
* 更新视图 | |
* @param {boolean} shouldSwichScene 是否应该判断切换场景 | |
* @param {boolean} shouldShowThumbnail 是否自动显示鹰眼图 | |
*/ | |
value: function updateView() { | |
var shouldSwichScene = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; | |
var shouldShowThumbnail = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; | |
// 更新位置 | |
var areaSize = this._area.getSize(); | |
var centerViewportPoint = this._viewport.getCenterPoint(); | |
var currentViewportPoint = this._viewport.getPoint(); | |
var scale = this._viewport.getScale(); | |
if (!this.onlyShowSelectSeatScene && shouldSwichScene) { | |
if (this._scene === Scene.SelectArea && scale > 1 / this.ScaleRatio6px) { | |
this.showSelectSeatScene(); | |
} else if (this._scene === Scene.SelectSeat && scale < 1 / this.ScaleRatio6px) { | |
this.showSelectAreaScene(); | |
} | |
} | |
var x = -(areaSize.width * scale - this._$container.clientWidth) / 2 + (centerViewportPoint.x - currentViewportPoint.x); | |
var y = -(areaSize.height * scale - this._$container.clientHeight) / 2 + (centerViewportPoint.y - currentViewportPoint.y); | |
if (this._scene === Scene.SelectArea) { | |
// 更新选区svg大小和位置 | |
addStyle(this._$venueSvg, { | |
width: this._svgWidth * scale, | |
height: this._svgHeight * scale, | |
left: x, | |
top: y | |
}); | |
} else { | |
// 更新选座canvas大小和位置 | |
this._ctx.setScale(scale); | |
this._ctx.setPosition({ | |
x: x, | |
y: y | |
}); | |
// 每300ms进行一次绘制 | |
if (this._prevTime === undefined || Date.now() - this._prevTime > 300) { | |
this.drawSeat(); | |
this._prevTime = Date.now(); | |
} | |
} | |
if (this._thumbnail) { | |
// 更新鹰眼图 | |
this._thumbnail.update(); | |
if (shouldShowThumbnail) { | |
this.showThumbnail(); | |
} | |
} | |
} | |
}, { | |
key: 'handleSelectSeat', | |
/** | |
* 处理选座事件 | |
* @param {Array} selectedSeats 已选中的座位 | |
* @param {Seat|[Seat]} changedSeat 本次变化的座位 | |
* @param {String} type 变化类型(选中/取消选中) | |
*/ | |
value: function handleSelectSeat(selectedSeats, changedSeat, type) { | |
var index = StandRender.indexOfFirstExceedSeat(selectedSeats, this._maxPickNumber, true); | |
if (index !== -1) { | |
for (var i = index; i < selectedSeats.length; i++) { | |
selectedSeats[i].cancelSelect(); | |
} | |
this._area.reserveNSelectSeats(index); | |
if (this.onError) { | |
this.onError({ | |
code: ErrorCode.ExceedLimitNumber, | |
message: ErrorMessage.exceeded_stand_purchase_limit, | |
messageKey: 'exceeded_stand_purchase_limit' | |
}); | |
} | |
return; | |
} | |
if (this.onSelectSeat) { | |
var selectedSeatsInfo = selectedSeats.map(function (seat) { | |
return seat.getInfo(); | |
}); | |
var changedSeatInfo = Array.isArray(changedSeat) ? changedSeat.map(function (seat) { | |
return seat.getInfo(); | |
}) : changedSeat.getInfo(); | |
this.onSelectSeat(selectedSeatsInfo, changedSeatInfo, type); | |
} | |
} | |
/** | |
* 处理错误 | |
* @param {Error} e 错误对象 | |
*/ | |
}, { | |
key: 'handleError', | |
value: function handleError(e) { | |
if (this.onError) { | |
this.onError(e); | |
} | |
} | |
/** | |
* 显示选区场景 | |
*/ | |
}, { | |
key: 'showSelectAreaScene', | |
value: function showSelectAreaScene() { | |
this._scene = Scene.SelectArea; | |
addStyle(this._$venueSvg, { | |
display: 'block' | |
}); | |
addStyle(this._$seatCanvas, { | |
display: 'none' | |
}); | |
this.updateView(undefined, false); | |
if (this.onSceneChange) { | |
this.onSceneChange(this._scene); | |
} | |
} | |
/** | |
* 显示选座场景 | |
*/ | |
}, { | |
key: 'showSelectSeatScene', | |
value: function showSelectSeatScene() { | |
this._scene = Scene.SelectSeat; | |
addStyle(this._$venueSvg, { | |
display: 'none' | |
}); | |
addStyle(this._$seatCanvas, { | |
display: 'block' | |
}); | |
this.updateView(undefined, false); | |
if (this.onSceneChange) { | |
this.onSceneChange(this._scene); | |
} | |
} | |
/** | |
* 高亮看台 | |
* @param {number} priceIndex 票价索引 | |
*/ | |
}, { | |
key: 'highlightStand', | |
value: function highlightStand(priceIndex) { | |
if (priceIndex === -1) { | |
var _iteratorNormalCompletion2 = true; | |
var _didIteratorError2 = false; | |
var _iteratorError2 = undefined; | |
try { | |
for (var _iterator2 = Object.values(this._standsMap)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | |
var stand = _step2.value; | |
if (stand.s !== 1) { | |
continue; | |
} | |
if (stand.rainbow) { | |
for (var i = 0; i < stand.$el.childNodes.length; i++) { | |
var $child = stand.$el.childNodes[i]; | |
var rowId = $child.getAttribute('row_id'); | |
var color = stand.rainbow[rowId]; | |
var colorAvailable = !stand.availableRainbowColors || stand.availableRainbowColors[color]; | |
if (stand.rainbow[rowId]) { | |
addStyle($child, { | |
fill: colorAvailable ? stand.rainbow[rowId] : NotSaleColor$1, | |
opacity: 1 | |
}); | |
} | |
} | |
} else { | |
addStyle(stand.$el, { | |
opacity: 1, | |
fill: stand.c | |
}); | |
} | |
} | |
} catch (err) { | |
_didIteratorError2 = true; | |
_iteratorError2 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion2 && _iterator2.return) { | |
_iterator2.return(); | |
} | |
} finally { | |
if (_didIteratorError2) { | |
throw _iteratorError2; | |
} | |
} | |
} | |
} else { | |
var price = Object.values(this._priceList).find(function (x) { | |
return x.index === priceIndex; | |
}); | |
if (price) { | |
var priceId = price.priceId; | |
var _iteratorNormalCompletion3 = true; | |
var _didIteratorError3 = false; | |
var _iteratorError3 = undefined; | |
try { | |
for (var _iterator3 = Object.values(this._standsMap)[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { | |
var _stand = _step3.value; | |
if (_stand.s !== 1) { | |
continue; | |
} | |
var opacity = -1; | |
if (_stand.j && _stand.j.match(priceId)) { | |
opacity = 1; | |
} else if (_stand.s === 1) { | |
opacity = 0.2; | |
} | |
if (opacity !== -1) { | |
if (_stand.rainbow) { | |
for (var _i = 0; _i < _stand.$el.childNodes.length; _i++) { | |
var _$child = _stand.$el.childNodes[_i]; | |
var _rowId = _$child.getAttribute('row_id'); | |
if (_stand.rainbow[_rowId]) { | |
addStyle(_$child, { | |
fill: opacity === 1 ? Util.getNormalizeColor(price.color) : _stand.rainbow[_rowId], | |
opacity: opacity | |
}); | |
} | |
} | |
} else { | |
addStyle(_stand.$el, { | |
fill: opacity === 1 ? Util.getNormalizeColor(price.color) : _stand.c, | |
opacity: opacity | |
}); | |
} | |
} | |
} | |
} catch (err) { | |
_didIteratorError3 = true; | |
_iteratorError3 = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion3 && _iterator3.return) { | |
_iterator3.return(); | |
} | |
} finally { | |
if (_didIteratorError3) { | |
throw _iteratorError3; | |
} | |
} | |
} | |
} | |
} | |
} | |
/** | |
* 渲染中网bbc看台选座 | |
* @param {Object} options 渲染参数 | |
*/ | |
}, { | |
key: 'render', | |
value: function render(options) { | |
var _this6 = this; | |
var _options$svgImageBody = options.svgImageBody, | |
svgImageBody = _options$svgImageBody === undefined ? '' : _options$svgImageBody, | |
_options$rainbowImage = options.rainbowImageBody, | |
rainbowImageBody = _options$rainbowImage === undefined ? '' : _options$rainbowImage, | |
_options$stands = options.stands, | |
stands = _options$stands === undefined ? [] : _options$stands, | |
_options$priceList = options.priceList, | |
priceList = _options$priceList === undefined ? [] : _options$priceList, | |
_options$fetchStandSe = options.fetchStandSeats, | |
fetchStandSeats = _options$fetchStandSe === undefined ? noop$1 : _options$fetchStandSe, | |
_options$maxPickNumbe = options.maxPickNumber, | |
maxPickNumber = _options$maxPickNumbe === undefined ? 6 : _options$maxPickNumbe, | |
_options$seatStyle = options.seatStyle, | |
seatStyle = _options$seatStyle === undefined ? 1 : _options$seatStyle, | |
_options$standGroup = options.standGroup, | |
standGroup = _options$standGroup === undefined ? '' : _options$standGroup, | |
_options$venueScale = options.venueScale, | |
venueScale = _options$venueScale === undefined ? 1 : _options$venueScale, | |
_options$saleablePric = options.saleablePriceIdList, | |
saleablePriceIdList = _options$saleablePric === undefined ? [] : _options$saleablePric; | |
var seatStaticData = options.seatStaticData, | |
seatStatusData = options.seatStatusData; | |
var UseCompress = seatStaticData && seatStatusData; | |
// 保存备用 | |
this._maxPickNumber = maxPickNumber; | |
this._seatStyle = seatStyle; | |
this._priceList = priceList.reduce(function (result, price, index) { | |
result[price.priceId] = Object.assign({ | |
index: index | |
}, price); | |
return result; | |
}, {}); | |
this._standGroup = standGroup ? standGroup.split('|') : []; | |
this._venueScale = venueScale; | |
this.isRainbow = !!rainbowImageBody; | |
// 预处理看台数据, 转为合适的结构 | |
this.getStandsMap(stands); | |
// 如果有静态压缩数据, 对其解码 | |
var parser = null; | |
var parseCompressData = function parseCompressData() { | |
// 静态压缩数据 | |
try { | |
parser = new KeylinSeatParser(seatStaticData); | |
parser.parseHeaders(); | |
} catch (err) { | |
UseCompress = false; | |
// render结束前尚未设置 onError 回调事件, 需要异步等待 | |
setTimeout(function () { | |
_this6.handleError({ | |
code: ErrorCode.DecompressSeatStaticFail, | |
message: err.message, | |
messageKey: 'decompress_seat_static_fail', | |
rawError: err, | |
expandInfo: err.expandInfo | |
}); | |
}); | |
} | |
_this6.standSeatsStatus = seatStatusData; | |
}; | |
// 获取座位数据的方法, 要区分是否有静态压缩数据 | |
this.fetchStandSeats = function () { | |
var _ref4 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee3(standIdList) { | |
var seats, _iteratorNormalCompletion4, _didIteratorError4, _iteratorError4, _iterator4, _step4, id, standSeats, _iteratorNormalCompletion6, _didIteratorError6, _iteratorError6, _iterator6, _step6, _seat, _iteratorNormalCompletion5, _didIteratorError5, _iteratorError5, _iterator5, _step5, seat; | |
return regeneratorRuntime.wrap(function _callee3$(_context3) { | |
while (1) { | |
switch (_context3.prev = _context3.next) { | |
case 0: | |
seats = []; | |
if (!UseCompress) { | |
_context3.next = 69; | |
break; | |
} | |
_iteratorNormalCompletion4 = true; | |
_didIteratorError4 = false; | |
_iteratorError4 = undefined; | |
_context3.prev = 5; | |
_iterator4 = standIdList[Symbol.iterator](); | |
case 7: | |
if (_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done) { | |
_context3.next = 33; | |
break; | |
} | |
id = _step4.value; | |
standSeats = parser.getStandSeats(id); | |
_iteratorNormalCompletion6 = true; | |
_didIteratorError6 = false; | |
_iteratorError6 = undefined; | |
_context3.prev = 13; | |
for (_iterator6 = standSeats[Symbol.iterator](); !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { | |
_seat = _step6.value; | |
_seat.standId = id; | |
} | |
_context3.next = 21; | |
break; | |
case 17: | |
_context3.prev = 17; | |
_context3.t0 = _context3['catch'](13); | |
_didIteratorError6 = true; | |
_iteratorError6 = _context3.t0; | |
case 21: | |
_context3.prev = 21; | |
_context3.prev = 22; | |
if (!_iteratorNormalCompletion6 && _iterator6.return) { | |
_iterator6.return(); | |
} | |
case 24: | |
_context3.prev = 24; | |
if (!_didIteratorError6) { | |
_context3.next = 27; | |
break; | |
} | |
throw _iteratorError6; | |
case 27: | |
return _context3.finish(24); | |
case 28: | |
return _context3.finish(21); | |
case 29: | |
seats = seats.concat(standSeats); | |
case 30: | |
_iteratorNormalCompletion4 = true; | |
_context3.next = 7; | |
break; | |
case 33: | |
_context3.next = 39; | |
break; | |
case 35: | |
_context3.prev = 35; | |
_context3.t1 = _context3['catch'](5); | |
_didIteratorError4 = true; | |
_iteratorError4 = _context3.t1; | |
case 39: | |
_context3.prev = 39; | |
_context3.prev = 40; | |
if (!_iteratorNormalCompletion4 && _iterator4.return) { | |
_iterator4.return(); | |
} | |
case 42: | |
_context3.prev = 42; | |
if (!_didIteratorError4) { | |
_context3.next = 45; | |
break; | |
} | |
throw _iteratorError4; | |
case 45: | |
return _context3.finish(42); | |
case 46: | |
return _context3.finish(39); | |
case 47: | |
if (!_this6.standSeatsStatus) { | |
_context3.next = 67; | |
break; | |
} | |
_iteratorNormalCompletion5 = true; | |
_didIteratorError5 = false; | |
_iteratorError5 = undefined; | |
_context3.prev = 51; | |
for (_iterator5 = seats[Symbol.iterator](); !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { | |
seat = _step5.value; | |
if (saleablePriceIdList.length !== 0 && !saleablePriceIdList.includes(seat.groupid === 0 ? seat.plid : seat.groupPriceid)) { | |
seat.s = 0; | |
} else { | |
seat.s = _this6.standSeatsStatus[seat.standId][seat.i]; | |
} | |
} | |
_context3.next = 59; | |
break; | |
case 55: | |
_context3.prev = 55; | |
_context3.t2 = _context3['catch'](51); | |
_didIteratorError5 = true; | |
_iteratorError5 = _context3.t2; | |
case 59: | |
_context3.prev = 59; | |
_context3.prev = 60; | |
if (!_iteratorNormalCompletion5 && _iterator5.return) { | |
_iterator5.return(); | |
} | |
case 62: | |
_context3.prev = 62; | |
if (!_didIteratorError5) { | |
_context3.next = 65; | |
break; | |
} | |
throw _iteratorError5; | |
case 65: | |
return _context3.finish(62); | |
case 66: | |
return _context3.finish(59); | |
case 67: | |
_context3.next = 72; | |
break; | |
case 69: | |
_context3.next = 71; | |
return fetchStandSeats(standIdList); | |
case 71: | |
seats = _context3.sent; | |
case 72: | |
return _context3.abrupt('return', seats); | |
case 73: | |
case 'end': | |
return _context3.stop(); | |
} | |
} | |
}, _callee3, _this6, [ | |
[5, 35, 39, 47], | |
[13, 17, 21, 29], | |
[22, , 24, 28], | |
[40, , 42, 46], | |
[51, 55, 59, 67], | |
[60, , 62, 66] | |
]); | |
})); | |
return function (_x7) { | |
return _ref4.apply(this, arguments); | |
}; | |
}(); | |
if (UseCompress && this.onlyShowSelectSeatScene) { | |
parseCompressData(); | |
} | |
// 处理svg | |
this.createSvgElement(rainbowImageBody, svgImageBody); | |
// 设置聚焦看台 | |
this._focusStand = null; | |
// 生成鹰眼图底图, 要展示座位: 透明底图, 其他: 带看台颜色底图 | |
var thumbnailBackgroundImage = null; | |
if (this._venueScale === 1) { | |
thumbnailBackgroundImage = this.generateTransparentSvg(svgImageBody); | |
} else { | |
thumbnailBackgroundImage = Util.svgToImageUrl(this._$venueSvg.parentNode.innerHTML); | |
} | |
// 初始化 | |
this.init(thumbnailBackgroundImage); | |
// 切换场景, 这里必须异步, 等业务方注册onSceneChange事件后再切, 否则业务方收不到第一次切换场景的消息 | |
// 业务方代码是同步的, 所以延时0s即可 | |
setTimeout(asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee4() { | |
var _ref6, _ref7; | |
return regeneratorRuntime.wrap(function _callee4$(_context4) { | |
while (1) { | |
switch (_context4.prev = _context4.next) { | |
case 0: | |
if (!_this6.onlyShowSelectSeatScene) { | |
_context4.next = 5; | |
break; | |
} | |
_this6.showSelectSeatScene(); | |
if (window.onTrcker) { | |
window.onTrcker({ | |
type: 'showStandTime', | |
c1: Date.now() - window.performance.timing.responseStart | |
}); | |
} | |
_context4.next = 15; | |
break; | |
case 5: | |
_this6.showSelectAreaScene(); | |
if (window.onTrcker) { | |
window.onTrcker({ | |
type: 'showVenueTime', | |
c1: Date.now() - window.performance.timing.responseStart | |
}); | |
} | |
if (!UseCompress) { | |
_context4.next = 15; | |
break; | |
} | |
_context4.next = 10; | |
return Promise.all([seatStaticData(), seatStatusData()]); | |
case 10: | |
_ref6 = _context4.sent; | |
_ref7 = slicedToArray(_ref6, 2); | |
seatStaticData = _ref7[0]; | |
seatStatusData = _ref7[1]; | |
parseCompressData(); | |
case 15: | |
case 'end': | |
return _context4.stop(); | |
} | |
} | |
}, _callee4, _this6); | |
})), 0); | |
// 延迟绘制, 保证座位优先显示 | |
setTimeout(function () { | |
_this6._thumbnail.draw(_this6._thumbnailCtx); | |
}, 500); | |
} | |
/* ======= 对外暴露方法 ======= */ | |
/** | |
* 更新视口聚焦的看台 | |
* @param {Number} standId 看台id | |
*/ | |
/** | |
* 高亮指定票价座位 | |
* @param {number} priceIndex 票价索引 | |
*/ | |
/** | |
* 跳转到选区场景初始视图 | |
*/ | |
/** | |
* 全量更新座位状态 | |
* @param {Object} seatsStatusData 座位状态数据 | |
*/ | |
/** | |
* 取消座位选中 | |
* @param {Number} seatId 座位id | |
*/ | |
/** | |
* 座位预锁定 | |
* @param {number[]} seatIds 要预锁的座位id列表 | |
*/ | |
}]); | |
return SVGRender; | |
}(); | |
var Venue = function () { | |
/** | |
* 构造函数 | |
* @param {HTMLElement} $container div容器 | |
* @param {string} backgroundImage 底图地址 | |
* @param {Object[]} stands 看台列表 | |
*/ | |
function Venue($container, backgroundImage, stands) { | |
var _this = this; | |
classCallCheck(this, Venue); | |
this.onTouchStart = function (e) { | |
_this._touchStatus = 'start'; | |
_this._prevTouchPoints = getEventPoints(e); | |
_this._prevTime = Date.now(); | |
}; | |
this.onTouchMove = function (e) { | |
e.preventDefault(); | |
if (_this._prevTouchPoints) { | |
var currentTouchPoints = getEventPoints(e); | |
// 过滤横向和纵向同时低于1.5px的move事件 | |
// 三星浏览器和vivo浏览器会因为点击触发小距离move而不好点中座位, 这里可以缓解该情况 | |
if (Math.abs(currentTouchPoints[0].x - _this._prevTouchPoints[0].x) <= 1.5 && Math.abs(currentTouchPoints[0].y - _this._prevTouchPoints[0].y) <= 1.5) { | |
return; | |
} | |
_this._touchStatus = 'move'; | |
if (currentTouchPoints.length === 1) { | |
// 单指拖动 | |
// 如果是二指缩放, 且手指离开时间不一致, 又触发了move事件, 将本次手指位置作为起始点 | |
if (_this._prevTouchPoints.length === 2) { | |
_this._prevTouchPoints = currentTouchPoints; | |
return; | |
} | |
// 移动视口位置 | |
_this._viewport.move(_this._prevTouchPoints[0].x - currentTouchPoints[0].x, _this._prevTouchPoints[0].y - currentTouchPoints[0].y); | |
// 记录当前点 | |
_this._prevTouchPoints = currentTouchPoints; | |
} else if (currentTouchPoints.length === 2) { | |
// 二指缩放 | |
if (_this._prevTouchPoints.length === 1) { | |
return; | |
} | |
// 根据移动距离计算线性缩放倍率变化值, 缩放视口大小 | |
var sx = _this._prevTouchPoints[0].x - _this._prevTouchPoints[1].x; | |
var sy = _this._prevTouchPoints[0].y - _this._prevTouchPoints[1].y; | |
var ex = currentTouchPoints[0].x - currentTouchPoints[1].x; | |
var ey = currentTouchPoints[0].y - currentTouchPoints[1].y; | |
var d1 = Math.sqrt(sx * sx + sy * sy); | |
var d2 = Math.sqrt(ex * ex + ey * ey); | |
_this._viewport.scaleMultip(d1 / d2); | |
_this._prevTouchPoints = currentTouchPoints; | |
} | |
_this.updateView(); | |
} | |
}; | |
this.onTouchEnd = function () { | |
var position = getPosition(_this._$div); | |
var scale = _this._viewport.getScale(); | |
// 如果status不是move, 说明是点击事件 | |
if (_this._touchStatus === 'start') { | |
var stand = _this.getIntersectStand({ | |
x: (_this._prevTouchPoints[0].x - position.left) / scale, | |
y: (_this._prevTouchPoints[0].y - position.top) / scale | |
}); | |
if (stand && _this.onClickStand) { | |
_this.onClickStand(stand); | |
} | |
} | |
_this._prevTouchPoints = null; | |
}; | |
this.onMouseWheel = function (e) { | |
e.preventDefault(); | |
_this._viewport.scale((e.deltaY || e.wheelDelta) / 500); | |
_this.updateView(); | |
}; | |
this._$container = $container; | |
this._backgroundImage = backgroundImage; | |
this._stands = stands; | |
this._stands.forEach(function (stand) { | |
stand.pis = getPoints(stand.pis); | |
stand.boundingRect = getBoundingRect(stand.pis); | |
}); | |
} | |
createClass(Venue, [{ | |
key: 'init', | |
value: function () { | |
var _ref = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee() { | |
var _this2 = this; | |
var $image, naturalWidth, naturalHeight, ratio, $bgImage, $canvas; | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
_context.next = 2; | |
return fetchImage(this._backgroundImage); | |
case 2: | |
$image = _context.sent; | |
naturalWidth = $image.naturalWidth, naturalHeight = $image.naturalHeight; | |
this._naturalWidth = naturalWidth; | |
this._naturalHeight = naturalHeight; | |
// 计算视口初始缩放倍率 | |
ratio = naturalWidth / this._$container.clientWidth; | |
if (this._$container.clientHeight * ratio < naturalHeight) { | |
ratio = naturalHeight / this._$container.clientHeight; | |
} | |
this._viewport = new Viewport(this._$container.clientWidth, this._$container.clientHeight, naturalWidth, naturalHeight, { | |
ratio: ratio, | |
renderPadding: false, | |
minScaleRatio: 0.5, | |
maxScaleRatio: ratio | |
}); | |
// 初始化选区div容器 | |
this._$div = document.createElement('div'); | |
addStyle(this._$div, { | |
position: 'absolute' | |
}); | |
this.updateView(); | |
this._$container.appendChild(this._$div); | |
// 场馆图 | |
$bgImage = document.createElement('img'); | |
$bgImage.src = this._backgroundImage; | |
addStyle($bgImage, { | |
width: '100%', | |
height: '100%', | |
position: 'absolute', | |
top: 0, | |
left: 0 | |
}); | |
this._$div.appendChild($bgImage); | |
// 初始化选区canvas | |
$canvas = createCanvas(naturalWidth, naturalHeight); | |
addStyle($canvas, { | |
width: '100%', | |
height: '100%', | |
position: 'absolute', | |
top: 0, | |
left: 0 | |
}); | |
this._$div.appendChild($canvas); | |
this._ctx = $canvas.getContext('2d'); | |
// 注册事件 | |
if (UA.isPC) { | |
this._$div.addEventListener('mousedown', this.onTouchStart); | |
this._$div.addEventListener('mousemove', throttle(this.onTouchMove, 100, 50)); | |
this._$div.addEventListener('mouseup', this.onTouchEnd); | |
this._$div.addEventListener('mouseleave', this.onMouseLeave); | |
} else { | |
this._$div.addEventListener('touchstart', this.onTouchStart); | |
this._$div.addEventListener('touchmove', throttle(this.onTouchMove, 100, 50)); | |
this._$div.addEventListener('touchend', this.onTouchEnd); | |
} | |
this._$div.addEventListener('mousewheel', this.onMouseWheel); | |
this._stands.forEach(function (stand) { | |
if (stand.s === 0) { | |
_this2.drawStand(stand.pis, 'rgba(239, 239, 239, 0.9)', 'transparent'); | |
} | |
}); | |
case 24: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, this); | |
})); | |
function init() { | |
return _ref.apply(this, arguments); | |
} | |
return init; | |
}() | |
}, { | |
key: 'updateView', | |
value: function updateView() { | |
var centerViewportPoint = this._viewport.getCenterPoint(); | |
var currentViewportPoint = this._viewport.getPoint(); | |
var scale = this._viewport.getScale(); | |
addStyle(this._$div, { | |
width: this._naturalWidth * scale, | |
height: this._naturalHeight * scale, | |
left: -(this._naturalWidth * scale - this._$container.clientWidth) / 2 + centerViewportPoint.x - currentViewportPoint.x, | |
top: -(this._naturalHeight * scale - this._$container.clientHeight) / 2 + centerViewportPoint.y - currentViewportPoint.y | |
}); | |
} | |
/** | |
* 绘制看台 | |
* @param {Object[]} points 坐标列表 | |
* @param {string} fillStyle 遮罩层样式 | |
*/ | |
}, { | |
key: 'drawStand', | |
value: function drawStand(points, fillStyle, strokeStyle) { | |
this._ctx.lineWidth = 2; | |
this._ctx.strokeStyle = strokeStyle; | |
this._ctx.beginPath(); | |
this._ctx.moveTo(points[0].x, points[0].y); | |
for (var i = 1; i < points.length; i++) { | |
this._ctx.lineTo(points[i].x, points[i].y); | |
} | |
this._ctx.moveTo(points[0].x, points[0].y); | |
this._ctx.fillStyle = fillStyle; | |
this._ctx.fill(); | |
this._ctx.stroke(); | |
} | |
}, { | |
key: 'highlightPrice', | |
value: function highlightPrice(priceId) { | |
var _this3 = this; | |
this._ctx.clearRect(0, 0, this._naturalWidth, this._naturalHeight); | |
this._stands.forEach(function (stand) { | |
if (stand.s !== 1) { | |
_this3.drawStand(stand.pis, 'rgba(239, 239, 239, 0.9)', 'transparent'); | |
return; | |
} | |
if (stand.j.indexOf(priceId) === -1) { | |
return; | |
} | |
_this3.drawStand(stand.pis, 'rgba(0, 0, 0, 0.6)', '#333'); | |
}); | |
} | |
}, { | |
key: 'getIntersectStand', | |
value: function getIntersectStand(point) { | |
var _iteratorNormalCompletion = true; | |
var _didIteratorError = false; | |
var _iteratorError = undefined; | |
try { | |
for (var _iterator = this._stands[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | |
var stand = _step.value; | |
var _stand$boundingRect = stand.boundingRect, | |
left = _stand$boundingRect.left, | |
right = _stand$boundingRect.right, | |
top = _stand$boundingRect.top, | |
bottom = _stand$boundingRect.bottom; | |
if (point.x >= left && point.x <= right && point.y >= top && point.y <= bottom) { | |
return stand; | |
} | |
} | |
} catch (err) { | |
_didIteratorError = true; | |
_iteratorError = err; | |
} finally { | |
try { | |
if (!_iteratorNormalCompletion && _iterator.return) { | |
_iterator.return(); | |
} | |
} finally { | |
if (_didIteratorError) { | |
throw _iteratorError; | |
} | |
} | |
} | |
return null; | |
} | |
}, { | |
key: 'hide', | |
value: function hide() { | |
addStyle(this._$div, { | |
display: 'none' | |
}); | |
} | |
}, { | |
key: 'show', | |
value: function show() { | |
addStyle(this._$div, { | |
display: 'block' | |
}); | |
} | |
}]); | |
return Venue; | |
}(); | |
var _class$16; | |
function _applyDecoratedDescriptor$5(target, property, decorators, descriptor, context) { | |
var desc = {}; | |
Object['ke' + 'ys'](descriptor).forEach(function (key) { | |
desc[key] = descriptor[key]; | |
}); | |
desc.enumerable = !!desc.enumerable; | |
desc.configurable = !!desc.configurable; | |
if ('value' in desc || desc.initializer) { | |
desc.writable = true; | |
} | |
desc = decorators.slice().reverse().reduce(function (desc, decorator) { | |
return decorator(target, property, desc) || desc; | |
}, desc); | |
if (context && desc.initializer !== void 0) { | |
desc.value = desc.initializer ? desc.initializer.call(context) : void 0; | |
desc.initializer = undefined; | |
} | |
if (desc.initializer === void 0) { | |
Object['define' + 'Property'](target, property, desc); | |
desc = null; | |
} | |
return desc; | |
} | |
var Stand$1 = (_class$16 = function (_MatrixStandRender) { | |
inherits(Stand, _MatrixStandRender); | |
function Stand($container) { | |
classCallCheck(this, Stand); | |
var _this = possibleConstructorReturn(this, (Stand.__proto__ || Object.getPrototypeOf(Stand)).call(this, $container)); | |
_this.highlightPrice = function (priceIndex) { | |
if (_this._area) { | |
_this._area.highlightPrice(priceIndex); | |
// 回到初始视图 | |
_this.initViewport(); | |
_this.updateView(); | |
} | |
}; | |
_this._$container = document.createElement('div'); | |
addStyle(_this._$container, { | |
width: '100%', | |
height: '100%', | |
position: 'absolute', | |
left: 0, | |
top: 0 | |
}); | |
$container.appendChild(_this._$container); | |
return _this; | |
} | |
/** | |
* 渲染选座视图 | |
* @param {Object[]} seats 座位列表 | |
* @param {Object[]} priceList 票价列表 | |
* @param {number} maxPickNumber 最大可选数量 | |
* @param {string} standName 看台名称 | |
* @param {string} standPriceList 看台可售票价 | |
* @param {number} prevHighlightPriceIndex 最后一次高亮票价的索引 | |
*/ | |
createClass(Stand, [{ | |
key: 'render', | |
value: function () { | |
var _ref = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee(seats, priceList, maxPickNumber, standName, standPriceList, prevHighlightPriceIndex) { | |
var _this2 = this; | |
var row, column, minRow, minColumn, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, seat, _loop, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, _seat, price; | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
if (seats.some(function (seat) { | |
return seat.s === 2; | |
})) { | |
this.onError({ | |
code: ErrorCode.Normal, | |
message: ErrorMessage.enter_select_seat(standName), | |
messageKey: 'enter_select_seat' | |
}); | |
} else { | |
this.onError({ | |
code: ErrorCode.Normal, | |
message: ErrorMessage.stand_no_chooseable_seat(standName), | |
messageKey: 'stand_no_chooseable_seat' | |
}); | |
} | |
this._priceList = priceList; | |
this._maxPickNumber = maxPickNumber; | |
// 计算最大和最小的行数/列数 | |
row = 0; | |
column = 0; | |
minRow = Number.MAX_SAFE_INTEGER; | |
minColumn = Number.MAX_SAFE_INTEGER; | |
_iteratorNormalCompletion = true; | |
_didIteratorError = false; | |
_iteratorError = undefined; | |
_context.prev = 10; | |
for (_iterator = seats[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | |
seat = _step.value; | |
seat.x = +seat.x; | |
seat.y = +seat.y; | |
if (seat.x > row) { | |
row = seat.x; | |
} | |
if (seat.x < minRow) { | |
minRow = seat.x; | |
} | |
if (seat.y > column) { | |
column = seat.y; | |
} | |
if (seat.y < minColumn) { | |
minColumn = seat.y; | |
} | |
} | |
// 计算总行数/列数 | |
_context.next = 18; | |
break; | |
case 14: | |
_context.prev = 14; | |
_context.t0 = _context['catch'](10); | |
_didIteratorError = true; | |
_iteratorError = _context.t0; | |
case 18: | |
_context.prev = 18; | |
_context.prev = 19; | |
if (!_iteratorNormalCompletion && _iterator.return) { | |
_iterator.return(); | |
} | |
case 21: | |
_context.prev = 21; | |
if (!_didIteratorError) { | |
_context.next = 24; | |
break; | |
} | |
throw _iteratorError; | |
case 24: | |
return _context.finish(21); | |
case 25: | |
return _context.finish(18); | |
case 26: | |
this.init(row - minRow + 1, column - minColumn + 1); | |
_loop = function _loop(_seat) { | |
var priceIndex = _this2._priceList.findIndex(function (price) { | |
return price.priceId === _seat.plid; | |
}); | |
// 保证座位行数/列数从0开始, 避免空白区域 | |
_this2._area.addSeat(_seat.x - minRow, _seat.y - minColumn, { | |
id: _seat.sid, | |
status: _seat.s, | |
row: _seat.rhint || '', | |
column: _seat.shint || '', | |
color: _this2._priceList[priceIndex] && _this2._priceList[priceIndex].color || NotSaleColor, | |
floor: _seat.fn, | |
priceIndex: priceIndex, | |
chinese: false, | |
isPackage: _seat.groupid !== 0, | |
packagePriceIndex: _this2._priceList.findIndex(function (price) { | |
return price.priceId === _seat.groupPriceid; | |
}), | |
packageCombinedId: _seat.groupid, | |
standId: _seat.standId, | |
plid: _seat.plid, | |
groupid: _seat.groupid, | |
groupPriceid: _seat.groupPriceid | |
}); | |
}; | |
_iteratorNormalCompletion2 = true; | |
_didIteratorError2 = false; | |
_iteratorError2 = undefined; | |
_context.prev = 31; | |
for (_iterator2 = seats[Symbol.iterator](); !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | |
_seat = _step2.value; | |
_loop(_seat); | |
} | |
_context.next = 39; | |
break; | |
case 35: | |
_context.prev = 35; | |
_context.t1 = _context['catch'](31); | |
_didIteratorError2 = true; | |
_iteratorError2 = _context.t1; | |
case 39: | |
_context.prev = 39; | |
_context.prev = 40; | |
if (!_iteratorNormalCompletion2 && _iterator2.return) { | |
_iterator2.return(); | |
} | |
case 42: | |
_context.prev = 42; | |
if (!_didIteratorError2) { | |
_context.next = 45; | |
break; | |
} | |
throw _iteratorError2; | |
case 45: | |
return _context.finish(42); | |
case 46: | |
return _context.finish(39); | |
case 47: | |
_context.next = 49; | |
return this.drawSeat(); | |
case 49: | |
this.drawThumbnail(); | |
this.drawLineNumber(); | |
// 如果有票价被选中, 并且当前看台存在该票价, 则高亮相应座位 | |
if (prevHighlightPriceIndex !== -1) { | |
price = priceList[prevHighlightPriceIndex]; | |
if (standPriceList.indexOf(price.priceId) !== -1) { | |
this.highlightPrice(prevHighlightPriceIndex); | |
} | |
} | |
case 52: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, this, [ | |
[10, 14, 18, 26], | |
[19, , 21, 25], | |
[31, 35, 39, 47], | |
[40, , 42, 46] | |
]); | |
})); | |
function render(_x, _x2, _x3, _x4, _x5, _x6) { | |
return _ref.apply(this, arguments); | |
} | |
return render; | |
}() | |
}, { | |
key: 'destroy', | |
value: function destroy() { | |
if (!this._ctx) { | |
return; | |
} | |
get(Stand.prototype.__proto__ || Object.getPrototypeOf(Stand.prototype), 'destroy', this).call(this); | |
} | |
}, { | |
key: 'hide', | |
value: function hide() { | |
addStyle(this._$container, { | |
display: 'none' | |
}); | |
} | |
}, { | |
key: 'show', | |
value: function show() { | |
addStyle(this._$container, { | |
display: 'block' | |
}); | |
} | |
}, { | |
key: 'onTouchEnd', | |
value: function onTouchEnd(e) { | |
get(Stand.prototype.__proto__ || Object.getPrototypeOf(Stand.prototype), 'onTouchEnd', this).call(this, e); | |
if (this._touchStatus === 'start') { | |
var offset = getOffset(e.currentTarget); | |
// 获取点击位置 | |
var points = getEventPoints(e); | |
var touchPoint = { | |
x: points[0].x - offset.left, | |
y: points[0].y - offset.top | |
}; | |
// 获取当前缩放倍数 | |
var scale = this._viewport.getScale(); | |
var maxScale = 0.75; | |
// 判断是否小于1倍(18px座位), 注意浮点数比较 | |
if (scale > maxScale || Math.abs(scale - maxScale) < 0.0001) { | |
return; | |
} | |
// 计算点击位置与div容器中心点的距离, 基于当前缩放倍率下 | |
var moveX = touchPoint.x - this._$container.clientWidth / 2; | |
var moveY = touchPoint.y - this._$container.clientHeight / 2; | |
// 放大+居中的过渡效果在PC火狐上非常不流畅, 在该问题解决前先不加过渡 | |
this._viewport.scale(1 / maxScale - 1 / scale); | |
var moveScale = maxScale === scale ? 1 : this._viewport.getScale() / scale; | |
this._viewport.move(moveX * moveScale, moveY * moveScale); | |
this.updateView(); | |
this.updateLineNumber(this._viewport.getLineNumberOffset(), this._viewport.getScale()); | |
} | |
} | |
}]); | |
return Stand; | |
}(MatrixStandRender), _applyDecoratedDescriptor$5(_class$16.prototype, 'onTouchEnd', [autobind], Object.getOwnPropertyDescriptor(_class$16.prototype, 'onTouchEnd'), _class$16.prototype), _class$16); | |
var JPGRender = function () { | |
/** | |
* 构造函数 | |
* @param {HTMLElement} $container 渲染容器div | |
*/ | |
/** | |
* 当前渲染中的看台id | |
*/ | |
/** | |
* 当前场景, 选区or选座 | |
*/ | |
function JPGRender($container) { | |
var _this = this; | |
classCallCheck(this, JPGRender); | |
this._scene = Scene.SelectArea; | |
this._seatDataCache = {}; | |
this._isReady = false; | |
this._selectedSeatsMap = {}; | |
this._currentStandId = null; | |
this._prevHighlightPriceIndex = -1; | |
this.highlightPrice = function (priceIndex) { | |
_this._prevHighlightPriceIndex = priceIndex; | |
if (_this._isReady) { | |
var price = _this._priceList[priceIndex] || {}; | |
var priceId = price.priceId || null; | |
if (!_this.onlySelectSeat) { | |
_this._venue.highlightPrice(priceId); | |
} | |
if (_this._stand) { | |
if (priceIndex === -1) { | |
_this._stand.highlightPrice(priceIndex); | |
} else { | |
var stand = _this._stands.find(function (s) { | |
return s.i === _this._currentStandId; | |
}); | |
if (stand && stand.j.indexOf(priceId) !== -1) { | |
_this._stand.highlightPrice(priceIndex); | |
} | |
} | |
} | |
} else { | |
setTimeout(function () { | |
return _this.highlightPrice(priceIndex); | |
}, 200); | |
} | |
}; | |
this.cancelSelectSeat = function (seatId) { | |
if (_this._scene === Scene.SelectSeat) { | |
var currentStandSeats = _this._selectedSeatsMap[_this._currentStandId] || []; | |
if (currentStandSeats.find(function (seat) { | |
return seat.id === seatId; | |
})) { | |
_this._stand._area.cancelSelectSeat(seatId); | |
return; | |
} | |
} | |
for (var standId in _this._selectedSeatsMap) { | |
var seats = _this._selectedSeatsMap[standId]; | |
var index = seats.findIndex(function (seat) { | |
return seat.id === seatId; | |
}); | |
if (index !== -1) { | |
var seat = seats[index]; | |
seats.splice(index, 1); | |
if (_this.onSelectSeat) { | |
var remainSeats = Object.values(_this._selectedSeatsMap).reduce(function (r, l) { | |
return r.concat(l); | |
}, []); | |
_this.onSelectSeat(remainSeats, seat, 'CancelSelect'); | |
} | |
} | |
} | |
var _options$maxPickNumbe = _this._options.maxPickNumber, | |
maxPickNumber = _options$maxPickNumbe === undefined ? 6 : _options$maxPickNumbe; | |
_this._stand.updateMaxPickNumber(maxPickNumber - _this.otherStandselectedSeatsCount); | |
}; | |
this._$container = $container; | |
} | |
/** | |
* 只有选座, 没有选区 | |
*/ | |
/** | |
* 最后一次高亮票价的索引 | |
*/ | |
/** | |
* 存储已选座位, key:看台id value:座位列表 | |
*/ | |
/** | |
* 座位数据缓存, key:看台id value:座位list | |
*/ | |
createClass(JPGRender, [{ | |
key: 'onPopState', | |
/** | |
* 浏览器历史回退事件 | |
*/ | |
value: function onPopState(e) { | |
var _e$state$scene = e.state.scene, | |
scene = _e$state$scene === undefined ? '' : _e$state$scene; | |
this._scene = scene; | |
if (scene === Scene.SelectArea) { | |
this._venue.show(); | |
this._stand.hide(); | |
} else if (scene === Scene.SelectSeat) { | |
this._stand.show(); | |
this._venue.hide(); | |
} | |
this.emitSceneChangeEvent(scene, this._currentStandId); | |
} | |
/** | |
* 对外通知场景切换事件 | |
* @param {string} scene 场景 | |
* @param {string} standId 看台id | |
*/ | |
}, { | |
key: 'emitSceneChangeEvent', | |
value: function emitSceneChangeEvent(scene) { | |
var standId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; | |
if (this.onSceneChange) { | |
this.onSceneChange(scene, scene === Scene.SelectSeat ? standId : ''); | |
} | |
/** | |
* ios safari(包含支付宝)上一个神奇的bug | |
* 从选座回退到选区会导致 <headbar> 里的所有内容点击事件不触发, 并且支付宝上还会点击一次屏幕就闪一下 | |
* 尝试绑定根元素的 click 事件且为捕获阶段, 也不会触发 | |
* 但是调用一次 window.scroll(0, 0) 就好了, 我不知道为什么, 去问神奇的海螺吧 | |
*/ | |
window.scroll(0, 0); | |
} | |
/** | |
* 渲染选座 | |
* @param {object} stand 看台信息 | |
*/ | |
}, { | |
key: 'renderStand', | |
value: function () { | |
var _ref = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee(stand) { | |
var _options, fetchStandSeats, _options$maxPickNumbe2, maxPickNumber, seats, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, seat; | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (1) { | |
switch (_context.prev = _context.next) { | |
case 0: | |
_options = this._options, fetchStandSeats = _options.fetchStandSeats, _options$maxPickNumbe2 = _options.maxPickNumber, maxPickNumber = _options$maxPickNumbe2 === undefined ? 6 : _options$maxPickNumbe2; | |
seats = this._seatDataCache[stand.i]; | |
if (seats) { | |
_context.next = 7; | |
break; | |
} | |
_context.next = 5; | |
return fetchStandSeats([stand.i]); | |
case 5: | |
seats = _context.sent; | |
this._seatDataCache[stand.i] = seats; | |
case 7: | |
this._currentStandId = stand.i; | |
_context.next = 10; | |
return this._stand.render(seats, this._priceList, maxPickNumber - this.otherStandselectedSeatsCount, stand.n, stand.j, this._prevHighlightPriceIndex); | |
case 10: | |
if (!this._selectedSeatsMap[stand.i]) { | |
_context.next = 30; | |
break; | |
} | |
_iteratorNormalCompletion = true; | |
_didIteratorError = false; | |
_iteratorError = undefined; | |
_context.prev = 14; | |
for (_iterator = this._selectedSeatsMap[stand.i][Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | |
seat = _step.value; | |
if (seat.standId === stand.i) { | |
this._stand.selectSeat(seat.id); | |
} | |
} | |
_context.next = 22; | |
break; | |
case 18: | |
_context.prev = 18; | |
_context.t0 = _context['catch'](14); | |
_didIteratorError = true; | |
_iteratorError = _context.t0; | |
case 22: | |
_context.prev = 22; | |
_context.prev = 23; | |
if (!_iteratorNormalCompletion && _iterator.return) { | |
_iterator.return(); | |
} | |
case 25: | |
_context.prev = 25; | |
if (!_didIteratorError) { | |
_context.next = 28; | |
break; | |
} | |
throw _iteratorError; | |
case 28: | |
return _context.finish(25); | |
case 29: | |
return _context.finish(22); | |
case 30: | |
case 'end': | |
return _context.stop(); | |
} | |
} | |
}, _callee, this, [ | |
[14, 18, 22, 30], | |
[23, , 25, 29] | |
]); | |
})); | |
function renderStand(_x2) { | |
return _ref.apply(this, arguments); | |
} | |
return renderStand; | |
}() | |
/** | |
* 处理选区页看台点击事件 | |
* @param {object} stand 看台信息 | |
*/ | |
}, { | |
key: 'onClickStand', | |
value: function () { | |
var _ref2 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee2(stand) { | |
return regeneratorRuntime.wrap(function _callee2$(_context2) { | |
while (1) { | |
switch (_context2.prev = _context2.next) { | |
case 0: | |
if (!(stand.s !== 1)) { | |
_context2.next = 2; | |
break; | |
} | |
return _context2.abrupt('return'); | |
case 2: | |
this._stand.destroy(); | |
this._scene = Scene.SelectSeat; | |
window.history.pushState({ | |
scene: this._scene | |
}, ''); | |
this._venue.hide(); | |
this._stand.show(); | |
this.renderStand(stand); | |
this.emitSceneChangeEvent(this._scene, stand.i); | |
case 9: | |
case 'end': | |
return _context2.stop(); | |
} | |
} | |
}, _callee2, this); | |
})); | |
function onClickStand(_x3) { | |
return _ref2.apply(this, arguments); | |
} | |
return onClickStand; | |
}() | |
}, { | |
key: 'handleSelectSeat', | |
value: function handleSelectSeat(selectedSeats, changedSeats, changeType) { | |
this._selectedSeatsMap[this._currentStandId] = selectedSeats; | |
if (this.onSelectSeat) { | |
var allStandSeats = Object.values(this._selectedSeatsMap); | |
var allSeats = allStandSeats.reduce(function (result, seats) { | |
return result.concat(seats); | |
}, []); | |
this.onSelectSeat(allSeats, changedSeats, changeType); | |
} | |
} | |
}, { | |
key: 'handleError', | |
value: function handleError() { | |
if (this.onError) { | |
this.onError.apply(this, arguments); | |
} | |
} | |
/** | |
* | |
* @param {Object} options | |
*/ | |
}, { | |
key: 'render', | |
value: function () { | |
var _ref3 = asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee3(options) { | |
var _options$stands, stands, _options$backgroundIm, backgroundImage, _options$priceList, priceList; | |
return regeneratorRuntime.wrap(function _callee3$(_context3) { | |
while (1) { | |
switch (_context3.prev = _context3.next) { | |
case 0: | |
this._options = options; | |
_options$stands = options.stands, stands = _options$stands === undefined ? [] : _options$stands, _options$backgroundIm = options.backgroundImage, backgroundImage = _options$backgroundIm === undefined ? '' : _options$backgroundIm, _options$priceList = options.priceList, priceList = _options$priceList === undefined ? [] : _options$priceList; | |
addStyle(this._$container, { | |
position: 'relative' | |
}); | |
this._priceList = priceList; | |
this._stands = stands; | |
// 单看台项目, 直接进入选座场景 | |
this._scene = !this.onlySelectSeat ? Scene.SelectArea : Scene.SelectSeat; | |
window.history.replaceState({ | |
scene: this._scene | |
}, ''); | |
window.addEventListener('popstate', this.onPopState.bind(this)); | |
this._stand = new Stand$1(this._$container); | |
this._stand.onSelectSeat = this.handleSelectSeat.bind(this); | |
this._stand.onError = this.handleError.bind(this); | |
if (!(this._scene === Scene.SelectArea)) { | |
_context3.next = 20; | |
break; | |
} | |
this._stand.hide(); | |
this._venue = new Venue(this._$container, backgroundImage, stands); | |
_context3.next = 16; | |
return this._venue.init(); | |
case 16: | |
this._venue.onClickStand = this.onClickStand.bind(this); | |
this.emitSceneChangeEvent(this._scene); | |
_context3.next = 23; | |
break; | |
case 20: | |
this.renderStand(stands[0]); | |
this._stand.show(); | |
this.emitSceneChangeEvent(this._scene, stands[0].i); | |
case 23: | |
this._isReady = true; | |
case 24: | |
case 'end': | |
return _context3.stop(); | |
} | |
} | |
}, _callee3, this); | |
})); | |
function render(_x4) { | |
return _ref3.apply(this, arguments); | |
} | |
return render; | |
}() | |
/* ======= 对外暴露方法 ======== */ | |
}, { | |
key: 'onlySelectSeat', | |
get: function get$$1() { | |
return this._stands.length < 2; | |
} | |
}, { | |
key: 'otherStandselectedSeatsCount', | |
get: function get$$1() { | |
var _this2 = this; | |
return Object.keys(this._selectedSeatsMap).reduce(function (count, standId) { | |
return count + (+standId === _this2._currentStandId ? 0 : _this2._selectedSeatsMap[standId].length); | |
}, 0); | |
} | |
}]); | |
return JPGRender; | |
}(); | |
window.selectSeatTiming = {}; | |
window.__DEBUG__ = /debug=true/i.test(window.location.search); | |
/** | |
* 渲染matrix看台选座 | |
* @param {Dom} $container div容器 | |
* @param {Binary} options.seatData 座位数据 | |
* @param {Array} options.seatStatus 座位状态数据 | |
* @param {Object} options.seatStatus 座位中文行号 | |
* @param {Array} options.priceList 票价列表 | |
* @param {Number} options.maxPickNumber 最大可选座位数量 | |
*/ | |
function renderStand($container) { | |
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, | |
seatData = _ref.seatData, | |
seatStatus = _ref.seatStatus, | |
seatChineseName = _ref.seatChineseName, | |
priceList = _ref.priceList, | |
maxPickNumber = _ref.maxPickNumber; | |
maxPickNumber = isNaN(maxPickNumber) ? 0 : maxPickNumber; | |
var render = new MatrixStandRender($container); | |
render.render(seatData, seatStatus, seatChineseName, priceList, maxPickNumber); | |
return render; | |
} | |
/** | |
* 渲染其它bbc看台选座 | |
* @param {Dom} $container div容器 | |
* @param {Array} options.seatList 座位数据 | |
* @param {Array} options.priceList 票价列表 | |
* @param {Number} options.maxPickNumber 最大可选座位数量 | |
*/ | |
function renderOtherBBCStand($container) { | |
var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, | |
seatList = _ref2.seatList, | |
priceList = _ref2.priceList, | |
maxPickNumber = _ref2.maxPickNumber; | |
maxPickNumber = isNaN(maxPickNumber) ? 0 : maxPickNumber; | |
var render = new OtherBBCStandRender($container); | |
render.render(seatList, priceList, maxPickNumber); | |
return render; | |
} | |
/** | |
* 渲染中网bbc看台选座 | |
* @param {Dom} $container div容器 | |
* @param {String} options.backgroundImage 底图 | |
* @param {String} options.svgImageBody svg底图内容 | |
* @param {String} options.rainbowImageBody svg彩虹图内容 | |
* @param {Array} options.stands 看台列表 | |
* @param {String} options.focusStandId 初始聚焦看台的ID | |
* @param {Array} options.priceList 票价列表 | |
* @param {Array} options.packagePriceList 票价列表 | |
* @param {Function} options.fetchStandSeats 获取看台座位数据, async函数 | |
* @param {Number} options.maxPickNumber 最大可选座位数量 | |
* @param {Number} options.seatStyle 座位样式, 1:圆形 2:八角(当圆形处理) 3:沙发 | |
* @param {String} options.standGroup 座位id分组 | |
* @param {Number} options.renderMode 接口返回字段, 渲染模式, 3: 鹰眼图展示座位, 其他: 无需处理 | |
*/ | |
function renderBBCStand($container) { | |
var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, | |
backgroundImage = _ref3.backgroundImage, | |
svgImageBody = _ref3.svgImageBody, | |
rainbowImageBody = _ref3.rainbowImageBody, | |
stands = _ref3.stands, | |
focusStandId = _ref3.focusStandId, | |
priceList = _ref3.priceList, | |
packagePriceList = _ref3.packagePriceList, | |
fetchStandSeats = _ref3.fetchStandSeats, | |
maxPickNumber = _ref3.maxPickNumber, | |
seatStyle = _ref3.seatStyle, | |
standGroup = _ref3.standGroup, | |
renderMode = _ref3.renderMode; | |
maxPickNumber = isNaN(maxPickNumber) ? 0 : maxPickNumber; | |
var render = new BBCStandRender($container); | |
render.render(backgroundImage, svgImageBody, rainbowImageBody, stands, focusStandId, priceList, packagePriceList, fetchStandSeats, maxPickNumber, seatStyle, standGroup, renderMode); | |
return render; | |
} | |
/** | |
* 渲染maitix看台选区 | |
* @param {DOM} $container div容器 | |
* @param {String} backgroundImageUrl 底图url | |
* @param {Array} standsData 区域数据 | |
* @param {Array} priceList 票价列表 | |
*/ | |
function renderVenue($container, backgroundImageUrl, standsData, priceList) { | |
var venue = new MaitixVenueRender($container); | |
venue.priceList = priceList; | |
venue.render(backgroundImageUrl, standsData); | |
return venue; | |
} | |
/** | |
* 渲染中网bbc看台选区 | |
* @param {DOM} $container div容器 | |
* @param {String} backgroundImageUrl 底图url | |
* @param {Array} standsData 区域数据 | |
* @param {Array} priceList 票价列表 | |
* @param {String} svgImageBody svg底图内容 | |
*/ | |
function renderBBCVenue($container, backgroundImageUrl, standsData, priceList, svgImageBody) { | |
var isRainbow = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false; | |
var venue = backgroundImageUrl.endsWith('.svg') ? new BBCSVGRender($container) : new BBCVenueRender($container); | |
venue.priceList = priceList; | |
venue.render(backgroundImageUrl, standsData, svgImageBody, isRainbow); | |
return venue; | |
} | |
/** | |
* 渲染SVG底图项目, 选区选座合一 | |
* @param {Dom} $container 容器div | |
* @param {Object} options 渲染参数 | |
*/ | |
function renderSvg($container) { | |
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | |
var render = new SVGRender($container); | |
render.render(options); | |
return render; | |
} | |
/** | |
* 渲染麒麟JPG底图项目 | |
* @param {HTMLElement} $container 容器div | |
* @param {Object} options 渲染参数 | |
*/ | |
function renderJpg($container) { | |
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | |
var render = new JPGRender($container); | |
render.render(options); | |
return render; | |
} | |
var index = { | |
generateSeatImage: generateSeatImage, | |
renderStand: renderStand, | |
renderOtherBBCStand: renderOtherBBCStand, | |
renderBBCStand: renderBBCStand, | |
renderVenue: renderVenue, | |
renderBBCVenue: renderBBCVenue, | |
renderSvg: renderSvg | |
}; | |
exports.generateSeatImage = generateSeatImage; | |
exports.renderStand = renderStand; | |
exports.renderOtherBBCStand = renderOtherBBCStand; | |
exports.renderBBCStand = renderBBCStand; | |
exports.renderVenue = renderVenue; | |
exports.renderBBCVenue = renderBBCVenue; | |
exports.renderSvg = renderSvg; | |
exports.renderJpg = renderJpg; | |
exports.KeylinSeatParser = KeylinSeatParser; | |
exports['default'] = index; | |
Object.defineProperty(exports, '__esModule', { | |
value: true | |
}); | |
}))); | |
var Buffer = buffer.Buffer | |
//# sourceMappingURL=damai-select-seat.js.map |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment