0

私はブラシを2本持っています。ブラシの種類がわかりません。それらは、ImageBrushes、SolidBrushes、または VisualBrushes にすることができます。「ブラシ」タイプの変数にそれぞれがあります。

2 つのブラシを組み合わせる必要があります。どうすればいいのですか?

これを試しました。しかし、うまくいきませんでした。これが、私が組み合わせる必要があるブラシの背面と前面です。

Border Bd = new Border();
Border Bdr = new Border();

Bd.Width = 1.0;
Bd.Height = 1.0;

Bd.Background = Back;
Bdr.Background = Front;

Bd.Child = Bdr;

Brush VB = new VisualBrush(Bd);

ブラシをアニメーション化するカスタム アニメーション クラスを作成しているため、これが必要です。いくつかのテストを行った後、エラーはブラシの組み合わせにあり、クラスの他の場所にはないと結論付けました。

結果のブラシは完全に透明になります。


[編集]

完全な BrushAnimation クラスは次のとおりです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Animation;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;

namespace WPFSoPaTest
{
    class BrushAnimation : AnimationTimeline
    {
                protected override Freezable CreateInstanceCore()
        {
            return new BrushAnimation();
        }
        public override Type TargetPropertyType
        {
            get { return typeof(Brush); }
        }
        static BrushAnimation()
        {
            FromProperty = DependencyProperty.Register("From", typeof(Brush),
                typeof(BrushAnimation));

            ToProperty = DependencyProperty.Register("To", typeof(Brush),
                typeof(BrushAnimation));
        }
        public static readonly DependencyProperty FromProperty;
        public Brush From
        {
            get
            {
                return (Brush)GetValue(BrushAnimation.FromProperty);
            }
            set
            {
                SetValue(BrushAnimation.FromProperty, value);
            }
        }
        public static readonly DependencyProperty ToProperty;
        public Brush To
        {
            get
            {
                return (Brush)GetValue(BrushAnimation.ToProperty);
            }
            set
            {
                SetValue(BrushAnimation.ToProperty, value);
            }
        }
        public override object GetCurrentValue(object defaultOriginValue,
        object defaultDestinationValue, AnimationClock animationClock)
        {
            Brush fromVal = ((Brush)GetValue(BrushAnimation.FromProperty)).CloneCurrentValue();
            Brush toVal = ((Brush)GetValue(BrushAnimation.ToProperty)).CloneCurrentValue();

            if ((double)animationClock.CurrentProgress == 0.0)
                return fromVal; //Here it workes fine.

            if ((double)animationClock.CurrentProgress == 1.0)
                return toVal;   //It workes also here fine.

            toVal.Opacity = (double)animationClock.CurrentProgress;


            Border Bd = new Border();
            Border Bdr = new Border();

            Bd.Width = 1.0;
            Bd.Height = 1.0;

            Bd.Background = fromVal;
            Bdr.Background = toVal;

            Bd.Visibility = Visibility.Visible;
            Bdr.Visibility = Visibility.Visible;
            Bd.Child = Bdr;

            Brush VB = new VisualBrush(Bd);
            return VB; //But here it return's a transparent brush.

            //If I return the 'toVal' variable here it animates correctly the opacity.
        }
    }
}
4

5 に答える 5

1

私は問題を発見しました。ビジュアルブラシはフリーズできません。コードを機能させるには、ブラシをフリーズする方法を見つける必要があります。

于 2009-10-22T00:06:59.133 に答える
1

ブラシをアニメーション化する必要があるのは、3D オブジェクトで使用しているマテリアルでブラシをアニメーション化するためです。マテリアルよりもブラシの方がアニメートしやすいと思いました。

上記の方法でブラシを組み合わせたことがありますが、ここではうまくいきませんでした。

少し考えた後、ブラシではなくマテリアルをアニメートすることにしました。ブラシをアニメートするよりも簡単な結果になりました。

[注]
このアニメーション クラスは、私のニーズに合わせて調整されています。マテリアル内のブラシのみをアニメーション化します。このクラスを使用して、マテリアルのブラシを別のブラシに置き換えています。

