157 lines
6.0 KiB
JavaScript
157 lines
6.0 KiB
JavaScript
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.запустить();
|
|
}
|