microsoft / xaml-standard

XAML Standard : a set of principles that drive XAML dialect alignment
Other
804 stars 50 forks source link

Add path control #209

Open heyixiaoran opened 7 years ago

heyixiaoran commented 7 years ago

I found path is not in Xamarin.Forms. I work on WPF. I use a lot of path to replace .png file. So I can change the path fill color by the trigger .Don't need to change .png file and more code. Don't need to add many size of the same .png file. It is very convenient. So can you add path to xaml-standard ?

insinfo commented 7 years ago

I agree with you, but I think it's better to put SVG SMIL support in XAML Standard, SVG is an open standard and a series of tools to create and edit SVG, support SVG makes it easy to create fluid, beautiful, dynamic and animated interfaces.

Like this:

<Button>...
<SVG >
<rect id="my-rect" r="30" cx="50" cy="50" fill="orange" />
  <animate 
    xlink:href="#my-rect"
    attributeName="cx"
    from="50"
    to="450" 
    dur="1s"
    begin="click"
    fill="freeze" />
</rect>
</SVG>
...</Button>

or like this:

<Button>...
    <SVG URI="icon.svg">
    </SVG>
...</Button>

tab-bar-icons-iphone-ramotion-animation-interface-design

<Style TargetType="Button">
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundTransparentBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" />
<Setter Property="Padding" Value="8,4,8,4" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="UseSystemFocusVisuals" Value="True" />
<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="Button">
      <Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
        <VisualStateManager.VisualStateGroups>
          <VisualStateGroup x:Name="CommonStates">
            <VisualState x:Name="Normal">
              <SVG URI="Normal.svg">
              </SVG>
            </VisualState>
            <VisualState x:Name="PointerOver">
               <SVG URI="PointerOver.svg">
               </SVG>
            <VisualState x:Name="Pressed">
               <SVG>
                <rect id="my-rect" r="30" cx="50" cy="50" fill="orange" />
                <animate 
                    xlink:href="#my-rect"
                    attributeName="cx"
                    from="50"
                    to="450" 
                    dur="1s"
                    begin="click"
                    fill="freeze" />
                </rect>
              </SVG>
            </VisualState>
            <VisualState x:Name="Disabled">
              <SVG URI="Disabled.svg">
                </SVG>
            </VisualState>
          </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <ContentPresenter x:Name="ContentPresenter"
                          BorderBrush="{TemplateBinding BorderBrush}"
                          BorderThickness="{TemplateBinding BorderThickness}"
                          Content="{TemplateBinding Content}"
                          ContentTransitions="{TemplateBinding ContentTransitions}"
                          ContentTemplate="{TemplateBinding ContentTemplate}"
                          Padding="{TemplateBinding Padding}"
                          HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                          VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                          AutomationProperties.AccessibilityView="Raw"/>
      </Grid>
    </ControlTemplate>
  </Setter.Value>
</Setter>
</Style>

https://github.com/Microsoft/xaml-standard/issues/112

heyixiaoran commented 7 years ago

@insinfo Yes. SVG is also good way . But SVG contain path data. So I think path is more base and more flexible. As your code. If you want ten buttons. You need have ten button template. I modify a template. You just provide path data .It's ok. And you can control it like a button

`<Button x:Class="PathButton.PathButton" 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" Style="{DynamicResource PathButtonStyle}" d:DesignHeight="300" d:DesignWidth="300" mc:Ignorable="d">

<Button.Resources>
    <Style x:Key="FocusVisual">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <Rectangle Margin="2"
                               SnapsToDevicePixels="true"
                               Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
                               StrokeDashArray="1 2"
                               StrokeThickness="1" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="PathButtonStyle"
           TargetType="{x:Type Button}">
        <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}" />
        <Setter Property="Background" Value="#00000000" />
        <Setter Property="BorderBrush" Value="#00000000" />
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
        <Setter Property="BorderThickness" Value="0,1,1,1" />
        <Setter Property="HorizontalContentAlignment" Value="Center" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="Padding" Value="1" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border x:Name="border"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            SnapsToDevicePixels="true">
                        <Path x:Name="Path"
                              Data="{Binding PathData}"
                              Fill="{Binding DefaultFillBrush}"
                              RenderTransformOrigin="0.5,0.5"
                              Stretch="Uniform" />
                    </Border>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsDefaulted" Value="True">
                            <Setter TargetName="Path" Property="Fill" Value="{Binding DefaultFillBrush}" />
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="Path" Property="Fill" Value="{Binding MouseOverBrush}" />
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter TargetName="Path" Property="Fill" Value="{Binding IsPressedBrush}" />
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter TargetName="Path" Property="Fill" Value="{Binding IsEnabledBrush}" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Button.Resources>

`