[注]
「to マテリアル」は最後に「from マテリアル」を完全に置き換えます。MaterialGroup で終了しません。

これが必要な人のための MaterialAnimation クラスです。Point3DCollectionAnimation クラスもあります。3D メッシュのアニメーション化に使用できます。とても便利です。この下にあります。

マテリアルアニメーション

システムを使用する;
System.Collections.Generic の使用;
System.Linq を使用します。
System.Text を使用します。
System.Windows.Media.Animation を使用します。
System.Windows を使用します。
System.Windows.Media の使用;
System.Windows.Controls を使用します。
System.Windows.Media.Media3D の使用;

名前空間 System.Windows.Media.Animation
{
    クラス MaterialAnimation : AnimationTimeline
    {
                protected override Freezable CreateInstanceCore()
        {
            新しい MaterialAnimation() を返します。

        }
        パブリック オーバーライド タイプ TargetPropertyType
        {
            get { return typeof(Material); }
        }
        static MaterialAnimation()
        {
            FromProperty = DependencyProperty.Register("From", typeof(Material),
                typeof(MaterialAnimation));

            ToProperty = DependencyProperty.Register("To", typeof(Material),
                typeof(MaterialAnimation));
        }
        public static readonly DependencyProperty FromProperty;
        パブリック マテリアル フロム
        {
            得る
            {
                return (Material)GetValue(MaterialAnimation.FromProperty);
            }
            設定
            {
                SetValue(MaterialAnimation.FromProperty, 値);
            }
        }
        public static readonly DependencyProperty ToProperty;
        公開素材へ
        {
            得る
            {
                return (Material)GetValue(MaterialAnimation.ToProperty);
            }
            設定
            {
                SetValue(MaterialAnimation.ToProperty, 値);
            }
        }
        パブリック オーバーライド オブジェクト GetCurrentValue (オブジェクト defaultOriginValue,
        object defaultDestinationValue, AnimationClock animationClock)
        {
            Material fromVal = ((Material)GetValue(MaterialAnimation.FromProperty)).CloneCurrentValue();
            Material toVal = ((Material)GetValue(MaterialAnimation.ToProperty)).CloneCurrentValue();

            if ((double)animationClock.CurrentProgress == 0.0)
                ヴァルから戻ります。// ここでは正常に動作します。

            if ((double)animationClock.CurrentProgress == 1.0)
                ヴァルに戻ります。//ここでも問題なく動作します。            

            if (toVal.GetType() == (新しい DiffuseMaterial()).GetType())
                ((DiffuseMaterial)toVal).Brush.Opacity = (double)animationClock.CurrentProgress;
            そうしないと
                if (toVal.GetType() == (新しい SpecularMaterial()).GetType())
                    ((SpecularMaterial)toVal).Brush.Opacity = (double)animationClock.CurrentProgress;
                そうしないと
                    ((EmissiveMaterial)toVal).Brush.Opacity = (double)animationClock.CurrentProgress;


            MaterialGroup MG = new MaterialGroup();

            MG.Children.Add(fromVal);
            MG.Children.Add(toVal);            

            MGを返します。
        }
    }
}


これが Point3DCollectionAnimation クラスです。

Point3Dコレクションアニメーション

システムを使用する;
System.Collections.Generic の使用;
System.Linq を使用します。
System.Text を使用します。
System.Windows.Media.Animation を使用します。
System.Windows を使用します。
System.Windows.Media.Media3D の使用;

