UNPKG

vue-typical

Version:

Vue Animated typing in ~400 bytes 🐡 of JavaScript.

69 lines (68 loc) 2.62 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; export default function typing(node, ...args) { return __awaiter(this, void 0, void 0, function* () { for (const arg of args) { switch (typeof arg) { case 'string': yield edit(node, arg); break; case 'number': yield wait(arg); break; case 'function': yield arg(node, ...args); break; default: yield arg; } } }); } function edit(node, text) { return __awaiter(this, void 0, void 0, function* () { const overlap = getOverlap(node.textContent, text); yield perform(node, [ ...deleter(node.textContent, overlap), ...writer(text, overlap), ]); }); } function wait(ms) { return __awaiter(this, void 0, void 0, function* () { yield new Promise((resolve) => setTimeout(resolve, ms)); }); } function perform(node, edits, speed = 60) { return __awaiter(this, void 0, void 0, function* () { for (const op of editor(edits)) { op(node); yield wait(speed + speed * (Math.random() - 0.5)); } }); } export function* editor(edits) { for (const edit of edits) { yield (node) => requestAnimationFrame(() => (node.textContent = edit)); } } export function* writer([...text], startIndex = 0, endIndex = text.length) { while (startIndex < endIndex) { yield text.slice(0, ++startIndex).join(''); } } export function* deleter([...text], startIndex = 0, endIndex = text.length) { while (endIndex > startIndex) { yield text.slice(0, --endIndex).join(''); } } export function getOverlap(start, [...end]) { return [...start, NaN].findIndex((char, i) => end[i] !== char); }