[CGPP] WPF2D-Clock

文章目录[x]
  1. 1:v.03
  2. 1.1:课内练习 2.1
  3. 1.2:课内练习 2.2
  4. 1.3:课内练习 2.3
  5. 1.4:结果
  6. 2:v.06 & 课内练习2.6, 2.7
  7. 2.1:课内练习2.4
  8. 3:v.06 & 课内练习2.8

CGPP即为《计算机图形学:原理与实践》
本书配套资料网站:Computer Graphics: Principles and Practice, 3rd Edition
点击 Ch.2 Lab 即可下载Lab

 

新建一个Clock.xaml,然后在 MainWindow 中写入以下代码

public MainWindow()
{
    InitializeComponent();

    var clock = new Chapter2.Clock();
    Content = clock;
}

 

v.03


<Canvas x:Class="CGPP.Chapter2.Clock"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Name="ClockCanvas" >
    
    <Ellipse Canvas.Left="-10.0" Canvas.Top="-10"
             Width="20.0" Height="20.0"
             Fill="LightGray" />

    <!-- Display Transformation -->
    <Canvas.RenderTransform>

        <TransformGroup>
            <!-- WPF中96个单位=1英寸 圆的抽象直径为20 要显示为一英寸 就要缩放96/20 = 4.8 -->
            <ScaleTransform ScaleX="4.8" ScaleY="4.8" CenterX="0" CenterY="0" />   <!-- 先缩放 -->
            <TranslateTransform X="48" Y="48" />  <!-- 再平移-->
        </TransformGroup>

    </Canvas.RenderTransform>
    
</Canvas>

 

课内练习 2.1


描述:调换 ScaleTransform 和 TranslateTransform 的顺序,观察结果,然后调整数值使其恢复我们所要的绘制结果。

结果:圆到原点的距离也被缩放了,所以圆距离原点更远了。

调整:

<TranslateTransform X="10" Y="10" />  <!-- 48 / 4.8 因为正确的结果为48,而下一步要被乘以4.8,所以这里就是10 -->
<ScaleTransform ScaleX="4.8" ScaleY="4.8" CenterX="0" CenterY="0" />

 

课内练习 2.2


描述:现在的圆紧挨着上边界和左边界,试修改 v.03 使圆向右移动1/8英寸,向下移动1/8英寸

<ScaleTransform ScaleX="4.8" ScaleY="4.8" CenterX="0" CenterY="0" />
<TranslateTransform X="48" Y="48" />
<TranslateTransform X="12" Y="12" />

毫无难度,再执行一次平移变换即可

 

课内练习 2.3


对 v.03 进行编辑,增加一个小蓝点作为  12:00 的标记

<!-- 12点 -->
<Ellipse Canvas.Left="-1" Canvas.Top="-10"
         Width="2" Height="2"
         Fill="Blue"/>

这样写就可以啦。

 

结果


 

v.06 & 课内练习2.6, 2.7


<Canvas x:Class="CGPP.Chapter2.Clock"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Name="ClockCanvas" >

    <Canvas.Resources>
        <ControlTemplate x:Key="ClockHandTemplate">
            <Canvas>
                <Polygon Points="-0.3,-1 -0.2,8 0,9 0.2,8 0.3,-1" Fill="Navy"/>
                <Line X1="0" Y1="-0.8" X2="0" Y2="8.4" Stroke="White" 
                      StrokeThickness="0.15" StrokeDashArray="7 2" StrokeDashCap="Round"
                      StrokeStartLineCap="Triangle" StrokeEndLineCap="Triangle" />
            </Canvas>
        </ControlTemplate>
        
        <ControlTemplate x:Key="ClockHandTemplateThick">
            <Polygon Points="-0.1,-1 -0.05,8 0,10 0.05,8 0.1,-1" Fill="Red"/>
        </ControlTemplate>
    </Canvas.Resources>
    
    <!-- The clock face -->
    <Ellipse Canvas.Left="-10.0" Canvas.Top="-10"
             Width="20.0" Height="20.0"
             Fill="LightGray" />

    <!-- 12点 -->
    <Ellipse Canvas.Left="-1" Canvas.Top="-10"
             Width="2" Height="2"
             Fill="Blue"/>
    
    <Control x:Name="HourHand" Template="{StaticResource ClockHandTemplate}" >
        <Control.RenderTransform>
            <TransformGroup>
                <ScaleTransform ScaleX="1.7" ScaleY="0.7" CenterX="0" CenterY="0"/>
                <RotateTransform Angle="45" CenterX="0" CenterY="0" />
            </TransformGroup>
        </Control.RenderTransform>
    </Control>
    
    <!-- The Minute Hand -->
    <Control x:Name="MinuteHand" Template="{StaticResource ClockHandTemplate}" />

    <Control x:Name="SecondHand"  Template="{StaticResource ClockHandTemplateThick}">
        <Control.RenderTransform>
            <TransformGroup>
                <RotateTransform Angle="30"/>
            </TransformGroup>
        </Control.RenderTransform>
    </Control>


    <!-- Display Transformation -->
    <Canvas.RenderTransform>

        <TransformGroup>
            <!-- WPF中96个单位=1英寸 圆的抽象直径为20 要显示为一英寸 就要缩放96/20 = 4.8 -->
            <ScaleTransform ScaleX="4.8" ScaleY="4.8" CenterX="0" CenterY="0" />
            <TranslateTransform X="48" Y="48" />
            <TranslateTransform X="12" Y="12" />
        </TransformGroup>

    </Canvas.RenderTransform>
    
