445 lines
16 KiB
JavaScript
445 lines
16 KiB
JavaScript
![]() |
import { CanvasTexture, Sprite, SpriteMaterial, SRGBColorSpace } from 'three';
|
||
|
|
||
|
function _arrayLikeToArray(r, a) {
|
||
|
(null == a || a > r.length) && (a = r.length);
|
||
|
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
||
|
return n;
|
||
|
}
|
||
|
function _arrayWithHoles(r) {
|
||
|
if (Array.isArray(r)) return r;
|
||
|
}
|
||
|
function _arrayWithoutHoles(r) {
|
||
|
if (Array.isArray(r)) return _arrayLikeToArray(r);
|
||
|
}
|
||
|
function _assertThisInitialized(e) {
|
||
|
if (undefined === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
||
|
return e;
|
||
|
}
|
||
|
function _callSuper(t, o, e) {
|
||
|
return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e, _getPrototypeOf(t).constructor) : o.apply(t, e));
|
||
|
}
|
||
|
function _classCallCheck(a, n) {
|
||
|
if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
|
||
|
}
|
||
|
function _defineProperties(e, r) {
|
||
|
for (var t = 0; t < r.length; t++) {
|
||
|
var o = r[t];
|
||
|
o.enumerable = o.enumerable || false, o.configurable = true, "value" in o && (o.writable = true), Object.defineProperty(e, _toPropertyKey(o.key), o);
|
||
|
}
|
||
|
}
|
||
|
function _createClass(e, r, t) {
|
||
|
return _defineProperties(e.prototype, r), Object.defineProperty(e, "prototype", {
|
||
|
writable: false
|
||
|
}), e;
|
||
|
}
|
||
|
function _getPrototypeOf(t) {
|
||
|
return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
|
||
|
return t.__proto__ || Object.getPrototypeOf(t);
|
||
|
}, _getPrototypeOf(t);
|
||
|
}
|
||
|
function _inherits(t, e) {
|
||
|
if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
|
||
|
t.prototype = Object.create(e && e.prototype, {
|
||
|
constructor: {
|
||
|
value: t,
|
||
|
writable: true,
|
||
|
configurable: true
|
||
|
}
|
||
|
}), Object.defineProperty(t, "prototype", {
|
||
|
writable: false
|
||
|
}), e && _setPrototypeOf(t, e);
|
||
|
}
|
||
|
function _isNativeReflectConstruct() {
|
||
|
try {
|
||
|
var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
|
||
|
} catch (t) {}
|
||
|
return (_isNativeReflectConstruct = function () {
|
||
|
return !!t;
|
||
|
})();
|
||
|
}
|
||
|
function _iterableToArray(r) {
|
||
|
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
|
||
|
}
|
||
|
function _iterableToArrayLimit(r, l) {
|
||
|
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
||
|
if (null != t) {
|
||
|
var e,
|
||
|
n,
|
||
|
i,
|
||
|
u,
|
||
|
a = [],
|
||
|
f = true,
|
||
|
o = false;
|
||
|
try {
|
||
|
if (i = (t = t.call(r)).next, 0 === l) {
|
||
|
if (Object(t) !== t) return;
|
||
|
f = !1;
|
||
|
} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
|
||
|
} catch (r) {
|
||
|
o = true, n = r;
|
||
|
} finally {
|
||
|
try {
|
||
|
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
|
||
|
} finally {
|
||
|
if (o) throw n;
|
||
|
}
|
||
|
}
|
||
|
return a;
|
||
|
}
|
||
|
}
|
||
|
function _nonIterableRest() {
|
||
|
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
||
|
}
|
||
|
function _nonIterableSpread() {
|
||
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
||
|
}
|
||
|
function _possibleConstructorReturn(t, e) {
|
||
|
if (e && ("object" == typeof e || "function" == typeof e)) return e;
|
||
|
if (undefined !== e) throw new TypeError("Derived constructors may only return object or undefined");
|
||
|
return _assertThisInitialized(t);
|
||
|
}
|
||
|
function _setPrototypeOf(t, e) {
|
||
|
return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
|
||
|
return t.__proto__ = e, t;
|
||
|
}, _setPrototypeOf(t, e);
|
||
|
}
|
||
|
function _slicedToArray(r, e) {
|
||
|
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
|
||
|
}
|
||
|
function _toConsumableArray(r) {
|
||
|
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
|
||
|
}
|
||
|
function _toPrimitive(t, r) {
|
||
|
if ("object" != typeof t || !t) return t;
|
||
|
var e = t[Symbol.toPrimitive];
|
||
|
if (undefined !== e) {
|
||
|
var i = e.call(t, r);
|
||
|
if ("object" != typeof i) return i;
|
||
|
throw new TypeError("@@toPrimitive must return a primitive value.");
|
||
|
}
|
||
|
return (String )(t);
|
||
|
}
|
||
|
function _toPropertyKey(t) {
|
||
|
var i = _toPrimitive(t, "string");
|
||
|
return "symbol" == typeof i ? i : i + "";
|
||
|
}
|
||
|
function _unsupportedIterableToArray(r, a) {
|
||
|
if (r) {
|
||
|
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
||
|
var t = {}.toString.call(r).slice(8, -1);
|
||
|
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : undefined;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var three = typeof window !== 'undefined' && window.THREE ? window.THREE // Prefer consumption from global THREE, if exists
|
||
|
: {
|
||
|
CanvasTexture: CanvasTexture,
|
||
|
Sprite: Sprite,
|
||
|
SpriteMaterial: SpriteMaterial,
|
||
|
SRGBColorSpace: SRGBColorSpace
|
||
|
};
|
||
|
var _default = /*#__PURE__*/function (_three$Sprite) {
|
||
|
function _default() {
|
||
|
var _this;
|
||
|
var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
||
|
var textHeight = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10;
|
||
|
var color = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'rgba(255, 255, 255, 1)';
|
||
|
_classCallCheck(this, _default);
|
||
|
_this = _callSuper(this, _default, [new three.SpriteMaterial()]);
|
||
|
_this._text = "".concat(text);
|
||
|
_this._textHeight = textHeight;
|
||
|
_this._color = color;
|
||
|
_this._backgroundColor = false; // no background color
|
||
|
|
||
|
_this._padding = 0;
|
||
|
_this._borderWidth = 0;
|
||
|
_this._borderRadius = 0;
|
||
|
_this._borderColor = 'white';
|
||
|
_this._strokeWidth = 0;
|
||
|
_this._strokeColor = 'white';
|
||
|
_this._fontFace = 'system-ui';
|
||
|
_this._fontSize = 90; // defines text resolution
|
||
|
_this._fontWeight = 'normal';
|
||
|
_this._canvas = document.createElement('canvas');
|
||
|
_this._genCanvas();
|
||
|
return _this;
|
||
|
}
|
||
|
_inherits(_default, _three$Sprite);
|
||
|
return _createClass(_default, [{
|
||
|
key: "text",
|
||
|
get: function get() {
|
||
|
return this._text;
|
||
|
},
|
||
|
set: function set(text) {
|
||
|
this._text = text;
|
||
|
this._genCanvas();
|
||
|
}
|
||
|
}, {
|
||
|
key: "textHeight",
|
||
|
get: function get() {
|
||
|
return this._textHeight;
|
||
|
},
|
||
|
set: function set(textHeight) {
|
||
|
this._textHeight = textHeight;
|
||
|
this._genCanvas();
|
||
|
}
|
||
|
}, {
|
||
|
key: "color",
|
||
|
get: function get() {
|
||
|
return this._color;
|
||
|
},
|
||
|
set: function set(color) {
|
||
|
this._color = color;
|
||
|
this._genCanvas();
|
||
|
}
|
||
|
}, {
|
||
|
key: "backgroundColor",
|
||
|
get: function get() {
|
||
|
return this._backgroundColor;
|
||
|
},
|
||
|
set: function set(color) {
|
||
|
this._backgroundColor = color;
|
||
|
this._genCanvas();
|
||
|
}
|
||
|
}, {
|
||
|
key: "padding",
|
||
|
get: function get() {
|
||
|
return this._padding;
|
||
|
},
|
||
|
set: function set(padding) {
|
||
|
this._padding = padding;
|
||
|
this._genCanvas();
|
||
|
}
|
||
|
}, {
|
||
|
key: "borderWidth",
|
||
|
get: function get() {
|
||
|
return this._borderWidth;
|
||
|
},
|
||
|
set: function set(borderWidth) {
|
||
|
this._borderWidth = borderWidth;
|
||
|
this._genCanvas();
|
||
|
}
|
||
|
}, {
|
||
|
key: "borderRadius",
|
||
|
get: function get() {
|
||
|
return this._borderRadius;
|
||
|
},
|
||
|
set: function set(borderRadius) {
|
||
|
this._borderRadius = borderRadius;
|
||
|
this._genCanvas();
|
||
|
}
|
||
|
}, {
|
||
|
key: "borderColor",
|
||
|
get: function get() {
|
||
|
return this._borderColor;
|
||
|
},
|
||
|
set: function set(borderColor) {
|
||
|
this._borderColor = borderColor;
|
||
|
this._genCanvas();
|
||
|
}
|
||
|
}, {
|
||
|
key: "fontFace",
|
||
|
get: function get() {
|
||
|
return this._fontFace;
|
||
|
},
|
||
|
set: function set(fontFace) {
|
||
|
this._fontFace = fontFace;
|
||
|
this._genCanvas();
|
||
|
}
|
||
|
}, {
|
||
|
key: "fontSize",
|
||
|
get: function get() {
|
||
|
return this._fontSize;
|
||
|
},
|
||
|
set: function set(fontSize) {
|
||
|
this._fontSize = fontSize;
|
||
|
this._genCanvas();
|
||
|
}
|
||
|
}, {
|
||
|
key: "fontWeight",
|
||
|
get: function get() {
|
||
|
return this._fontWeight;
|
||
|
},
|
||
|
set: function set(fontWeight) {
|
||
|
this._fontWeight = fontWeight;
|
||
|
this._genCanvas();
|
||
|
}
|
||
|
}, {
|
||
|
key: "strokeWidth",
|
||
|
get: function get() {
|
||
|
return this._strokeWidth;
|
||
|
},
|
||
|
set: function set(strokeWidth) {
|
||
|
this._strokeWidth = strokeWidth;
|
||
|
this._genCanvas();
|
||
|
}
|
||
|
}, {
|
||
|
key: "strokeColor",
|
||
|
get: function get() {
|
||
|
return this._strokeColor;
|
||
|
},
|
||
|
set: function set(strokeColor) {
|
||
|
this._strokeColor = strokeColor;
|
||
|
this._genCanvas();
|
||
|
}
|
||
|
}, {
|
||
|
key: "_genCanvas",
|
||
|
value: function _genCanvas() {
|
||
|
var _this2 = this;
|
||
|
var canvas = this._canvas;
|
||
|
var ctx = canvas.getContext('2d');
|
||
|
var relFactor = 1 / this.textHeight;
|
||
|
var border = Array.isArray(this.borderWidth) ? this.borderWidth : [this.borderWidth, this.borderWidth]; // x,y border
|
||
|
var relBorder = border.map(function (b) {
|
||
|
return b * _this2.fontSize * relFactor;
|
||
|
}); // border in canvas units
|
||
|
|
||
|
var borderRadius = Array.isArray(this.borderRadius) ? this.borderRadius : [this.borderRadius, this.borderRadius, this.borderRadius, this.borderRadius]; // tl tr br bl corners
|
||
|
var relBorderRadius = borderRadius.map(function (b) {
|
||
|
return b * _this2.fontSize * relFactor;
|
||
|
}); // border radius in canvas units
|
||
|
|
||
|
var padding = Array.isArray(this.padding) ? this.padding : [this.padding, this.padding]; // x,y padding
|
||
|
var relPadding = padding.map(function (p) {
|
||
|
return p * _this2.fontSize * relFactor;
|
||
|
}); // padding in canvas units
|
||
|
|
||
|
var lines = this.text.split('\n');
|
||
|
var font = "".concat(this.fontWeight, " ").concat(this.fontSize, "px ").concat(this.fontFace);
|
||
|
ctx.font = font; // measure canvas with appropriate font
|
||
|
var innerWidth = Math.max.apply(Math, _toConsumableArray(lines.map(function (line) {
|
||
|
return ctx.measureText(line).width;
|
||
|
})));
|
||
|
var innerHeight = this.fontSize * lines.length;
|
||
|
canvas.width = innerWidth + relBorder[0] * 2 + relPadding[0] * 2;
|
||
|
canvas.height = innerHeight + relBorder[1] * 2 + relPadding[1] * 2;
|
||
|
|
||
|
// paint border
|
||
|
if (this.borderWidth) {
|
||
|
ctx.strokeStyle = this.borderColor;
|
||
|
if (relBorder[0]) {
|
||
|
// left + right borders
|
||
|
var hb = relBorder[0] / 2;
|
||
|
ctx.lineWidth = relBorder[0];
|
||
|
ctx.beginPath();
|
||
|
ctx.moveTo(hb, relBorderRadius[0]);
|
||
|
ctx.lineTo(hb, canvas.height - relBorderRadius[3]);
|
||
|
ctx.moveTo(canvas.width - hb, relBorderRadius[1]);
|
||
|
ctx.lineTo(canvas.width - hb, canvas.height - relBorderRadius[2]);
|
||
|
ctx.stroke();
|
||
|
}
|
||
|
if (relBorder[1]) {
|
||
|
// top + bottom borders
|
||
|
var _hb = relBorder[1] / 2;
|
||
|
ctx.lineWidth = relBorder[1];
|
||
|
ctx.beginPath();
|
||
|
ctx.moveTo(Math.max(relBorder[0], relBorderRadius[0]), _hb);
|
||
|
ctx.lineTo(canvas.width - Math.max(relBorder[0], relBorderRadius[1]), _hb);
|
||
|
ctx.moveTo(Math.max(relBorder[0], relBorderRadius[3]), canvas.height - _hb);
|
||
|
ctx.lineTo(canvas.width - Math.max(relBorder[0], relBorderRadius[2]), canvas.height - _hb);
|
||
|
ctx.stroke();
|
||
|
}
|
||
|
if (this.borderRadius) {
|
||
|
// strike rounded corners
|
||
|
var cornerWidth = Math.max.apply(Math, _toConsumableArray(relBorder));
|
||
|
var _hb2 = cornerWidth / 2;
|
||
|
ctx.lineWidth = cornerWidth;
|
||
|
ctx.beginPath();
|
||
|
[!!relBorderRadius[0] && [relBorderRadius[0], _hb2, _hb2, relBorderRadius[0]], !!relBorderRadius[1] && [canvas.width - relBorderRadius[1], canvas.width - _hb2, _hb2, relBorderRadius[1]], !!relBorderRadius[2] && [canvas.width - relBorderRadius[2], canvas.width - _hb2, canvas.height - _hb2, canvas.height - relBorderRadius[2]], !!relBorderRadius[3] && [relBorderRadius[3], _hb2, canvas.height - _hb2, canvas.height - relBorderRadius[3]]].filter(function (d) {
|
||
|
return d;
|
||
|
}).forEach(function (_ref) {
|
||
|
var _ref2 = _slicedToArray(_ref, 4),
|
||
|
x0 = _ref2[0],
|
||
|
x1 = _ref2[1],
|
||
|
y0 = _ref2[2],
|
||
|
y1 = _ref2[3];
|
||
|
ctx.moveTo(x0, y0);
|
||
|
ctx.quadraticCurveTo(x1, y0, x1, y1);
|
||
|
});
|
||
|
ctx.stroke();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// paint background
|
||
|
if (this.backgroundColor) {
|
||
|
ctx.fillStyle = this.backgroundColor;
|
||
|
if (!this.borderRadius) {
|
||
|
ctx.fillRect(relBorder[0], relBorder[1], canvas.width - relBorder[0] * 2, canvas.height - relBorder[1] * 2);
|
||
|
} else {
|
||
|
// fill with rounded corners
|
||
|
ctx.beginPath();
|
||
|
ctx.moveTo(relBorder[0], relBorderRadius[0]);
|
||
|
[[relBorder[0], relBorderRadius[0], canvas.width - relBorderRadius[1], relBorder[1], relBorder[1], relBorder[1]],
|
||
|
// t
|
||
|
[canvas.width - relBorder[0], canvas.width - relBorder[0], canvas.width - relBorder[0], relBorder[1], relBorderRadius[1], canvas.height - relBorderRadius[2]],
|
||
|
// r
|
||
|
[canvas.width - relBorder[0], canvas.width - relBorderRadius[2], relBorderRadius[3], canvas.height - relBorder[1], canvas.height - relBorder[1], canvas.height - relBorder[1]],
|
||
|
// b
|
||
|
[relBorder[0], relBorder[0], relBorder[0], canvas.height - relBorder[1], canvas.height - relBorderRadius[3], relBorderRadius[0]] // t
|
||
|
].forEach(function (_ref3) {
|
||
|
var _ref4 = _slicedToArray(_ref3, 6),
|
||
|
x0 = _ref4[0],
|
||
|
x1 = _ref4[1],
|
||
|
x2 = _ref4[2],
|
||
|
y0 = _ref4[3],
|
||
|
y1 = _ref4[4],
|
||
|
y2 = _ref4[5];
|
||
|
ctx.quadraticCurveTo(x0, y0, x1, y1);
|
||
|
ctx.lineTo(x2, y2);
|
||
|
});
|
||
|
ctx.closePath();
|
||
|
ctx.fill();
|
||
|
}
|
||
|
}
|
||
|
ctx.translate.apply(ctx, _toConsumableArray(relBorder));
|
||
|
ctx.translate.apply(ctx, _toConsumableArray(relPadding));
|
||
|
|
||
|
// paint text
|
||
|
ctx.font = font; // Set font again after canvas is resized, as context properties are reset
|
||
|
ctx.fillStyle = this.color;
|
||
|
ctx.textBaseline = 'bottom';
|
||
|
var drawTextStroke = this.strokeWidth > 0;
|
||
|
if (drawTextStroke) {
|
||
|
ctx.lineWidth = this.strokeWidth * this.fontSize / 10;
|
||
|
ctx.strokeStyle = this.strokeColor;
|
||
|
}
|
||
|
lines.forEach(function (line, index) {
|
||
|
var lineX = (innerWidth - ctx.measureText(line).width) / 2;
|
||
|
var lineY = (index + 1) * _this2.fontSize;
|
||
|
drawTextStroke && ctx.strokeText(line, lineX, lineY);
|
||
|
ctx.fillText(line, lineX, lineY);
|
||
|
});
|
||
|
|
||
|
// Inject canvas into sprite
|
||
|
if (this.material.map) this.material.map.dispose(); // gc previous texture
|
||
|
var texture = this.material.map = new three.CanvasTexture(canvas);
|
||
|
texture.colorSpace = three.SRGBColorSpace;
|
||
|
var yScale = this.textHeight * lines.length + border[1] * 2 + padding[1] * 2;
|
||
|
this.scale.set(yScale * canvas.width / canvas.height, yScale, 0);
|
||
|
}
|
||
|
}, {
|
||
|
key: "clone",
|
||
|
value: function clone() {
|
||
|
return new this.constructor(this.text, this.textHeight, this.color).copy(this);
|
||
|
}
|
||
|
}, {
|
||
|
key: "copy",
|
||
|
value: function copy(source) {
|
||
|
three.Sprite.prototype.copy.call(this, source);
|
||
|
this.color = source.color;
|
||
|
this.backgroundColor = source.backgroundColor;
|
||
|
this.padding = source.padding;
|
||
|
this.borderWidth = source.borderWidth;
|
||
|
this.borderColor = source.borderColor;
|
||
|
this.fontFace = source.fontFace;
|
||
|
this.fontSize = source.fontSize;
|
||
|
this.fontWeight = source.fontWeight;
|
||
|
this.strokeWidth = source.strokeWidth;
|
||
|
this.strokeColor = source.strokeColor;
|
||
|
return this;
|
||
|
}
|
||
|
}]);
|
||
|
}(three.Sprite);
|
||
|
|
||
|
export { _default as default };
|