function Анимация(элемент, параметры) { this.анимировать = function() { if (!this.переключитьКадр()) { this.идёт = false; return; } let x0 = this.началоДиапазона[0]; let y0 = this.началоДиапазона[1]; let x = this.поГоризонтали ? x0 + this.номерКадра * this.кадр[0] : x0; let y = this.поГоризонтали ? y0 : y0 + this.номерКадра * this.кадр[1]; элемент.style.backgroundPosition = `${x}px -${y}px`; }; this.запустить = function() { this.идёт = false; if (!this.разобратьПараметры()) { return; } this.номерДиапазона = 0; this.подготовитьДиапазон(); this.номерОтрисовки = null; this.идёт = true; }; this.обновить = function(время) { let итерация = Math.floor(время / this.скорость); if (this.номерОтрисовки == итерация) { return; } this.анимировать(); this.номерОтрисовки = итерация; }; this.переключитьКадр = function() { this.номерКадра += 1; // Кадры ещё есть. if (this.номерКадра < this.колвоКадров) { return true; } // Кадры диапазона завершились. // Переключаем на следующий диапазон, если: // 1. сейчас первый (начальный) диапазон // 2. всего диапазонов хотя бы два if ( this.номерДиапазона == 0 && this.диапазоны.length > 1 ) { this.номерДиапазона++; this.подготовитьДиапазон(); this.номерКадра = 0; return true; } // Пробуем использовать следующее воспроизведение. this.номерВоспроизведения += 1; this.номерКадра = 0; // Воспроизведений не осталось. if ( this.воспроизведений > 0 && this.номерВоспроизведения >= this.воспроизведений ) { return false; } return true; }; this.подготовитьДиапазон = function() { let н = this.номерДиапазона; let ширинаДиапазона = Math.abs(this.диапазоны[н][2] - this.диапазоны[н][0]); let высотаДиапазона = Math.abs(this.диапазоны[н][3] - this.диапазоны[н][1]); let ширинаКадра = this.кадр[0]; let высотаКадра = this.кадр[1]; let кадровПоГоризонтали = Math.floor(ширинаДиапазона / ширинаКадра); let кадровПоВертикали = Math.floor(высотаДиапазона / высотаКадра); this.номерВоспроизведения = 0; this.поГоризонтали = кадровПоГоризонтали > кадровПоВертикали; this.номерКадра = -1; this.колвоКадров = this.поГоризонтали ? кадровПоГоризонтали : кадровПоВертикали; this.началоДиапазона = [this.диапазоны[н][0], this.диапазоны[н][1]]; }; this.разобратьДиапазоны = function() { let ключи = Object.keys(параметры).sort(); let префикс = "диапазоны"; var значения = []; for (var номер in ключи) { let ключ = ключи[номер]; if (ключ.startsWith(префикс)) { let значение = Number(параметры[ключ]); if (!isNaN(значение)) { значения.push(значение); } } } if (значения.length % 4 == 0) { var диапазоны = []; let колво = значения.length / 4; for (var д = 0; д < колво; ++д) { var диапазон = []; for (var н = 0; н < 4; ++н) { диапазон.push(значения[д * 4 + н]); } диапазоны.push(диапазон); } return диапазоны; } return null; }; this.разобратьПараметры = function() { let п = параметры; let воспроизведений = Number(п["воспроизведений"]); let скорость = Number(п["скорость"]); let к0 = Number(п["кадр.0"]); let к1 = Number(п["кадр.1"]); let диапазоны = this.разобратьДиапазоны(); if ( воспроизведений == null || скорость == null || к0 == null || к1 == null || диапазоны == null ) { return false; } this.воспроизведений = воспроизведений; this.диапазоны = диапазоны; this.кадр = [к0, к1]; this.скорость = скорость; return true; }; // Конструктор. this.запустить(); }