WPF であの花を降らせてみた


WPF で雪を降らせていたら、あの花を降らせてみてと言われたので、降らせてみた。

あの花 by WPF

 

ついでに、FlowerFactory をMomijiFactory に書き換えて、もみじにしてみた。

もみじ by WPF

 

メインXAML

<Window x:Class=”WpfAnohana.MainWindow”
        Background=”LightGray”
        xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
        xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
        Title=”MainWindow” Height=”480″ Width=”640″ Loaded=”Window_Loaded”>
    <Grid x:Name=”grid”>
        <Grid.Effect>
            <BlurEffect Radius=”5″></BlurEffect>
        </Grid.Effect>
    </Grid>
</Window>

メイン.cs

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace WpfAnohana
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            CreateFlowers();
        //    CreateMomiji();
        }

        // トランジション用(未実装)
        Queue<Viewbox> vb = new Queue<Viewbox>(2020);  

        private void CreateFlowers()
        {
            // Small Size, Fast
            CreateFlowers(0.05, 0.1, 1000, 5);
            // Medium Size
            CreateFlowers(0.1, 0.3, 1000, 10);
            // Large Size
            CreateFlowers(0.3, 1.0, 10, 10);
        }

        private void CreateMomiji()
        {
            // Small Size, Fast
            CreateMomiji(0.05, 0.1, 1000, 5);
            // Medium Size
            CreateMomiji(0.1, 0.3, 1000, 10);
            // Large Size
            CreateMomiji(0.3, 1.0, 20, 10);
        }

        private void CreateFlowers(double minSize, double maxSize, int count, int duration)
        {
            var flowerFactory = new FlowerFactory();
            for (int i = 0; i < count; i++)
            {
                var flower = (Flower)flowerFactory.Create(minSize + GetRnd(maxSize-minSize), duration);
                vb.Enqueue(flower);
                this.grid.Children.Add(flower);
                flower.BeginAnimation();
            }
        }

        private void CreateMomiji(double minSize, double maxSize, int count, int duration)
        {
            var momijiFactory = new MomijiFactory();
            for (int i = 0; i < count; i++)
            {
                var momiji = (Momiji)momijiFactory.Create(minSize + GetRnd(maxSize – minSize), duration);
                vb.Enqueue(momiji);
                this.grid.Children.Add(momiji);
                momiji.BeginAnimation();
            }
        }

        static Random rnd = new Random();

        static double GetRnd(double range)
        {
            return (rnd.NextDouble() * range);
        }
    }
}

ShapeFactory.cs

using System;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace WpfAnohana
{
    /// <summary>
    /// ———————————————————————–
    /// Factory パターン
    /// ———————————————————————–
    /// </summary>
    abstract public class ShapeFactory
    {
        abstract public Viewbox Create(double size, int duration);
    }

    /// <summary>
    /// ———————————————————————–
    /// </summary>
    public class AnimatedViewbox : Viewbox
    {
        protected DoubleAnimationUsingKeyFrames daukfRot = null;
        protected DoubleAnimationUsingKeyFrames daukfX = null;
        protected DoubleAnimationUsingKeyFrames daukfY = null;

        public RotateTransform RotTrans { get; set; }
        public TranslateTransform TransX { get; set; }
        public TranslateTransform TransY { get; set; }

        public static DoubleAnimationUsingKeyFrames DoubleAnimation(TimeSpan beginTime, TimeSpan duration, int from, int to)
        {
            var daukfRot = new DoubleAnimationUsingKeyFrames();

            var ldkfR1 = new LinearDoubleKeyFrame
            {
                KeyTime = KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0)),
                Value = from
            };

            var ldkfR2 = new LinearDoubleKeyFrame
            {
                KeyTime = KeyTime.FromTimeSpan(duration),
                Value = to
            };

            daukfRot.KeyFrames.Add(ldkfR1);
            daukfRot.KeyFrames.Add(ldkfR2);
            daukfRot.BeginTime = beginTime;
            daukfRot.Duration = duration;
            daukfRot.RepeatBehavior = RepeatBehavior.Forever;

            return daukfRot;
        }

        public void BeginAnimation()
        {
            TransX.BeginAnimation(TranslateTransform.XProperty, daukfX);
            TransY.BeginAnimation(TranslateTransform.YProperty, daukfY);
            RotTrans.BeginAnimation(RotateTransform.AngleProperty, daukfRot);
        }

        static Random rnd = new Random();

        static double GetRnd(double range)
        {
            return (rnd.NextDouble() * range);
        }
    }
}

