You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
6.0KB

  1. function Анимация(элемент, параметры)
  2. {
  3. this.анимировать = function()
  4. {
  5. if (!this.переключитьКадр())
  6. {
  7. this.идёт = false;
  8. return;
  9. }
  10. let x0 = this.началоДиапазона[0];
  11. let y0 = this.началоДиапазона[1];
  12. let x = this.поГоризонтали ? x0 + this.номерКадра * this.кадр[0] : x0;
  13. let y = this.поГоризонтали ? y0 : y0 + this.номерКадра * this.кадр[1];
  14. элемент.style.backgroundPosition = `${x}px -${y}px`;
  15. };
  16. this.запустить = function()
  17. {
  18. this.идёт = false;
  19. if (!this.разобратьПараметры())
  20. {
  21. return;
  22. }
  23. this.номерДиапазона = 0;
  24. this.подготовитьДиапазон();
  25. this.номерОтрисовки = null;
  26. this.идёт = true;
  27. };
  28. this.обновить = function(время)
  29. {
  30. let итерация = Math.floor(время / this.скорость);
  31. if (this.номерОтрисовки == итерация)
  32. {
  33. return;
  34. }
  35. this.анимировать();
  36. this.номерОтрисовки = итерация;
  37. };
  38. this.переключитьКадр = function()
  39. {
  40. this.номерКадра += 1;
  41. // Кадры ещё есть.
  42. if (this.номерКадра < this.колвоКадров)
  43. {
  44. return true;
  45. }
  46. // Кадры диапазона завершились.
  47. // Переключаем на следующий диапазон, если:
  48. // 1. сейчас первый (начальный) диапазон
  49. // 2. всего диапазонов хотя бы два
  50. if (
  51. this.номерДиапазона == 0 &&
  52. this.диапазоны.length > 1
  53. ) {
  54. this.номерДиапазона++;
  55. this.подготовитьДиапазон();
  56. this.номерКадра = 0;
  57. return true;
  58. }
  59. // Пробуем использовать следующее воспроизведение.
  60. this.номерВоспроизведения += 1;
  61. this.номерКадра = 0;
  62. // Воспроизведений не осталось.
  63. if (
  64. this.воспроизведений > 0 &&
  65. this.номерВоспроизведения >= this.воспроизведений
  66. ) {
  67. return false;
  68. }
  69. return true;
  70. };
  71. this.подготовитьДиапазон = function()
  72. {
  73. let н = this.номерДиапазона;
  74. let ширинаДиапазона = Math.abs(this.диапазоны[н][2] - this.диапазоны[н][0]);
  75. let высотаДиапазона = Math.abs(this.диапазоны[н][3] - this.диапазоны[н][1]);
  76. let ширинаКадра = this.кадр[0];
  77. let высотаКадра = this.кадр[1];
  78. let кадровПоГоризонтали = Math.floor(ширинаДиапазона / ширинаКадра);
  79. let кадровПоВертикали = Math.floor(высотаДиапазона / высотаКадра);
  80. this.номерВоспроизведения = 0;
  81. this.поГоризонтали = кадровПоГоризонтали > кадровПоВертикали;
  82. this.номерКадра = -1;
  83. this.колвоКадров = this.поГоризонтали ? кадровПоГоризонтали : кадровПоВертикали;
  84. this.началоДиапазона = [this.диапазоны[н][0], this.диапазоны[н][1]];
  85. };
  86. this.разобратьДиапазоны = function()
  87. {
  88. let ключи = Object.keys(параметры).sort();
  89. let префикс = "диапазоны";
  90. var значения = [];
  91. for (var номер in ключи)
  92. {
  93. let ключ = ключи[номер];
  94. if (ключ.startsWith(префикс))
  95. {
  96. let значение = Number(параметры[ключ]);
  97. if (!isNaN(значение))
  98. {
  99. значения.push(значение);
  100. }
  101. }
  102. }
  103. if (значения.length % 4 == 0)
  104. {
  105. var диапазоны = [];
  106. let колво = значения.length / 4;
  107. for (var д = 0; д < колво; ++д)
  108. {
  109. var диапазон = [];
  110. for (var н = 0; н < 4; ++н)
  111. {
  112. диапазон.push(значения[д * 4 + н]);
  113. }
  114. диапазоны.push(диапазон);
  115. }
  116. return диапазоны;
  117. }
  118. return null;
  119. };
  120. this.разобратьПараметры = function()
  121. {
  122. let п = параметры;
  123. let воспроизведений = Number(п["воспроизведений"]);
  124. let скорость = Number(п["скорость"]);
  125. let к0 = Number(п["кадр.0"]);
  126. let к1 = Number(п["кадр.1"]);
  127. let диапазоны = this.разобратьДиапазоны();
  128. if (
  129. воспроизведений == null ||
  130. скорость == null ||
  131. к0 == null ||
  132. к1 == null ||
  133. диапазоны == null
  134. ) {
  135. return false;
  136. }
  137. this.воспроизведений = воспроизведений;
  138. this.диапазоны = диапазоны;
  139. this.кадр = [к0, к1];
  140. this.скорость = скорость;
  141. return true;
  142. };
  143. // Конструктор.
  144. this.запустить();
  145. }