</Canvas>

课内练习2.6 描述:创建一个新的源模板,来构造一根细的红色秒针
课内练习2.7描述:在时钟模板中添加一些新的元素(例如:沿着指针方向添加一条中分细线)

 

课内练习2.4


描述:请重新开启一个空白画布,添加所需XAML代码来构造一个时间定为在1:45的时钟。如果你愿意,也可以在添加一个表示12:00的圆点

<Canvas x:Class="CGPP.Chapter2.ExceriseClock"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CGPP.Chapter2"
        mc:Ignorable="d">

    <!-- 显示 1:45 -->

    <Canvas.Resources>
        <ControlTemplate x:Key="ClockHandTemplate">
            <Polygon Points="-0.3,-1 -0.2,8 0,9 0.2,8 0.3,-1" Fill="Navy"/>
        </ControlTemplate>
    </Canvas.Resources>

    <Ellipse Canvas.Left="-10" Canvas.Top="-10"
             Width="20" Height="20"
             Fill="LightGray"/>

    <Ellipse Canvas.Left="-1" Canvas.Top="-10"
             Width="2" Height="2"
             Fill="CadetBlue"/>

    <Control x:Name="HourHand" Template="{StaticResource ClockHandTemplate}" >
        <Control.RenderTransform>
            <TransformGroup>
                <ScaleTransform ScaleX="1.7" ScaleY="0.7" />
                <RotateTransform Angle="-150" CenterX="0" CenterY="0" />
            </TransformGroup>
        </Control.RenderTransform>
    </Control>

    <Control x:Name="MinuteHand" Template="{StaticResource ClockHandTemplate}" >
        <Control.RenderTransform>
            <TransformGroup>
                <RotateTransform Angle="90" CenterX="0" CenterY="0" />
            </TransformGroup>
        </Control.RenderTransform>
    </Control>

    <Canvas.RenderTransform>
        <TransformGroup>
            <ScaleTransform ScaleX="4.8" ScaleY="4.8"/>
            <TranslateTransform X="48" Y="48" />
        </TransformGroup>
    </Canvas.RenderTransform>

</Canvas>

 

v.06 & 课内练习2.8


<Control x:Name="HourHand" Template="{StaticResource ClockHandTemplate}" >
        <Control.RenderTransform>
            <TransformGroup>
                <ScaleTransform ScaleX="1.7" ScaleY="0.7" CenterX="0" CenterY="0"/>
                <!-- Rotate into 12 o'clock default position -->
                <RotateTransform Angle="180" CenterX="0" CenterY="0" />
                <!-- Additional rotation for animation to show actual time -->
                <RotateTransform x:Name="ActualTimeHour" Angle="0" />
            </TransformGroup>
        </Control.RenderTransform>
    </Control>
    
    <!-- The Minute Hand -->
    <Control x:Name="MinuteHand" Template="{StaticResource ClockHandTemplate}" >
        <Control.RenderTransform>
            <TransformGroup>
                <RotateTransform Angle="180" CenterX="0" CenterY="0"/>
                <RotateTransform x:Name="ActualTimeMinute" Angle="0"/>
            </TransformGroup>
        </Control.RenderTransform>
    </Control>

    <Control x:Name="SecondHand"  Template="{StaticResource ClockHandTemplateThick}">
        <Control.RenderTransform>
            <TransformGroup>
                <RotateTransform Angle="30" CenterX="0" CenterY="0"/>
                <RotateTransform x:Name="ActualTimeSecond" Angle="0"/>
            </TransformGroup>
        </Control.RenderTransform>
    </Control>

    <!-- Animate HourHand/MinuteHand/SecondHand-->
    <Canvas.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <!-- THE HOUR HAND, currently rotating at a frenetic pace for demo's sake... -->
                    <DoubleAnimation 
                        Storyboard.TargetName="ActualTimeHour"
                        Storyboard.TargetProperty="Angle" 
                        From="0.0" To="360.0"
                        Duration="23:59:59.00" RepeatBehavior="Forever" />
                    <DoubleAnimation
                        Storyboard.TargetName="ActualTimeMinute"
                        Storyboard.TargetProperty="Angle" 
                        From="0.0" To="360.0" 
                        Duration="00:59:59.00" RepeatBehavior="Forever" />
                    <DoubleAnimation 
                        Storyboard.TargetName="ActualTimeSecond"
                        Storyboard.TargetProperty="Angle"
                        From="0.0" To="360.0" 
                        Duration="00:00:59.00" RepeatBehavior="Forever" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Canvas.Triggers>

课内练习2.8描述:给分针和秒针增加动画,并且要求时间和现实同步(这个没写)

 

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像