FlowerFactory.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace WpfAnohana
{
    /// <summary>
    /// ———————————————————————–
    /// </summary>
    public class FlowerFactory : ShapeFactory
    {
        public override Viewbox Create(double size, int duration)
        {
            var flower = new Flower(size, duration);
            return flower;
        }
    }

    /// <summary>
    /// ———————————————————————–
    /// </summary>
    public class Flower : AnimatedViewbox
    {
        public Flower(double size, int duration)
        {
            Reverse = true;
            RenderTransform = GetTransform(size);
            HorizontalAlignment = HorizontalAlignment.Left;
            VerticalAlignment = VerticalAlignment.Top;
            RenderTransformOrigin = new Point(0.5, 0.5);
            Width = 100;
            Height = 100;
            Child = CreateFlowerPath(FlowerColor.GetNext());

            CreateAnimation(duration);
        }

        public bool Reverse { get; set; }

        private void CreateAnimation(int duration)
        {
            var begin0 = new TimeSpan(0, 0, 0);
            var duration10 = new TimeSpan(0, 0, duration);
            var beginTimeRnd = new TimeSpan(0, 0, 0, 0, (int)GetRnd(duration * 1000));

            int fromY = Reverse ? 600 : -50;
            int toY = Reverse ? -50: 600;

            daukfRot = DoubleAnimation(begin0, duration10, 0, 360 * 2);
            daukfX = DoubleAnimation(beginTimeRnd, duration10, 0, (int)GetRnd(200) – 100);
            daukfY = DoubleAnimation(beginTimeRnd, duration10, fromY, toY);
        }

        private TransformGroup GetTransform(double size)
        {
            var tg = new TransformGroup();
            var st = new ScaleTransform(size, size);
            var skewt = new SkewTransform();
            var tt = new TranslateTransform(GetRnd(640+200) – 100, -150);
            TransX = new TranslateTransform(0, 0);
            TransY = new TranslateTransform(0, 0);
            RotTrans = new RotateTransform();

            tg.Children.Add(st);
            tg.Children.Add(skewt);
            tg.Children.Add(RotTrans);
            tg.Children.Add(TransY);
            tg.Children.Add(TransX);
            tg.Children.Add(tt);

            return tg;
        }

        private static Shape CreateFlowerPath(Color col)
        {
            const string PathData = “M248,64 C236.5247,64.625058 225.71435,67.192184 215.5,71.5 L207.5,95.5 191.5,79.5 C179.10929,77.102304 168.53048,80.027027 159.5,87.5 159.50162,99.540561 161.46431,108.60788 167.5,111.5 L183.5,119.5 159.5,135.5 C160.12292,156.23214 162.17492,169.92602 167.5,167.5 172.91066,172.67869 180.71148,173.07705 191.5,167.5 L207.5,151.5 C203.2411,162.05534 202.55968,170.46419 207.5,175.5 219.38597,184.51719 230.14356,187.65745 239.5,183.5 L255.5,167.5 C252.80927,155.47101 245.02601,144.74873 231.5,135.5 L263.5,143.5 C272.5318,139.39663 278.23003,131.78108 279.5,119.5 276.83333,114.16667 274.16667,108.83333 271.5,103.5 262.70483,100.69259 251.88845,100.91719 239.5,103.5 248.65115,105.75263 260.3255,80.446287 248,64 z”;
           
            var g = PathGeometry.Parse(PathData);
            var br = new SolidColorBrush(col);
            var p = new Path();
            p.Width = 50;
            p.Height = 50;
            p.RenderTransformOrigin = new Point(0.5, 0.5);
            p.Stretch = Stretch.Fill;
            p.Data = g;
            p.Fill = br;

            return p;
        }

        static Random rnd = new Random();

        static double GetRnd(double range)
        {
            return (rnd.NextDouble() * range);
        }

        class FlowerColor
        {
            static Color[] col = {
                          Color.FromRgb(222,89,182),
                              Color.FromRgb(247,203,224),
                              Color.FromRgb(239,78,100),
                              Color.FromRgb(243,141,147),
                              Color.FromRgb(240,154,232),
                              Color.FromRgb(244,228,188),
                              Color.FromRgb(246,187,167)
                      };

            static int i = -1;
            public static Color GetNext()
            {
                if (++i >= col.Length)
                    i = 0;
                return col[i];
            }
        }
    }
}

