Comparing version 8.6.6 to 8.7.0
@@ -1,2 +0,2 @@ | ||
import { Options } from "./types"; | ||
import { CursorOptions, Options } from "./types"; | ||
export declare const DATA_ATTRIBUTE = "data-typeit-id"; | ||
@@ -12,4 +12,5 @@ export declare const CURSOR_CLASS = "ti-cursor"; | ||
}; | ||
export declare const DEFAULT_OPTIONS: Options; | ||
export declare const DEFAULT_OPTIONS: Options & { | ||
cursor: Required<CursorOptions>; | ||
}; | ||
export declare const PLACEHOLDER_CSS: string; | ||
export declare const CURSOR_ANIMATION_RESTART_DELAY = 500; |
@@ -1,2 +0,2 @@ | ||
import { El, QueueMapPair } from "../types"; | ||
import { CursorOptions, El, QueueMapPair } from "../types"; | ||
interface FireItemArgs { | ||
@@ -7,4 +7,5 @@ index: number; | ||
cursor: El | undefined; | ||
cursorOptions: CursorOptions; | ||
} | ||
declare let fireItem: ({ index, queueItems, wait, cursor, }: FireItemArgs) => Promise<number>; | ||
declare let fireItem: ({ index, queueItems, wait, cursor, cursorOptions, }: FireItemArgs) => Promise<number>; | ||
export default fireItem; |
@@ -1,14 +0,8 @@ | ||
/// <reference types="web-animations-js" /> | ||
import { El } from "../types"; | ||
declare global { | ||
interface AnimationEffect { | ||
getKeyframes: () => any; | ||
} | ||
} | ||
import { El, CursorOptions } from "../types"; | ||
interface rebuildCursorAnimationArgs { | ||
cursor: El | undefined; | ||
frames: AnimationKeyFrame[]; | ||
timingOptions: any; | ||
cursorOptions: CursorOptions; | ||
options: any; | ||
} | ||
declare let rebuildCursorAnimation: ({ cursor, frames, timingOptions, }: rebuildCursorAnimationArgs) => Animation; | ||
declare let rebuildCursorAnimation: ({ cursor, options, cursorOptions, }: rebuildCursorAnimationArgs) => Animation; | ||
export default rebuildCursorAnimation; |
@@ -6,7 +6,7 @@ /// <reference types="web-animations-js" /> | ||
*/ | ||
declare let setCursorAnimation: ({ cursor, frames, timingOptions, }: { | ||
declare let setCursorAnimation: ({ cursor, frames, options, }: { | ||
cursor: El; | ||
frames?: AnimationKeyFrame[] | null; | ||
timingOptions: Partial<AnimationEffectTiming>; | ||
}) => Animation | null; | ||
frames: AnimationKeyFrame[]; | ||
options: Partial<AnimationEffectTiming>; | ||
}) => Animation; | ||
export default setCursorAnimation; |
// TypeIt by Alex MacArthur - https://typeitjs.com | ||
var isArray = (thing) => Array.isArray(thing); | ||
var asArray = (value) => { | ||
const isArray = (thing) => Array.isArray(thing); | ||
const asArray = (value) => { | ||
return isArray(value) ? value : [value]; | ||
@@ -9,4 +9,3 @@ }; | ||
asArray(steps).forEach((step) => { | ||
var _a; | ||
return _q.set(Symbol((_a = step.char) == null ? void 0 : _a.innerText), buildQueueItem({ ...step })); | ||
return _q.set(Symbol(step.char?.innerText), buildQueueItem({ ...step })); | ||
}); | ||
@@ -52,4 +51,4 @@ return this; | ||
}; | ||
var toArray = (val) => Array.from(val); | ||
var createTextNode = (content) => document.createTextNode(content); | ||
const toArray = (val) => Array.from(val); | ||
const createTextNode = (content) => document.createTextNode(content); | ||
let expandTextNodes = (element) => { | ||
@@ -68,3 +67,3 @@ [...element.childNodes].forEach((child) => { | ||
}; | ||
var getParsedBody = (content) => { | ||
const getParsedBody = (content) => { | ||
let doc = document.implementation.createHTMLDocument(); | ||
@@ -85,3 +84,16 @@ doc.body.innerHTML = content; | ||
breakLines: true, | ||
cursor: true, | ||
cursor: { | ||
autoPause: true, | ||
autoPauseDelay: 500, | ||
animation: { | ||
frames: [0, 0, 1].map((n) => { | ||
return { opacity: n }; | ||
}), | ||
options: { | ||
iterations: Infinity, | ||
easing: "steps(2, start)", | ||
fill: "forwards" | ||
} | ||
} | ||
}, | ||
cursorChar: "|", | ||
@@ -112,3 +124,2 @@ cursorSpeed: 1e3, | ||
const PLACEHOLDER_CSS = `[${DATA_ATTRIBUTE}]:before {content: '.'; display: inline-block; width: 0; visibility: hidden;}`; | ||
const CURSOR_ANIMATION_RESTART_DELAY = 500; | ||
function walkElementNodes(element, shouldReverse = false, shouldIncludeCursor = false) { | ||
@@ -118,5 +129,4 @@ let cursor = element.querySelector(`.${CURSOR_CLASS}`); | ||
acceptNode: (node) => { | ||
var _a, _b; | ||
if (cursor && shouldIncludeCursor) { | ||
if ((_a = node.classList) == null ? void 0 : _a.contains(CURSOR_CLASS)) { | ||
if (node.classList?.contains(CURSOR_CLASS)) { | ||
return NodeFilter.FILTER_ACCEPT; | ||
@@ -128,3 +138,3 @@ } | ||
} | ||
return ((_b = node.classList) == null ? void 0 : _b.contains(CURSOR_CLASS)) ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT; | ||
return node.classList?.contains(CURSOR_CLASS) ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT; | ||
} | ||
@@ -148,4 +158,4 @@ }); | ||
} | ||
var createElement = (el) => document.createElement(el); | ||
var appendStyleBlock = (styles, id = "") => { | ||
const createElement = (el) => document.createElement(el); | ||
const appendStyleBlock = (styles, id = "") => { | ||
let styleBlock = createElement("style"); | ||
@@ -156,3 +166,3 @@ styleBlock.id = id; | ||
}; | ||
var calculateDelay = (delayArg) => { | ||
const calculateDelay = (delayArg) => { | ||
if (!isArray(delayArg)) { | ||
@@ -163,3 +173,3 @@ delayArg = [delayArg / 2, delayArg / 2]; | ||
}; | ||
var randomInRange = (value, range2) => { | ||
const randomInRange = (value, range2) => { | ||
return Math.abs(Math.random() * (value + range2 - (value - range2)) + (value - range2)); | ||
@@ -176,8 +186,8 @@ }; | ||
} | ||
var destroyTimeouts = (timeouts) => { | ||
const destroyTimeouts = (timeouts) => { | ||
timeouts.forEach(clearTimeout); | ||
return []; | ||
}; | ||
var generateHash = () => Math.random().toString().substring(2, 9); | ||
var isInput = (el) => "value" in el; | ||
const generateHash = () => Math.random().toString().substring(2, 9); | ||
const isInput = (el) => "value" in el; | ||
let getAllChars = (element) => { | ||
@@ -189,3 +199,3 @@ if (isInput(element)) { | ||
}; | ||
var fireWhenVisible = (element, func) => { | ||
const fireWhenVisible = (element, func) => { | ||
let observer = new IntersectionObserver((entries, observer2) => { | ||
@@ -204,7 +214,7 @@ entries.forEach((entry) => { | ||
}; | ||
var isNumber = (value) => Number.isInteger(value); | ||
const isNumber = (value) => Number.isInteger(value); | ||
let select = (selector, element = document, all = false) => { | ||
return element[`querySelector${all ? "All" : ""}`](selector); | ||
}; | ||
let isBodyElement = (node) => /body/i.test(node == null ? void 0 : node.tagName); | ||
let isBodyElement = (node) => /body/i.test(node?.tagName); | ||
let insertIntoElement = (originalTarget, character) => { | ||
@@ -222,4 +232,4 @@ if (isInput(originalTarget)) { | ||
}; | ||
var merge = (originalObj, newObj) => Object.assign({}, originalObj, newObj); | ||
var removeNode = (node, rootElement) => { | ||
const merge = (originalObj, newObj) => Object.assign({}, originalObj, newObj); | ||
const removeNode = (node, rootElement) => { | ||
if (!node) | ||
@@ -231,6 +241,6 @@ return; | ||
}; | ||
var repositionCursor = (element, allChars, newCursorPosition) => { | ||
const repositionCursor = (element, allChars, newCursorPosition) => { | ||
let nodeToInsertBefore = allChars[newCursorPosition - 1]; | ||
let cursor = select(`.${CURSOR_CLASS}`, element); | ||
element = (nodeToInsertBefore == null ? void 0 : nodeToInsertBefore.parentNode) || element; | ||
element = nodeToInsertBefore?.parentNode || element; | ||
element.insertBefore(cursor, nodeToInsertBefore || null); | ||
@@ -241,3 +251,3 @@ }; | ||
} | ||
var isNonVoidElement = (el) => /<(.+)>(.*?)<\/(.+)>/.test(el.outerHTML); | ||
const isNonVoidElement = (el) => /<(.+)>(.*?)<\/(.+)>/.test(el.outerHTML); | ||
let wait = (callback, delay, timeouts) => { | ||
@@ -270,3 +280,3 @@ return new Promise((resolve) => { | ||
}; | ||
var duplicate = (value, times) => new Array(times).fill(value); | ||
const duplicate = (value, times) => new Array(times).fill(value); | ||
const countStepsToSelector = ({ | ||
@@ -304,23 +314,12 @@ queueItems, | ||
let getAnimationFromElement = (element) => { | ||
return element == null ? void 0 : element.getAnimations().find((animation) => { | ||
return element?.getAnimations().find((animation) => { | ||
return animation.id === element.dataset.tiAnimationId; | ||
}); | ||
}; | ||
const DEFAULT_TIMING_OPTIONS = { | ||
iterations: Infinity, | ||
easing: "steps(2, start)", | ||
fill: "forwards" | ||
}; | ||
const DEFAULT_FRAMES = [0, 0, 1].map((n) => { | ||
return { opacity: n }; | ||
}); | ||
let setCursorAnimation = ({ | ||
cursor, | ||
frames = null, | ||
timingOptions = {} | ||
frames, | ||
options | ||
}) => { | ||
let animation = cursor.animate(frames || DEFAULT_FRAMES, { | ||
...DEFAULT_TIMING_OPTIONS, | ||
...timingOptions | ||
}); | ||
let animation = cursor.animate(frames, options); | ||
animation.pause(); | ||
@@ -337,6 +336,6 @@ animation.id = cursor.dataset.tiAnimationId; | ||
cursor, | ||
frames, | ||
timingOptions | ||
options, | ||
cursorOptions | ||
}) => { | ||
if (!cursor) | ||
if (!cursor || !cursorOptions) | ||
return; | ||
@@ -346,3 +345,3 @@ let animation = getAnimationFromElement(cursor); | ||
if (animation) { | ||
timingOptions.delay = animation.effect.getComputedTiming().delay; | ||
options.delay = animation.effect.getComputedTiming().delay; | ||
oldCurrentTime = animation.currentTime; | ||
@@ -353,4 +352,4 @@ animation.cancel(); | ||
cursor, | ||
frames, | ||
timingOptions | ||
frames: cursorOptions.animation.frames, | ||
options | ||
}); | ||
@@ -362,6 +361,3 @@ if (oldCurrentTime) { | ||
}; | ||
let execute = (queueItem) => { | ||
var _a; | ||
return (_a = queueItem.func) == null ? void 0 : _a.call(globalThis); | ||
}; | ||
let execute = (queueItem) => queueItem.func?.call(null); | ||
let fireItem = async ({ | ||
@@ -371,3 +367,4 @@ index, | ||
wait: wait2, | ||
cursor | ||
cursor, | ||
cursorOptions | ||
}) => { | ||
@@ -379,2 +376,3 @@ let queueItem = queueItems[index][1]; | ||
let shouldBeGrouped = () => futureItem && !futureItem.delay; | ||
let shouldPauseCursor = queueItem.shouldPauseCursor() && cursorOptions.autoPause; | ||
while (shouldBeGrouped()) { | ||
@@ -393,31 +391,41 @@ instantQueue.push(futureItem); | ||
} | ||
let fire = async () => { | ||
let animation = getAnimationFromElement(cursor); | ||
let timingOptions2 = {}; | ||
let frames2 = null; | ||
if (animation) { | ||
timingOptions2 = cursor ? { | ||
...animation.effect.getComputedTiming(), | ||
delay: queueItem.shouldPauseCursor() ? CURSOR_ANIMATION_RESTART_DELAY : 0 | ||
} : {}; | ||
frames2 = cursor ? animation.effect.getKeyframes() : []; | ||
let animation = getAnimationFromElement(cursor); | ||
let options; | ||
if (animation) { | ||
options = { | ||
...animation.effect.getComputedTiming(), | ||
delay: shouldPauseCursor ? cursorOptions.autoPauseDelay : 0 | ||
}; | ||
} | ||
await wait2(async () => { | ||
if (animation && shouldPauseCursor) { | ||
animation.cancel(); | ||
} | ||
await wait2(async () => { | ||
if (animation && queueItem.shouldPauseCursor()) { | ||
animation.cancel(); | ||
} | ||
await beforePaint(() => { | ||
execute(queueItem); | ||
}); | ||
}, queueItem.delay); | ||
return { frames: frames2, timingOptions: timingOptions2 }; | ||
}; | ||
let { frames, timingOptions } = await fire(); | ||
await beforePaint(() => { | ||
execute(queueItem); | ||
}); | ||
}, queueItem.delay); | ||
await rebuildCursorAnimation({ | ||
cursor, | ||
frames, | ||
timingOptions | ||
options, | ||
cursorOptions | ||
}); | ||
return index; | ||
}; | ||
let processCursorOptions = (cursorOptions) => { | ||
if (typeof cursorOptions === "object") { | ||
let newOptions = {}; | ||
let { frames: defaultFrames, options: defaultOptions } = DEFAULT_OPTIONS.cursor.animation; | ||
newOptions.animation = cursorOptions.animation || {}; | ||
newOptions.animation.frames = cursorOptions.animation?.frames || defaultFrames; | ||
newOptions.animation.options = merge(defaultOptions, cursorOptions.animation?.options || {}); | ||
newOptions.autoPause = cursorOptions.autoPause ?? DEFAULT_OPTIONS.cursor.autoPause; | ||
newOptions.autoPauseDelay = cursorOptions.autoPauseDelay || DEFAULT_OPTIONS.cursor.autoPauseDelay; | ||
return newOptions; | ||
} | ||
if (cursorOptions === true) { | ||
return DEFAULT_OPTIONS.cursor; | ||
} | ||
return cursorOptions; | ||
}; | ||
const TypeIt = function(element, options = {}) { | ||
@@ -437,3 +445,3 @@ let _wait = async (callback, delay, silent = false) => { | ||
}; | ||
let _fireItemWithCursor = (index, queueItems) => { | ||
let _fireItemWithContext = (index, queueItems) => { | ||
return fireItem({ | ||
@@ -443,3 +451,4 @@ index, | ||
wait: _wait, | ||
cursor: _cursor | ||
cursor: _cursor, | ||
cursorOptions: _opts.cursor | ||
}); | ||
@@ -460,3 +469,3 @@ }; | ||
}; | ||
let _getDerivedCursorPosition = () => _predictedCursorPosition != null ? _predictedCursorPosition : _cursorPosition; | ||
let _getDerivedCursorPosition = () => _predictedCursorPosition ?? _cursorPosition; | ||
let _generateTemporaryOptionQueueItems = (newOptions = {}) => { | ||
@@ -490,6 +499,10 @@ return [ | ||
_cursor.dataset.tiAnimationId = _id; | ||
let { animation } = _opts.cursor; | ||
let { frames, options: options2 } = animation; | ||
setCursorAnimation({ | ||
frames, | ||
cursor: _cursor, | ||
timingOptions: { | ||
duration: _opts.cursorSpeed | ||
options: { | ||
duration: _opts.cursorSpeed, | ||
...options2 | ||
} | ||
@@ -528,3 +541,3 @@ }); | ||
for (let index = 0; index < queueItems.length; index++) { | ||
await _fireItemWithCursor(index, queueItems); | ||
await _fireItemWithContext(index, queueItems); | ||
} | ||
@@ -565,3 +578,3 @@ _queue.reset(); | ||
if (!queueItem.deletable || queueItem.deletable && _getAllChars().length) { | ||
let newIndex = await _fireItemWithCursor(index, queueItems); | ||
let newIndex = await _fireItemWithContext(index, queueItems); | ||
Array(newIndex - index).fill(index + 1).map((x, y) => x + y).forEach((i) => { | ||
@@ -766,2 +779,3 @@ let [key] = queueItems[i]; | ||
let _statuses = merge({}, DEFAULT_STATUSES); | ||
options.cursor = processCursorOptions(options.cursor ?? DEFAULT_OPTIONS.cursor); | ||
let _opts = merge(DEFAULT_OPTIONS, options); | ||
@@ -774,12 +788,6 @@ _opts = merge(_opts, { | ||
let _id = generateHash(); | ||
let _queue = Queue([ | ||
{ | ||
func: () => { | ||
}, | ||
delay: _opts.startDelay | ||
} | ||
]); | ||
let _queue = Queue([{ delay: _opts.startDelay }]); | ||
_element.dataset.typeitId = _id; | ||
appendStyleBlock(PLACEHOLDER_CSS); | ||
let _shouldRenderCursor = _opts.cursor && !_elementIsInput(); | ||
let _shouldRenderCursor = !!_opts.cursor && !_elementIsInput(); | ||
let _cursor = _setUpCursor(); | ||
@@ -791,2 +799,4 @@ _opts.strings = _maybePrependHardcodedStrings(asArray(_opts.strings)); | ||
}; | ||
export { TypeIt as default }; | ||
export { | ||
TypeIt as default | ||
}; |
// TypeIt by Alex MacArthur - https://typeitjs.com | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).TypeIt=t()}(this,(function(){"use strict";var e=e=>Array.isArray(e),t=t=>e(t)?t:[t];var n=e=>Array.from(e),r=e=>document.createTextNode(e);let i=e=>([...e.childNodes].forEach((e=>{if(e.nodeValue)return[...e.nodeValue].forEach((t=>{e.parentNode.insertBefore(r(t),e)})),void e.remove();i(e)})),e);var a=e=>{let t=document.implementation.createHTMLDocument();return t.body.innerHTML=e,i(t.body)};const l="ti-cursor",s={started:!1,completed:!1,frozen:!1,destroyed:!1},o={breakLines:!0,cursor:!0,cursorChar:"|",cursorSpeed:1e3,deleteSpeed:null,html:!0,lifeLike:!0,loop:!1,loopDelay:750,nextStringDelay:750,speed:100,startDelay:250,startDelete:!1,strings:[],waitUntilVisible:!1,beforeString:()=>{},afterString:()=>{},beforeStep:()=>{},afterStep:()=>{},afterComplete:()=>{}};function u(e,t=!1,n=!1){let r,i=e.querySelector(".ti-cursor"),a=document.createTreeWalker(e,NodeFilter.SHOW_ALL,{acceptNode:e=>{var t,r;if(i&&n){if(null==(t=e.classList)?void 0:t.contains(l))return NodeFilter.FILTER_ACCEPT;if(i.contains(e))return NodeFilter.FILTER_REJECT}return(null==(r=e.classList)?void 0:r.contains(l))?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}),s=[];for(;r=a.nextNode();)r.originalParent||(r.originalParent=r.parentNode),s.push(r);return t?s.reverse():s}function d(e,t=!0){return t?u(a(e)):n(e).map(r)}var c=e=>document.createElement(e),f=(e,t="")=>{let n=c("style");n.id=t,n.appendChild(r(e)),document.head.appendChild(n)},h=t=>(e(t)||(t=[t/2,t/2]),t),y=(e,t)=>Math.abs(Math.random()*(e+t-(e-t))+(e-t));let p=e=>e/2;var m=e=>"value"in e;let g=e=>"function"==typeof e?e():e;var b=e=>Number.isInteger(e);let v=(e,t=document,n=!1)=>t["querySelector"+(n?"All":"")](e);var w=(e,t)=>Object.assign({},e,t);let T={"font-family":"","font-weight":"","font-size":"","font-style":"","line-height":"",color:"",transform:"translateX(-.125em)"};var E=(e,t)=>new Array(t).fill(e);const S=({queueItems:e,selector:t,cursorPosition:n,to:r})=>{if(b(t))return-1*t;let i=new RegExp("END","i").test(r),a=t?[...e].reverse().findIndex((({char:e})=>{let n=e.parentElement,r=n.matches(t);return!(!i||!r)||r&&n.firstChild.isSameNode(e)})):-1;return a<0&&(a=i?0:e.length-1),a-n+(i?0:1)};let N=e=>new Promise((t=>{requestAnimationFrame((async()=>{t(await e())}))})),C=e=>null==e?void 0:e.getAnimations().find((t=>t.id===e.dataset.tiAnimationId));const L={iterations:1/0,easing:"steps(2, start)",fill:"forwards"},I=[0,0,1].map((e=>({opacity:e})));let M=({cursor:e,frames:t=null,timingOptions:n={}})=>{let r=e.animate(t||I,{...L,...n});return r.pause(),r.id=e.dataset.tiAnimationId,N((()=>{N((()=>{r.play()}))})),r},x=e=>{var t;return null==(t=e.func)?void 0:t.call(globalThis)},P=async({index:e,queueItems:t,wait:n,cursor:r})=>{let i=t[e][1],a=[],l=e,s=i,o=()=>s&&!s.delay;for(;o();)a.push(s),o()&&l++,s=t[l]?t[l][1]:null;if(a.length)return await N((async()=>{for(let e of a)await x(e)})),l-1;let{frames:u,timingOptions:d}=await(async()=>{let e=C(r),t={},a=null;return e&&(t=r?{...e.effect.getComputedTiming(),delay:i.shouldPauseCursor()?500:0}:{},a=r?e.effect.getKeyframes():[]),await n((async()=>{e&&i.shouldPauseCursor()&&e.cancel(),await N((()=>{x(i)}))}),i.delay),{frames:a,timingOptions:t}})();return await(({cursor:e,frames:t,timingOptions:n})=>{if(!e)return;let r,i=C(e);i&&(n.delay=i.effect.getComputedTiming().delay,r=i.currentTime,i.cancel());let a=M({cursor:e,frames:t,timingOptions:n});return r&&(a.currentTime=r),a})({cursor:r,frames:u,timingOptions:d}),e};return function(e,r={}){let N=async(e,t,n=!1)=>{X.frozen&&await new Promise((e=>{this.unfreeze=()=>{X.frozen=!1,e()}})),n||await K.beforeStep(this),await((e,t,n)=>new Promise((r=>{n.push(setTimeout((async()=>{await e(),r()}),t||0))})))(e,t,J),n||await K.afterStep(this)},C=(e,t)=>P({index:e,queueItems:t,wait:N,cursor:ee}),L=e=>((e,t)=>{if(!e)return;let n=e.parentNode;(n.childNodes.length>1||n.isSameNode(t)?e:n).remove()})(e,j),I=()=>m(j),x=(e=0)=>function(e){let{speed:t,deleteSpeed:n,lifeLike:r}=e;return n=null!==n?n:t/3,r?[y(t,p(t)),y(n,p(n))]:[t,n]}(K)[e],A=()=>(e=>m(e)?n(e.value):u(e,!0).filter((e=>!(e.childNodes.length>0))))(j),D=(e,t)=>(Y.add(e),((e={})=>{let t=e.delay;t&&Y.add({delay:t})})(t),this),O=()=>null!=W?W:U,H=(e={})=>[{func:()=>B(e)},{func:()=>B(K)}],F=e=>{let t=K.nextStringDelay;Y.add([{delay:t[0]},...e,{delay:t[1]}])},k=async()=>{!I()&&ee&&j.appendChild(ee),Z&&(((e,t)=>{let n=`[data-typeit-id='${e}'] .ti-cursor`,r=getComputedStyle(t),i=Object.entries(T).reduce(((e,[t,n])=>`${e} ${t}: var(--ti-cursor-${t}, ${n||r[t]});`),"");f(`${n} { display: inline-block; width: 0; ${i} }`,e)})(G,j),ee.dataset.tiAnimationId=G,M({cursor:ee,timingOptions:{duration:K.cursorSpeed}}))},R=()=>{let e=K.strings.filter((e=>!!e));e.forEach(((t,n)=>{if(this.type(t),n+1===e.length)return;let r=K.breakLines?[{func:()=>z(c("BR")),typeable:!0}]:E({func:V,delay:x(1)},Y.getTypeable().length);F(r)}))},$=async(e=!0)=>{X.started=!0;let t=t=>{Y.done(t,!e)};try{let n=[...Y.getQueue()];for(let e=0;e<n.length;e++){let[r,i]=n[e];if(!i.done){if(!i.deletable||i.deletable&&A().length){let r=await C(e,n);Array(r-e).fill(e+1).map(((e,t)=>e+t)).forEach((e=>{let[r]=n[e];t(r)})),e=r}t(r)}}if(!e)return this;if(X.completed=!0,await K.afterComplete(this),!K.loop)throw"";let r=K.loopDelay;N((async()=>{await(async e=>{let t=O();t&&await q({value:t});let n=A().map((e=>[Symbol(),{func:V,delay:x(1),deletable:!0,shouldPauseCursor:()=>!0}]));for(let r=0;r<n.length;r++)await C(r,n);Y.reset(),Y.set(0,{delay:e})})(r[0]),$()}),r[1])}catch(n){}return this},q=async e=>{var t,n,r;t=e,n=U,r=A(),U=Math.min(Math.max(n+t,0),r.length),((e,t,n)=>{let r=t[n-1],i=v(".ti-cursor",e);(e=(null==r?void 0:r.parentNode)||e).insertBefore(i,r||null)})(j,A(),U)},z=e=>((e,t)=>{if(m(e))return void(e.value=`${e.value}${t.textContent}`);t.innerHTML="";let n=(r=t.originalParent,/body/i.test(null==r?void 0:r.tagName)?e:t.originalParent||e);var r;n.insertBefore(t,v(".ti-cursor",n)||null)})(j,e),B=async e=>K=w(K,e),_=async()=>{I()?j.value="":A().forEach(L)},V=()=>{let e=A();e.length&&(I()?j.value=j.value.slice(0,-1):L(e[U]))};this.break=function(e){return D({func:()=>z(c("BR")),typeable:!0},e)},this.delete=function(e=null,t={}){e=g(e);let n=H(t),r=e,{instant:i,to:a}=t,l=Y.getTypeable(),s=null===r?l.length:b(r)?r:S({queueItems:l,selector:r,cursorPosition:O(),to:a});return D([n[0],...E({func:V,delay:i?0:x(1),deletable:!0},s),n[1]],t)},this.empty=function(e={}){return D({func:_},e)},this.exec=function(e,t={}){let n=H(t);return D([n[0],{func:()=>e(this)},n[1]],t)},this.move=function(e,t={}){e=g(e);let n=H(t),{instant:r,to:i}=t,a=S({queueItems:Y.getTypeable(),selector:null===e?"":e,to:i,cursorPosition:O()}),l=a<0?-1:1;return W=O()+a,D([n[0],...E({func:()=>q(l),delay:r?0:x(),cursorable:!0},Math.abs(a)),n[1]],t)},this.options=function(e,t={}){return e=g(e),B(e),D({},t)},this.pause=function(e,t={}){return D({delay:g(e)},t)},this.type=function(e,t={}){e=g(e);let{instant:n}=t,r=H(t),i=d(e,K.html).map((e=>{return{func:()=>z(e),char:e,delay:n||(t=e,/<(.+)>(.*?)<\/(.+)>/.test(t.outerHTML))?0:x(),typeable:e.nodeType===Node.TEXT_NODE};var t})),a=[r[0],{func:async()=>await K.beforeString(e,this)},...i,{func:async()=>await K.afterString(e,this)},r[1]];return D(a,t)},this.is=function(e){return X[e]},this.destroy=function(e=!0){J.forEach(clearTimeout),J=[],g(e)&&ee&&L(ee),X.destroyed=!0},this.freeze=function(){X.frozen=!0},this.unfreeze=()=>{},this.reset=function(e){!this.is("destroyed")&&this.destroy(),e?(Y.wipe(),e(this)):Y.reset(),U=0;for(let t in X)X[t]=!1;return j[I()?"value":"innerHTML"]="",this},this.go=function(){return X.started?this:(k(),K.waitUntilVisible?(((e,t)=>{new IntersectionObserver(((n,r)=>{n.forEach((n=>{n.isIntersecting&&(t(),r.unobserve(e))}))}),{threshold:1}).observe(e)})(j,$.bind(this)),this):($(),this))},this.flush=function(e=(()=>{})){return k(),$(!1).then(e),this},this.getQueue=()=>Y,this.getOptions=()=>K,this.updateOptions=e=>B(e),this.getElement=()=>j;let j="string"==typeof(Q=e)?v(Q):Q;var Q;let J=[],U=0,W=null,X=w({},s),K=w(o,r);K=w(K,{html:!I()&&K.html,nextStringDelay:h(K.nextStringDelay),loopDelay:h(K.loopDelay)});let G=Math.random().toString().substring(2,9),Y=function(e){let n=function(e){return t(e).forEach((e=>{var t;return a.set(Symbol(null==(t=e.char)?void 0:t.innerText),r({...e}))})),this},r=e=>(e.shouldPauseCursor=function(){return Boolean(this.typeable||this.cursorable||this.deletable)},e),i=()=>Array.from(a.values()),a=new Map;return n(e),{add:n,set:function(e,t){let n=[...a.keys()];a.set(n[e],r(t))},wipe:function(){a=new Map,n(e)},reset:function(){a.forEach((e=>delete e.done))},destroy:e=>a.delete(e),done:(e,t=!1)=>t?a.delete(e):a.get(e).done=!0,getItems:(e=!1)=>e?i():i().filter((e=>!e.done)),getQueue:()=>a,getTypeable:()=>i().filter((e=>e.typeable))}}([{func:()=>{},delay:K.startDelay}]);j.dataset.typeitId=G,f("[data-typeit-id]:before {content: '.'; display: inline-block; width: 0; visibility: hidden;}");let Z=K.cursor&&!I(),ee=(()=>{if(I())return;let e=c("span");return e.className=l,Z?(e.innerHTML=a(K.cursorChar).innerHTML,e):(e.style.visibility="hidden",e)})();K.strings=(e=>{let t=j.innerHTML;return t?(j.innerHTML="",K.startDelete?(j.innerHTML=t,i(j),F(E({func:V,delay:x(1),deletable:!0},A().length)),e):t.replace(/<!--(.+?)-->/g,"").trim().split(/<br(?:\s*?)(?:\/)?>/).concat(e)):e})(t(K.strings)),K.strings.length&&R()}})); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).TypeIt=t()}(this,(function(){"use strict";const e=e=>Array.isArray(e),t=t=>e(t)?t:[t];const n=e=>Array.from(e),r=e=>document.createTextNode(e);let i=e=>([...e.childNodes].forEach((e=>{if(e.nodeValue)return[...e.nodeValue].forEach((t=>{e.parentNode.insertBefore(r(t),e)})),void e.remove();i(e)})),e);const a=e=>{let t=document.implementation.createHTMLDocument();return t.body.innerHTML=e,i(t.body)},o="ti-cursor",s={started:!1,completed:!1,frozen:!1,destroyed:!1},l={breakLines:!0,cursor:{autoPause:!0,autoPauseDelay:500,animation:{frames:[0,0,1].map((e=>({opacity:e}))),options:{iterations:1/0,easing:"steps(2, start)",fill:"forwards"}}},cursorChar:"|",cursorSpeed:1e3,deleteSpeed:null,html:!0,lifeLike:!0,loop:!1,loopDelay:750,nextStringDelay:750,speed:100,startDelay:250,startDelete:!1,strings:[],waitUntilVisible:!1,beforeString:()=>{},afterString:()=>{},beforeStep:()=>{},afterStep:()=>{},afterComplete:()=>{}};function u(e,t=!1,n=!1){let r,i=e.querySelector(".ti-cursor"),a=document.createTreeWalker(e,NodeFilter.SHOW_ALL,{acceptNode:e=>{if(i&&n){if(e.classList?.contains(o))return NodeFilter.FILTER_ACCEPT;if(i.contains(e))return NodeFilter.FILTER_REJECT}return e.classList?.contains(o)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}),s=[];for(;r=a.nextNode();)r.originalParent||(r.originalParent=r.parentNode),s.push(r);return t?s.reverse():s}function c(e,t=!0){return t?u(a(e)):n(e).map(r)}const d=e=>document.createElement(e),f=(e,t="")=>{let n=d("style");n.id=t,n.appendChild(r(e)),document.head.appendChild(n)},h=t=>(e(t)||(t=[t/2,t/2]),t),y=(e,t)=>Math.abs(Math.random()*(e+t-(e-t))+(e-t));let p=e=>e/2;const m=e=>"value"in e;let g=e=>"function"==typeof e?e():e;const b=e=>Number.isInteger(e);let w=(e,t=document,n=!1)=>t["querySelector"+(n?"All":"")](e);const T=(e,t)=>Object.assign({},e,t);let v={"font-family":"","font-weight":"","font-size":"","font-style":"","line-height":"",color:"",transform:"translateX(-.125em)"};const E=(e,t)=>new Array(t).fill(e),P=({queueItems:e,selector:t,cursorPosition:n,to:r})=>{if(b(t))return-1*t;let i=new RegExp("END","i").test(r),a=t?[...e].reverse().findIndex((({char:e})=>{let n=e.parentElement,r=n.matches(t);return!(!i||!r)||r&&n.firstChild.isSameNode(e)})):-1;return a<0&&(a=i?0:e.length-1),a-n+(i?0:1)};let S=e=>new Promise((t=>{requestAnimationFrame((async()=>{t(await e())}))})),N=e=>e?.getAnimations().find((t=>t.id===e.dataset.tiAnimationId)),L=({cursor:e,frames:t,options:n})=>{let r=e.animate(t,n);return r.pause(),r.id=e.dataset.tiAnimationId,S((()=>{S((()=>{r.play()}))})),r},C=e=>e.func?.call(null),D=async({index:e,queueItems:t,wait:n,cursor:r,cursorOptions:i})=>{let a=t[e][1],o=[],s=e,l=a,u=()=>l&&!l.delay,c=a.shouldPauseCursor()&&i.autoPause;for(;u();)o.push(l),u()&&s++,l=t[s]?t[s][1]:null;if(o.length)return await S((async()=>{for(let e of o)await C(e)})),s-1;let d,f=N(r);return f&&(d={...f.effect.getComputedTiming(),delay:c?i.autoPauseDelay:0}),await n((async()=>{f&&c&&f.cancel(),await S((()=>{C(a)}))}),a.delay),await(({cursor:e,options:t,cursorOptions:n})=>{if(!e||!n)return;let r,i=N(e);i&&(t.delay=i.effect.getComputedTiming().delay,r=i.currentTime,i.cancel());let a=L({cursor:e,frames:n.animation.frames,options:t});return r&&(a.currentTime=r),a})({cursor:r,options:d,cursorOptions:i}),e};return function(e,r={}){let S=async(e,t,n=!1)=>{X.frozen&&await new Promise((e=>{this.unfreeze=()=>{X.frozen=!1,e()}})),n||await G.beforeStep(this),await((e,t,n)=>new Promise((r=>{n.push(setTimeout((async()=>{await e(),r()}),t||0))})))(e,t,J),n||await G.afterStep(this)},N=(e,t)=>D({index:e,queueItems:t,wait:S,cursor:ee,cursorOptions:G.cursor}),C=e=>((e,t)=>{if(!e)return;let n=e.parentNode;(n.childNodes.length>1||n.isSameNode(t)?e:n).remove()})(e,V),I=()=>m(V),M=(e=0)=>function(e){let{speed:t,deleteSpeed:n,lifeLike:r}=e;return n=null!==n?n:t/3,r?[y(t,p(t)),y(n,p(n))]:[t,n]}(G)[e],x=()=>(e=>m(e)?n(e.value):u(e,!0).filter((e=>!(e.childNodes.length>0))))(V),A=(e,t)=>(Y.add(e),((e={})=>{let t=e.delay;t&&Y.add({delay:t})})(t),this),H=()=>W??U,O=(e={})=>[{func:()=>B(e)},{func:()=>B(G)}],F=e=>{let t=G.nextStringDelay;Y.add([{delay:t[0]},...e,{delay:t[1]}])},k=async()=>{if(!I()&&ee&&V.appendChild(ee),Z){((e,t)=>{let n=`[data-typeit-id='${e}'] .ti-cursor`,r=getComputedStyle(t),i=Object.entries(v).reduce(((e,[t,n])=>`${e} ${t}: var(--ti-cursor-${t}, ${n||r[t]});`),"");f(`${n} { display: inline-block; width: 0; ${i} }`,e)})(K,V),ee.dataset.tiAnimationId=K;let{animation:e}=G.cursor,{frames:t,options:n}=e;L({frames:t,cursor:ee,options:{duration:G.cursorSpeed,...n}})}},R=()=>{let e=G.strings.filter((e=>!!e));e.forEach(((t,n)=>{if(this.type(t),n+1===e.length)return;let r=G.breakLines?[{func:()=>z(d("BR")),typeable:!0}]:E({func:j,delay:M(1)},Y.getTypeable().length);F(r)}))},$=async(e=!0)=>{X.started=!0;let t=t=>{Y.done(t,!e)};try{let n=[...Y.getQueue()];for(let e=0;e<n.length;e++){let[r,i]=n[e];if(!i.done){if(!i.deletable||i.deletable&&x().length){let r=await N(e,n);Array(r-e).fill(e+1).map(((e,t)=>e+t)).forEach((e=>{let[r]=n[e];t(r)})),e=r}t(r)}}if(!e)return this;if(X.completed=!0,await G.afterComplete(this),!G.loop)throw"";let r=G.loopDelay;S((async()=>{await(async e=>{let t=H();t&&await q({value:t});let n=x().map((e=>[Symbol(),{func:j,delay:M(1),deletable:!0,shouldPauseCursor:()=>!0}]));for(let r=0;r<n.length;r++)await N(r,n);Y.reset(),Y.set(0,{delay:e})})(r[0]),$()}),r[1])}catch(n){}return this},q=async e=>{var t,n,r;t=e,n=U,r=x(),U=Math.min(Math.max(n+t,0),r.length),((e,t,n)=>{let r=t[n-1],i=w(".ti-cursor",e);(e=r?.parentNode||e).insertBefore(i,r||null)})(V,x(),U)},z=e=>((e,t)=>{if(m(e))return void(e.value=`${e.value}${t.textContent}`);t.innerHTML="";let n=(r=t.originalParent,/body/i.test(r?.tagName)?e:t.originalParent||e);var r;n.insertBefore(t,w(".ti-cursor",n)||null)})(V,e),B=async e=>G=T(G,e),_=async()=>{I()?V.value="":x().forEach(C)},j=()=>{let e=x();e.length&&(I()?V.value=V.value.slice(0,-1):C(e[U]))};this.break=function(e){return A({func:()=>z(d("BR")),typeable:!0},e)},this.delete=function(e=null,t={}){e=g(e);let n=O(t),r=e,{instant:i,to:a}=t,o=Y.getTypeable(),s=null===r?o.length:b(r)?r:P({queueItems:o,selector:r,cursorPosition:H(),to:a});return A([n[0],...E({func:j,delay:i?0:M(1),deletable:!0},s),n[1]],t)},this.empty=function(e={}){return A({func:_},e)},this.exec=function(e,t={}){let n=O(t);return A([n[0],{func:()=>e(this)},n[1]],t)},this.move=function(e,t={}){e=g(e);let n=O(t),{instant:r,to:i}=t,a=P({queueItems:Y.getTypeable(),selector:null===e?"":e,to:i,cursorPosition:H()}),o=a<0?-1:1;return W=H()+a,A([n[0],...E({func:()=>q(o),delay:r?0:M(),cursorable:!0},Math.abs(a)),n[1]],t)},this.options=function(e,t={}){return e=g(e),B(e),A({},t)},this.pause=function(e,t={}){return A({delay:g(e)},t)},this.type=function(e,t={}){e=g(e);let{instant:n}=t,r=O(t),i=c(e,G.html).map((e=>{return{func:()=>z(e),char:e,delay:n||(t=e,/<(.+)>(.*?)<\/(.+)>/.test(t.outerHTML))?0:M(),typeable:e.nodeType===Node.TEXT_NODE};var t})),a=[r[0],{func:async()=>await G.beforeString(e,this)},...i,{func:async()=>await G.afterString(e,this)},r[1]];return A(a,t)},this.is=function(e){return X[e]},this.destroy=function(e=!0){J.forEach(clearTimeout),J=[],g(e)&&ee&&C(ee),X.destroyed=!0},this.freeze=function(){X.frozen=!0},this.unfreeze=()=>{},this.reset=function(e){!this.is("destroyed")&&this.destroy(),e?(Y.wipe(),e(this)):Y.reset(),U=0;for(let t in X)X[t]=!1;return V[I()?"value":"innerHTML"]="",this},this.go=function(){return X.started?this:(k(),G.waitUntilVisible?(((e,t)=>{new IntersectionObserver(((n,r)=>{n.forEach((n=>{n.isIntersecting&&(t(),r.unobserve(e))}))}),{threshold:1}).observe(e)})(V,$.bind(this)),this):($(),this))},this.flush=function(e=(()=>{})){return k(),$(!1).then(e),this},this.getQueue=()=>Y,this.getOptions=()=>G,this.updateOptions=e=>B(e),this.getElement=()=>V;let V="string"==typeof(Q=e)?w(Q):Q;var Q;let J=[],U=0,W=null,X=T({},s);r.cursor=(e=>{if("object"==typeof e){let t={},{frames:n,options:r}=l.cursor.animation;return t.animation=e.animation||{},t.animation.frames=e.animation?.frames||n,t.animation.options=T(r,e.animation?.options||{}),t.autoPause=e.autoPause??l.cursor.autoPause,t.autoPauseDelay=e.autoPauseDelay||l.cursor.autoPauseDelay,t}return!0===e?l.cursor:e})(r.cursor??l.cursor);let G=T(l,r);G=T(G,{html:!I()&&G.html,nextStringDelay:h(G.nextStringDelay),loopDelay:h(G.loopDelay)});let K=Math.random().toString().substring(2,9),Y=function(e){let n=function(e){return t(e).forEach((e=>a.set(Symbol(e.char?.innerText),r({...e})))),this},r=e=>(e.shouldPauseCursor=function(){return Boolean(this.typeable||this.cursorable||this.deletable)},e),i=()=>Array.from(a.values()),a=new Map;return n(e),{add:n,set:function(e,t){let n=[...a.keys()];a.set(n[e],r(t))},wipe:function(){a=new Map,n(e)},reset:function(){a.forEach((e=>delete e.done))},destroy:e=>a.delete(e),done:(e,t=!1)=>t?a.delete(e):a.get(e).done=!0,getItems:(e=!1)=>e?i():i().filter((e=>!e.done)),getQueue:()=>a,getTypeable:()=>i().filter((e=>e.typeable))}}([{delay:G.startDelay}]);V.dataset.typeitId=K,f("[data-typeit-id]:before {content: '.'; display: inline-block; width: 0; visibility: hidden;}");let Z=!!G.cursor&&!I(),ee=(()=>{if(I())return;let e=d("span");return e.className=o,Z?(e.innerHTML=a(G.cursorChar).innerHTML,e):(e.style.visibility="hidden",e)})();G.strings=(e=>{let t=V.innerHTML;return t?(V.innerHTML="",G.startDelete?(V.innerHTML=t,i(V),F(E({func:j,delay:M(1),deletable:!0},x().length)),e):t.replace(/<!--(.+?)-->/g,"").trim().split(/<br(?:\s*?)(?:\/)?>/).concat(e)):e})(t(G.strings)),G.strings.length&&R()}})); |
@@ -0,1 +1,2 @@ | ||
/// <reference types="web-animations-js" /> | ||
export declare type TypeItInstance = (element: El | string, options: Options) => void; | ||
@@ -6,6 +7,15 @@ export declare type Character = { | ||
}; | ||
export declare type Options = { | ||
export interface CursorAnimationOptions { | ||
frames?: AnimationKeyFrame[]; | ||
options?: Partial<AnimationEffectTiming>; | ||
} | ||
export interface CursorOptions { | ||
autoPause?: boolean; | ||
autoPauseDelay?: number; | ||
animation?: CursorAnimationOptions; | ||
} | ||
export interface Options { | ||
breakLines?: boolean; | ||
cursor?: boolean; | ||
cursorChar?: string; | ||
cursor?: CursorOptions | boolean; | ||
cursorSpeed?: number; | ||
@@ -28,3 +38,3 @@ deleteSpeed?: null | number; | ||
afterComplete?: Function; | ||
}; | ||
} | ||
export declare type ActionOpts = Options & { | ||
@@ -31,0 +41,0 @@ to?: Sides; |
{ | ||
"name": "typeit", | ||
"version": "8.6.6", | ||
"version": "8.7.0", | ||
"description": "The most versatile animated typing utility on the planet.", | ||
@@ -42,10 +42,11 @@ "author": "Alex MacArthur <alex@macarthur.me> (https://macarthur.me)", | ||
"devDependencies": { | ||
"@babel/preset-env": "^7.18.6", | ||
"@babel/preset-env": "^7.18.9", | ||
"@babel/preset-typescript": "^7.18.6", | ||
"@types/web-animations-js": "^2.2.12", | ||
"jest": "^28.1.2", | ||
"jest-cli": "^28.1.2", | ||
"jest-environment-jsdom": "^28.1.2", | ||
"jest": "^28.1.3", | ||
"jest-cli": "^28.1.3", | ||
"jest-environment-jsdom": "^28.1.3", | ||
"terser": "^5.14.2", | ||
"typescript": "^4.7.4", | ||
"vite": "^2.9.14" | ||
"vite": "^3.0.2" | ||
}, | ||
@@ -62,3 +63,3 @@ "jest": { | ||
}, | ||
"gitHead": "4747a0d6a4440e09103b16624b7a912ce7c72e97" | ||
"gitHead": "9dadb02e14ffad67e9c859430aafcc6db1583d22" | ||
} |
@@ -1,2 +0,2 @@ | ||
import { Options } from "./types"; | ||
import { CursorOptions, Options } from "./types"; | ||
@@ -13,5 +13,21 @@ export const DATA_ATTRIBUTE = "data-typeit-id"; | ||
}; | ||
export const DEFAULT_OPTIONS: Options = { | ||
export const DEFAULT_OPTIONS: Options & { | ||
cursor: Required<CursorOptions>; | ||
} = { | ||
breakLines: true, | ||
cursor: true, | ||
cursor: { | ||
autoPause: true, | ||
autoPauseDelay: 500, | ||
animation: { | ||
frames: [0, 0, 1].map((n) => { | ||
return { opacity: n }; | ||
}), | ||
options: { | ||
iterations: Infinity, | ||
easing: "steps(2, start)", | ||
fill: "forwards", | ||
}, | ||
}, | ||
}, | ||
cursorChar: "|", | ||
@@ -37,2 +53,1 @@ cursorSpeed: 1000, | ||
export const PLACEHOLDER_CSS = `[${DATA_ATTRIBUTE}]:before {content: '.'; display: inline-block; width: 0; visibility: hidden;}`; | ||
export const CURSOR_ANIMATION_RESTART_DELAY = 500; |
@@ -1,3 +0,2 @@ | ||
import { CURSOR_ANIMATION_RESTART_DELAY } from "../constants"; | ||
import { El, QueueItem, QueueMapPair } from "../types"; | ||
import { CursorOptions, El, QueueItem, QueueMapPair } from "../types"; | ||
import beforePaint from "./beforePaint"; | ||
@@ -7,3 +6,3 @@ import getAnimationFromElement from "./getAnimationFromElement"; | ||
let execute = (queueItem: QueueItem) => queueItem.func?.call(this); | ||
let execute = (queueItem: QueueItem) => queueItem.func?.call(null); | ||
@@ -15,2 +14,3 @@ interface FireItemArgs { | ||
cursor: El | undefined; | ||
cursorOptions: CursorOptions; | ||
} | ||
@@ -23,2 +23,3 @@ | ||
cursor, | ||
cursorOptions, | ||
}: FireItemArgs): Promise<number> => { | ||
@@ -30,2 +31,4 @@ let queueItem = queueItems[index][1]; | ||
let shouldBeGrouped = () => futureItem && !futureItem.delay; | ||
let shouldPauseCursor = | ||
queueItem.shouldPauseCursor() && cursorOptions.autoPause; | ||
@@ -54,46 +57,31 @@ // Crawl through the queue and group together all items that | ||
let fire = async (): Promise<{ | ||
timingOptions: object; | ||
frames: AnimationKeyFrame[]; | ||
}> => { | ||
// An animation is only registered on the cursor when it's made visible. | ||
// If the cursor has been disabled, there won't be one here. | ||
let animation = getAnimationFromElement(cursor); | ||
let timingOptions: object = {}; | ||
let frames: AnimationKeyFrame[] = null; | ||
// An animation is only registered on the cursor when it's made visible. | ||
// If the cursor has been disabled, there won't be one here. | ||
let animation = getAnimationFromElement(cursor); | ||
let options; | ||
if (animation) { | ||
timingOptions = cursor | ||
? { | ||
...animation.effect.getComputedTiming(), | ||
delay: queueItem.shouldPauseCursor() | ||
? CURSOR_ANIMATION_RESTART_DELAY | ||
: 0, | ||
} | ||
: {}; | ||
frames = cursor ? animation.effect.getKeyframes() : []; | ||
if (animation) { | ||
options = { | ||
...animation.effect.getComputedTiming(), | ||
delay: shouldPauseCursor ? cursorOptions.autoPauseDelay : 0, | ||
}; | ||
} | ||
await wait(async () => { | ||
// If it's a qualified queue item, pause the cursor at the | ||
// beginning of the item's execution by destroying the aniatmion. | ||
// Immediately after completing, the animation will be recreated (with a delay). | ||
if (animation && shouldPauseCursor) { | ||
animation.cancel(); | ||
} | ||
await wait(async () => { | ||
// If it's a qualified queue item, pause the cursor at the | ||
// beginning of the item's execution by destroying the aniatmion. | ||
// Immediately after completing, the animation will be recreated (with a delay). | ||
if (animation && queueItem.shouldPauseCursor()) { | ||
animation.cancel(); | ||
} | ||
await beforePaint(() => { | ||
execute(queueItem); | ||
}); | ||
}, queueItem.delay); | ||
await beforePaint(() => { | ||
execute(queueItem); | ||
}); | ||
}, queueItem.delay); | ||
return { frames, timingOptions }; | ||
}; | ||
let { frames, timingOptions } = await fire(); | ||
await rebuildCursorAnimation({ | ||
cursor, | ||
frames, | ||
timingOptions, | ||
options, | ||
cursorOptions, | ||
}); | ||
@@ -100,0 +88,0 @@ |
@@ -1,16 +0,9 @@ | ||
import { El } from "../types"; | ||
import beforePaint from "./beforePaint"; | ||
import { El, CursorOptions } from "../types"; | ||
import getAnimationFromElement from "./getAnimationFromElement"; | ||
import setCursorAnimation from "./setCursorAnimation"; | ||
declare global { | ||
interface AnimationEffect { | ||
getKeyframes: () => any; | ||
} | ||
} | ||
interface rebuildCursorAnimationArgs { | ||
cursor: El | undefined; | ||
frames: AnimationKeyFrame[]; | ||
timingOptions: any; | ||
cursorOptions: CursorOptions; | ||
options: any; | ||
} | ||
@@ -20,6 +13,6 @@ | ||
cursor, | ||
frames, | ||
timingOptions, | ||
options, | ||
cursorOptions, | ||
}: rebuildCursorAnimationArgs): Animation => { | ||
if (!cursor) return; | ||
if (!cursor || !cursorOptions) return; | ||
@@ -32,3 +25,3 @@ let animation = getAnimationFromElement(cursor); | ||
if (animation) { | ||
timingOptions.delay = animation.effect.getComputedTiming().delay; | ||
options.delay = animation.effect.getComputedTiming().delay; | ||
@@ -45,10 +38,8 @@ // This needs to be set later, since there's no way to pass | ||
cursor, | ||
frames, | ||
timingOptions, | ||
frames: cursorOptions.animation.frames, | ||
options, | ||
}); | ||
// By setting the currentTime, the animation will | ||
// be in sync with the previous one. But when we're | ||
// totally pausing the animation (indicated by a `delay` | ||
// value), there's no need to do this. | ||
// be in sync with the previous one. | ||
if (oldCurrentTime) { | ||
@@ -55,0 +46,0 @@ newAnimation.currentTime = oldCurrentTime; |
import { El } from "../types"; | ||
import beforePaint from "./beforePaint"; | ||
const DEFAULT_TIMING_OPTIONS: Partial<AnimationEffectTiming> = { | ||
iterations: Infinity, | ||
easing: "steps(2, start)", | ||
fill: "forwards", | ||
}; | ||
const DEFAULT_FRAMES: AnimationKeyFrame[] = [0, 0, 1].map((n) => { | ||
return { opacity: n }; | ||
}); | ||
/** | ||
@@ -19,13 +9,10 @@ * Create and return an animation for the cursor. | ||
cursor, | ||
frames = null, | ||
timingOptions = {}, | ||
frames, | ||
options, | ||
}: { | ||
cursor: El; | ||
frames?: AnimationKeyFrame[] | null; | ||
timingOptions: Partial<AnimationEffectTiming>; | ||
}): Animation | null => { | ||
let animation = cursor.animate(frames || DEFAULT_FRAMES, { | ||
...DEFAULT_TIMING_OPTIONS, | ||
...timingOptions, | ||
}); | ||
frames: AnimationKeyFrame[]; | ||
options: Partial<AnimationEffectTiming>; | ||
}): Animation => { | ||
let animation = cursor.animate(frames, options); | ||
@@ -32,0 +19,0 @@ animation.pause(); |
@@ -33,2 +33,3 @@ import Queue from "./Queue"; | ||
QueueMapPair, | ||
CursorOptions, | ||
} from "./types"; | ||
@@ -45,2 +46,3 @@ import { | ||
import setCursorAnimation from "./helpers/setCursorAnimation"; | ||
import processCursorOptions from "./helpers/processCursorOptions"; | ||
@@ -72,3 +74,3 @@ // Necessary for publicly exposing types. | ||
let _fireItemWithCursor = ( | ||
let _fireItemWithContext = ( | ||
index: number, | ||
@@ -82,2 +84,3 @@ queueItems: QueueMapPair[] | ||
cursor: _cursor as El, | ||
cursorOptions: _opts.cursor as CursorOptions, | ||
}); | ||
@@ -165,6 +168,11 @@ }; | ||
let { animation } = _opts.cursor as CursorOptions; | ||
let { frames, options } = animation; | ||
setCursorAnimation({ | ||
frames, | ||
cursor: _cursor as El, | ||
timingOptions: { | ||
options: { | ||
duration: _opts.cursorSpeed, | ||
...options, | ||
}, | ||
@@ -232,3 +240,3 @@ }); | ||
for (let index = 0; index < queueItems.length; index++) { | ||
await _fireItemWithCursor(index, queueItems); | ||
await _fireItemWithContext(index, queueItems); | ||
} | ||
@@ -318,3 +326,3 @@ | ||
) { | ||
let newIndex = await _fireItemWithCursor(index, queueItems); | ||
let newIndex = await _fireItemWithContext(index, queueItems); | ||
@@ -649,2 +657,6 @@ // Ensure each skipped item goes through the cleanup process, | ||
options.cursor = processCursorOptions( | ||
options.cursor ?? DEFAULT_OPTIONS.cursor | ||
); | ||
let _opts: Options = merge(DEFAULT_OPTIONS, options); | ||
@@ -658,8 +670,3 @@ _opts = merge(_opts, { | ||
let _id = generateHash(); | ||
let _queue = Queue([ | ||
{ | ||
func: () => {}, | ||
delay: _opts.startDelay, | ||
}, | ||
]); | ||
let _queue = Queue([{ delay: _opts.startDelay }]); | ||
@@ -671,3 +678,3 @@ _element.dataset.typeitId = _id; | ||
let _shouldRenderCursor = _opts.cursor && !_elementIsInput(); | ||
let _shouldRenderCursor = !!_opts.cursor && !_elementIsInput(); | ||
let _cursor = _setUpCursor(); | ||
@@ -674,0 +681,0 @@ |
@@ -8,6 +8,19 @@ export type TypeItInstance = (element: El | string, options: Options) => void; | ||
export type Options = { | ||
export interface CursorAnimationOptions { | ||
frames?: AnimationKeyFrame[]; | ||
options?: Partial<AnimationEffectTiming>; | ||
} | ||
export interface CursorOptions { | ||
autoPause?: boolean; | ||
autoPauseDelay?: number; | ||
animation?: CursorAnimationOptions; | ||
} | ||
export interface Options { | ||
breakLines?: boolean; | ||
cursor?: boolean; | ||
cursorChar?: string; | ||
cursor?: CursorOptions | boolean; | ||
// @todo: Remove in next major release. | ||
cursorSpeed?: number; | ||
@@ -30,3 +43,3 @@ deleteSpeed?: null | number; | ||
afterComplete?: Function; | ||
}; | ||
} | ||
@@ -33,0 +46,0 @@ export type ActionOpts = Options & { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
120251
94
2356
9