精华内容
下载资源
问答
  • 废话不多说,前面几天我发布了:[Material Design] 教你做一个Material风格、动画的按钮(MaterialButton) 在其中我讲解了我对 Android L 中 Material 效果的按钮的动画实现方式,今天的文章将基于其上进行进阶讲解新...

    原创作品,转载请注明出处:http://blog.csdn.net/qiujuer/article/details/39998961

    做 Android 动画效果一段时间了,感觉深深喜欢上了钻研特效。在手机上显示自己的特效是一件很不错的事情。

    废话不多说,前面几天我发布了:[Material Design] 教你做一个Material风格、动画的按钮(MaterialButton)

    在其中我讲解了我对 Android L 中 Material 效果的按钮的动画实现方式,今天的文章将基于其上进行进阶讲解新的特效。

    在 MaterialButton 中的特效原理是:用户点击时启动一个动画,该动画是在点击位置画颜色渐变同时半径变大的圆,从而实现扩散效果;具体可点击上面的链接查看一下。在按钮中的这样的特效距离谷歌的还是有很大的差距的,下面来对比一下:

    官方的:


    我们上个版本的:


    可以看出谷歌的是有位移效果,而我们的是原地扩散的效果,当然动画速度这个与PS的设置有关,不做比较,实际速度比上面的略快。

    下面咱们就来试试做做位移的特效,先画个图给大家看看:


    相信大家都能看懂,第一种就是之前的实现方式,只是在原地扩散,第二种就是新的,将在扩散的同时向中心靠拢,且为了达到更加好的视觉效果,靠拢中心的XY轴速度并不是一样的,X轴的靠拢时间=整个扩散时间,向Y轴靠拢的时间~=整个扩散时间*0.3(且都是先快后慢),现在来看看成品效果:


    点击中间的时候与第一种差距不大,但是点击两边的时候将会有明显的差距,能感觉到向中心靠拢的触觉。是不是和谷歌的相比起来又近了一些了?


    说了这个多的理论与演示,下面来说说整个的实现:

    首先我们抽取上一篇文章的成果作为这篇的开头,具体怎么新建控件就不再做介绍了,先看看上一篇的代码成果(该代码进行了一定的修改):

    public class MaterialButton extends Button {
        private static final Interpolator ANIMATION_INTERPOLATOR = new DecelerateInterpolator();
        private static final long ANIMATION_TIME = 600;
    
        private Paint backgroundPaint;
        private static ArgbEvaluator argbEvaluator = new ArgbEvaluator();
        private float paintX, paintY, radius;
    
    
        public MaterialButton(Context context) {
            super(context);
            init(null, 0);
        }
    
        public MaterialButton(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(attrs, 0);
        }
    
        public MaterialButton(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init(attrs, defStyle);
        }
    
        @SuppressWarnings("deprecation")
        private void init(AttributeSet attrs, int defStyle) {
            ...
        }
    
    
        @SuppressWarnings("NullableProblems")
        @Override
        protected void onDraw(Canvas canvas) {
            canvas.save();
            canvas.drawCircle(paintX, paintY, radius, backgroundPaint);
            canvas.restore();
    
            super.onDraw(canvas);
        }
    
        @SuppressWarnings("NullableProblems")
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                paintX = event.getX();
                paintY = event.getY();
                startRoundAnimator();
            }
            return super.onTouchEvent(event);
        }
    
        /**
         * =============================================================================================
         * The Animator methods
         * =============================================================================================
         */
    
        /**
         * Start Round Animator
         */
        private void startRoundAnimator() {
            float start, end, height, width;
            long time = (long) (ANIMATION_TIME * 1.85);
    
            //Height Width
            height = getHeight();
            width = getWidth();
    
            //Start End
            if (height < width) {
                start = height;
                end = width;
            } else {
                start = width;
                end = height;
            }
    
            float startRadius = (start / 2 > paintY ? start - paintY : paintY) * 1.15f;
            float endRadius = (end / 2 > paintX ? end - paintX : paintX) * 0.85f;
    
            //If The approximate square approximate square
            if (startRadius > endRadius) {
                startRadius = endRadius * 0.6f;
                endRadius = endRadius / 0.8f;
                time = (long) (time * 0.5);
            }
    
            AnimatorSet set = new AnimatorSet();
            set.playTogether(
                    ObjectAnimator.ofFloat(this, mRadiusProperty, startRadius, endRadius),
                    ObjectAnimator.ofObject(this, mBackgroundColorProperty, argbEvaluator, attributes.getColor(1), attributes.getColor(2))
            );
            // set Time
            set.setDuration((long) (time / end * endRadius));
            set.setInterpolator(ANIMATION_INTERPOLATOR);
            set.start();
        }    
    
    
        /**
         * =============================================================================================
         * The custom properties
         * =============================================================================================
         */
    
        
        private Property<MaterialButton, Float> mRadiusProperty = new Property<MaterialButton, Float>(Float.class, "radius") {
            @Override
            public Float get(MaterialButton object) {
                return object.radius;
            }
    
            @Override
            public void set(MaterialButton object, Float value) {
                object.radius = value;
                invalidate();
            }
        };
    
        private Property<MaterialButton, Integer> mBackgroundColorProperty = new Property<MaterialButton, Integer>(Integer.class, "bg_color") {
            @Override
            public Integer get(MaterialButton object) {
                return object.backgroundPaint.getColor();
            }
    
            @Override
            public void set(MaterialButton object, Integer value) {
                object.backgroundPaint.setColor(value);
            }
        };
    
    }
    
    在上述代码中我们实现了点击时进行扩散的效果,初始化控件部分由于我加入了许多的代码这里删除了,具体可以看看我的项目实现,最后会给出地址。

    现在基于此开工!

    首先我们建立 两个新的属性 分别X坐标与Y坐标属性:

    private Property<MaterialButton, Float> mPaintXProperty = new Property<MaterialButton, Float>(Float.class, "paintX") {
            @Override
            public Float get(MaterialButton object) {
                return object.paintX;
            }
    
            @Override
            public void set(MaterialButton object, Float value) {
                object.paintX = value;
            }
        };
    
        private Property<MaterialButton, Float> mPaintYProperty = new Property<MaterialButton, Float>(Float.class, "paintY") {
            @Override
            public Float get(MaterialButton object) {
                return object.paintY;
            }
    
            @Override
            public void set(MaterialButton object, Float value) {
                object.paintY = value;
            }
        };
    在这两个属性中并未调用第一篇所说的 “ invalidate();”方法进行界面刷新,因为该方法应该放在持续时间最长的半径属性中调用。

    之后我们获取到高宽 以及根据高和宽 计算出对应的 开始半径与结束半径:

    <span style="white-space:pre">	</span>float start, end, height, width, speed = 0.3f;
            long time = ANIMATION_TIME;
    
            //Height Width
            height = getHeight();
            width = getWidth();
    
            //Start End
            if (height < width) {
                start = height;
                end = width;
            } else {
                start = width;
                end = height;
            }
            start = start / 2 > paintY ? start - paintY : paintY;
            end = end * 0.8f / 2f;
    
            //If The approximate square approximate square
            if (start > end) {
                start = end * 0.6f;
                end = end / 0.8f;
                time = (long) (time * 0.65);
                speed = 1f;
            }
    我们首先比较了高与宽的长度 把短的赋予为开始半径 长的赋予为结束半径。

    第二步,我们把开始长度除以2  得出其一半的长度 然后与 点击时的Y轴坐标比较,如果Y轴较长则取Y,如果不够则取其相减结果。这样能保证点击开始时的半径能刚好大于其高或者宽(短的一边),这样就不会出现小圆扩散的效果,看起来将会由椭圆的效果(当然以后将会直接画出椭圆)

    第三步,我们运算出结束半径,同时保证结束半径为长的一边的一半的8/10 这样的效果是不会出现布满整个控件的情况。8/10 的空间刚好是个不错的选择。

    第四步,判断开始长度是否大于结束长度,如果是(近似正方形情况),进行一定规则的重新运算,保证其开始半径能刚好与控件长度差不多(0.48左右),结束半径能刚刚布满控件,同时减少动画时间

    当然,我现在才发现了一个BUG,在第二步的地方的BUG,大家看看,希望能提出是哪里的BUG;就当是一个互动!该BUG将会在下个版本修复。


    之后我们建立每个属性的动画,并给每个属性动画设置对应的时间:

    <span style="white-space:pre">	</span>//PaintX
            ObjectAnimator aPaintX = ObjectAnimator.ofFloat(this, mPaintXProperty, paintX, width / 2);
            aPaintX.setDuration(time);
            //PaintY
            ObjectAnimator aPaintY = ObjectAnimator.ofFloat(this, mPaintYProperty, paintY, height / 2);
            aPaintY.setDuration((long) (time * speed));
            //Radius
            ObjectAnimator aRadius = ObjectAnimator.ofFloat(this, mRadiusProperty, start, end);
            aRadius.setDuration(time);
            //Background
            ObjectAnimator aBackground = ObjectAnimator.ofObject(this, mBackgroundColorProperty, argbEvaluator, attributes.getColor(1), attributes.getColor(2));
            aBackground.setDuration(time);

    可以看见Y轴的时间乘以了一个speed变量,该变量默认是0.3 如果是近似正方形将初始化为1以便能同时对齐到中心位置,在上一步中有对应变量。

    然后咱们把所有的属性动画添加到一个动画集并设置其速度方式为:先快后慢。最后启动该动画集。

            //AnimatorSet
            AnimatorSet set = new AnimatorSet();
            set.playTogether(aPaintX, aPaintY, aRadius, aBackground);
            set.setInterpolator(ANIMATION_INTERPOLATOR);
            set.start();


    以上就是最新的动画效果的实现原理及代码了,当然我们可以将其合并到第一篇的代码中,并使用一个 Bool 属性来控制使用哪一种动画:

    public class MaterialButton extends Button {
        private static final Interpolator ANIMATION_INTERPOLATOR = new DecelerateInterpolator();
        private static final long ANIMATION_TIME = 600;
    
        private Paint backgroundPaint;
        private static ArgbEvaluator argbEvaluator = new ArgbEvaluator();
        private float paintX, paintY, radius;
        private Attributes attributes;
    
        public MaterialButton(Context context) {
            super(context);
            init(null, 0);
        }
    
        public MaterialButton(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(attrs, 0);
        }
    
        public MaterialButton(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init(attrs, defStyle);
        }
    
        @SuppressWarnings("deprecation")
        private void init(AttributeSet attrs, int defStyle) {
            ...
        }
    
    
        @SuppressWarnings("NullableProblems")
        @Override
        protected void onDraw(Canvas canvas) {
            canvas.save();
            canvas.drawCircle(paintX, paintY, radius, backgroundPaint);
            canvas.restore();
    
            super.onDraw(canvas);
        }
    
        @SuppressWarnings("NullableProblems")
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (attributes.isMaterial() && event.getAction() == MotionEvent.ACTION_DOWN) {
                paintX = event.getX();
                paintY = event.getY();
                if (attributes.isAutoMove())
                    startMoveRoundAnimator();
                else
                    startRoundAnimator();
            }
            return super.onTouchEvent(event);
        }
    
        /**
         * =============================================================================================
         * The Animator methods
         * =============================================================================================
         */
    
        /**
         * Start Round Animator
         */
        private void startRoundAnimator() {
            float start, end, height, width;
            long time = (long) (ANIMATION_TIME * 1.85);
    
            //Height Width
            height = getHeight();
            width = getWidth();
    
            //Start End
            if (height < width) {
                start = height;
                end = width;
            } else {
                start = width;
                end = height;
            }
    
            float startRadius = (start / 2 > paintY ? start - paintY : paintY) * 1.15f;
            float endRadius = (end / 2 > paintX ? end - paintX : paintX) * 0.85f;
    
            //If The approximate square approximate square
            if (startRadius > endRadius) {
                startRadius = endRadius * 0.6f;
                endRadius = endRadius / 0.8f;
                time = (long) (time * 0.5);
            }
    
            AnimatorSet set = new AnimatorSet();
            set.playTogether(
                    ObjectAnimator.ofFloat(this, mRadiusProperty, startRadius, endRadius),
                    ObjectAnimator.ofObject(this, mBackgroundColorProperty, argbEvaluator, attributes.getColor(1), attributes.getColor(2))
            );
            // set Time
            set.setDuration((long) (time / end * endRadius));
            set.setInterpolator(ANIMATION_INTERPOLATOR);
            set.start();
        }
    
        /**
         * Start Move Round Animator
         */
        private void startMoveRoundAnimator() {
            float start, end, height, width, speed = 0.3f;
            long time = ANIMATION_TIME;
    
            //Height Width
            height = getHeight();
            width = getWidth();
    
            //Start End
            if (height < width) {
                start = height;
                end = width;
            } else {
                start = width;
                end = height;
            }
            start = start / 2 > paintY ? start - paintY : paintY;
            end = end * 0.8f / 2f;
    
            //If The approximate square approximate square
            if (start > end) {
                start = end * 0.6f;
                end = end / 0.8f;
                time = (long) (time * 0.65);
                speed = 1f;
            }
    
            //PaintX
            ObjectAnimator aPaintX = ObjectAnimator.ofFloat(this, mPaintXProperty, paintX, width / 2);
            aPaintX.setDuration(time);
            //PaintY
            ObjectAnimator aPaintY = ObjectAnimator.ofFloat(this, mPaintYProperty, paintY, height / 2);
            aPaintY.setDuration((long) (time * speed));
            //Radius
            ObjectAnimator aRadius = ObjectAnimator.ofFloat(this, mRadiusProperty, start, end);
            aRadius.setDuration(time);
            //Background
            ObjectAnimator aBackground = ObjectAnimator.ofObject(this, mBackgroundColorProperty, argbEvaluator, attributes.getColor(1), attributes.getColor(2));
            aBackground.setDuration(time);
    
            //AnimatorSet
            AnimatorSet set = new AnimatorSet();
            set.playTogether(aPaintX, aPaintY, aRadius, aBackground);
            set.setInterpolator(ANIMATION_INTERPOLATOR);
            set.start();
        }
    
    
        /**
         * =============================================================================================
         * The custom properties
         * =============================================================================================
         */
    
        private Property<MaterialButton, Float> mPaintXProperty = new Property<MaterialButton, Float>(Float.class, "paintX") {
            @Override
            public Float get(MaterialButton object) {
                return object.paintX;
            }
    
            @Override
            public void set(MaterialButton object, Float value) {
                object.paintX = value;
            }
        };
    
        private Property<MaterialButton, Float> mPaintYProperty = new Property<MaterialButton, Float>(Float.class, "paintY") {
            @Override
            public Float get(MaterialButton object) {
                return object.paintY;
            }
    
            @Override
            public void set(MaterialButton object, Float value) {
                object.paintY = value;
            }
        };
    
        private Property<MaterialButton, Float> mRadiusProperty = new Property<MaterialButton, Float>(Float.class, "radius") {
            @Override
            public Float get(MaterialButton object) {
                return object.radius;
            }
    
            @Override
            public void set(MaterialButton object, Float value) {
                object.radius = value;
                invalidate();
            }
        };
    
        private Property<MaterialButton, Integer> mBackgroundColorProperty = new Property<MaterialButton, Integer>(Integer.class, "bg_color") {
            @Override
            public Integer get(MaterialButton object) {
                return object.backgroundPaint.getColor();
            }
    
            @Override
            public void set(MaterialButton object, Integer value) {
                object.backgroundPaint.setColor(value);
            }
        };
    
    }


    在最后附上两种方式运行后的效果对比图:




    还不错吧?
    要是感觉比较和你的胃口,这里有我的整个项目:

    Genius-Android


    APK与动画MP4


    最新文章终极解决方案(2015-01-07):

    打造极致Material Design动画风格Button

    展开全文
  • 和为View对象设置动画一样容易,属性系统也提供了为ViewGroups设置动画的能力。 你可以在LayoutTransition 类中为ViewGroups设置动画。在你往ViewGroup添加或移除view或者调用View的setVisibility()方法时, ...
    和为View对象设置动画一样容易,属性系统也提供了为ViewGroups设置动画的能力。
    你可以在LayoutTransition 类中为ViewGroups设置动画。在你往ViewGroup添加或移除view或者调用View的setVisibility()方法时,


    在ViewGroups内的Views会有一个显示或消失动画。当你往ViewGroup中添加View时,ViewGroup中的其他Views也可以在他们移动到新位


    置时设置动画。通过调用setAnimator()并传递一个如下的 LayoutTransition 常量,你可以定义一个在LayoutTransition 中定义一个


    如下的动画:
    APPEARING:一个标记标记动画出现在容器中新添加的item
    CHANGE_APPEARING:一个标记标记动画出现在容器中由于新添加的item而导致改变的items上面
    DISAPPEARING:一个标记标记动画出现在容器中移除的item
    CHANGE_DISAPPEARING:一个标记标记动画出现在容器中由于新移除的item而导致改变的items上面
    你可以为这四种类型的事件自定义动画来设置自己的布局动画,也可以仅仅告诉动画系统使用缺省的动画
    在 API Demos中的LayoutAnimations实例展示了如何定义布局动画,以及如何为视图对象定义自己想要的动画
    LayoutAnimationsByDefault 以及相应的资源目录下的layout_animations_by_default.xml 文件展示了如何用XML方式来使能缺省的布


    局动画。你唯一需要做的就是把ViewGroup的属性android:animateLayoutchanges设置为true,例如:
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:id="@+id/verticalContainer"
        android:animateLayoutChanges="true" />
    把android:animateLayoutchanges设置为true之后,ViewGroup将自动为添加到ViewGroup或从ViewGroup中移除的View,已经ViewGroup


    中剩余的View设置动画
    展开全文
  • ObjectAnimator animator = ObjectAnimator.ofFloat(mTitle, View.TRANSLATION_Y, -...如题,mTitle是一个TextView,mContentLayout是一个铺满的ScrollView,但是向上平移的时候底部出现了空白,ScrollView却会向上平移
  • WPF中自动增加行(动画)的TextBox

    千次阅读 2016-07-23 21:27:49
    WPF中自动增加行(动画)的TextBoxWPF中的Textbox控件是可以自动换行的,只要设置TextWrapping属性为”Wrap”即可,但是存在一个问题:Textbox的高度是固定的,当输入文本过多时就会出现如下情况。Textbox虽然没有...

    WPF中自动增加行(动画)的TextBox

    WPF中的Textbox控件是可以自动换行的,只要设置TextWrapping属性为”Wrap”即可,但是存在一个问题:Textbox的高度是固定的,当输入文本过多时就会出现如下情况。

    Textbox虽然没有自动增加高度的属性,但是我们可以通过设置来实现这一个功能。相关xaml代码如下

     <Grid VerticalAlignment="Top" HorizontalAlignment="Left" Width="36" Height="100">
         <TextBox x:Name="textBox" TextWrapping="Wrap" VerticalAlignment="Top" />
     </Grid>
    

    效果如下
    这里写图片描述

    这里需要注意的是

    • 如果设置了textBox的Width、Height或者Margin属性,那么此textBox的大小就已经限制死了,不会自动增加,会出现上图中的情况。
    • 如果想设置textBox的大小和位置,需要把textBox放在一个Grid中,通过Grid的属性来控制textBox(上文中xaml文件中的方法)

    其实到此为止所需要的功能已经实现了,但是为了让让textbox更美观,我加了一个动画

    效果如下:

    表面上看是一个textbox,其实是一个Grid加上2个textBox(一个显示,一个隐藏),xaml代码如下

    <Grid>
        <TextBox x:Name="txtVisible" TextWrapping="Wrap"/>
        <TextBox x:Name="txtHidden" TextWrapping="Wrap" Visibility="Hidden" VerticalAlignment="Top"/>
    </Grid>
    

    Grid是用来控制textbox的大小的,两个textbox中,显示的那个用于输入文字,隐藏的用于触发动画。原理如下
    在txtVisible中输入文字的同时,txtVisible把text传递给txtHidden,当txtHidden中的内容已经满一行时,会触发SizeChange事件,这个事件再触发txtVisible高度变化动画。代码如下

    public partial class txt : UserControl
    {
    
        private HeightAnimation anim;
        private double _animationDuration;
    
        public txt()
        {
            InitializeComponent();
    
            // Initialize the animation
            anim = new HeightAnimation(this);
            AnimationDuration = 500; //default value
    
            // Add the handlers to the required events
            txtHidden.SizeChanged += TxtHidden_SizeChanged;
            txtVisible.TextChanged += TxtVisible_TextChanged;
        }
    
        /// <summary>
        /// Gets or sets a value indicating whether the control is animated on loaded.
        /// </summary>
        public bool AnimateOnLoaded { get; set; } = false;
    
        /// <summary>
        /// Gets or sets a value indicating whether the control is animated.
        /// </summary>
        public bool IsAnimated { get; set; } = true;
    
        /// <summary>
        /// Gets or sets the duration of the animation.
        /// </summary>
        public double AnimationDuration
        {
            get { return _animationDuration; }
            set
            {
                _animationDuration = value;
                anim.Duration = new Duration(TimeSpan.FromMilliseconds(value));
            }
        }
    
        /// <summary>
        /// Gets or sets the text contents of the AnimatedTextBox.
        /// </summary>
        public string Text
        {
            get { return txtHidden.Text; }
            set
            {
                txtHidden.Text = value;
                txtVisible.Text = value;
            }
        }
    
    
        private void TxtVisible_TextChanged(object sender, TextChangedEventArgs e)
        {
            // When the user's writing in txtVisible, we copy the text to txtHidden
            txtHidden.Text = txtVisible.Text;
        }
    
        private void TxtHidden_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            OnHeightChanged(e.PreviousSize.Height, e.NewSize.Height);
        }
    
        /// <summary>
        /// To execute when the txtHidden's Height has changed.
        /// </summary>
        private void OnHeightChanged(double previousHeight, double newHeight)
        {
            //Animation type, increase txtVisible's height or decrease
            anim.ChangeType = (newHeight > previousHeight) ? HeightAnimation.ChangeTypes.Increased : HeightAnimation.ChangeTypes.Decreased;
    
            // Animate the Height from the txtHidden's previousHeight to its newHeight
            anim.From = previousHeight;
            anim.To = newHeight;
    
            // Start the animation
            anim.BeginAnimation();
        }
    
        /// <summary>
        /// Manages the AnimatedTextBox Height's animation.
        /// </summary>
        private class HeightAnimation
        {
    
            private Storyboard sb;
            private DoubleAnimation anim;
            private double _from;
            private double _to;
            private Duration _duration;
            private FrameworkElement _fe;
            private ChangeTypes _changeType;
    
            /// <summary>
            /// The possible types of the Height change.
            /// </summary>
            public enum ChangeTypes
            {
                Increased,
                Decreased
            }
    
            /// <summary>
            /// Constructor of the class.
            /// </summary>
            public HeightAnimation(FrameworkElement fe)
            {
                // Set the FrameworkElement which manages the animation
                _fe = fe;
    
                // Initialize the Storyboard
                sb = new Storyboard();
                sb.AutoReverse = false;
    
                // Initialize the animation
                anim = new DoubleAnimation();
                anim.Name = "anim";
    
                // Set the EasingFunction on a new instance of CubicEase whose EasingMode is EaseInOut
                anim.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseInOut };
    
                // Bind the Animation with the txtVisible TextBox
                Storyboard.SetTargetName(anim, "txtVisible");
    
                // Add the animation to the Storyboard's children
                sb.Children.Add(anim);
            }
    
            /// <summary>
            /// Gets or sets the type of the Height change.
            /// </summary>
            public ChangeTypes ChangeType
            {
                get { return _changeType; }
                set
                {
                    _changeType = value;
    
                    /* If the Height has inreased, set the target property to MaxHeight, else to MinHeight
                     * (instead of animating directly the Height, we animate MaxHeight/MinHeight to prevent the AnimatedTextBox
                     * from growing/shrinking suddenly) */
                    Storyboard.SetTargetProperty(anim, new PropertyPath(string.Format("(TextBox.{0})", (value == ChangeTypes.Increased) ? "MaxHeight" : "MinHeight")));
                }
            }
    
            /// <summary>
            /// Gets or sets the animation's starting Height.
            /// </summary>
            public double From
            {
                get { return _from; }
                set
                {
                    _from = value;
                    anim.From = value;
                }
            }
    
            /// <summary>
            /// Gets or sets the animation's ending Height.
            /// </summary>
            public double To
            {
                get { return _to; }
                set
                {
                    _to = value;
                    anim.To = value;
                }
            }
    
            /// <summary>
            /// Gets or sets the animation's duration.
            /// </summary>
            public Duration Duration
            {
                get { return _duration; }
                set
                {
                    _duration = value;
                    anim.Duration = value;
                }
            }
    
            /// <summary>
            /// Begins the animation.
            /// </summary>
            public void BeginAnimation()
            {
                _fe.BeginStoryboard(sb);
            }
        }
    }
    
    展开全文
  • Unity进阶 - 动画系统 - 导入设置

    千次阅读 2016-09-13 17:02:41
    Unity进阶 - 动画系统 - 导入设置
    
    

    相关文章阅读
    Unity 进阶 - 动画系统 - Mecanim动画系统
    Unity进阶 - 动画系统 - 给人物角色制作动画
    Unity进阶 - 动画系统 - 人形动画的导入

    一、设置Avatar

    首先我们进入Unity,先导入一个人形动画——把动画设置成人形动画, 接下来需要设置Avatar.

     

    二,骨骼映射

     

    Avatar是一套骨骼映射系统,导入模型A,我们改模型A创建Avatar,就是把模型A中的建模时的骨骼直接映射到Unity标准骨骼之中了。如果在导入模型B,创建Avatar,就是把模型B中的建模时的骨骼直接映射到Unity标准骨骼之中了。

    在Unity中演示动画是在Unity标准骨骼中——我们可以实现人形动画的重用。

    接下来让我们在Unity中演示一下:

    配置Avatar需要打开一个新场景——我们需要对之前内容进行保存!


    三、Avatar配置场景


    Hierarchy视图:展示是我们当前角色所有的骨骼

    Scene视图:展示我们这个角色模型及关键部位的骨骼在哪里?绿色的就是模型中关键位置的骨骼。

    Inspector视图:属性面板是为了专门做骨骼映射的一个界面,上面一共有两个选项卡,一个是Mapping用来做骨骼映射的。另外一个是muscles&Settings是用来做肌肉映射的

    四,如何配置Avatar


    把骨骼映射关系制作完毕就可以了,一般情况下系统给你会自动映射一遍,当前我们所看到的结果就是系统自动映射完毕的结果。一般情况下是没有问题的,但是也会有出息问题的时候。左侧的层级列表是我们建模时候搭建的骨骼,右边的绿色小人是Unity标准骨骼系统,我们要做的就是在把左侧的骨骼一一对应到右侧的绿色小人的圆圈中。实心的圈表示关键部位的骨骼,必须对应到左侧的骨骼。虚线的圈是可选的,左侧不对应也没有关系的。

    骨骼映射出现问题


    我们要做的第一步就是检查自动映射的结果是否正确?


     

    也可以通过中间的场景视图来检查


    设置Avatar未完待续……




    展开全文
  • 我们已经导入了一个带有多组动画的模型,见《Godot Engine:Blender模型导入Godot自动生成的场景结构》 1. 添加AnimationTree 在Beefy场景中添加一个AnimationTree节点 当前AnimationTree的默认属性是下面这个样子 ...
  • 文本提示显示5秒后消失动画制作效果如上,配置如下: 1、载入整个网页时,隐藏元件,元件名称“文件生成中tip” 2、点击【导出CSV文件】按钮,添加鼠标点击时的动作显示-旋转-等待-隐藏动画 ①显示元件,逐渐...
  • 粉色星星为textview,下面的动画设置到textview上。左右摆动时要像第二排的效果,textview可以完整的显示;如果动画设置不对,则摆动过程中会被背景图掩盖,显示效果如第三排所示。思路有两个:1.dialog2....
  • 用 height 是不行的。不过,用 max-height 和 min-height 可以实现同等效果。.box{ max-height: 120px; min-height: 120px; overflow: hidden; transition: max-height ease-out 0.2s;... max-heig
  • 在Focusky(也称为“FS软件")里,不仅可以嵌入本地视频,还可以设置视频自动播放或点击播放。...注意:当设置自动播放时,需注意视频不要超出帧(路径)的边框,否则会出现视频无法自动播放的问题。 ...
  • 自动弹出dialog,或者自动弹出popuwind时,我们会加入一些写的动画,style 在一些简单的,我们会弄一些帧动画先拿几个轮子 比较有代表性 Android 控件的显示隐藏上下左右移动动画 ...
  • 本文将详细介绍 Android 动画中 属性动画的原理 & 使用 相关文章阅读: 1. Android 动画系列 Android 动画:手把手教你使用 补间动画 Android 动画:你真的会使用插值器与估值器吗?(含详细实例教学) 2. ...
  • (前提是动画本身没有问题)这个时候如果单帧观察,会发现模型发生奇怪的位移或旋转等问题,但是NavMeshAgent组件的位置没有变化,把它设置为enabled=false; 模型不再抖动。所以发现问题的所在了。。。。还需要清楚...
  • Android的动画分为了三种, 分别是 帧动画、View动画、属性动画。 1、帧动画动画就是顺序播放一组预先定义好的图片,就类似于我们观看视频,就是一张一张的图片连续播放。 帧动画的使用很简单,总共就两个步骤...
  • unity3d 动画卡帧 动画合成 动画层次

    千次阅读 2013-02-26 16:22:12
    unity3d 中动画的添加 http://unity3d.com/support/documentation/Manual/Character-Animation.html#AnimLayers 在unity3d中,我们能很方便的使用4个动画,默认的是走,跑,跳,待机动作,可当...
  • iOS动画解析

    万次阅读 2016-04-25 21:40:43
    iOS引入动画效果可以使我们的软件得到更好的用户体验,因此动画的深入研究无疑对于开发者一个很好的加分项。 常见的iOS对动画的操作分为两类: CALayer层的操作 UIView的操作 二者有何区别 UIView里面包含有一个...
  • 背景自动切换动画和通过过渡实现图片平移代码HTMLCSS 代码 HTML <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>study17</title> <link href=...
  • 偶然间在网页上看到一个过山车动画觉得很炫,就想用swift纯代码实现了一个类似的效果,因为没有设计天赋,所以就完全高仿的人家的效果-.-下面上效果图: 给大家介绍一下项目中主要会用到的类: CAShapeLayer ...
  • Unity_DOTween动画的学习(五)_Tweener的使用和注意事项_DOPlay播一次_DOPlayForward播多次_DOPlayBackwards倒放_SetAutoKill动画自动销毁 1.多次播放的正确使用方式: using System.Collections; using System....
  • 一、分割动画Perfab:Import Animation是否导入动画勾选后可在下方分割动画Start:开始帧End:结束帧Loop Time:循环播放Loop Pose...Animator组件可搜索添加,也可设置为Generic、Humanoid时自动添加1、在AnimContr...
  • 博主声明: 转载请在开头附加本文链接及作者信息,并... Android 提供了一种简单而好用的帧动画,所谓帧动画,就是一帧一帧的播放,你可以想象一下民国时期那种电影片的效果,它用的就是一帧一帧的播放,说白了就是...
  • 首先感谢众多网友的支持,最近我实在是事情太多,所以没有写太多。...本系列的前几篇文章讲解了自动布局的原理,以及如何添加约束。这篇文章主要介绍以下内容: 某些用户控件具有自身内容尺寸约束 使用视图调试工
  • iOS动画实战之Lottie动画

    千次阅读 2018-07-18 16:11:36
    如果把iOS动画分为两类: 交互式动画, 播放式动画, 那么其中的播放动画完全可以使用Lottie来完成, 例如: 作为收藏按钮, 是不是很活泼? 返回与菜单之间的切换, 生动有趣! 还有各种形变动画. 这里先放上...
  • Qt之界面出现、消失动画效果

    千次阅读 2017-05-08 19:45:30
    (2013-01-18 10:03:33) 转载▼ ... 在学习Qt的这2、3个月里,对Qt越发感兴趣,从刚开始的盲目、无所适从到现在的学习、研究、熟练、掌握的过程中,我学到了很...关于Qt界面的出现消失效果,我简单介绍两种方法。
  • [Unity动画]给人物模型添加简单的动画

    万次阅读 多人点赞 2016-08-25 13:02:23
    给unity人物模型添加动画,首先你得有个模型,在预制体中,有导入设置,重点是Rig设置。第一个选项是动画的类型,因为导入的是人物模型,所以应该选择人形;第二个是人物骨骼,这里已经设好了;第三个选项是对物体...
  • Layout Animations主要使用LayoutTransition为布局的容器设置动画,当容器中的视图层次发生变化时存在过渡的动画效果。LayoutTransition This class enables automatic animations on layout changes in ViewGroup ...
  • 解决方法是在每次触发动画事件前先把所有动画都取消掉。 //编辑 $('table').on('click','.edit',function(){ $("#editWrap").stop(true);//清除元素的所有动画 //这里省略动画效果 } ...
  •  对于手机自动锁屏的问题一般都是在项目尾声的时候发现由于手机自动锁屏所带来的各种问题,例如,在cocos2d中我们调用暂停游戏的函数后,如果用户无操作,手机自动锁屏后,解锁再次进入游戏就会发现游戏不处于暂停...
  • Untiy5序列帧动画的解决方案

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 76,526
精华内容 30,610
关键字:

怎么设置动画自动出现