Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSS动画之transition #185

Open
FrankKai opened this issue Mar 12, 2020 · 0 comments
Open

CSS动画之transition #185

FrankKai opened this issue Mar 12, 2020 · 0 comments
Labels

Comments

@FrankKai
Copy link
Owner

FrankKai commented Mar 12, 2020

css的transition属性其实远远比看起来复杂或者说蕴含着细节。想在工作中更加熟练的运用transition的话,看完这篇博文你就知道了···

  • 不增加transition属性的css属性就不存在”transition“吗?
  • 哪些CSS属性可以被转换呢?
  • 如何定义transitions?
  • transition中断会如何表现?
  • 如何为transition定义多个过渡的动画?
  • transition属性给元素和伪元素使用效果一样吗?
  • transition定义多个属性的动画时,一定要时间相同吗?
  • transiton定义多个动画时如果4个参数都写上过长怎么办?
  • 上一个问题有没有更加简便的写法?
  • 有没有需要注意的触发transition的情况?
  • transition结合javascript实现动画路径效果
  • 可以检测到transition的start和finish吗?

不增加transition属性的css属性就不存在”transition“吗?

CSS transitions是提供了一种通过CSS属性控制动画速度的方式。不同于改变属性立刻生效,你可以在一段时间里去完成变化。 例如,如果你想改变元素的颜色,从白变为黑,通常改变是瞬间的。开启了CSS transitions之后,变化发生的时间间隔遵循一个加速度曲线,所有这些都可以定制。

涉及在两种状态之间转换的动画通常被称作隐式转换(implicit transitions),因为在开始和结束状态之间的状态是浏览器定义的。①

注①:这里的隐式动画可以是普通css属性的改变。

image

CSS transition使你决定动画化哪一个属性。(显式地列举出来),当动画开始时(可以设置delay),转化持续多久(可以设置duration),以及transition如何运行(定义一个时间函数,开始线性或者快速,结束慢。)

哪些CSS属性可以被转换呢?

Web作者可以定义哪个属性动画化,以哪种方式动画化。这也就是说可以制作出复杂的转换。因为transition属性对于某些属性不生效,可动画的属性列表有限集。

这个有限集会所规范变化。
auto的行为是复杂的,在不同浏览器可能有不同表现,不建议设置transition的auto属性。

如何定义transitions?

CSS Transitions由缩写属性transition属性控制。这是配置transition的最好方式,因为这样可以避免不同步的参数,调试css时这可能是非常令人沮丧的。

通过以下的子属性,你能控制transition的独立组件:

注意,这些transition无限循环只对我们的例子有用;CSS transition s只能可视化属性从开始到结束的变化。如果你想可视化一个循环,请查看CSS的animation属性。

transition包含哪些属性:一共只有四个。

  • transition-property
  • transition-duration
  • transition-timing-function
  • transition-delay
transition-property

应用transition到的css属性,列出这些属性的一个name或者多个names。只有在这里列举出的属性可以transition;其他属性的改变还是瞬间的。

transition-duration

transition-duration: 1s
指定transition的持续时间。你可以为素有属性指定一个duration,或者为每个属性指定一个属性。

transition-timing-function

transition-timing-function: ease
transition-timing-function: linear
transition-timing-function: step-end
transition-timing-function: steps(4, end)
指定一个函数去定义如何计算属性的中间值。Timing functions决定了transition计算中间值的过程。大多数timing functions可以通过提供提供相应函数的图形来指定,建议另一一个三次贝塞尔的四个点来定义。这里有一个Easing Functions Cheat Sheet

transition-delay

transition-delay: 0.5s
定义了transition隔多久开始执行动画。

缩写属性transition
div {
     transition: <property> <duration><timing-function><delay>
}
简单例子
<h1 id="delay">This is an about page</h1>

#delay {
  font-size: 14px;
  transition-property: font-size;
  // 经过性能分析工具发现,这里的duration使得动画从start->end和end->start都是4秒
  transition-duration: 4s;
  transition-delay: 2s;
  &:hover {
    font-size: 30px;
  }
}

image

