Я использую React/Redux и сохраняю данные анимации в JSON и пытаюсь отобразить его на странице React.
Я использую setTimeout
(для пауз) и setInterval
(для движения анимации). Тем не менее, мне кажется, у меня проблемы с пониманием того, как правильно реализовать анимацию, и думаю, что я иду совсем по-другому.
Данные JSON:
"objects": [
{
"title": "puppy",
"image_set": [
{
"image": "images/puppy_sitting.png",
"startx": 520,
"starty": 28,
"pause": 1000
},
{
"image": "images/puppy_walking.png",
"startx": 520,
"starty": 28,
"endx": 1,
"endy": 1,
"time": 1000
},
{
"image": "images/puppy_crouching.png",
"startx": 1,
"starty": 1,
"endx": 500,
"endy": 400,
"time": 2000
}
]
},
{
"title": "scorpion",
"image_set": [
{
"image": "images/scorping_sleeping.png",
"startx": 100,
"starty": 400,
"pause": 5000
},
{
"image": "images/scorpion_walking.png",
"startx": 100,
"starty": 400,
"endx": 500,
"endy": 400,
"time": 7000
},
{
"image": "images/scorpion_walking.png",
"startx": 500,
"starty": 400,
"endx": 100,
"endy": 400,
"time": 2000
},
{
"image": "images/scorpion_walking.png",
"startx": 100,
"starty": 400,
"endx": 200,
"endy": 400,
"time": 7000
},
{
"image": "images/scorpion_walking.png",
"startx": 200,
"starty": 400,
"endx": 100,
"endy": 400,
"time": 1000
}
]
}
]
Каждый объект может иметь несколько связанных с ними изображений. Анимация будет продолжать повторяться без остановок. Каждый объект должен перемещаться одновременно с каждым из других объектов, чтобы я мог создать сцену различных животных и объектов, перемещающихся вокруг нее.
Анимационный код:
Я почти уверен, что я ругаю неправильное дерево здесь, но мой код выглядит примерно так:
// image_set is the list of images for a specific object
// object_num is the array index corresponding to the JSON objects array
// selected is the array index corresponding to which image in the image_set will be displayed
runAnimation(image_set, object_num, selected){
// Uses prevState so that we keep state immutable
this.setState(prevState => {
let images = [...prevState.images];
if (!images[object_num]){
images.push({image: null, x: 0, y: 0})
}
images[object_num].image = image_set[selected].image;
images[object_num].x = this.getFactoredX(image_set[selected].startx);
images[object_num].y = this.getFactoredY(image_set[selected].starty);
return {images: images};
})
if (image_set[selected].endx && image_set[selected].endy && image_set[selected].time){
let x = this.getFactoredX(image_set[selected].startx)
let y = this.getFactoredY(image_set[selected].starty)
let startx = x
let starty = y
let endx = this.getFactoredX(image_set[selected].endx)
let endy = this.getFactoredY(image_set[selected].endy)
let time = image_set[selected].time
let x_increment = (endx - x) / (time / 50)
let y_increment = (endy - y) / (time / 50)
let int = setInterval(function(){
x += x_increment
y += y_increment
if (x > endx || y > endy){
clearInterval(int)
}
this.setState(prevState => {
let images = [...prevState.images]
if (images[object_num]){
images[object_num].x = x
images[object_num].y = y
}
return {images: images};
})
}.bind(this),
50
)
}
if (image_set[selected].pause && image_set[selected].pause > 0){
selected++
if (selected == image_set.length){
selected = 0
}
setTimeout(function() {
this.runAnimation(image_set, object_num, selected)
}.bind(this),
image_set[selected].pause
)
}
else {
selected++
if (selected == image_set.length){
selected = 0
}
setTimeout(function() {
this.runAnimation(image_set, object_num, selected)
}.bind(this),
50
)
}
}
Redux и this.props.data
Redux вводит данные в качестве реквизита. Итак, у меня есть функция, вызываемая из моих функций componentDidMount и componentWillReceiveProps, которая передает исходное изображение, установленное в loadAnimationFunction.
Мой рендер()
В моей функции render()
меня есть что-то вроде этого:
if (this.state.images.length > 1){
animated = this.state.images.map((image, i) => {
let x_coord = image.x
let y_coord = image.y
return (
<div key={i} style={{transform: "scale(" + this.state.x_factor + ")", transformOrigin: "top left", position: "absolute", left: x_coord, top: y_coord}}>
<img src={'/api/get_image.php?image=${image.image}'} />
</div>
)
})
}
x_factor/y_factor
Во всем моем коде есть ссылка на х и у фактор. Это связано с тем, что фон, в котором появляются анимации, может быть меньше или меньше. Поэтому я также масштабирую положение начальных и конечных координат x/y для каждой анимации, а также масштабирует сами анимированные изображения.
время и время паузы
Время указывает время в мс, которое должна принимать анимация. Время паузы указывает, как долго в секундах приостанавливаться до перехода к следующей анимации.
Эта проблема
Код не перемещает анимацию плавно, и они, похоже, периодически спотыкаются.
Кроме того, когда я нажимаю кнопку мыши на любой странице, это заставляет анимацию переходить в другую позицию. Почему щелчок мышью влияет на анимацию?
Одна вещь, которую я заметил, это то, что если у меня консоль открыта для целей отладки, это действительно замедляет анимацию.
Что я могу сделать с моим кодом, чтобы анимация работала так, как ожидалось?