157 lines
5.9 KiB
JavaScript
157 lines
5.9 KiB
JavaScript
/*!
|
|
* VERSION: 0.6.2
|
|
* DATE: 2018-05-30
|
|
* UPDATES AND DOCS AT: http://greensock.com
|
|
*
|
|
* @license Copyright (c) 2008-2019, GreenSock. All rights reserved.
|
|
* This work is subject to the terms at http://greensock.com/standard-license or for
|
|
* Club GreenSock members, the software agreement that was issued with your membership.
|
|
*
|
|
* @author: Jack Doyle, jack@greensock.com
|
|
*/
|
|
/* eslint-disable */
|
|
|
|
import { _gsScope } from "./TweenLite.js";
|
|
|
|
var _getText = function(e) {
|
|
var type = e.nodeType,
|
|
result = "";
|
|
if (type === 1 || type === 9 || type === 11) {
|
|
if (typeof(e.textContent) === "string") {
|
|
return e.textContent;
|
|
} else {
|
|
for ( e = e.firstChild; e; e = e.nextSibling ) {
|
|
result += _getText(e);
|
|
}
|
|
}
|
|
} else if (type === 3 || type === 4) {
|
|
return e.nodeValue;
|
|
}
|
|
return result;
|
|
},
|
|
_emoji = "[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2694-\u2697]|\uD83E[\uDD10-\uDD5D]|[\uD800-\uDBFF][\uDC00-\uDFFF]",
|
|
_emojiExp = new RegExp(_emoji),
|
|
_emojiAndCharsExp = new RegExp(_emoji + "|.", "g"),
|
|
_emojiSafeSplit = function(text, delimiter) {
|
|
return ((delimiter === "" || !delimiter) && _emojiExp.test(text)) ? text.match(_emojiAndCharsExp) : text.split(delimiter || "");
|
|
},
|
|
/* //previous emoji-related splitting. New method above is faster and more concise.
|
|
_emojiStart = 0xD800,
|
|
_emojiEnd = 0xDBFF,
|
|
_emojiLowStart = 0xDC00,
|
|
_emojiRegionStart = 0x1F1E6,
|
|
_emojiRegionEnd = 0x1F1FF,
|
|
_emojiModStart = 0x1f3fb,
|
|
_emojiModEnd = 0x1f3ff,
|
|
_emojiPairCode = function(s) {
|
|
return ((s.charCodeAt(0) - _emojiStart) << 10) + (s.charCodeAt(1) - _emojiLowStart) + 0x10000;
|
|
},
|
|
_emojiSafeSplit = function(text, delimiter) { //like calling String.split(delimiter) except that it keeps emoji characters together.
|
|
if (delimiter !== "") {
|
|
return text.split(delimiter);
|
|
}
|
|
var l = text.length,
|
|
a = [],
|
|
character, i, emojiPair1, emojiPair2, j;
|
|
for (i = 0; i < l; i++) {
|
|
character = text.charAt(i);
|
|
if ((character.charCodeAt(0) >= _emojiStart && character.charCodeAt(0) <= _emojiEnd) || (text.charCodeAt(i+1) >= 0xFE00 && text.charCodeAt(i+1) <= 0xFE0F)) { //special emoji characters use 2 or 4 unicode characters that we must keep together.
|
|
emojiPair1 = _emojiPairCode(text.substr(i, 2));
|
|
emojiPair2 = _emojiPairCode(text.substr(i + 2, 2));
|
|
j = ((emojiPair1 >= _emojiRegionStart && emojiPair1 <= _emojiRegionEnd && emojiPair2 >= _emojiRegionStart && emojiPair2 <= _emojiRegionEnd) || (emojiPair2 >= _emojiModStart && emojiPair2 <= _emojiModEnd)) ? 4 : 2;
|
|
a.push(text.substr(i, j));
|
|
i += j - 1;
|
|
} else {
|
|
a.push(character);
|
|
}
|
|
}
|
|
return a;
|
|
},
|
|
*/
|
|
TextPlugin = _gsScope._gsDefine.plugin({
|
|
propName: "text",
|
|
API: 2,
|
|
version:"0.6.2",
|
|
|
|
//called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
|
|
init: function(target, value, tween, index) {
|
|
var i = target.nodeName.toUpperCase(),
|
|
shrt;
|
|
if (typeof(value) === "function") {
|
|
value = value(index, target);
|
|
}
|
|
this._svg = (target.getBBox && (i === "TEXT" || i === "TSPAN"));
|
|
if (!("innerHTML" in target) && !this._svg) {
|
|
return false;
|
|
}
|
|
this._target = target;
|
|
if (typeof(value) !== "object") {
|
|
value = {value:value};
|
|
}
|
|
if (value.value === undefined) {
|
|
this._text = this._original = [""];
|
|
return true;
|
|
}
|
|
this._delimiter = value.delimiter || "";
|
|
this._original = _emojiSafeSplit(_getText(target).replace(/\s+/g, " "), this._delimiter);
|
|
this._text = _emojiSafeSplit(value.value.replace(/\s+/g, " "), this._delimiter);
|
|
this._runBackwards = (tween.vars.runBackwards === true);
|
|
if (this._runBackwards) {
|
|
i = this._original;
|
|
this._original = this._text;
|
|
this._text = i;
|
|
}
|
|
if (typeof(value.newClass) === "string") {
|
|
this._newClass = value.newClass;
|
|
this._hasClass = true;
|
|
}
|
|
if (typeof(value.oldClass) === "string") {
|
|
this._oldClass = value.oldClass;
|
|
this._hasClass = true;
|
|
}
|
|
i = this._original.length - this._text.length;
|
|
shrt = (i < 0) ? this._original : this._text;
|
|
this._fillChar = value.fillChar || (value.padSpace ? " " : "");
|
|
if (i < 0) {
|
|
i = -i;
|
|
}
|
|
while (--i > -1) {
|
|
shrt.push(this._fillChar);
|
|
}
|
|
return true;
|
|
},
|
|
|
|
//called each time the values should be updated, and the ratio gets passed as the only parameter (typically it's a value between 0 and 1, but it can exceed those when using an ease like Elastic.easeOut or Back.easeOut, etc.)
|
|
set: function(ratio) {
|
|
if (ratio > 1) {
|
|
ratio = 1;
|
|
} else if (ratio < 0) {
|
|
ratio = 0;
|
|
}
|
|
if (this._runBackwards) {
|
|
ratio = 1 - ratio;
|
|
}
|
|
var l = this._text.length,
|
|
i = (ratio * l + 0.5) | 0,
|
|
applyNew, applyOld, str;
|
|
if (this._hasClass) {
|
|
applyNew = (this._newClass && i !== 0);
|
|
applyOld = (this._oldClass && i !== l);
|
|
str = (applyNew ? "<span class='" + this._newClass + "'>" : "") + this._text.slice(0, i).join(this._delimiter) + (applyNew ? "</span>" : "") + (applyOld ? "<span class='" + this._oldClass + "'>" : "") + this._delimiter + this._original.slice(i).join(this._delimiter) + (applyOld ? "</span>" : "");
|
|
} else {
|
|
str = this._text.slice(0, i).join(this._delimiter) + this._delimiter + this._original.slice(i).join(this._delimiter);
|
|
}
|
|
if (this._svg) { //SVG text elements don't have an "innerHTML" in Microsoft browsers.
|
|
this._target.textContent = str;
|
|
} else {
|
|
this._target.innerHTML = (this._fillChar === " " && str.indexOf(" ") !== -1) ? str.split(" ").join(" ") : str;
|
|
}
|
|
}
|
|
|
|
}),
|
|
p = TextPlugin.prototype;
|
|
|
|
p._newClass = p._oldClass = p._delimiter = "";
|
|
|
|
|
|
export { TextPlugin, TextPlugin as default }; |