精华内容
下载资源
问答
  • Android群英传知识点回顾——第七章:Android动画机制与使用技巧知识点目录 7.1 Android View动画框架 7.1.1 透明度动画 7.1.2 旋转动画 7.1.3 位移动画 7.1.4 缩放动画 7.1.5 动画集合 7.2 Android属性...

    Android群英传知识点回顾——第七章:Android动画机制与使用技巧


    知识点目录

    • 7.1 Android View动画框架
      • 7.1.1 透明度动画
      • 7.1.2 旋转动画
      • 7.1.3 位移动画
      • 7.1.4 缩放动画
      • 7.1.5 动画集合
    • 7.2 Android属性动画分析
      • 7.2.1 ObjectAnimator
      • 7.2.2 PropertyValuesHolder
      • 7.2.3 ValueAnimator
      • 7.2.4 动画事件的监听
      • 7.2.5 AnimatorSet
      • 7.2.6 在XML中使用属性动画
      • 7.2.7 View的animate方法
    • 7.3 Android布局动画
    • 7.4 Interpolators
    • 7.5 自定义动画
    • 7.6 Android5.X SVG矢量动画机制
      • 7.6.1 <path>标签
      • 7.6.2 SVG常用指令
      • 7.6.3 SVG编辑器
      • 7.6.4 Android中使用SVG
      • 7.6.5 SVG动画实例
    • 7.7 Android动画特效
      • 7.7.1 灵动菜单
      • 7.7.2 计时器动画
      • 7.7.3 下拉展开动画

    知识点回顾

    这篇知识点不多,也容易理解,只是经典代码回顾案例比较多,所以整章篇幅偏长,不过经典代码回顾的案例很nice,建议大家多多实践经典代码回顾

    7.1 Android View动画框架

    Android 动画分为:

    • View动画:又称视图动画、又称补间动画、又称Tween动画(常用)
    • 属性动画:通过改变属性值产生动画

    View动画中定义了透明度、旋转、缩放和位移动画,其实现原理是:

    每次绘制视图时View所在的ViewGroup中的drawChild函数获取该View的Animation的Transformation值,然后调用canvas.concat(transformToApply.getMatrix()),通过矩阵运算完成动画帧

    7.1.1 透明度动画

    AlphaAnimation aa = new AlphaAnimation(0,1);
    aa.setDuration(1000);
    view.startAnimation(aa);

    7.1.2 旋转动画

    RotateAnimation ra = new RotateAnimation(0,360,100,100);
    ra.setDuration(1000);
    view.startAnimation(ra);

    其参数分别为旋转起始角度和旋转中心点的坐标,下面以自身中心点设置旋转动画:

    RotateAnimation ra = new RotateAnimation(0,360,RotateAnimation.RELATIVE_TO_SELF,0.5F,RotateAnimation.RELATIVE_TO_SELF,0.5F);

    7.1.3 位移动画

    TranslateAnimation ta = new TranslateAnimation(0,200,0,300);
    ta.setDuration(1000);
    view.startAnimation(ta);

    7.1.4 缩放动画

    ScaleAnimation sa = new ScaleAnimation(0,2,0,2);
    sa.setDuration(1000);
    view.startAnimation(sa);

    与旋转动画一样,缩放动画也可以设置缩放的中心点,这里以自身中心设置缩放动画:

    ScaleAnimation sa = new ScaleAnimation(0,1,0,1,RotateAnimation.RELATIVE_TO_SELF,0.5F,RotateAnimation.RELATIVE_TO_SELF,0.5F);
    sa.setDuration(1000);
    view.startAnimation(sa);

    7.1.5 动画集合

    通过AnimationSet,将动画组合起来:

    AnimationSet as = new AnimationSet(true);
    as.setDuration(1000);
    
    AlphaAnimation aa = new AlphaAnimation(0,1);
    aa.setDuration(1000);
    as.addAnimation(aa);
    
    TranslateAnimation ta = new TranslateAnimation(0,200,0,300);
    ta.setDuration(1000);
    as.addAnimation(ta);
    
    view.startAnimation(as);

    系统还提供了View动画的监听回调:

    
    animation.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
        }
    
        @Override
        public void onAnimationEnd(Animation animation) {
        }
    
        @Override
        public void onAnimationRepeat(Animation animation) {
        }
    });

    通过监听回调,可以获得到动画的开始、结束和重复事件

    7.2 Android属性动画分析

    • 在Animator框架中使用最多的就是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator进行更精细化的控制,只控制一个对象的一个属性,而使用多个ObjectAnimator组合到AnimatorSet形成一个动画
    • 属性动画通过调用属性的get、set方法来真实地控制了一个View的属性值

    7.2.1 ObjectAnimator

    • 创建一个ObjectAnimator只需通过他的静态工厂直接返回一个ObjectAnimator对象
    • 参数包括一个对象和对象的属性名字,这个属性必须有get和set函数,内部会通过Java反射机制来调用set函数修改对象属性值
    • 调用setInterpolator来设置相应的插值器
    • 旧版本的动画所产生的动画,并不能改变事件响应的位置,知识单纯地改变了显示
    ObjectAnimator animator = ObjectAnimator.ofFloat(view,"translationX",300);
    animator.setDuration(300);
    animator.start();

    参数介绍:

    • 第一个参数:被操作的View
    • 第二个参数:要操作的属性
    • 第三个参数:可变数组,需要传递去该属性变化的一个取值过程

    在使用ObjectAnimator特别重要的是操纵的属性必须具有get、set方法,不然ObjectAnimator就无法起效,下面介绍一些常用可以直接使用的属性:

    • translationX和translationY:作为一种增量来控制着View对象从它布局容器的左上角坐标偏移的位置
    • rotation、rotationX和rotationY:控制View对象围绕支点进行2D和3D旋转
    • scaleX和scaleY:控制View对象围绕它的支点进行2D缩放
    • pivotX和pivotY:控制View对象的支点位置,围绕这个支点进行旋转和缩放变换处理,默认情况下,该支点的位置就是View对象的中心点
    • x和y:它描述了View对象在它的容器中的最终位置,它是最初的左上角坐标和 translationX和 translationY值的累计和
    • alpha:它表示View对象的alpha透明度,默认值是1(不透明),0代表完全透明(不可见)

    如果属性中没有get、set方法,可以通过下面方法来实现:

    • 通过自定义一个属性或者包装类,间接地给这个属性添加get、set方法
    • 通过ValueAnimator实现

    这里以自定义一个属性增加get、set方法为例:

    private static class WrapperView {
    
        private View mTarget;
    
        public WrapperView(View target) {
            mTarget = target;
        }
    
        public int getWidth() {
            return mTarget.getLayoutParams().width;
        }
    
        public void setWidth(int width) {
            mTarget.getLayoutParams().width = width;
            mTarget.requestLayout();
        }
    }

    通过代码使用:

    WrapperView wrapper = new WrapperView(mButton);
    ObjectAnimator.ofInt(wrapper ,"width",500).setDuration(5000).start();

    7.2.2 PropertyValuesHolder

    类似View动画中的AnimationSet,可以实现多个属性动画的组合:

    PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("translationX",300f);
    PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("scaleX",1f,0,1f);
    PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("scaleY",1f,0,1f);
    ObjectAnimator.ofPropertyValuesHolder(view,pvh1,pvh2,pvh3).setDuration(1000).start();        

    7.2.3 ValueAnimator

    • ObjectAnimator继承自ValueAnimator
    • ValueAnimator本身不提供任何动画效果,它更像一个数值发生器,用来产生具有一定规律的数字,从而让调用者来控制动画的实现过程,通过AnimatorUpdateListener监听数值的变换:
    ValueAnimator animator = ValueAnimator.ofFloat(0,100);
    animator.setTarget(view);
    animator.setDuration(1000).start();
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            float value = (float) animation.getAnimatedValue();
            //TODO use the value
        }
    });

    7.2.4 动画事件的监听

    系统还提供了属性动画的监听回调:

    ObjectAnimator anim = ObjectAnimator.ofFloat(view,"alpha",0.5f);
    anim.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
    
        }
    
        @Override
        public void onAnimationEnd(Animator animation) {
    
        }
    
        @Override
        public void onAnimationCancel(Animator animation) {
    
        }
    
        @Override
        public void onAnimationRepeat(Animator animation) {
    
        }
    });

    当然,系统还提供了一个可选择性的监听事件,选择需要的事件监听:

    anim.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
    
        }
    });

    7.2.5 AnimatorSet

    AnimatorSet功能和PropertyValuesHolder和AnimationSet是一样的效果,只不过针对不同的动画

    ObjectAnimator animator1 = ObjectAnimator.ofFloat(view, "translationX", 300f);
    ObjectAnimator animator2 = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0, 1f);
    ObjectAnimator animator3 = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0, 1f);
    AnimatorSet set = new AnimatorSet();
    set.setDuration(1000);
    set.playTogether(animator1,animator2,animator3);
    set.start();

    AnimatorSet不仅仅通过playTogether(),还有其他方法控制多个效果的协同工作:playSequentially()、animSet.play().with()、before()、after()

    7.2.6 在XML中使用属性动画

    属性动画同视图动画一样,也可以在XML文件中编写:

    <?xml version="1.0" encoding="utf-8"?>
    <objectAnimator       
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:propertyName="scaleX"
        android:valueFrom="1.0"
        android:valueTo="2.0"
        android:valueType="floatType">
    </objectAnimator>

    在程序中使用也很简单:

    private void scaleX(View view){
        Animator anim = AnimatorInflater.loadAnimator(this,R.animator.scaleX);
        anim.setTarget(mMv);
        anim.start();
    }

    7.2.7 View的animate方法

    Google给View增加了animate方法来直接驱动属性动画:

    animate.animate().alpha(0).y(300).setDuration(300).withStartAction(new Runnable() {
        @Override
        public void run() {
    
        }
    }).withEndAction(new Runnable() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
    
                }
            });
        }
    }).start();

    7.3 Android布局动画

    所谓布局动画指的是作用在ViewGroup上,给ViewGroup增加View时添加一个动画过度效果

    最简单的布局动画在ViewGroup的XML中,系统默认的也是无法替换的:

    android:animateLayoutChanges="true"

    还可以通过LayoutAnimationController类实现自定义子View的过渡效果:

    LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
    //设置过渡动画
    ScaleAnimation sa = new ScaleAnimation(0, 1, 0, 1);
    sa.setDuration(2000);
    //设置布局动画的显示属性
    LayoutAnimationController lac = new LayoutAnimationController(sa, 0.5F);
    lc.setOrder(LayoutAnimationController.ORDER_NORMAL);
    //为ViewGroup设置布局动画
    ll.setLayoutAnimation(lac);

    LayoutAnimationController 第一个参数是需要的动画,第二个参数是每个子View显示的delay时间,若时间不为0,还可以setOrder设置子View的显示顺序:

    • LayoutAnimationController.ORDER_NORMAL:顺序
    • LayoutAnimationController.ORDER_RANDOM:随机
    • LayoutAnimationController.ORDER_REVEESE:反序

    7.4 Interpolators(插值器)

    插值器是一个可以控制动画变换速率的一个属性值,有点类似于物理的中的加速度,常见的插值器有:

    • LinearInterpolator:线性插值器,匀速运动
    • AccelerateDecelerateInterpolator:加速减速插值器,动画两头慢中间快
    • DecelerateInterpolator:减速插值器,动画越来越慢
    • BounceInterpolator:弹跳插值器,动画结束时有个弹跳效果

    7.5 自定义动画

    • 需要实现它的applyTransformation的逻辑
    • 需要覆盖父类的initalize方法实现一些初始化工作
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        super.applyTransformation(interpolatedTime, t);
    }
    • 第一个参数是插值器的时间因子,由动画当前完成的百分比和当前时间所对应的插值所计算得来的,取值范围为0到1.0
    • 第二个参数是矩阵封装类,一般使用该类获取矩阵对象
    final Matrix matrix = t.getMatrix();

    通过对matrix的变换操作就可以实现动画效果,我们以模拟电视机关闭的效果为例:

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        final Matrix matrix = t.getMatrix();
        matrix.preScale(1, 1 - interpolatedTime, mCenterwidth,mCenterheight);
        super.applyTransformation(interpolatedTime, t);
    }

    android.graphics.Camera中的Camera类,它封装了openGL的3D动画,从而可以风场方便地创建3D动画效果,只要移动Camera就能拍摄到具有立体感的图像:

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        //设置默认时长
        setDuration(2000);
        //设置动画结束后保留状态
        setFillAfter(true);
        //设置默认插值器
        setInterpolator(new BounceInterpolator());
        mCenterWidth = width / 2;
        mCenterHeight = height / 2;
    }
    
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        final Matrix matrix = t.getMatrix();
        mCamera.save();
        //使用Camera设置旋转的角度
        mCamera.rotateY(mRotateY * interpolatedTime);
        //将旋转变换作用到matrix上
        mCamera.getMatrix(matrix);
        mCamera.restore();
        //通过pre方法设置矩形作用前的偏移量来改变旋转中心
        matrix.preTranslate(mCenterWidth, mCenterHeight);
        matrix.postTranslate(-mCenterWidth, -mCenterHeight);
    }

    点击后开始动画,这样一个Button会在设置的时长内,使用相应的插值器来完成动画:

    7.6 Android5.X SVG矢量动画机制

    什么是SVG:

    • 可伸缩矢量图形(Scalable Vector Graphics)
    • 定义用于网络的基于矢量的图形
    • 使用XML格式定义图形
    • 图片在放大或改变尺寸的情况下其图形质量不会有所损失
    • 万维网联盟的标准
    • 与诸多DOM和XSL之类的W3C标准是一个整体

    Android5.X之后添加了对SVG的<path>标签的支持,其优点是:

    • 放大不会失真
    • bitmap需要为不同分辨率设计多套图标,而矢量图则不需要

    7.6.1 <path>标签

    使用<path>标签有以下指令:

    • M = moveto(M X,Y):将画笔移动到指定的坐标位置,但未发生绘制
    • L = lineto(L X,Y):画直线到指定的坐标位置
    • H = horizontal lineto( H X):画水平线到指定的X坐标位置
    • V = vertical lineto(V Y ):画垂直线到指定的Y坐标
    • C = curveto(C ,X1,Y1,X2,Y2,ENDX,ENDY):三次贝塞尔曲线
    • S = smooth curveto(S X2,Y2,ENDX,ENDY):三次贝塞尔曲线
    • Q = quadratic Belzier curve(Q X Y,ENDX,ENDY):二次贝塞尔曲线
    • T = smooth quadratic Belzier curvrto(T,ENDX,ENDY):映射前面路径的终点
    • A = elliptical Are(A RX,RY,XROTATION,FLAG1FLAG2,X,Y):弧线
    • Z = closepath():关闭路径

    使用上面指令时,需要注意以下几点:

    • 坐标轴以(0,0)位中心,X轴水平向右,Y轴水平向下
    • 所有指令大小写均可,大写绝对定位,参照全局坐标系,小写相对定位,参照父容器坐标系
    • 指令和数据间的空格可以无视
    • 同一指令出现多次可以只用一个

    7.6.2 SVG常用指令

    • L
      绘制直线的指令是“L”,代表从当前点绘制直线到给定点,“L”之后的参数是一个点坐标,同时,还可以使用“H”和“V”指令来绘制水平、竖直线,后面的参数是x坐标或y坐标
    • M
      M指令类似Android绘图中的path类moveto方法,即代表画笔移动到某一点,但并不发生绘图动作
    • A
      A指令是用来绘制一条弧线,且允许弧线不闭合,可以把A指令绘制的弧度想象成椭圆的某一段,A指令一下有七个参数
      • RX,RY:所在的椭圆的半轴大小
      • XROTATION:椭圆的X轴与水平方向顺时针方向的夹角,可以想象成一个水平的椭圆饶中心点顺时针旋转XROTATION 的角度
      • FLAG1:只有两个值,1表示大角度弧度,0为小角度弧度
      • FLAG2:只有两个值,确定从起点到终点的方向1顺时针,0逆时针
      • X,Y轴:终点坐标

    7.6.3 SVG编辑器

    7.6.4 Android中使用SVG

    Android5.X提供了两个API来支持SVG:

    • VectorDrawable:在XML中可以创建一个静态的SVG图形
    • AnimatedVectorDrawable:给VectorDrawable提供动画效果

    VectorDrawable的使用是通过<vector>标签来声明的:

    <?xml version="1.0" encoding="utf-8"?>
    <vector 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="200dp"
        android:height="200dp"
        android:viewportHeight="100dp"
        android:viewportWidth="100dp">
    </vector>

    如果做过Web的应该对viewport应该很熟悉

    • height:表示SVG的高度200dp
    • width:表示SVG的宽度200dp
    • viewportHeight:表示SVG图形被划分成100份
    • viewportWidth:表示SVG图形被划分成100份
    • 如果在绘图中使用坐标(50,50),则意味着该坐标为正中间

    接下来,给<vector>标签增加显示path:

    <?xml version="1.0" encoding="utf-8"?>
    <vector    
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="200dp"
        android:height="200dp"
        android:viewportHeight="100dp"
        android:viewportWidth="100dp">
        <group
            android:name="test"
            android:rotation="0">
            <path
                android:fillColor="@android:color/holo_blue_light"
                android:pathData="
                    M 25 50 
                    a 25,25 0 1,0 50,0" />
        </group>
    </vector>

    然后就可以在布局文件中直接使用:

    <ImageView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:src="@drawable/vector" />

    效果图:这是一个填充的图形,因为我们用的是fillColor

    如果要绘制一个非填充的图形,使用下面的代码:

    <path
        android:pathData="
            M 25 50
            a 25,25 0 1,0 50,0"
        android:strokeColor="@android:color/holo_blue_light"
        android:strokeWidth="2"
       />

    效果图:

    AnimatedVectorDrawable使用:Google工程师将其比喻为一个胶水,通过其连接静态的VectorDrawable和动态的objectAnimator

    首先在XML文件中通过<animated-vector>标签来声明对AnimatedVectorDrawable的使用:

    <animated-vector
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:drawable="@drawable/vector">
        <target
            android:name="test"
            android:animation="@anim/anim_earth" />
    </animated-vector>

    特别注意的是:这个target里面的name要和VectorDrawable的name对应,animation要和动画资源文件对应

    对应的VectorDrawable文件:

    <vector 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="200dp"
        android:height="200dp"
        android:viewportHeight="100"
        android:viewportWidth="100">
        <group
            android:name="test"
            android:rotation="0">
            <path
                android:pathData="
                    M 25 50
                    a 25,25 0 1,0 50,0"
                android:strokeColor="@android:color/holo_blue_light"
                android:strokeWidth="2"
               />
        </group>
    </vector>

    对应的animation文件:

    <objectAnimator     
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="4000"
        android:propertyName="rotation"
        android:valueFrom="0"
        android:valueTo="360" />

    特别注意的是:在<group>标签和<path>标签中添加了rotate、fillColor、pathData等属性,那么可以通过objectAnimator指定android:propertyName=”XXXX”属性来控制哪一种属性,如果指定属性为pathData,那么需要添加一个属性——android:valueType=”pathType”来告诉系统进行pathData的变换

    在布局文件中使用:

    <ImageView
        android:id="@+id/image"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/anim_vector" />

    在Activity中开启动画:

    ImageView image = (ImageView) findViewById(R.id.image);
    ((Animatable)image.getDrawable()).start();

    效果图

    7.6.5 SVG动画实例

    • 线图动画……见经典代码回顾案例一
    • 模拟三球仪……见经典代码回顾案例二
    • 轨迹动画……见经典代码回顾案例三

    7.7 Android动画特效

    • 灵动菜单……见经典代码回顾案例四
    • 计时器动画……见经典代码回顾案例五
    • 下拉展开动画……见经典代码回顾案例六

    经典代码回顾

    案例一:线图动画

    定义我们的VectorDrawable

    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="200dp"
        android:height="200dp"
        android:viewportHeight="100"
        android:viewportWidth="100">
        <group>
            <path
                android:name="path1"
                android:pathData="
                M 20,80
                L 50,80 80,80"
                android:strokeColor="@android:color/holo_green_dark"
                android:strokeLineCap="round"
                android:strokeWidth="5" />
    
            <path
                android:name="path2"
                android:pathData="
                M 20,20
                L 50,20 80,20"
                android:strokeColor="@android:color/holo_green_dark"
                android:strokeLineCap="round"
                android:strokeWidth="5" />
        </group>
    </vector>

    定义两个Path的objectAnimator,从path1到path2

    <objectAnimator
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="5000"
        android:interpolator="@android:anim/bounce_interpolator"
        android:propertyName="pathData"
        android:valueFrom="
                M 20,80
                L 50,80 80,80"
        android:valueTo="
                M 20,80
                L 50,50 80,80"
        android:valueType="pathType" />
    
    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="5000"
        android:interpolator="@android:anim/bounce_interpolator"
        android:propertyName="pathData"
        android:valueFrom="
                M 20,20
                L 50,20 80,20"
        android:valueTo="
                M 20,20
                L 50,50 80,20"
        android:valueType="pathType" />

    定义AnimatedVectorDrawable连接VectorDrawable和objectAnimator

    <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:drawable="@drawable/trick">
        <target
            android:name="path1"
            android:animation="@anim/anim_path1" />
        <target
            android:name="path2"
            android:animation="@anim/anim_path2" />
    </animated-vector>

    布局文件中使用这个AnimatedVectorDrawable

    <ImageView
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:src="@drawable/trick_anim"
         android:id="@+id/image"/>

    代码中启动动画

    ImageView image = (ImageView) findViewById(R.id.image);
    Drawable drawable = image.getDrawable();
    if (drawable instanceof Animatable) {
        ((Animatable) drawable).start();
    }

    效果图:为了大家方便观看,我把持续时间被我调成了5s


    案例二:模拟三球仪

    定义我们的VectorDrawable

    <?xml version="1.0" encoding="utf-8"?>
    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="200dp"
        android:height="200dp"
        android:viewportHeight="100"
        android:viewportWidth="100">
        <group
            android:name="sun"
            android:pivotX="60"
            android:pivotY="50"
            android:rotation="0">
    
            <path
                android:name="path_sun"
                android:fillColor="@android:color/holo_blue_light"
                android:pathData="
                    M 50,50
                    a 10,10 0 1,0 20,0
                    a 10,10 0 1,0 -20,0" />
    
            <group
                android:name="earth"
                android:pivotX="75"
                android:pivotY="50"
                android:rotation="0">
    
                <path
                    android:name="path_earth"
                    android:fillColor="@android:color/holo_orange_dark"
                    android:pathData="
                        M 70,50
                        a 5,5 0 1,0 10,0
                        a 5,5 0 1,0 -10,0" />
    
                <group>
                    <path
                        android:fillColor="@android:color/holo_green_dark"
                        android:pathData="
                            M 90,50
                            m -5 0
                            a 4,4 0 1,0 8 0
                            a 4,4 0 1,0 -8,0" />
                </group>
            </group>
        </group>
    </vector>

    定义两个objectAnimator,代码都是一样的

    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="4000"
        android:propertyName="rotation"
        android:valueFrom="0"
        android:valueTo="360" />
    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="4000"
        android:propertyName="rotation"
        android:valueFrom="0"
        android:valueTo="360" />

    定义AnimatedVectorDrawable连接VectorDrawable和objectAnimator

    <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:drawable="@drawable/earth_moon_system">
        <target
            android:name="sun"
            android:animation="@anim/anim_sun" />
        <target
            android:name="earth"
            android:animation="@anim/anim_earth" />
    </animated-vector>

    布局文件中使用这个AnimatedVectorDrawable

    <ImageView
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/sun_system" />

    代码中启动动画

    ImageView image = (ImageView) findViewById(R.id.image);
    Drawable drawable = image.getDrawable();
    if (drawable instanceof Animatable) {
        ((Animatable) drawable).start();
    }

    效果图


    案例三:轨迹动画

    定义我们的VectorDrawable

    <?xml version="1.0" encoding="utf-8"?>
    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="160dp"
        android:height="30dp"
        android:viewportHeight="30"
        android:viewportWidth="160">
    
        <path
            android:name="search"
            android:pathData="M141 , 17 A9 ,9 0 1 , 1 ,142 , 16 L149 ,23"
            android:strokeAlpha="0.8"
            android:strokeColor="#ff3570be"
            android:strokeLineCap="square"
            android:strokeWidth="2" />
    
        <path
            android:name="bar"
            android:pathData="M0,23 L149 ,23"
            android:strokeAlpha="0.8"
            android:strokeColor="#ff3570be"
            android:strokeLineCap="square"
            android:strokeWidth="2"
            />
    </vector>

    定义两个objectAnimator,代码都是一样的

    <?xml version="1.0" encoding="utf-8"?>
    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:propertyName="trimPathStart"
        android:valueFrom="0"
        android:valueTo="1"
        android:valueType="floatType" />
    

    定义AnimatedVectorDrawable连接VectorDrawable和objectAnimator

    <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:drawable="@drawable/searchbar">
        <target
            android:name="search"
            android:animation="@anim/anim_searchbar" />
    </animated-vector>

    布局文件中使用这个AnimatedVectorDrawable

    <ImageView
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/search_anim" />

    代码中启动动画

    ImageView image = (ImageView) findViewById(R.id.image);
    Drawable drawable = image.getDrawable();
    if (drawable instanceof Animatable) {
        ((Animatable) drawable).start();
    }

    效果图


    案例四:灵动菜单

    布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/imageView_b"
            android:src="@drawable/b"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true" />
    
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/imageView_c"
            android:src="@drawable/c"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true" />
    
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/imageView_d"
            android:src="@drawable/d"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true" />
    
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/imageView_e"
            android:src="@drawable/e"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true" />
    
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/imageView_a"
            android:src="@drawable/a"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true" />
    
    </RelativeLayout>

    Activity文件

    public class PropertyTest extends Activity implements View.OnClickListener {
    
        private int[] mRes = {R.id.imageView_a, R.id.imageView_b, R.id.imageView_c,
                R.id.imageView_d, R.id.imageView_e};
        private List<ImageView> mImageViews = new ArrayList<ImageView>();
        private boolean mFlag = true;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.property);
            for (int i = 0; i < mRes.length; i++) {
                ImageView imageView = (ImageView) findViewById(mRes[i]);
                imageView.setOnClickListener(this);
                mImageViews.add(imageView);
            }
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.imageView_a:
                    if (mFlag) {
                        startAnim();
                    } else {
                        closeAnim();
                    }
                    break;
                default:
                    Toast.makeText(PropertyTest.this, "" + v.getId(),
                            Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    
        private void closeAnim() {
            ObjectAnimator animator0 = ObjectAnimator.ofFloat(mImageViews.get(0),
                    "alpha", 0.5F, 1F);
            ObjectAnimator animator1 = ObjectAnimator.ofFloat(mImageViews.get(1),
                    "translationY", 200F, 0);
            ObjectAnimator animator2 = ObjectAnimator.ofFloat(mImageViews.get(2),
                    "translationX", 200F, 0);
            ObjectAnimator animator3 = ObjectAnimator.ofFloat(mImageViews.get(3),
                    "translationY", -200F, 0);
            ObjectAnimator animator4 = ObjectAnimator.ofFloat(mImageViews.get(4),
                    "translationX", -200F, 0);
            AnimatorSet set = new AnimatorSet();
            set.setDuration(500);
            set.setInterpolator(new BounceInterpolator());
            set.playTogether(animator0, animator1, animator2, animator3, animator4);
            set.start();
            mFlag = true;
        }
    
        private void startAnim() {
            ObjectAnimator animator0 = ObjectAnimator.ofFloat(
                    mImageViews.get(0),
                    "alpha",
                    1F,
                    0.5F);
            ObjectAnimator animator1 = ObjectAnimator.ofFloat(
                    mImageViews.get(1),
                    "translationY",
                    200F);
            ObjectAnimator animator2 = ObjectAnimator.ofFloat(
                    mImageViews.get(2),
                    "translationX",
                    200F);
            ObjectAnimator animator3 = ObjectAnimator.ofFloat(
                    mImageViews.get(3),
                    "translationY",
                    -200F);
            ObjectAnimator animator4 = ObjectAnimator.ofFloat(
                    mImageViews.get(4),
                    "translationX",
                    -200F);
            AnimatorSet set = new AnimatorSet();
            set.setDuration(500);
            set.setInterpolator(new BounceInterpolator());
            set.playTogether(
                    animator0,
                    animator1,
                    animator2,
                    animator3,
                    animator4);
            set.start();
            mFlag = false;
        }
    }

    效果图


    案例五:计时器动画

    布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Click Me"
            android:textSize="60sp"
            android:onClick="tvTimer"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true" />
    </RelativeLayout>

    Activity文件

    public class TimerTest extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.timer);
        }
    
        public void tvTimer(final View view) {
            ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 100);
            valueAnimator.addUpdateListener(
                    new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    ((TextView) view).setText("$ " +
                            (Integer) animation.getAnimatedValue());
                }
            });
            valueAnimator.setDuration(3000);
            valueAnimator.start();
        }
    }

    效果图


    案例六:下拉展开动画

    布局文件

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:onClick="llClick"
            android:background="@android:color/holo_blue_bright"
            android:orientation="horizontal">
    
            <ImageView
                android:id="@+id/app_icon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:src="@mipmap/ic_launcher" />
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:gravity="left"
                android:text="Click Me"
                android:textSize="30sp" />
        </LinearLayout>
    
        <LinearLayout
            android:id="@+id/hidden_view"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:background="@android:color/holo_orange_light"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:visibility="gone">
    
            <ImageView
                android:src="@mipmap/ic_launcher"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center" />
    
            <TextView
                android:id="@+id/tv_hidden"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="center"
                android:textSize="20sp"
                android:text="I am hidden" />
        </LinearLayout>
    </LinearLayout>

    Activity文件

    public class DropTest extends Activity {
    
        private LinearLayout mHiddenView;
        private float mDensity;
        private int mHiddenViewMeasuredHeight;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.drop);
            mHiddenView = (LinearLayout) findViewById(R.id.hidden_view);
            // 获取像素密度
            mDensity = getResources().getDisplayMetrics().density;
            // 获取布局的高度
            mHiddenViewMeasuredHeight = (int) (mDensity * 40 + 0.5);
        }
    
        public void llClick(View view) {
            if (mHiddenView.getVisibility() == View.GONE) {
                // 打开动画
                animateOpen(mHiddenView);
            } else {
                // 关闭动画
                animateClose(mHiddenView);
            }
        }
    
        private void animateOpen(final View view) {
            view.setVisibility(View.VISIBLE);
            ValueAnimator animator = createDropAnimator(
                    view,
                    0,
                    mHiddenViewMeasuredHeight);
            animator.start();
        }
    
        private void animateClose(final View view) {
            int origHeight = view.getHeight();
            ValueAnimator animator = createDropAnimator(view, origHeight, 0);
            animator.addListener(new AnimatorListenerAdapter() {
                public void onAnimationEnd(Animator animation) {
                    view.setVisibility(View.GONE);
                }
            });
            animator.start();
        }
    
        private ValueAnimator createDropAnimator(
                final View view, int start, int end) {
            ValueAnimator animator = ValueAnimator.ofInt(start, end);
            animator.addUpdateListener(
                    new ValueAnimator.AnimatorUpdateListener() {
    
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    int value = (Integer) valueAnimator.getAnimatedValue();
                    ViewGroup.LayoutParams layoutParams =
                            view.getLayoutParams();
                    layoutParams.height = value;
                    view.setLayoutParams(layoutParams);
                }
            });
            return animator;
        }
    }

    效果图

    经典回顾源码下载

    github:https://github.com/CSDNHensen/QunYingZhuang

    展开全文
  • 定义动画关键帧方案 @keyframe 动画名{ 0%(from){ 样式 } 100%(to){ 样式 }}设置动画名称(关键帧)animation-name:动画名;动画播放时间animation-duration: 2s;动画播放完成后的停止位置 默认是backwards:播放...
    定义动画关键帧方案
    @keyframe 动画名{
    0%(from){
    样式
    }
    100%(to){
    样式
    }
    }
     
    设置动画名称(关键帧)
    animation-name:动画名;
    动画播放时间
    animation-duration: 2s;
    动画播放完成后的停止位置
    默认是backwards:播放完成后回到第一个关键帧样式
    forwards:播放完成后回到最后一个关键帧样式
    animation-fill-mode:forwards;
    动画关键帧执行方向
    指动画方案 0%-100% normal
    100%往0% reverse
    0%-100%-0% alternate(至少要播放2次,否则无法实现)
    animation-direction:alternate;
    动画播放次数 infinite 表示无限次数
    animation-iteration-count:infinite;
    动画延时
    animation-delay: 3s;
    动画的播放控制 播放running(默认值) 暂停:paused;
    animation-play-state: paused;
    多个动画样式的设置
    例如:animation:move 2s 1 linear,rotate 2s 2s 1 linear;
     
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
    	<meta charset="UTF-8">
    	<title>轮播图</title>
    	<style media="screen">
    	@-webkit-keyframes mov1{
    		0%{
    			transform: translateX(0);
    		}
    		20%{
    			transform: translateX(0);
    		}
    		25%{
    			transform: translateX(-800px);
    		}
    		45%{
    			transform: translateX(-800px);
    		}
    		50%{
    			transform: translateX(-1600px);
    		}
    		70%{
    			transform: translateX(-1600px);
    		}
    		75%{
    			transform: translateX(-2400px);
    		}
    		95%{
    			transform: translateX(-2400px);
    		}
    		100%{
    			transform: translateX(-3200px);
    		}
    	}
    	@-webkit-keyframes mov2{
    		0%{
    			transform: translateY(0);
    		}
    		20%{
    			transform: translateY(0);
    		}
    		25%{
    			transform: translateY(-40px);
    		}
    		45%{
    			transform:translateY(-40px);
    		}
    		50%{
    			transform: translateY(-80px);
    		}
    		70%{
    			transform: translateY(-80px);
    		}
    		75%{
    			transform: translateY(-120px);
    		}
    		95%{
    			transform: translateY(-120px);
    		}
    		100%{
    			transform: translateY(-160px);
    		}
    	}
    	@-webkit-keyframes span1{
    		0%{
    			background: white;
    		}
    		24%{
    			background: white;
    		}
    		25%{
    			background: gray;
    		}
    		100%{
    			background: gray;
    		}
    	}
    	@-webkit-keyframes span2{
    		0%{
    			background:gray;
    		}
    		24%{
    			background: gray;
    		}
    		25%{
    			background: white;
    		}
    		49%{
    			background: white;
    		}
    		50%{
    			background: gray;
    		}
    		100%{
    			background: gray;
    		}
    	}
        @-webkit-keyframes span3{
            0%{
              background: gray;
            }
            24%{
              background: gray;
            }
            25%{
              background: gray;
            }
            49%{
              background: gray;
            }
            50%{
              background: white;
            }
            74%{
              background: white;
            }
            75%{
              background: gray;
            }
            100%{
              background: gray;
            }
          }
       @-webkit-keyframes span4{
            0%{
              background: gray;
            }
            24%{
              background: gray;
            }
            25%{
              background: gray;
            }
            49%{
              background: gray;
            }
            50%{
              background: gray;
            }
            74%{
              background: gray;
            }
            75%{
              background: white;
            }
            99%{
              background: white;
            }
            100%{
              background: gray;
            }
          }
    
           body,span,p{
    			padding:0;
    			margin:0;
    		}
    		.wrap{
    			width: 800px;
    			margin:200px auto;
    		}
    		.box{
    			position: relative;
    			overflow:hidden;
    		}
    		img{
    			width: 20%;
    			float: left;
    		}
    		.scroll:after{
                content: "";
                display: block;
                clear: both;
          	}
    		.mask{
    			position: absolute;
    			left:0;
    			bottom: 0;
    			z-index: 10;
    			background: rgba(0,0,0,0.6);
    			width: 100%;
    			height: 40px;
    
    		}
    		.text{
    			width: 100%;
    			height: 40px;
    			position: absolute;
    			left:0;
    			bottom:0;
    			z-index: 20;
    			line-height: 40px;
    			overflow:hidden;
    			color:black;
    			text-align: center;
    		}
    		.text p{
    		      animation: mov2 10s linear  infinite;
    
    		}
    		.scroll{
    			width: 4000px;
    			animation: mov1 10s linear infinite;
    		}
    		.btn{
    			margin:10px;
    			text-align: center;
    		}
    		span{
    			width: 7px;
    			height: 7px;
    			background: gray;
    			border:1px solid gray;
    			border-radius: 100%;
    			display: inline-block;
    			margin:0 10px;
    			
    		}
    	  .btn span:nth-child(1){
            animation: span1 10s linear infinite;
          }
          .btn span:nth-child(2){
            animation: span2 10s linear infinite;
          }
          .btn span:nth-child(3){
            animation: span3 10s linear infinite;
          }
          .btn span:nth-child(4){
            animation: span4 10s linear infinite;
          }
    
    		.wrap:hover .scroll{
    			animation-play-state: paused;
    		}
    		.wrap:hover p{
                animation-play-state: paused;
          	}
          	.wrap:hover span{
                animation-play-state: paused;
         	}
    
    	</style>
    
    </head>
    <body>
    	<div class="wrap">
    		<div class="box">
    			<div class="scroll">
    				<img src="./1.jpg" alt="">
    				<img src="./2.jpg" alt="">
    				<img src="./3.jpg" alt="">
    				<img src="./4.jpg" alt="">
    			</div>
    			<div class="mask"></div>
    			<div class="text">
    					<p>看头条</p>
                		<p>癌症大数据</p>
                		<p>今日头条</p>
                		<p>易车网</p>
    			</div>
    		</div>
    		<div class="btn">
    			<span></span>
    			<span></span>
    			<span></span>
    			<span></span>
    		</div>
    	</div>
    
    </body>
    </html>

     
     
     
    展开全文
  • myslide 插件开发知识点总结和 css3 动画性能问题的研究这篇文章主要是总结最近开发过程中遇到的问题。有几个问题又是不容易发现原因的问题,但是最后的结果又是很简单的。1.手机端的 slider 插件是否有必要集成点按...

    myslide 插件开发知识点总结和 css3 动画性能问题的研究

    这篇文章主要是总结最近开发过程中遇到的问题。有几个问题又是不容易发现原因的问题,但是最后的结果又是很简单的。


    1.手机端的 slider 插件是否有必要集成点按操作

    对于我自己开发的版本来说还是集成了这个操作的。但是参考了京东,天猫,淘宝电商网站首页的 slider 图片轮播插件都没有支持点按操作。那么是为什么呢?

    我想到的答案可能如下:

    对于移动端来说,屏幕太小,轮播图上的显示当前图片状态的圆点,人的手指不容易选中。

    2.this到底指向谁,改变 this 的指向

    JavaScript 中this在使用过程中比较容易出错的。那么this到底是指向谁呢?我看到最多的一句话是:

    this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象;

    来看两段代码:

    var a = {
        m: 12,
        b: {
            m: 13,
            func: function() {
                console.log(this.m);   //result: 13
            }
        }
    };
    a.b.func();

    通过输出的结果,我们这个知道,当调用this的时候,this指向的是对象b

    var a = {
        m: 12,
        b: {
            m: 13,
            func: function() {
                console.log(this.m);   //undefined
                console.log(this);      //window
            }
        }
    };
    
    var cc=a.b.func;
    cc();     //相当于 window.cc();

    由以上代码的输出结果是当this被调用的时候 this 指向的是当前的 window 相当于window.cc(),这个时候实际上是 window 调用了 this

    上面的代码也印证了小结开头提到的那句话。但是很多时候根据实际情况我们需要改变this的指向,那我们该怎么做呢?

    比如下面这样,我有一个公共的 js 对象来保存一些公用的 DOM 操作的方法,比如:

    var Doing.prototype={
        likeSport:function(){
            //这里使用原型的方式定义对象,就是想要这里的 this  始终指向送的都是 Doing
            console.log(this.test2()'like speak');
        },
        getName:function(){
            // console.log('zhiqiang');
            return 'zhiqiang'
        }
    }

    我的应用场景如下,当我单击 test 节点的时候,打印出我喜欢的运动。

    <div class="father">
        <div class="test">我喜欢的运动是什么?</div>
    </div>
    new Dong();
    
    var Dong = function(){
        var _this = this;
        $('.father').on('click','.test',function(){
            console.log(this);   //this  指向的是 test 节点对象
            _this.likeSport();   //这时 likeSport方法中的 this 指向的是 .test 节点对象  
         });
    };
    

    根据以上的代码,虽然我使用了 _this 缓存了 this 的只想,以使在单击函数的回掉中可以使用,但是这样直接调用 Dong 对象的方法,会改变 likeSportthis 的指向。

    那么我们怎么让我们在单击函数的回掉中调用 likeSport的方法时,likeSport 的方法中的this仍然指向的是Dong呢?

    这个时候就要用到 call或者 apply 来解决问题了。

    call 和 apply 都是可以指定 function函数运行时,this 的值。两者唯一的区别就是 call 第二个参数接受的是参数列表,而 apply 接受的是一个参数数组。

    fun.call(this,tp1,tp2);
    fun.apply(this,[tp1,tp2]);

    按照以上的知识点来修改我们的代码

    $('.father').on('click','.test',function(){
        console.log(this);   //this  指向的是 test 节点对象
        _this.likeSport().call(_this);   //这时 likeSport方法中的 this 指向的是 Dong
     });

    3.使用CSS3 动画性能的问题

    为什么使用 css3属性来做动画?使用 css 3做动画有什么好处呢?

    我们先借助 chrome 开发者工具对动画渲染做一个检测,先来看使用margin-left来做动画发生了什么

    2016-03-19 19_02_41

    再来看使用 translate3d 做动画发生了什么

    2016-03-19 18_42_21

    我们可以很明显的看到,在使用 margin-left做动画的过程中,浏览器每时每刻都在发生渲染操作,而使用 translate3d 只是在开始和结束的时候发生渲染操作。

    来看看 csstrigger 网站上对 margin-left 和 transform 的区别:

    qq20160319-0
    qq20160319-1

    由上面可以知道,我们在使用 margin-left 这样的属性的时候,会触发页面的重排和重绘,而使用 transform 的时候,可以调用 gpu 对渲染进行帮助。

    容易忽略的问题:

    1. 在使用 jQuery 或者 Zepto 的 animate 方法做动画的时候,我的代码可能是这样的

    test.animate({left:'15px'},1000);
    test.animate({transform:'translate3d(0,15px,0)'},1000);

    但是根据 API 文档,我们可以直接这样写

    test.animate({translate3d:'0,15px,0'},1000);

    这种写法比上面的写法简洁一些。

    2. 在使用 CSS3 属性做动画的时候,数值要加单位,不然会没有效果,比如下面的代码

    var size = 150;
    test.animate({'translate3d': '-' + size + ',0,0'},1000)

    这样写是正确的:

    var size = 150;
    test.animate({'translate3d': '-' + size + 'px,0,0'},1000)

    4.scroll 滚动动画的问题

    我们会有这样的业务场景,需要从页面的最低部返回页面的头部,或者是返回到页面的某个部分。
    能够想到的解决方案有两种:
    1. 使用锚点;
    2. 使用 js 来滚动页面

    使用锚点没有什么可以多说的,也很简单,但是滚动效果比较生硬。使用 js 来滚动页面的话,可以设置滚动动画,来使页面的滚动的效果更加友好。

    在网上如果搜索scroll 动画最多的答案就是使用下面这样的代码:

        $('.body1').animate({scrollTop:200},2000);

    但是我在使用这样代码的时候,却没有出现我想要的效果,最后通过各种尝试还是找到原因的。就是的父级元素没有设置overflow:auto

    overflow 这个属性还是很有用的。比如:触发盒子的 BFC 还有就是禁止元素在水平或者竖直方向滚动。

    注意:
    jQuery 支持这样的滚动动画,但是 Zepto 不支持这个操作滚动动画;

    这里写图片描述

    展开全文
  • H5+CSS3简单动画 知识点 汇总

    千次阅读 2016-03-30 17:41:58
    乱入几个:  ...检索或设置对象动画在循环中是否反向运动 如果提供多个属性值,以逗号进行分隔。 对应的脚本特性为 animationDirection 。  


    乱入几个: 

    1.h5的一个语义化标签

      figure :用于规定独立的流内容(图像 图表 照片 代码等)

      figcapition:与figure配套使用,用于标签定义figure元素标题

    2.媒体查询:

    通过不同的媒体类型和条件定义样式规则 ;媒体查询大部分媒体特性都接受min和max 用于表示“大于等于”或“小于等于”:width: min-width;max-width 

      媒体查询可以用在@media和import规则上,也可以用在HTML和XML中。

     @media screen and (width:800px){...} 

     @import url(example.css) screen and (width:800px);

    <link media="screen and (width:800px)" rel="stylesheet" href="example.css">


    css3:

      优点:方便,无需js,适合做图片、文字的简单效果;

      缺点:不灵活;效果有限

    划重点:

    1. transform:变形。【transform:translate / rotete / scale / skew(平移 旋转,缩放,斜切)】

    2. transition: 过渡。【transition: property, duration, timing-function(Linear,ease,ease-in,ease-out,ease-in-out), delay】

    • 必须要设置两个属性:  设置过渡效果的 CSS 属性的名称; 完成过渡效果需要多少秒或毫秒。                

     3、animation:动画。【animation:name/ duration/ timing-function/ iteration-count(播放次数)/ direction/ play-stete】


    具体介绍:

      Transform :用于元素的变形处理  属性:  translate,Rotate,scale,skew  (平移 ,旋转,缩放,斜切)

     

    transition: 用于设置四个过渡属性 属性:property,duration,timing-function,delay

    transition-property 规定设置过渡效果的 CSS 属性的名称。
    transition-duration 规定完成过渡效果需要多少秒或毫秒。
    transition-timing-function 规定速度效果的速度曲线。  (Linear,ease,ease-in,ease-out,ease-in-out)
    transition-delay 定义过渡效果何时开始。

    animation:所有动画属性的简写属性,除了 animation-play-state 属性。

    animation-name 规定需要绑定到选择器的 keyframe 名称。。
    animation-duration 规定完成动画所花费的时间,以秒或毫秒计。
    animation-timing-function 规定动画的速度曲线。
    animation-delay 规定在动画开始之前的延迟。
    animation-iteration-count 规定动画应该播放的次数。
    animation-direction 规定是否应该轮流反向播放动画。

    举例(chrome浏览器下):

    1. -webkit-animation: myfirst 2s linear 1s infinite both;

      -webkit-animation-name: myfirst;
      -webkit-animation-duration: 5s;
      -webkit-animation-timing-function: linear;
      -webkit-animation-delay: 2s;
      -webkit-animation-iteration-count: infinite;
      -webkit-animation-direction: alternate;
      -webkit-animation-play-state: running;
    2. @-wbkit-keyframes myfirst {

          }


        -常用参考手册-

    属性 描述 CSS
    @keyframes 规定动画。 3
    animation 所有动画属性的简写属性,除了 animation-play-state 属性。 3
    animation-name 规定 @keyframes 动画的名称。 3
    animation-duration 规定动画完成一个周期所花费的秒或毫秒。默认是 0。 3
    animation-timing-function 规定动画的速度曲线。默认是 "ease"。 3
    animation-delay 规定动画何时开始。默认是 0。 3
    animation-iteration-count 规定动画被播放的次数。默认是 1。 3
    animation-direction 规定动画是否在下一周期逆向地播放。默认是 "normal"。 3
    animation-play-state 规定动画是否正在运行或暂停。默认是 "running"。 3
    animation-fill-mode 规定对象动画时间之外的状态。 3

    animation-timing-function<single-animation-timing-function>[,<single-animation-timing-function>]*

    <single-animation-timing-function> = ease | linear | ease-in | ease-out | ease-in-out | step-start | step-end | steps(<integer>[, [ start | end ] ]?) | cubic-bezier(<number>,<number><number><number>)

    默认值:ease

    适用于:所有元素,包含伪对象:after和:before

    继承性:无

    动画性:否

    计算值:指定值

    媒体:视觉

    取值:

    • linear:线性过渡。等同于贝塞尔曲线(0.0, 0.0, 1.0, 1.0)

    • ease:平滑过渡。等同于贝塞尔曲线(0.25, 0.1, 0.25, 1.0)

    • ease-in:由慢到快。等同于贝塞尔曲线(0.42, 0, 1.0, 1.0)

    • ease-out:由快到慢。等同于贝塞尔曲线(0, 0, 0.58, 1.0)

    • ease-in-out:由慢到快再到慢。等同于贝塞尔曲线(0.42, 0, 0.58, 1.0)

    • step-start:等同于 steps(1, start)

    • step-end:等同于 steps(1, end)

    • steps(<integer>[, [ start | end ] ]?):接受两个参数的步进函数。第一个参数必须为正整数,指定函数的步数。第二个参数取值可以是start或end,指定每一步的值发生变化的时间点。第二个参数是可选的,默认值为end。

    • cubic-bezier(<number>, <number>, <number>, <number>):

    • 特定的贝塞尔曲线类型,4个数值需在[0, 1]区间内

    animation-fill-modenone | forwards | backwards | both [ , none | forwards | backwards | both ]*

    默认值:none

    适用于:所有元素,包含伪对象:after和:before

    继承性:无


    取值:

    • none:默认值。不设置对象动画之外的状态

    • forwards:设置对象状态为动画结束时的状态

    • backwards:设置对象状态为动画开始时的状态

    • both:设置对象状态为动画结束或开始的状态

    说明:

    检索或设置对象动画时间之外的状态

    • 如果提供多个属性值,以逗号进行分隔。

    • 对应的脚本特性为animationFillMode


    animation-direction:normal | alternate [ , normal | alternate ]*

    默认值:normal

    适用于:所有元素,包含伪对象:after和:before

    继承性:无


    取值:

    • normal:正常方向

    • alternate:正常与反向交替

    说明:

    检索或设置对象动画在循环中是否反向运动

    • 如果提供多个属性值,以逗号进行分隔。

    • 对应的脚本特性为animationDirection



      

    展开全文
  • 重温了一下《IOS 7 Programming: Pushing the Limits》这本书,有许多零碎的知识点,记录一下,勉强算作是学习笔记吧。 CALayer Part 1 动画的基本单元就是 UIView,它是非常重量级的对象,所以不能多用。但你又...
  • MotionLayout是ConstraintLayout的子类,所以它是一种布局类型,但是它能够为布局属性添加动画效果,是开发者实现动画效果的另一个新的选择。 MotionLayout基础 让动画跑起来 在入门练习的例子中,我们先利用...
  • 相关知识点的整理,应为我对动画相关的部分,不是很熟悉,所以对于第一篇文章上面所涉及的只是进行了总结和整理。1.android 自定义view之 onMeasure()可以说重载onMeasure(),onLayout(),onDraw()三个函数构建了...
  • View Animation: 视图动画在古老的Android版本系统中就已经提供了,只能被用来设置View的动画动画名称 对应的子类 xml中标签 描述 缩放动画 ScaleAnimation &amp;amp;lt; scale /&amp;amp;gt; S 平移...
  • 自定义动画简单的说就是,图片按照一定的间隔时间、一定的顺序、一帧一帧的进行播放显示的效果。 在cocos2dx种,有两种方法来实现动画,但是都比较费劲 第一种方法是: 首先自己使用代码来实现动画效果。...
  • 看到网上很多展示html5...我这几天刚好学习了一下,也趁着此刻有时间从需求分析、知识点、程序编写一步步给大家解剖下,要是在各位关公面前耍大刀了,可别见笑哟。 最终效果图如下: 一、需求分析 1、圆形雪花
  • Unity知识点整理

    千次阅读 2016-07-26 00:04:45
    1.Awake函数和Start函数的区别,调用顺序...Unity知识点整理链接: http://blog.csdn.net/candycat1992/article/details/22927713 http://blog.csdn.net/zy19940906/article/details/47833819 ...
  • 动画这一知识点算是水比较深了,主要在自定义动画中可是大有文章,并且技术都会了后就需要看设计能力了。 当然这些不是笔者博客的重点,笔者还是基本只讲技术上的,本篇博客就讲一讲简单的设置Activity的跳转动画。...
  • Unity动画知识之二:Animator动画状态机

    万次阅读 多人点赞 2016-11-09 00:56:15
     上次我们讲过Unity游戏动画从入门到住院,今天我们来讲一下动画状态机。  好了,现在我们已经成功的导入了动画。接下来要玩的东西就很装13啦。因为大部分动画师是用不到这家伙的,需要掌握这个技能的,至少也...
  • 本文旨在总结iOS知识网络,知识点,该知识网络罗列出常见UIKit、Foundation的对象特点和一些使用经验,可以看成是一本书;文本编辑采用树的形式,对知识点进行罗列,并标注一些使用经验(★)希望对初学者有用或给...
  • Spine骨骼动画知识普及

    千次阅读 2016-12-14 19:22:31
    一些基本概念 以下将介绍一些骨骼动画的基础概念,便于对骨骼动画不甚了解...在游戏里动画大体有两种制作方式:逐帧动画和补间动画。 逐帧动画即为每一帧画出一张图,然后通过按照一定速度(帧率,每秒多少帧)来
  • Android群英传知识点回顾——第十二章:Android5.X新特性详解知识点目录 12.1 Android5.X UI设计初步 12.1.1 材料的形态模拟 12.1.2 更加真实的动画 12.1.3 大色块的使用 12.2 Material Design主题 12.3 ...
  • Unity 动画知识之一

    千次阅读 2016-11-07 23:59:19
    由于动画导入该如何设置取决于使用的是那种动画系统,所以我会把三种动画系统的导入设置分开讲,三种动画系统会有一些重合的内容,这类内容前边讲过之后后面就不会再重复了。  好 首先是Legacy动画系统(以下...
  • 目录CSS和JS部分知识点的运用(小A一轮)首页首页大标题蓝色边框动画的实现头部导航条黄色块的实现第三个英文标题透明字体的实现通过伪元素修饰各个标题右侧导航条右侧导航栏的样式实现右侧导航栏展开内容的动画实现...
  • Unity 知识点复习

    千次阅读 多人点赞 2018-02-28 18:08:41
    a) 子节点自己的中心,子物体的位置,由自己的中心和锚点来决定; 4. Text RichText:富文本: 支持Html的标签 i. <color></color>颜色 ii. <size></size>字体大小 iii. <b></b>加粗 iv. <i></i>...
  • Android 重点难点知识点总结回顾

    千次阅读 2018-03-24 23:18:33
    分别为继承自View完全自定义、继承自自现有控件(如ImageView)实现特定效果、继承自ViewGroup实现布局类,在其中比较重要的知识点就是View的测量与布局、View的绘制、处理触摸事件、动画等; 对于继承自view的控件...
  • 文章博客地址:元旦假期里,闲的无事,看到美团加载数据的动画,就突想写个Demo把动画知识集成一下。后来想了想,还是直接用一个Demo来把所有动画知识穿插起来算了,该Demo涉及大多数动画应用场景。本篇案例,使用补...
  • 介绍AnimatorSet是组合动画,前面在ObjectAnimator.ofPropertyValuesHolder(),时也可以做到控制多个属性做动画,但是.ofPropertyValuesHolder(),仅仅是将多个属性同时做动画却无法灵活控制每个属性的播放顺序,针对...
  • 动画:用动画给面试官解释 TCP 三次握手过程

    万次阅读 多人点赞 2019-10-12 07:55:38
    对于这部分掌握以及 TCP 的四次挥手,小鹿将会以动画的形式呈现给每个人,这样将复杂的知识简单化,理解起来也容易了很多,尤其对于一个初学者来说。 学习导图 一、TCP 是什么? TCP(Transmissio...
  • CSS3知识点总结

    千次阅读 多人点赞 2016-05-13 22:20:41
    CSS3知识点总结
  • 本文主要讲解如何实现ViewPager自定义的页面切换动画效果。通过实现PageTransformer接口,然后利用position在这个过程的变化来动态设置页面的尺寸比例、透明度、以及偏移量。
  • iOS开发零碎知识点

    万次阅读 多人点赞 2016-08-11 10:37:32
    记录一些常用和不常用的iOS知识点,防止遗忘丢失。(来源为收集自己项目中用到的或者整理看到博客中的知识点),如有错误,欢迎大家批评指正;如有好的知识点,也欢迎大家联系我,添加上去。谢谢! 欢迎大家关注...
  • turtle(海龟)知识点整理

    千次阅读 多人点赞 2021-01-16 19:17:03
    turtle(海龟)知识点 知识点大纲 目录 turtle(海龟)知识点 知识点大纲 Python的一个简单介绍 安装turtle库 turtle绘图的基础知识 1、画布 1.1 绘图坐标系 2、画笔 2.1 RGB色彩体系 3、绘图命令方法 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 83,202
精华内容 33,280
关键字:

动画设置知识点