class Filpper { constructor(el, template, startVal = 0, startDir = 'up') { this.el = el; this.template = template; this.startVal = startVal; this.startDir = startDir; this.templateData = { curSize: '', curVal: '0', nextSize: '', nextVal: '0' }; this.templateAsStr = template.innerHTML; this.tokens = getSubstitutionTokens(this.templateAsStr); this.templateData.curVal = startVal.toString(); this.setDirection(startDir); this.update(startVal); } update(newVal) { this.templateData.nextVal = newVal.toString(); this.setSizes(); this.runAnimation(); } setDirection(direction) { if (direction.toLowerCase() === 'up') { this.el.classList.add('up'); this.el.classList.remove('down'); } else { this.el.classList.add('down'); this.el.classList.remove('up'); } } setSizes() { const td = this.templateData; this.templateData.curSize = this.getSize(td.curVal); this.templateData.nextSize = this.getSize(td.nextVal); } getSize(val) { return val.toString().length > 1 ? 'small' : ''; } runAnimation() { const inner = processTemplateSubstitutions(this.templateAsStr, this.tokens, this.templateData); this.el.innerHTML = inner; window.requestAnimationFrame(() => { this.el.classList.remove('changed'); window.requestAnimationFrame(() => this.el.classList.add('changing')); }); setTimeout(() => { this.el.classList.add('changed'); this.el.classList.remove('changing'); this.templateData.curVal = this.templateData.nextVal; }, this.duration * 0.9); } } ; // -------------------------------------------------------------------------------------------------------------------- // Teplating Helpers const processTemplateSubstitutions = (template, tokens, data) => { const processedTemplate = tokens.reduce((str, token) => str.replace(new RegExp(`{{\\s${token}\\s+}}`, 'gm'), path(data, token)), template); return processedTemplate; }; const getSubstitutionTokens = (template) => { let resArr = []; let tempArr; const regex = new RegExp('{{\\s+(.*?)\\s+}}', 'g'); while ((tempArr = regex.exec(template)) !== null) { resArr.push(tempArr[1]); } return Array.from(new Set(resArr)); }; const path = (obj, path, defaultval = '') => { // Safely get nested properties without triggering type errors // Usage: fetch(obj, 'a.b.c.d') // Returns d if d exists, else defaultval or an empty string if (typeof defaultval === 'undefined') defaultval = null; if (typeof obj !== 'object') return defaultval; if (typeof path !== 'string') return defaultval; var props = path.split('.'); var test_first = (obj, props) => { if (props.length) { var first = props[0]; if (obj.hasOwnProperty(first)) { var rest = props.slice(1); return test_first(obj[first], rest); // Recursive chomp } else { return defaultval; // The default value, or null } } else { return obj; // The chomped object's last primitive property if it exists } }; return test_first(obj, props); }; // -------------------------------------------------------------------------------------------------------------------- // Run the flipper var card = document.querySelector('.flipper-card'); var template = document.querySelector('#flipper-card-template'); var c = new Filpper(card, template); c.update(1); setTimeout(() => c.update(2), 1000); setTimeout(() => c.update(3), 2000); setTimeout(() => c.update(4), 3000); setTimeout(() => c.update(5), 4000); setTimeout(() => c.update('A'), 5000); setTimeout(() => c.update('B'), 6000); setTimeout(() => c.update('C'), 7000); setTimeout(() => c.update('D'), 8000); setTimeout(() => c.update('E'), 9000); //# sourceMappingURL=index.js.map