当前位置: 代码网 > it编程>App开发>Windows Phone > 基于WPF实现元旦祝福动画效果

基于WPF实现元旦祝福动画效果

2026年01月01日 Windows Phone 我要评论
一、设计思路在wpf中创建元旦祝福动画,我们将结合多种动画元素,打造一个生动、喜庆的节日效果。主要设计思路包括:节日主题色彩:以红色、金色为主色调,象征新年的喜庆与希望核心动画元素:渐变显示的新年祝福

一、设计思路

在wpf中创建元旦祝福动画,我们将结合多种动画元素,打造一个生动、喜庆的节日效果。主要设计思路包括:

节日主题色彩:以红色、金色为主色调,象征新年的喜庆与希望

核心动画元素

  • 渐变显示的新年祝福文字
  • 飘落的雪花/彩屑动画
  • 绽放的烟花效果
  • 3d旋转的"2026"年份数字

交互体验:支持用户点击触发特定动画效果

二、完整wpf实现

下面是完整的xaml和c#代码实现:

<window
    x:class="yd_animal.mainwindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:yd_animal"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    title="元旦快乐 2026"
    width="1000"
    height="700"
    background="black"
    windowstartuplocation="centerscreen"
    mc:ignorable="d">
    <window.resources>
        <!--  雪花样式  -->
        <style x:key="snowflakestyle" targettype="ellipse">
            <setter property="width" value="8" />
            <setter property="height" value="8" />
            <setter property="fill" value="white" />
            <setter property="opacity" value="0.8" />
        </style>

        <!--  烟花粒子样式  -->
        <style x:key="fireworkparticlestyle" targettype="ellipse">
            <setter property="width" value="6" />
            <setter property="height" value="6" />
            <setter property="opacity" value="0.9" />
        </style>
    </window.resources>

    <grid>
        <!--  背景渐变  -->
        <rectangle>
            <rectangle.fill>
                <lineargradientbrush startpoint="0,0" endpoint="1,1">
                    <gradientstop offset="0" color="#0c0032" />
                    <gradientstop offset="0.5" color="#190061" />
                    <gradientstop offset="1" color="#240090" />
                </lineargradientbrush>
            </rectangle.fill>
        </rectangle>

        <!--  星星背景  -->
        <canvas x:name="starscanvas" />

        <!--  雪花容器  -->
        <canvas x:name="snowcanvas" />

        <!--  烟花容器  -->
        <canvas x:name="fireworkscanvas" />

        <!--  主内容区域  -->
        <grid>
            <grid.rowdefinitions>
                <rowdefinition height="*" />
                <rowdefinition height="auto" />
                <rowdefinition height="*" />
            </grid.rowdefinitions>

            <!--  顶部祝福语  -->
            <viewport3d x:name="year3dviewport" grid.row="0">
                <!--  3d年份动画  -->
            </viewport3d>

            <!--  中央祝福文字  -->
            <stackpanel
                grid.row="1"
                horizontalalignment="center"
                verticalalignment="center">
                <textblock
                    x:name="maingreeting"
                    margin="0,20"
                    horizontalalignment="center"
                    fontsize="72"
                    fontweight="bold"
                    foreground="transparent"
                    text="元旦快乐">
                    <textblock.effect>
                        <dropshadoweffect
                            blurradius="20"
                            shadowdepth="0"
                            color="gold" />
                    </textblock.effect>
                </textblock>

                <textblock
                    x:name="subgreeting"
                    margin="0,10"
                    horizontalalignment="center"
                    fontsize="36"
                    foreground="transparent"
                    text="新年新气象,好运常相伴">
                    <textblock.effect>
                        <dropshadoweffect
                            blurradius="15"
                            shadowdepth="0"
                            color="lightcoral" />
                    </textblock.effect>
                </textblock>
            </stackpanel>

            <!--  底部交互区域  -->
            <stackpanel
                grid.row="2"
                margin="0,0,0,50"
                horizontalalignment="center"
                verticalalignment="bottom"
                orientation="horizontal">
                <button
                    x:name="fireworksbutton"
                    width="120"
                    height="40"
                    margin="10"
                    background="#ff4081"
                    click="fireworksbutton_click"
                    content="绽放烟花"
                    fontweight="bold"
                    foreground="white" />

                <button
                    x:name="snowbutton"
                    width="120"
                    height="40"
                    margin="10"
                    background="#2196f3"
                    click="snowbutton_click"
                    content="飘落雪花"
                    fontweight="bold"
                    foreground="white" />

                <button
                    x:name="resetbutton"
                    width="120"
                    height="40"
                    margin="10"
                    background="#4caf50"
                    click="resetbutton_click"
                    content="重置动画"
                    fontweight="bold"
                    foreground="white" />
            </stackpanel>
        </grid>

        <!--  倒计时显示  -->
        <border
            x:name="countdownpanel"
            margin="0,20,0,0"
            padding="20,10"
            horizontalalignment="center"
            verticalalignment="top"
            background="#80000000"
            cornerradius="10"
            visibility="collapsed">
            <textblock
                x:name="countdowntext"
                fontsize="48"
                fontweight="bold"
                foreground="white"
                text="3" />
        </border>
    </grid>