MomijiFactory.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace WpfAnohana
{

    /// <summary>
    /// ———————————————————————–
    /// </summary>
    public class MomijiFactory : ShapeFactory
    {
        public override Viewbox Create(double size, int duration)
        {
            var momiji = new Momiji(size, duration);
            return momiji;
        }
    }

    /// <summary>
    /// ———————————————————————–
    /// </summary>
    public class Momiji : AnimatedViewbox
    {
        public Momiji(double size, int duration)
        {
            RenderTransform = GetTransform(size);
            HorizontalAlignment = HorizontalAlignment.Left;
            VerticalAlignment = VerticalAlignment.Top;
            RenderTransformOrigin = new Point(0.5, 0.5);
            Width = 100;
            Height = 100;
            Child = CreateMomijiPath(MomijiColor.GetNext());

            CreateAnimation(duration);
        }

        private void CreateAnimation(int duration)
        {
            var begin0 = new TimeSpan(0, 0, 0);
            var duration10 = new TimeSpan(0, 0, duration);
            var beginTimeRnd = new TimeSpan(0, 0, 0, 0, (int)GetRnd(duration * 1000));

            daukfRot = DoubleAnimation(begin0, duration10, 0, 360 * 2);
            daukfX = DoubleAnimation(beginTimeRnd, duration10, 0, (int)GetRnd(200) – 100);
            daukfY = DoubleAnimation(beginTimeRnd, duration10, -50, 600);
        }

        private TransformGroup GetTransform(double size)
        {
            var tg = new TransformGroup();
            var st = new ScaleTransform(size, size);
            var skewt = new SkewTransform();
            var tt = new TranslateTransform(GetRnd(640) – 100, -150);
            TransX = new TranslateTransform(0, 0);
            TransY = new TranslateTransform(0, 0);
            RotTrans = new RotateTransform();

            tg.Children.Add(st);
            tg.Children.Add(skewt);
            tg.Children.Add(RotTrans);
            tg.Children.Add(TransY);
            tg.Children.Add(TransX);
            tg.Children.Add(tt);

            return tg;
        }

        private static Shape CreateMomijiPath(Color col)
        {
            const string PathData = “M183.66667,86.666667 C189.39235,102.51222 195.97031,115.69911 204.00303,124.34783 189.46184,124.37625 176.55191,127.63058 166.26051,130.07866 177.67961,136.62725 192.00787,141.50314 209.25719,141.39676 203.19164,149.57713 198.0335,156.49435 192.99912,166.33255 202.42621,162.74626 210.94614,156.64738 218.66605,148.33266 L222.66553,167.66588 C225.54016,165.52929 227.12504,154.35884 228.999,141.99936 234.06358,144.63928 238.15358,153.77991 241.33226,168.99921 L243.66592,167.99921 C241.1493,155.99855 236.78856,146.70538 230.66566,139.99937 241.69194,144.10578 251.73257,143.90948 260.99883,140.3327 255.36431,137.34626 248.38965,134.93892 240.33229,132.99941 250.52631,127.61701 259.03319,119.28195 265.66548,107.66621 L234.3321,118.99948 C236.99567,104.86417 236.63427,91.185053 232.99878,77.999712 226.74482,85.30016 221.8588,98.979918 218.33224,118.99948 209.59223,103.54312 197.83014,93.109381 183.66667,86.666667 z”;

            var g = PathGeometry.Parse(PathData);
            var br = new SolidColorBrush(col);
            var p = new Path();
            p.RenderTransformOrigin = new Point(0.5, 0.5);
            p.Stretch = Stretch.Fill;
            p.Data = g;
            p.Fill = br;

            return p;
        }

        static Random rnd = new Random();

        static double GetRnd(double range)
        {
            return (rnd.NextDouble() * range);
        }

        class MomijiColor
        {
            static Color[] col = {
                          Color.FromRgb((byte)0xdc,(byte)0x14,(byte)0x3c),
                          Color.FromRgb(239, 119,33),
                          Color.FromRgb(255, 51,45),
                          Color.FromRgb(239, 119,33),
                          Color.FromRgb(255, 51,45),
                          Colors.Gold,
                          Color.FromRgb(34,136,34)
                      };

            static int i = -1;
            public static Color GetNext()
            {
                if (++i >= col.Length)
                    i = 0;
                return col[i];
            }
        }
    }
}

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中


%d人のブロガーが「いいね」をつけました。