index.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. class Filpper {
  2. constructor(el, template, startVal = 0, startDir = 'up') {
  3. this.el = el;
  4. this.template = template;
  5. this.startVal = startVal;
  6. this.startDir = startDir;
  7. this.templateData = {
  8. curSize: '',
  9. curVal: '0',
  10. nextSize: '',
  11. nextVal: '0'
  12. };
  13. this.templateAsStr = template.innerHTML;
  14. this.tokens = getSubstitutionTokens(this.templateAsStr);
  15. this.templateData.curVal = startVal.toString();
  16. this.setDirection(startDir);
  17. this.update(startVal);
  18. }
  19. update(newVal) {
  20. this.templateData.nextVal = newVal.toString();
  21. this.setSizes();
  22. this.runAnimation();
  23. }
  24. setDirection(direction) {
  25. if (direction.toLowerCase() === 'up') {
  26. this.el.classList.add('up');
  27. this.el.classList.remove('down');
  28. }
  29. else {
  30. this.el.classList.add('down');
  31. this.el.classList.remove('up');
  32. }
  33. }
  34. setSizes() {
  35. const td = this.templateData;
  36. this.templateData.curSize = this.getSize(td.curVal);
  37. this.templateData.nextSize = this.getSize(td.nextVal);
  38. }
  39. getSize(val) {
  40. return val.toString().length > 1 ? 'small' : '';
  41. }
  42. runAnimation() {
  43. const inner = processTemplateSubstitutions(this.templateAsStr, this.tokens, this.templateData);
  44. this.el.innerHTML = inner;
  45. window.requestAnimationFrame(() => {
  46. this.el.classList.remove('changed');
  47. window.requestAnimationFrame(() => this.el.classList.add('changing'));
  48. });
  49. setTimeout(() => {
  50. this.el.classList.add('changed');
  51. this.el.classList.remove('changing');
  52. this.templateData.curVal = this.templateData.nextVal;
  53. }, this.duration * 0.9);
  54. }
  55. }
  56. ;
  57. // --------------------------------------------------------------------------------------------------------------------
  58. // Teplating Helpers
  59. const processTemplateSubstitutions = (template, tokens, data) => {
  60. const processedTemplate = tokens.reduce((str, token) => str.replace(new RegExp(`{{\\s${token}\\s+}}`, 'gm'), path(data, token)), template);
  61. return processedTemplate;
  62. };
  63. const getSubstitutionTokens = (template) => {
  64. let resArr = [];
  65. let tempArr;
  66. const regex = new RegExp('{{\\s+(.*?)\\s+}}', 'g');
  67. while ((tempArr = regex.exec(template)) !== null) {
  68. resArr.push(tempArr[1]);
  69. }
  70. return Array.from(new Set(resArr));
  71. };
  72. const path = (obj, path, defaultval = '') => {
  73. // Safely get nested properties without triggering type errors
  74. // Usage: fetch(obj, 'a.b.c.d')
  75. // Returns d if d exists, else defaultval or an empty string
  76. if (typeof defaultval === 'undefined')
  77. defaultval = null;
  78. if (typeof obj !== 'object')
  79. return defaultval;
  80. if (typeof path !== 'string')
  81. return defaultval;
  82. var props = path.split('.');
  83. var test_first = (obj, props) => {
  84. if (props.length) {
  85. var first = props[0];
  86. if (obj.hasOwnProperty(first)) {
  87. var rest = props.slice(1);
  88. return test_first(obj[first], rest); // Recursive chomp
  89. }
  90. else {
  91. return defaultval; // The default value, or null
  92. }
  93. }
  94. else {
  95. return obj; // The chomped object's last primitive property if it exists
  96. }
  97. };
  98. return test_first(obj, props);
  99. };
  100. // --------------------------------------------------------------------------------------------------------------------
  101. // Run the flipper
  102. var card = document.querySelector('.flipper-card');
  103. var template = document.querySelector('#flipper-card-template');
  104. var c = new Filpper(card, template);
  105. c.update(1);
  106. setTimeout(() => c.update(2), 1000);
  107. setTimeout(() => c.update(3), 2000);
  108. setTimeout(() => c.update(4), 3000);
  109. setTimeout(() => c.update(5), 4000);
  110. setTimeout(() => c.update('A'), 5000);
  111. setTimeout(() => c.update('B'), 6000);
  112. setTimeout(() => c.update('C'), 7000);
  113. setTimeout(() => c.update('D'), 8000);
  114. setTimeout(() => c.update('E'), 9000);
  115. //# sourceMappingURL=index.js.map