本文共 16629 字,大约阅读时间需要 55 分钟。
framer x使用教程
The web is vast and it's full of static websites and apps. But just because those apps are static, it doesn't mean they have to be boring.
网络非常庞大,到处都是静态的网站和应用。 但是,仅仅因为这些应用程序是静态的,并不意味着它们一定很无聊。
How can we use Framer Motion to add some animations to our web apps and provide a more interactive experience?
我们如何使用Framer Motion将一些动画添加到我们的Web应用程序中并提供更具交互性的体验?
is an API that comes straight from the Framer API. It provides ready-to-go animations and gesture controls that makes it easy to create dynamic effects.
是直接来自Framer API的API。 它提供了随时可用的动画和手势控件,可轻松创建动态效果。
What is ? Framer itself is a UI prototyping tool that allows you to create interactive interfaces with animations that you can hand off to your team, while the is a Javascript library that lets you do that with code.
什么是 ? Framer本身是一个UI原型制作工具,可让您创建带有动画的交互式界面,您可以将该动画传递给您的团队,而是一个Javascript库,可用于编写代码。
The Motion API stems from that work, but is conveniently available as a separate package that we can use for animation control.
Motion API源自这项工作,但是可以作为单独的软件包方便地使用,我们可以将其用于动画控制。
We’re going to use the concepts of Framer Motion to add interaction and page transition effects to our app.
我们将使用Framer Motion的概念向我们的应用程序添加交互和页面过渡效果。
We’ll start off with some basic animations that happen when the page load, learn how to trigger them on hover, and build out a wrapper that allows us to gracefully transition our pages in Next.js.
我们将从页面加载时发生的一些基本动画开始,学习如何在悬停时触发它们,并构建一个包装器,使我们能够在Next.js中正常转换页面。
This is the second part of series of articles walking through building a Rick and Morty wiki. focuses on requesting the data from the Rick and Morty API and creating dynamic pages.
这是构建Rick and Morty Wiki的系列文章的第二部分。 着重于从Rick and Morty API请求数据并创建动态页面。
While you can follow along without walking through the first one, it might be helpful to have a place to start from. Otherwise, you should be able to follow along most of this with any React app.
尽管您可以不遵循第一个步骤地进行学习,但是找到一个起点可能会有所帮助。 否则,您应该能够在任何React应用程序中遵循大部分内容。
Since we’re going to use Framer Motion to provide our animation features, the first thing we want to do is install it!
由于我们将使用Framer Motion提供动画功能,因此我们要做的第一件事就是安装它!
Once you have the app running locally, you can install it with:
在本地运行应用程序后,可以使用以下命令进行安装:
yarn add framer-motion# ornpm install framer-motion
And at this point you can start back up your development server and we’ll be ready to go!
现在,您可以启动您的开发服务器了,我们就可以开始了!
To get started, we’re going to animate the page title in our wiki app. Particularly, we’re going to configure Framer Motion to make the title fade in and grow when the page first loads.
首先,我们将为Wiki应用程序中的页面标题设置动画。 特别是,我们将配置成帧器运动以使标题淡入并在页面首次加载时增长。
First things first, we need to import Motion into our app.
首先,我们需要将Motion导入到我们的应用程序中。
Start off by adding the following import statement to the top of pages/index.js
:
首先将以下import语句添加到pages/index.js
的顶部:
import { motion } from 'framer-motion';
And now that we’re ready to use motion
, we can get started by wrapping out <h1>
title with a motion component:
现在我们已经准备好使用motion
,我们可以通过将<h1>
标题包装到运动组件<h1>
开始使用:
Wubba Lubba Dub Dub!
Wrapping our element is what’s going to allow us to hook into the .
包装元素是使我们能够连接到 。
If we reload our page though, it won’t be doing anything yet. That’s because we haven’t yet configured our animation, so let’s do that!
但是,如果我们重新加载页面,它将不会做任何事情。 那是因为我们还没有配置动画,所以让我们开始吧!
When using the Motion API with our <motion.x>
component, we have two basic concepts we need to use:
将Motion API与<motion.x>
组件一起使用时,我们需要使用两个基本概念:
Each of the animation lifecycle props such as initial
and animate
allow us to define our animation’s name as a variant.
每个动画生命周期道具(例如initial
animate
和animate
允许我们将动画名称定义为一个变体。
Our variants
prop is where we configure those animations by defining variant names along with the animation we’d like them to perform.
我们的variants
道具是通过定义变体名称以及我们希望它们执行的动画来配置这些动画的地方。
So to start, let’s add two lifecycle definitions to our title component by adding two lifecycle props:
首先,让我们通过添加两个生命周期道具,将两个生命周期定义添加到标题组件中:
Wubba Lubba Dub Dub!
Now, we want to define those:
现在,我们要定义这些:
Wubba Lubba Dub Dub!
We’re defining two variants — hidden and visible — which we then reference in the initial
and animate
lifecycle props.
我们定义了两个变体-隐藏的和可见的,然后在initial
和animate
生命周期道具中引用它们。
Now again, reloading the page, it still won’t do anything since we still haven’t defined the animations themselves, so let’s do that:
再一次,重新加载页面,由于我们还没有定义动画本身,它仍然不会做任何事情,所以让我们这样做:
Wubba Lubba Dub Dub!
Here’s what’s going on:
这是怎么回事:
So in the above, what’s actually happening is .4s after the page loads, we’re going to fade in the title and make it look like it’s slightly growing.
因此,在上面,实际发生的是页面加载后的0.4秒,我们将淡入标题,使其看起来略有增长。
And if we save that and reload the page, we can see our title’s effect!
如果保存并重新加载页面,我们可以看到标题的效果!
Now that we have a basic understanding of how to add animations when the page loads, let’s starting adding some interaction.
现在,我们对如何在页面加载时添加动画有了基本的了解,让我们开始添加一些交互。
We’re going to add some hover effects to each character card. That way, when your cursor moves over one of the cards, we’ll trigger our animation.
我们将为每个角色卡添加一些悬停效果。 这样,当您的光标移到其中一张卡片上时,我们将触发动画。
First, inside of our unordered list grid <ul className=“grid”>
, let’s update the list element <li>
to be a <motion.li>
element:
首先,在我们的无序列表网格<ul className=“grid”>
,让我们将列表元素<li>
更新为<motion.li>
元素:
...
If you save and reload the page, you’ll notice that we actually have an issue.
如果您保存并重新加载页面,您会注意到我们实际上存在问题。
Because of the integration between motion and the Next.js CSS integration, our app is getting tripped up on the class name.
由于motion和Next.js CSS集成之间的集成,我们的应用程序在类名上被绊倒了。
While this isn’t fixing it at it’s “core”, we can fix this for our demo by removing the jsx
prop from our top <style>
block where inside, we have our .card
definition.
虽然这不能解决它的“核心”问题,但是我们可以通过从顶部的<style>
块中移除jsx
道具来解决此问题,其中我们在其中拥有.card
定义。
Change:
更改:
To:
至:
Now if we reload our page, we’re back to where we started off.
现在,如果我们重新加载页面,我们将回到开始的地方。
In order to add our hover effect, we’re going to create a new prop on our <motion.li>
component called whileHover
and fill it with some base styles:
为了添加悬停效果,我们将在<motion.li>
组件上创建一个名为whileHover
的新道具,并用一些基本样式填充它:
Above, we’re telling motion that when someone hovers over our element, we want it to grow by scaling it to 1.2 and we want that animation to last .2s.
上面,我们告诉运动,当有人将鼠标悬停在元素上时,我们希望通过将其缩放到1.2来使其增长,并且希望该动画持续0.2s。
And if we reload the page, we can see our animation!
如果重新加载页面,我们可以看到动画!
If you look at the bottom of the effect though, when the card grows, it’s overlapping with the card below it and looks a bit broken. We can fix that by applying some z-indexing and a background color!
但是,如果您查看效果的底部,则当卡片长大时,它与下面的卡片重叠,看起来有点破损。 我们可以通过应用一些z索引和背景色来解决此问题!
And if we reload the page again, we can now see that as our card grows, it appears on top of the card below it!
而且,如果我们再次重新加载页面,现在我们可以看到随着卡片的增加,它会显示在卡片下方的顶部!
Triggering some animations when the page loads and hover effects is cool, but it’s a nice touch when your app can provide graceful transitions between pages. That can be part of what makes it feel more like a “web app” as opposed to a static “website”.
在页面加载和悬停效果时触发一些动画很酷,但是当您的应用可以在页面之间提供优美的过渡时,这是一个很好的选择。 这可能是使其感觉更像是“网络应用程序”而不是静态“网站”的一部分。
To do this, we’ll need to with a wrapper around the root pages of the website. This will allow us to hook into the navigation lifecycle and properly animate our pages.
为此,我们需要在网站的根页面周围使用包装器 。 这将使我们能够进入导航生命周期并正确地为页面设置动画。
Getting started, we need to create a new file under the pages
directory called _app.js
:
开始之前,我们需要在pages
目录下创建一个名为_app.js
的新文件:
// In pages/_app.jsfunction App({ Component, pageProps }) { return ()}export default App;
While we don’t necessarily have to understand the specifics of what’s happening, we’re basically creating a wrapper where we can patch in additional functionality.
虽然我们不必一定要了解发生的事情的细节,但是我们基本上是在创建包装器,在其中可以修补其他功能。
With this new file, if you reload the page, you shouldn’t see any changes yet.
有了这个新文件,如果您重新加载页面,那么您应该不会看到任何更改。
Next, we’re going to add our foundation that allows us to set up our page transitions.
接下来,我们将添加基础,使我们可以设置页面过渡。
First, let’s import motion at the top of our page:
首先,让我们在页面顶部导入动作:
import { motion } from 'framer-motion';
Then, similar to our other animations, let’s create a new <motion.div>
component that wraps around our page.
然后,与其他动画类似,让我们创建一个新的<motion.div>
组件,该组件环绕我们的页面。
Here, we’re setting an initial state with an opacity of 0 and an animate state with an opacity of 1, with the idea that it will fade in.
在这里,我们将设置不透明度为0的初始状态和不透明度为1的动画状态,以使其逐渐消失。
Now if you hit refresh, you’ll notice that the page fades in. But if you click on one of the characters, when the character page loads, it doesn’t fade in.
现在,如果单击刷新,您会注意到页面淡入。但是,如果单击一个字符,则在加载字符页面时,它不会淡入。
The issue is, currently, the motion component doesn’t understand it’s a new route, so we need to force it to recognize that and update.
问题是,当前,运动组件不知道这是一条新路线,因此我们需要强制其识别并更新。
To do this, we’re going to destructure the router
argument in our App props:
为此,我们将在App道具中分解router
参数:
function App({ Component, pageProps, router }) {
And on our motion component, we’re going to use it as a key:
在运动组件上,我们将其用作键:
Now if we reload the page and navigate between our character page and our homepage, you’ll see it’s now fading in the content!
现在,如果我们重新加载页面并在角色页面和主页之间导航,您将看到内容正在逐渐消失!
Now that we’ve got the basics of setting up animations in our app’s lifecycle, we can get more advanced by using .
现在,我们已经拥有在应用程序生命周期中设置动画的基础知识,我们可以通过使用来获得更高级的设置。
The way keyframes work, is when we define an animation, we can set that animation to move through a set of different values for our given property, allowing us to build custom animations to our liking.
关键帧的工作方式是在定义动画时,可以将动画设置为针对给定属性在一组不同的值之间移动,从而使我们可以根据自己的喜好创建自定义动画。
For instance, say we want to make an element on hover grow to 2x the size, make it a little bit smaller to 1.5x the size, and then back up to 2x the size all in one animation sequence. We can do that with keyframes!
例如,假设我们要使一个悬停的元素增长到2倍的大小,使其稍小到1.5倍的大小,然后在一个动画序列中将其全部恢复到2倍的大小。 我们可以使用关键帧做到这一点!
The syntax for that would look like this:
其语法如下所示:
scale: [1, 2, 1.5, 2]
We’re specifying our sequence using an array that says we want our element to start off at it’s normal size at 1x, then the next frame it will grow to 2x, then shrink a little to 1.5x, then finally grow back to 2x.
我们使用一个数组指定序列,该数组表示我们希望元素以其正常大小1x开始,然后下一帧将增长到2x,然后缩小到1.5x,最后再增长回2x。
To test this out, we’re going to make some changes on our hover effect that we’ve already configured for our character cards.
为了验证这一点,我们将对已经为角色卡配置的悬停效果进行一些更改。
In pages/index.js
, update the whileHover
property on our motion list elements to:
在pages/index.js
,将运动列表元素上的whileHover
属性更新为:
We’re specifying 2 sets of keyframes, which are the following:
我们指定了2组关键帧,如下:
And if we reload the page and hover over our elements, we can see our effects in action!
而且,如果我们重新加载页面并将鼠标悬停在元素上,那么我们可以看到效果在起作用!
Without keyframes, we can only do animation effects from a single initial state to another single value. But with our keyframes, we can add more dynamic animations moving around to different values.
没有关键帧,我们只能将动画效果从单个初始状态转换为另一个单个值。 但是有了关键帧,我们可以添加更多动态动画,以移动到不同的值。
To add another layer of fun to this, we can play with other properties that make our animations even more dynamic.
要为此增加更多的乐趣,我们可以使用其他属性使动画更加动态。
To start, we’re going to kick our hover effects up a notch.
首先,我们将悬停效果提高一个档次。
On our pages/index.js
file inside the whileHover
prop of our <motion.li>
card element, let’s add the following property:
在<motion.li>
卡元素的whileHover
内的pages/index.js
文件中,让我们添加以下属性:
filter: [ 'hue-rotate(0)', 'hue-rotate(360deg)', 'hue-rotate(45deg)', 'hue-rotate(0)'],
Here, we’re setting up a new set of keyframes that will “rotate” the hue of the image based on the .
在这里,我们将设置一组新的关键帧,这些关键帧将基于 “旋转”图像的 。
And if we save and reload our page, this gives us a nice little color effect.
而且,如果我们保存并重新加载页面,这将为我们带来很好的色彩效果。
But that’s too subtle enough for me — I want it a little more weird.
但这对我来说太微妙了-我想要它更奇怪。
Let’s update our filter property to the following:
让我们将filter属性更新为以下内容:
filter: [ 'hue-rotate(0) contrast(100%)', 'hue-rotate(360deg) contrast(200%)', 'hue-rotate(45deg) contrast(300%)', 'hue-rotate(0) contrast(100%)'],
Now, not only does the color change, we use the to make the colors more extreme giving us an even stranger effect.
现在,不仅颜色发生了变化,我们还使用了使颜色更加极端,从而给我们带来了更加陌生的效果。
Next, we can do something a bit similar with our page transitions!
接下来,我们可以对页面过渡做一些类似的事情!
To do this, we’re going to use a new part of the Motion component lifecycle — the exit. To do this, we need to make use of Motion’s component which allows us to animate components when they’re removed from the React tree.
为此,我们将使用Motion组件生命周期的新部分-出口。 为此,我们需要使用Motion的组件,当从React树中删除组件时,该组件可以为它们设置动画。
So to start, let’s open up pages/_app.js
and import that component at the top:
首先,让我们打开pages/_app.js
并在顶部导入该组件:
import { motion, AnimatePresence } from 'framer-motion';
Next, we want to wrap our <motion.div>
component with our new AnimatePresence
component:
接下来,我们要用新的AnimatePresence
组件包装<motion.div>
组件:
With our component wrapped, we can now set our new lifecycle prop exit
along with its variant:
包装完组件后,我们现在可以设置新的生命周期道具exit
及其变体:
In the above, we’re:
在上面,我们是:
Configuring a pageExit
variant
配置pageExit
变体
We set out exit
lifecycle prop to pageExit
我们向pageExit
设置了exit
生命周期道具
Inside of our pageExit
variant, we set the background color to white and we add a filter to invert the colors
在pageExit
变体内部,我们将背景色设置为白色,并添加了一个滤镜以反转颜色
Note: it’s important to set the background color to white, otherwise, the invert filter won’t apply to the background.
注意:将背景颜色设置为白色非常重要,否则,反转滤镜将不适用于背景。
And if we save and reload the page, when we navigate to another element, we get our effect!
而且,如果我们保存并重新加载页面,则导航到另一个元素时,我们将获得效果!
If you check out my original demo that I wrote this tutorial based on, I add a feature that makes the results float in by shifting up slightly.
如果您查看了我编写本教程所基于的原始演示,那么我将添加一项功能,使结果略微上移即可浮动结果。
We can do that with the transition property and the setting the on our list elements.
我们可以使用过渡属性以及在列表元素上设置来做到这一点。
Currently the buttons are just static. Add some hover and click effects to the buttons like Load More at the bottom.
当前按钮是静态的。 将鼠标悬停并单击效果到底部的“加载更多”之类的按钮。
This is Rick and Morty after all, make it as weird as you can! But still make sure it’s usable.
毕竟,这是瑞克和莫蒂,让它尽可能古怪! 但是仍然要确保它是可用的。
翻译自:
framer x使用教程
转载地址:http://nyuzd.baihongyu.com/