Создайте анимацию Blink в WPF в коде позади

Я хочу применить анимацию Blink к Canvas, чтобы все объекты, которые я нарисовал на ней, мигали вместе с ней.

Я несколько преуспел, используя приведенный ниже код, который довольно быстро изменяет свойство Opacity для Canvas для достижения этого эффекта, но я не удовлетворен этим.

Я бы предпочел чистое мерцание без каких-либо FadeOut/FadeIn, как в моем текущем коде. Как я могу сделать это правильно?

var blinkAnimation = new DoubleAnimation
{
    From = 1,
    To = 0
};

var blinkStoryboard = new Storyboard
{
    Duration = TimeSpan.FromMilliseconds(500),
    RepeatBehavior = RepeatBehavior.Forever,
    AutoReverse = true
};

Storyboard.SetTarget(blinkAnimation, MyCanvas);
Storyboard.SetTargetProperty(blinkAnimation, new PropertyPath(OpacityProperty));

blinkStoryboard.Children.Add(blinkAnimation);
MyCanvas.BeginStoryboard(blinkStoryboard);

Может быть, я могу сделать это с помощью VisibilityProperty, но у меня не получилось.


person Vahid    schedule 11.05.2014    source источник
comment
Возможно, пришло время прочитать Обзор анимации и Советы и рекомендации по анимации статьи в MSDN.   -  person Clemens    schedule 11.05.2014
comment
Спасибо, Клеменс, я думаю, что да. На самом деле со вчерашнего дня мне нужно было только получить этот эффект, я был немного ленив, чтобы прочитать много нового материала для этого. Но теперь обязательно посмотрю.   -  person Vahid    schedule 11.05.2014


Ответы (2)


Вы можете использовать вторую анимацию с соответствующим BeginTime:

var switchOffAnimation = new DoubleAnimation
{
    To = 0,
    Duration = TimeSpan.Zero
};

var switchOnAnimation = new DoubleAnimation
{
    To = 1,
    Duration = TimeSpan.Zero,
    BeginTime = TimeSpan.FromSeconds(0.5)
};

var blinkStoryboard = new Storyboard
{
    Duration = TimeSpan.FromSeconds(1),
    RepeatBehavior = RepeatBehavior.Forever
};

Storyboard.SetTarget(switchOffAnimation, MyCanvas);
Storyboard.SetTargetProperty(switchOffAnimation, new PropertyPath(Canvas.OpacityProperty));
blinkStoryboard.Children.Add(switchOffAnimation);

Storyboard.SetTarget(switchOnAnimation, MyCanvas);
Storyboard.SetTargetProperty(switchOnAnimation, new PropertyPath(Canvas.OpacityProperty));
blinkStoryboard.Children.Add(switchOnAnimation);

MyCanvas.BeginStoryboard(blinkStoryboard);
person Clemens    schedule 11.05.2014

Если вы хотите, чтобы ваша анимация была включена/выключена, вы можете изменить анимацию на DoubleAnimationUsingKeyFrames.

var blinkAnimation = new DoubleAnimationUsingKeyFrames();
blinkAnimation.KeyFrames.Add(new DiscreteDoubleKeyFrame(1, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0))));
blinkAnimation.KeyFrames.Add(new DiscreteDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(250))));

var blinkStoryboard = new Storyboard
{
    Duration = TimeSpan.FromMilliseconds(500),
    RepeatBehavior = RepeatBehavior.Forever,
};

Storyboard.SetTarget(blinkAnimation, MyCanvas);
Storyboard.SetTargetProperty(blinkAnimation, new PropertyPath(OpacityProperty));

blinkStoryboard.Children.Add(blinkAnimation);
blinkStoryboard.Begin();
person dkozl    schedule 11.05.2014
comment
Мне тоже нравится такой подход. Но ведет себя немного странно. Сначала было немного быстро. Я играл с длительностью, но не смог почувствовать эффект Blink. Возможно, я ввожу неправильные значения. - person Vahid; 11.05.2014
comment
Второе KeyFrame время должно составлять половину продолжительности Storyboard. В этом случае 250/500, поэтому, если вы хотите, чтобы весь цикл занимал, например, 1 секунду, тогда секунда KeyFrame должна начинаться с 500 мс, а продолжительность Storyboard должна составлять 1000 мс. - person dkozl; 11.05.2014