</window>

后台代码:

using system.text;
using system.windows;
using system.windows.controls;
using system.windows.data;
using system.windows.documents;
using system.windows.input;
using system.windows.media;
using system.windows.media.animation;
using system.windows.media.imaging;
using system.windows.media.media3d;
using system.windows.navigation;
using system.windows.shapes;
using system.windows.threading;

namespace yd_animal;

/// <summary>
/// interaction logic for mainwindow.xaml
/// </summary>
public partial class mainwindow : window
{
    private random random = new random();
    private list<ellipse> snowflakes = new list<ellipse>();
    private list<ellipse> fireworks = new list<ellipse>();
    private storyboard mainstoryboard = new storyboard();

    public mainwindow()
    {
        initializecomponent();
        loaded += mainwindow_loaded;
    }

    private void mainwindow_loaded(object sender, routedeventargs e)
    {
        createstarsbackground();
        initializeanimations();
        startmainanimation();
    }

    // 创建星空背景
    private void createstarsbackground()
    {
        for (int i = 0; i < 150; i++)
        {
            ellipse star = new ellipse
            {
                width = random.next(1, 4),
                height = random.next(1, 4),
                fill = brushes.white,
                opacity = random.nextdouble() * 0.5 + 0.3
            };

            canvas.setleft(star, random.nextdouble() * this.width);
            canvas.settop(star, random.nextdouble() * this.height);
            starscanvas.children.add(star);

            // 添加星星闪烁动画
            doubleanimation opacityanim = new doubleanimation
            {
                from = star.opacity * 0.5,
                to = star.opacity,
                duration = timespan.fromseconds(random.nextdouble() * 2 + 1),
                autoreverse = true,
                repeatbehavior = repeatbehavior.forever
            };
            star.beginanimation(ellipse.opacityproperty, opacityanim);
        }
    }

    // 初始化主动画
    private void initializeanimations()
    {
        // 主祝福文字渐变显示
        coloranimation maintextcoloranim = new coloranimation
        {
            from = colors.transparent,
            to = colors.gold,
            duration = timespan.fromseconds(2),
            begintime = timespan.fromseconds(0.5)
        };

        coloranimation subtextcoloranim = new coloranimation
        {
            from = colors.transparent,
            to = color.fromrgb(255, 105, 180), // 粉色
            duration = timespan.fromseconds(2),
            begintime = timespan.fromseconds(1.5)
        };

        // 创建3d年份动画
        create3dyearanimation();

        // 添加到故事板
        storyboard.settarget(maintextcoloranim, maingreeting);
        storyboard.settargetproperty(maintextcoloranim,
            new propertypath("(textblock.foreground).(solidcolorbrush.color)"));

        storyboard.settarget(subtextcoloranim, subgreeting);
        storyboard.settargetproperty(subtextcoloranim,
            new propertypath("(textblock.foreground).(solidcolorbrush.color)"));

        mainstoryboard.children.add(maintextcoloranim);
        mainstoryboard.children.add(subtextcoloranim);

        // 添加文字抖动效果
        addtextjitteranimation();
    }

    // 创建3d年份旋转动画
    private void create3dyearanimation()
    {
        // 创建3d模型
        model3dgroup yearmodel = new model3dgroup();

        // 创建数字"2026"的3d文本
        for (int i = 0; i < 4; i++)
        {
            string digit = "2026"[i].tostring();

            geometrymodel3d digitmodel = create3dtext(digit,
                new diffusematerial(new solidcolorbrush(
                    color.fromrgb((byte)(255 - i * 30), (byte)(200 - i * 20), 50))),
                new point3d(i * 2.5 - 3.75, 0, 0));

            yearmodel.children.add(digitmodel);
        }

        // 设置3d相机
        perspectivecamera camera = new perspectivecamera(
            new point3d(0, 0, 10),
            new vector3d(0, 0, -1),
            new vector3d(0, 1, 0), 45);

        // 创建光源
        ambientlight ambientlight = new ambientlight(colors.white);
        directionallight directionallight = new directionallight(colors.white,
            new vector3d(-1, -1, -1));

        yearmodel.children.add(ambientlight);
        yearmodel.children.add(directionallight);

        // 创建modelvisual3d
        modelvisual3d modelvisual = new modelvisual3d();
        modelvisual.content = yearmodel;

        // 添加到viewport3d
        year3dviewport.children.add(modelvisual);
        year3dviewport.camera = camera;

        // 添加3d旋转动画
        axisanglerotation3d rotation = new axisanglerotation3d(
            new vector3d(0, 1, 0), 0);

        rotatetransform3d rotatetransform = new rotatetransform3d(rotation);
        yearmodel.transform = rotatetransform;

        doubleanimation rotateanim = new doubleanimation
        {
            from = 0,
            to = 360,
            duration = timespan.fromseconds(20),
            repeatbehavior = repeatbehavior.forever
        };

        rotation.beginanimation(axisanglerotation3d.angleproperty, rotateanim);
    }