名前空間 System.Windows.Media.Animation
{
    public class Point3DCollectionAnimation : AnimationTimeline
    {
        protected override Freezable CreateInstanceCore()
        {
            新しい Point3DCollectionAnimation() を返します。
        }
        パブリック オーバーライド タイプ TargetPropertyType
        {
            get { return typeof(Point3DCollection); }
        }
        static Point3DCollectionAnimation()
        {
            FromProperty = DependencyProperty.Register("From", typeof(Point3DCollection),
                typeof(Point3DCollectionAnimation));

            ToProperty = DependencyProperty.Register("To", typeof(Point3DCollection),
                typeof(Point3DCollectionAnimation));
        }
        public static readonly DependencyProperty FromProperty;
        public Point3DCollection から
        {
            得る
            {
                return (Point3DCollection)GetValue(Point3DCollectionAnimation.FromProperty);
            }
            設定
            {
                SetValue(Point3DCollectionAnimation.FromProperty, 値);
            }
        }
        public static readonly DependencyProperty ToProperty;
        public Point3DCollection へ
        {
            得る
            {
                return (Point3DCollection)GetValue(Point3DCollectionAnimation.ToProperty);
            }
            設定
            {
                SetValue(Point3DCollectionAnimation.ToProperty, 値);
            }
        }
        パブリック オーバーライド オブジェクト GetCurrentValue (オブジェクト defaultOriginValue,
        object defaultDestinationValue, AnimationClock animationClock)
        {
            Point3DCollection fromVal = ((Point3DCollection)GetValue(Point3DCollectionAnimation.FromProperty));
            Point3DCollection toVal = ((Point3DCollection)GetValue(Point3DCollectionAnimation.ToProperty));

            Point3DCollection ret;

            int t = 0;
            if (fromVal.Count > toVal.Count)
            {
                ret = fromVal.Clone();
                foreach (toVal の Point3D tov)
                {
                    Point3D frov = fromVal[t];
                    Point3D newv = 新しい Point3D();

                    newv.X = (double)animationClock.CurrentProgress * (tov.X - frov.X) + frov.X;
                    newv.Y = (double)animationClock.CurrentProgress * (tov.Y - frov.Y) + frov.Y;
                    newv.Z = (double)animationClock.CurrentProgress * (tov.Z - frov.Z) + frov.Z;
                    ret[t] = newv;
                    t++;
                }
            }
            そうしないと
            {
                ret = toVal.Clone();
                foreach (fromVal の Point3D frov)
                {
                    Point3D tov = toVal[t];
                    Point3D newv = 新しい Point3D();

                    newv.X = (double)animationClock.CurrentProgress * (tov.X - frov.X) + frov.X;
                    newv.Y = (double)animationClock.CurrentProgress * (tov.Y - frov.Y) + frov.Y;
                    newv.Z = (double)animationClock.CurrentProgress * (tov.Z - frov.Z) + frov.Z;
                    ret[t] = newv;
                    t++;
                }
            }

            retを返します。
        }
    }
}

これらのクラスが必要な人にとって役立つことを願っています。インターネットで割り当てを検索しましたが、見つかりませんでした。これらのクラスを必要としている人がもっといると確信しています。

コメントを残してください。

于 2009-10-10T04:24:21.780 に答える
1

アーロン、私は上記のようにあなたの BrushAnimation クラスを使用しましたが、それは私の特定のニーズに対応しています。ただし、StackOverflow はクリエイティブ コモンズ ライセンスの下で動作することに気付きました。したがって、技術的には、商用アプリケーションでそのクラスを使用することはできませんでした (クリエイティブ コモンズ ライセンスの対象になりたくありません)。許可してもよろしいですか?私はまだあなたの仕事を信用できます.

私はまだコメントをすることができないので、これについてあなたに連絡する他の方法を見つけることができませんでした.

于 2011-03-11T18:36:29.933 に答える
0

The above approach should work as long as you have transparent pixels in the front brush. If not the front brush would just overlay the back brush. You should provide a more complete example to see what is actually going on.

于 2009-10-09T07:33:04.333 に答える
0

それを達成するためにvisualbrushを使用できます

<Grid.Background>
       <VisualBrush>
                <VisualBrush.Visual>
                    <Grid 
                        Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}, Mode=OneWay}" 
                        Height="{Binding Path=ActualHeight, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}, Mode=OneWay}">

                        <Rectangle Fill="Blue" />
                        <Image Source="your image path" Stretch="Uniform" />

                    </Grid>
                </VisualBrush.Visual>
            </VisualBrush>
        </Grid.Background>
于 2016-12-20T10:44:13.400 に答える