Use like this

<pathButton:PathButton x:Name="Button" Width="50" Height="50" PathData="M31.679651,15.723C22.841078,15.723 15.677,22.887022 15.677,31.724249 15.677,40.562878 22.841078,47.727002 31.679651,47.727002 40.518124,47.727002 47.682003,40.562878 47.682003,31.724249 47.682003,22.887022 40.518124,15.723 31.679651,15.723z M25.174641,0L30.947304,8.1649995 30.977009,8.163671C31.891628,8.1361193,32.811726,8.1617675,33.732849,8.2423577L34.116646,8.2807278 40.096367,0.5289996 49.181995,4.5158782 47.510448,14.236901 47.626137,14.339919C48.479649,15.11912,49.268909,15.955267,49.990528,16.839653L50.234638,17.14785 60.403648,15.836 64.007996,25.079203 55.322643,31.217757 55.324234,31.258986C55.34618,32.174153,55.314838,33.094563,55.22847,34.015755L55.226952,34.030385 63.345997,40.294331 59.359104,49.380002 49.249798,47.645153 49.143776,47.764214C48.695721,48.255009,48.228832,48.72456,47.744774,49.172226L47.324875,49.549786 48.723995,60.394425 39.48156,64 33.403603,55.403061 33.023663,55.43042C32.149929,55.481137,31.270197,55.483376,30.38839,55.435608L29.679308,55.383191 23.130268,63.875 14.041999,59.886834 15.844025,49.393521 15.71986,49.282948C15.207753,48.815411,14.718776,48.32737,14.253661,47.820706L13.803129,47.315312 3.612031,48.630002 0.0080004195,39.385499 8.0905037,33.673707 8.0481892,33.048829C7.9875851,31.908507,8.0095654,30.758269,8.1175261,29.606822L8.1191311,29.59272 0,23.328246 3.9867127,14.242 14.093521,15.978928 14.104487,15.966273C15.033746,14.935561,16.045525,13.997155,17.124784,13.156928L17.159048,13.131042 15.929999,3.6040602z" Click="Button_OnClick"/>

You can search PathButton from Nuget . And Metro Studio provide 5K+ . I also can make a path though Blend . Is very easy.

insinfo commented 7 years ago

Yes, what I posted was just an example, this can and should be improved, the great advantage I see of SVG SMIL is that the developer would not have to worry about the graphics and the animations, the designer would do the graphics and the animations in the software of its choice and would deliver the SVGs already ready for the developer

heyixiaoran commented 7 years ago

Sorry I don‘t use SVG before . So you mean SVG is contains animation? If Yes .It's so cool . Thank you for let me know it.

insinfo commented 7 years ago

Yes SVG support animations: Currently it is possible to do SVG animations in 4 ways, natively the SVG specification provides for the "SMIL" language integrated within the SVG to be used in the animations or by "CSS Animations" within SVG, or even by "WEB Animations", or even pure "Javascript", all these specifications and standards are from W3C. Currently Firefox, Chrome, Opera, Safari, Android and IOS support SMIL

insinfo commented 7 years ago

http://www.bifter.co.uk/issues/17.svg http://www.bifter.co.uk/issue/17/ http://www.joningram.co.uk/article/svg-smil-frame-animation/ https://codyhouse.co/gem/animate-svg-icons-with-css-and-snap/ https://css-tricks.com/guide-svg-animations-smil/

Browser Support and Fallbacks Browser support for SMIL animations is pretty decent. They work in all browsers except in Internet Explorer and Opera Mini. For a thorough overview of browser support, you can refer to the compatibility table on Can I Use.

If you need to provide a fallback for SMIL animations, you can test for browser support on-the-fly using Modernizr. If SMIL is not supported, you can then provide some kind of fallback (JavaScript animations, an alternate experience, etc).

michael-hawker commented 7 years ago

@insinfo from what I've been reading looks like SMIL is being moved away from on the web: https://developer.mozilla.org/en-US/docs/Web/SVG/SVG_animation_with_SMIL https://wpdev.uservoice.com/forums/257854-microsoft-edge-developer/suggestions/6509024-svg-animation-elements

It's even called out in the article you linked to on css-tricks.

insinfo commented 7 years ago

In fact, google chrome is the only one that has marked SMIL as deprecated, but will still support it for a while, since there is not yet a standard that is complete like SMIL, WEB Animation is still in development and has not been finalized by W3C and CSS Animations is not as complete as SMIL.

juepiezhongren commented 7 years ago

path is a requested, but considering it is relatively low element, there should be interface just like IPathRender provided where both skiasharp or cairo or things else could come to do the actual work!