    // 创建3d文字
    private geometrymodel3d create3dtext(string text, material material, point3d position)
    {
        // 简化版:创建长方体代替真正的3d文字
        meshgeometry3d mesh = new meshgeometry3d();

        // 创建立方体的8个顶点
        double size = 1.0;
        point3d[] points = new point3d[]
        {
                new point3d(-size, -size, -size),
                new point3d(size, -size, -size),
                new point3d(size, size, -size),
                new point3d(-size, size, -size),
                new point3d(-size, -size, size),
                new point3d(size, -size, size),
                new point3d(size, size, size),
                new point3d(-size, size, size)
        };

        // 添加顶点
        foreach (var point in points)
        {
            mesh.positions.add(new point3d(
                point.x + position.x,
                point.y + position.y,
                point.z + position.z));
        }

        // 添加三角形面
        int[][] triangles = new int[][]
        {
                new int[] {0, 1, 2}, new int[] {2, 3, 0}, // 前面
                new int[] {1, 5, 6}, new int[] {6, 2, 1}, // 右面
                new int[] {5, 4, 7}, new int[] {7, 6, 5}, // 后面
                new int[] {4, 0, 3}, new int[] {3, 7, 4}, // 左面
                new int[] {3, 2, 6}, new int[] {6, 7, 3}, // 上面
                new int[] {4, 5, 1}, new int[] {1, 0, 4}  // 下面
        };

        foreach (var triangle in triangles)
        {
            mesh.triangleindices.add(triangle[0]);
            mesh.triangleindices.add(triangle[1]);
            mesh.triangleindices.add(triangle[2]);
        }

        return new geometrymodel3d(mesh, material);
    }

    // 添加文字抖动动画
    private void addtextjitteranimation()
    {
        doubleanimationusingkeyframes jitteranim = new doubleanimationusingkeyframes();
        jitteranim.duration = timespan.fromseconds(10);
        jitteranim.repeatbehavior = repeatbehavior.forever;

        double basey = 0;
        for (int i = 0; i <= 100; i++)
        {
            double time = i * 0.1;
            double offset = math.sin(time * 3) * 2 +
                           math.sin(time * 7) * 1;

            jitteranim.keyframes.add(
                new lineardoublekeyframe(basey + offset,
                keytime.fromtimespan(timespan.fromseconds(time))));
        }

        storyboard.settarget(jitteranim, maingreeting);
        storyboard.settargetproperty(jitteranim,
            new propertypath("(uielement.rendertransform).(translatetransform.y)"));

        // 初始化变换
        maingreeting.rendertransform = new translatetransform();
        mainstoryboard.children.add(jitteranim);
    }

    // 开始主动画
    private void startmainanimation()
    {
        // 开始倒计时
        startcountdown();

        // 延迟开始主动画
        dispatchertimer timer = new dispatchertimer
        {
            interval = timespan.fromseconds(3.2)
        };
        timer.tick += (s, e) =>
        {
            timer.stop();
            mainstoryboard.begin();
            startsnowanimation();
        };
        timer.start();
    }

    // 开始倒计时
    private void startcountdown()
    {
        countdownpanel.visibility = visibility.visible;

        int count = 3;
        dispatchertimer countdowntimer = new dispatchertimer
        {
            interval = timespan.fromseconds(1)
        };

        countdowntimer.tick += (s, e) =>
        {
            if (count > 0)
            {
                countdowntext.text = count.tostring();

                // 添加缩放动画
                scaletransform scale = new scaletransform(1, 1);
                countdowntext.rendertransform = scale;

                doubleanimation scaleanim = new doubleanimation
                {
                    from = 3,
                    to = 1,
                    duration = timespan.fromseconds(0.3)
                };
                scale.beginanimation(scaletransform.scalexproperty, scaleanim);
                scale.beginanimation(scaletransform.scaleyproperty, scaleanim);

                count--;
            }
            else
            {
                countdowntimer.stop();
                countdownpanel.visibility = visibility.collapsed;
            }
        };
        countdowntimer.start();
    }

    // 雪花动画
    private void startsnowanimation()
    {
        for (int i = 0; i < 100; i++)
        {
            createsnowflake();
        }
    }

    private void createsnowflake()
    {
        ellipse snowflake = new ellipse
        {
            width = random.next(5, 15),
            height = random.next(5, 15),
            fill = new radialgradientbrush(
                colors.white,
                color.fromargb(150, 255, 255, 255)),
            opacity = random.nextdouble() * 0.7 + 0.3
        };

        // 随机位置
        double startx = random.nextdouble() * this.width;
        canvas.setleft(snowflake, startx);
        canvas.settop(snowflake, -20);

        snowcanvas.children.add(snowflake);
        snowflakes.add(snowflake);

        // 创建动画
        doubleanimation fallanim = new doubleanimation
        {
            to = this.height + 20,
            duration = timespan.fromseconds(random.nextdouble() * 5 + 5)
        };

        doubleanimation xanim = new doubleanimation
        {
            from = startx,
            to = startx + random.nextdouble() * 100 - 50,
            duration = fallanim.duration,
            autoreverse = true
        };

        doubleanimation opacityanim = new doubleanimation
        {
            from = snowflake.opacity,
            to = 0,
            duration = fallanim.duration
        };

        // 动画完成事件
        fallanim.completed += (s, e) =>
        {
            snowcanvas.children.remove(snowflake);
            snowflakes.remove(snowflake);
            createsnowflake();
        };

        // 开始动画
        snowflake.beginanimation(canvas.topproperty, fallanim);
        snowflake.beginanimation(canvas.leftproperty, xanim);
        snowflake.beginanimation(ellipse.opacityproperty, opacityanim);
    }

    // 烟花按钮事件
    private void fireworksbutton_click(object sender, routedeventargs e)
    {
        launchfirework(random.next(100, (int)this.width - 100),
                      this.height - 100);
    }

    // 发射烟花
    private void launchfirework(double x, double y)
    {
        // 创建上升的火花
        ellipse spark = new ellipse
        {
            width = 8,
            height = 8,
            fill = brushes.white,
            opacity = 1
        };

        canvas.setleft(spark, x);
        canvas.settop(spark, this.height);
        fireworkscanvas.children.add(spark);

        // 上升动画
        doubleanimation riseanim = new doubleanimation
        {
            to = y,
            duration = timespan.fromseconds(1)
        };

        riseanim.completed += (s, e) =>
        {
            fireworkscanvas.children.remove(spark);
            createfireworkexplosion(x, y);
        };

        spark.beginanimation(canvas.topproperty, riseanim);
    }

    // 创建烟花爆炸效果
    private void createfireworkexplosion(double x, double y)
    {
        int particles = 30;
        color[] colors = { colors.red, colors.gold, colors.orange,
                              colors.pink, colors.cyan };

        for (int i = 0; i < particles; i++)
        {
            ellipse particle = new ellipse
            {
                width = 6,
                height = 6,
                fill = new solidcolorbrush(colors[random.next(colors.length)]),
                opacity = 0.9
            };

            canvas.setleft(particle, x);
            canvas.settop(particle, y);
            fireworkscanvas.children.add(particle);
            fireworks.add(particle);

            // 计算随机方向
            double angle = random.nextdouble() * math.pi * 2;
            double distance = random.nextdouble() * 100 + 50;
            double endx = x + math.cos(angle) * distance;
            double endy = y + math.sin(angle) * distance;

            // 创建动画
            doubleanimation xanim = new doubleanimation
            {
                to = endx,
                duration = timespan.fromseconds(1)
            };

            doubleanimation yanim = new doubleanimation
            {
                to = endy,
                duration = timespan.fromseconds(1)
            };

            doubleanimation opacityanim = new doubleanimation
            {
                to = 0,
                duration = timespan.fromseconds(1)
            };

            // 动画完成事件
            opacityanim.completed += (s, e) =>
            {
                fireworkscanvas.children.remove(particle);
                fireworks.remove(particle);
            };

            // 开始动画
            particle.beginanimation(canvas.leftproperty, xanim);
            particle.beginanimation(canvas.topproperty, yanim);
            particle.beginanimation(ellipse.opacityproperty, opacityanim);
        }
    }

    // 雪花按钮事件
    private void snowbutton_click(object sender, routedeventargs e)
    {
        for (int i = 0; i < 50; i++)
        {
            createsnowflake();
        }
    }

    // 重置动画
    private void resetbutton_click(object sender, routedeventargs e)
    {
        // 清除所有动画
        mainstoryboard.stop();

        // 清除所有雪花
        foreach (var snowflake in snowflakes.tolist())
        {
            snowcanvas.children.remove(snowflake);
        }
        snowflakes.clear();

        // 清除所有烟花
        foreach (var firework in fireworks.tolist())
        {
            fireworkscanvas.children.remove(firework);
        }
        fireworks.clear();

        // 重置文字颜色
        maingreeting.foreground = new solidcolorbrush(colors.transparent);
        subgreeting.foreground = new solidcolorbrush(colors.transparent);

        // 重新开始动画
        initializeanimations();
        startmainanimation();
    }
}

运行效果:

三、动画效果说明

1. 主要动画效果

  • 3d年份旋转:数字"2026"在3d空间中持续旋转
  • 祝福文字渐变:"元旦快乐"和"新年新气象"文字从透明逐渐显现
  • 文字抖动效果:主标题有轻微的上下抖动,增加生动感
  • 星空背景:随机生成的星星带有闪烁效果
  • 雪花飘落:点击按钮可触发雪花飘落效果
  • 烟花绽放:点击按钮可在指定位置发射烟花

2. 交互功能

  • 绽放烟花按钮:在随机位置发射烟花
  • 飘落雪花按钮:增加雪花飘落数量
  • 重置动画按钮:重置所有动画到初始状态

四、技术要点

1. wpf动画系统

  • 使用storyboard管理复杂动画序列
  • 利用doubleanimation实现属性值动画
  • 通过keyframe动画创建更复杂的运动轨迹

2. 3d图形

  • 使用wpf 3d功能创建旋转的年份数字
  • 通过viewport3dmodelvisual3dgeometrymodel3d构建3d场景

3. 视觉效果

  • 利用dropshadoweffect创建文字发光效果
  • 通过渐变画刷创建丰富的色彩过渡
  • 使用透明度动画实现淡入淡出效果

五、扩展建议

  1. 添加音效:可以为烟花和倒计时添加音效
  2. 更多祝福语:可以随机显示不同的元旦祝福语
  3. 用户自定义:允许用户输入自己的祝福语
  4. 导出功能:添加导出为视频或gif的功能
  5. 响应式设计:适配不同窗口大小的布局

这个元旦祝福动画展示了wpf强大的动画和图形功能,通过代码和设计的结合,创造出既美观又有节日氛围的动画效果。您可以根据需要调整颜色、动画速度和其他参数,创建出独一无二的元旦祝福动画。

以上就是基于wpf实现元旦祝福动画效果的详细内容,更多关于wpf元旦祝福动画的资料请关注代码网其它相关文章!

(0)

相关文章:

  • WPF实现自定义控件的几种方法

    引言windows presentation foundation (wpf) 是微软提供的一种用于构建 windows 应用程序的开发框架。它以其强大的数据绑定、资源管理和可视化…

    2024年12月07日 App开发
  • WPF实现数据绑定的几种方法

    一、数据绑定概述1. 什么是数据绑定数据绑定是将应用程序的数据和 ui 元素连接起来的一种技术。在 wpf 中,数据绑定提供了一种声明性的方法,使 ui 层和业务逻辑层的代码更加分…

    2024年12月07日 App开发
  • WPF仿Tabcontrol实现切换多个不同View

    WPF仿Tabcontrol实现切换多个不同View

    在同一块区域显示不同的视图内容,直接使用tabcontrol,可能要重写tabitem的控件模板,最直接的方法通过按钮的切换,控制一个contentcontro... [阅读全文]
  • WPF如何在圆形上优雅地添加刻度线

    思路我们可以使用ellipse先画出一个圆当背景,然后用canvas再叠加画上刻度线,就能得到如下的效果我们先用ellipse画一个橙色的圆,然后将canvas的宽度和高度绑定到e…

    2024年11月22日 App开发
  • WPF实现Drawer抽屉控件

    WPF实现Drawer抽屉控件

    drawer 抽屉控件的实现框架支持.net4 至 .net8;visual studio 2022;抽屉控件的逻辑实现定义了一个名为drawer的自定义控件,... [阅读全文]
  • WPF实现图片按像素拉伸

    WPF实现图片按像素拉伸

    wpf中的图片组件,本身是支持不同的拉伸效果。具体如下:none, 不做拉伸fill 完全填充(会变形)uniform 等比缩放,不会变形uniformtofi... [阅读全文]

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com