transition中断会如何表现?
给定时间内终止悬浮,观察到动画沿着原来的轨迹返回。当再次悬浮上来时,可以接着上一次继续进行动画直到完成动画。

例如在上面的动画中,悬浮时font-size逐渐增大,突然移开鼠标,font-size增长停止,如果2秒内再悬浮上去,可以继续增大,如果2秒内移开,那么会自动缩小到原始尺寸。

多个属性一起动画的例子

首先想一个问题,如何为transition定义多个过渡的动画?
逗号分隔即可,transition: {foo},{bar}

.box {
    border-style: solid;
    border-width: 1px;
    display: block;
    width: 100px;
    height: 100px;
    background-color: #0000FF;
    transition: width 2s,height 2s,background-color 2s,transform 2s;
}
.box:hover {
  background-color: #ffcccc;
  width: 200px;
  height: 200px;
  transform: rotate(180deg);
}

transition属性给元素和伪元素使用效果一样吗?

不一样。
写在元素内部可以实现过渡效果,中断时贝塞尔曲线缓慢回退,而如果写在伪元素内部的话,伪元素活动终止立即终止动画。
transion属性想要实现平滑过渡效果的话,写在元素内部更好,不要写在伪元素内部。

transition定义多个属性的动画时,一定要时间相同吗?

可以不相同。
时间短的先执行完,时间长的后执行完。
互不影响。

transiton定义多个动画时如果4个参数都写上过长怎么办?

可以拆开写。而且可以仅写一次。
拿上面的例子来说。

.box {
    transition-property: width,height,background-color,transform;
    transition-duration: 2s;
    transition-timing-function: ease-in-out;
    transition-delay: 1s;
}

上面的例子会被解析为:

.box {
    transition-property: width,height,background-color,transform;
    transition-duration: 2s,2s,2s,2s;
    transition-timing-function: ease-in-out,ease-in-out,ease-in-out,ease-in-out;
    transition-delay: 1s,1s,1s,1s;
}

上一个问题有没有更加简便的写法?

.box {
    transition: all 2s ease-in-out 1s;
}

如果说所有属性都要增加过渡效果,可以使用all去指代。
但其实如果不是所有属性都加transition动画,部分加也可以使用all,因为只有发生变化的属性才会触发transition动画。

如果所有属性的缓动动画效果要同步,用all是最简洁快捷的。

有没有需要注意的触发transition的情况?

  • 使用appendChild()新增DOM
  • 移除元素的display:none属性

做了上面的事情以后,如果想修改css属性值,触发css属性的transition的话,最好加一个几毫秒的setTimeout 。留几毫秒后再修改,是为了确保DOM的css属性被渲染到CSS树上,从而做到过渡。
否则,其初始状态和结束状态是一样的,因为如果不延时执行的话,状态直接被修改为final状态。

transition结合javascript实现动画路径效果

<template>
    <div id="foo"></div>
</template>

<script>
export default {
  mounted() {
    const f = document.getElementById("foo");
    document.addEventListener(
      "click",
      function(ev) {
        console.log(ev.clientX, ev.clientY);
        f.style.transform = "translateY(" + (ev.clientY - 25) + "px)";
        f.style.transform += "translateX(" + (ev.clientX - 25) + "px)";
      },
      false
    );
  }
};
</script>

<style lang="scss" scoped>
#foo {
  border-radius: 50px;
  width: 50px;
  height: 50px;
  background: #c00;
  position: absolute;
  top: 0;
  left: 0;
  transition: transform 1s; // 这一行代码可以实现小球动画轨迹,一种过渡效果
}
</style>

可以检测到transition的start和finish吗?

可以为发生transition的元素增加事件。

  • transitionrun 开始运行transition,在delay的时间前运行
  • transitionstart 在delay的时间后运行transition
  • transitionend 结束transition
el.addEventListener('transitionrun', (event)=>{
    // event.propertyName 发生transition的css属性名
    // event.elapsedTime transition动画发生的时长
}, true);

如果transition在完成前取消的话,transitionend事件不会触发。因为display既没有变为none,动画的属性也没有发生改变。

参考资料:Using CSS transitions

@FrankKai FrankKai added the CSS label Mar 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant