- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在使用 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 将数据作为 props 引入。因此,我有一个从我的 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 因子。这是因为动画出现的背景可能会缩小或放大。因此,我还缩放了每个动画的开始和结束 x/y 坐标的位置,并缩放了动画图像本身。
时间和暂停时间
Time 指示动画应该花费的时间(以毫秒为单位)。暂停时间表示在移动到下一个动画之前暂停多长时间(以毫秒为单位)。
问题
代码没有流畅地移动动画,它们似乎偶尔会跳来跳去。
此外,当我在页面上的任意位置单击鼠标时,它会导致动画跳转到另一个位置。为什么点击鼠标会影响动画?
我注意到的一件事是,如果我打开控制台进行调试,这确实会减慢动画速度。
我可以对我的代码做些什么以使动画按预期工作?
最佳答案
您正在尝试使用 setInterval
对坐标和 absolute
位置执行 setState
来为您的元素设置动画。所有这些都无法实现出色的性能。
首先,setInterval
不应该用于动画,你应该更喜欢 requestAnimationFrame因为它将允许 60fps 动画,因为动画将在浏览器的下一次重绘之前运行。
其次,执行 setState
会重新渲染您的整个组件,这可能会对渲染时间产生影响,因为我假设您的组件不会只渲染您的图像。您应该尽量避免重新渲染未更改的内容,因此请尝试为动画隔离图像。
最后,当您使用 left
和 top
属性定位您的元素时,但您应该坚持这一点,定位,而不是动画浏览器会逐个像素地制作动画,并且无法创造出良好的性能。相反,您应该使用 CSS translate()
,因为它可以进行亚像素计算,并将改为在 GPU 上工作,让您可以实现 60fps 的动画。有一个 good article Paul Irish 对此的看法。
也就是说,您可能应该使用 react-motion这将使您获得流畅的动画:
import { Motion, spring } from 'react-motion'
<Motion defaultStyle={{ x: 0 }} style={{ x: spring(image.x), y: spring(image.y) }}>
{({ x, y }) => (
<div style={{
transform: `translate(${x}px, ${y}px)`
}}>
<img src={`/api/get_image.php?image=${image.image}`} />
</div>
)}
</Motion>
还有 React Transition Group,Transition可以像上面解释的那样使用 translate
动画移动你的元素。你还应该去看看 React 动画文档 here .
也值得一试,是React Pose ,它非常易于使用,并且使用干净的 API 也能很好地执行。 Here是 React 的入门页面。
这是一个快速演示,它使用您的概念和坐/走/运行循环。请注意,react-motion 是唯一一种无需对过渡持续时间进行硬编码即可处理帧之间过渡的方法,这将 go against a fluid UI ,状态只处理不同的步骤。
引用 react-motion Readme :
For 95% of use-cases of animating components, we don't have to resort to using hard-coded easing curves and duration. Set up a stiffness and damping for your UI element, and let the magic of physics take care of the rest. This way, you don't have to worry about petty situations such as interrupted animation behavior. It also greatly simplifies the API.
如果您对默认 Spring 不满意,可以更改dampling
和stiffness
参数。有一个 app这可以帮助您获得最令您满意的那一款。
关于javascript - 基于 JSON 数据的 React JS 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53531445/
问题是,当用户回复彼此的帖子时,我必须这样做: margin-left:40px; 对于 1 级深度 react margin-left:80px; 对于 2 层深等 但是我想让 react div
我试图弄清楚如何将 React Router 与 React VR 连接起来。 首先,我应该使用 react-router dom/native ?目前尚不清楚,因为 React VR 构建在 Rea
我是 React 或一般编码背景的新手。我不确定这些陈述之间有什么区别 import * as react from 'react' 和 import react from 'react' 提前致谢!
我正在使用最新的稳定版本的 react、react-native、react-test-renderer、react-dom。 然而,react-native 依赖于 react@16.0.0-alp
是否 react 原生 应用程序开发可以通过软件架构实现,例如 MVC、MVP、MVVM ? 谢谢你。 最佳答案 是的。 React Native 只是你提到的那些软件设计模式中的“V”。如果你考虑其
您好我正在尝试在我的导航器右按钮中绑定(bind)一个功能, 但它给出了错误。 这是我的代码: import React, { Component } from 'react'; import Ico
我使用react native创建了一个应用程序,我正在尝试生成apk。在http://facebook.github.io/react-native/docs/signed-apk-android.
1 [我尝试将分页的 z-index 更改为 0,但没有成功] 这是我的codesandbox的链接:请检查最后一个选择下拉列表,它位于分页后面。 https://codesandbox.io/s/j
我注意到 React 可以这样导入: import * as React from 'react'; ...或者像这样: import React from 'react'; 第一个导入 react
我是 react-native 的新手。我正在使用 React Native Paper 为所有屏幕提供主题。我也在使用 react 导航堆栈导航器和抽屉导航器。首先,对于导航,论文主题在导航组件中不
我有一个使用 Ignite CLI 创建的 React Native 应用程序.我正在尝试将 TabNavigator 与 React Navigation 结合使用,但我似乎无法弄清楚如何将数据从一
我正在尝试在我的 React 应用程序中进行快照测试。我已经在使用 react-testing-library 进行一般的单元测试。然而,对于快照测试,我在网上看到了不同的方法,要么使用 react-
我正在使用 react-native 构建跨平台 native 应用程序,并使用 react-navigation 在屏幕之间导航和使用 redux 管理导航状态。当我嵌套导航器时会出现问题。 例如,
由于分页和 React Native Navigation,我面临着一种复杂的问题。 单击具有类别列表的抽屉,它们都将转到屏幕 问题陈述: 当我随机点击类别时,一切正常。但是,在分页过程中遇到问题。假
这是我的抽屉导航: const DashboardStack = StackNavigator({ Dashboard: { screen: Dashboard
尝试构建 react-native android 应用程序但出现以下错误 info Running jetifier to migrate libraries to AndroidX. You ca
我目前正在一个应用程序中实现 React Router v.4,我也在其中使用 Webpack 进行捆绑。在我的 webpack 配置中,我将 React、ReactDOM 和 React-route
我正在使用 React.children 渲染一些带有 react router 的子路由(对于某个主路由下的所有子路由。 这对我来说一直很好,但是我之前正在解构传递给 children 的 Prop
当我运行 React 应用程序时,它显示 export 'React'(导入为 'React')在 'react' 中找不到。所有页面错误 see image here . 最佳答案 根据图像中的错误
当我使用这个例子在我的应用程序上实现 Image-slider 时,我遇到了这个错误。 import React,{Component} from 'react' import {View,T
我是一名优秀的程序员,十分优秀!