├── .editorconfig ├── .gitattributes ├── .gitignore ├── DesignAndAnimationLab ├── CodeMaid.config ├── DesignAndAnimationLab.sln ├── DesignAndAnimationLab.sln.DotSettings ├── DesignAndAnimationLab │ ├── AnimationTimelines │ │ ├── BackEase.cs │ │ ├── BounceEase.cs │ │ ├── CircleEase.cs │ │ ├── CubicEase.cs │ │ ├── DoubleTimeline.cs │ │ ├── EasingFunctionBase.cs │ │ ├── EasingMode.cs │ │ ├── ElasticEase.cs │ │ ├── ExponentialEase.cs │ │ ├── PowerEase.cs │ │ ├── QuadraticEase.cs │ │ ├── QuarticEase.cs │ │ ├── QuinticEase.cs │ │ ├── SineEase.cs │ │ ├── TimelineProgresser.cs │ │ └── Vector2Timeline.cs │ ├── App.xaml │ ├── App.xaml.cs │ ├── Assets │ │ ├── BrushAssets │ │ │ └── NoiseTexture.png │ │ ├── Fonts │ │ │ └── Richasy_BiliBili.ttf │ │ ├── Images │ │ │ ├── heart.png │ │ │ ├── macOS-Catalina-Dark-Mode.jpg │ │ │ ├── mask.png │ │ │ ├── sea.jpg │ │ │ ├── sea2.jpg │ │ │ ├── tuna_sprite.png │ │ │ └── wallpaper.jpg │ │ ├── LockScreenLogo.scale-200.png │ │ ├── SplashScreen.scale-200.png │ │ ├── Square150x150Logo.scale-200.png │ │ ├── Square44x44Logo.scale-200.png │ │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ │ ├── StoreLogo.png │ │ └── Wide310x150Logo.scale-200.png │ ├── BlankPage1.xaml │ ├── BlankPage1.xaml.cs │ ├── Common │ │ ├── DoubleUtil.cs │ │ ├── Extensions.cs │ │ ├── Utils.cs │ │ └── VisualExtensions.cs │ ├── Controls │ │ ├── GeometryCreator.cs │ │ ├── GooeyButton.cs │ │ ├── GooeyButton.xaml │ │ ├── GooeyButtonItem.cs │ │ ├── GooeyButtonItem.xaml │ │ ├── GooeyButtonItemsPanel.cs │ │ ├── InnerShadowBox.cs │ │ ├── InnerShadowBox.xaml │ │ ├── ProgressButton.Constants.cs │ │ ├── ProgressButton.Properties.cs │ │ ├── ProgressButton.cs │ │ └── ProgressState.cs │ ├── Demos │ │ ├── AcrylicAndBlur │ │ │ ├── AcrylicAndBlurDemo.xaml │ │ │ ├── AcrylicAndBlurDemo.xaml.cs │ │ │ └── HostBackdropBlurBrush.cs │ │ ├── BlendMixImage │ │ │ ├── BlendMixImage.xaml │ │ │ └── BlendMixImage.xaml.cs │ │ ├── BlendMixText │ │ │ ├── BlendMixText.xaml │ │ │ └── BlendMixText.xaml.cs │ │ ├── BubbleButton │ │ │ ├── Bubble.cs │ │ │ ├── BubbleButtonDemo.xaml │ │ │ ├── BubbleButtonDemo.xaml.cs │ │ │ ├── BubbleView.cs │ │ │ └── SimpleShadowPanel.cs │ │ ├── ControlCenter │ │ │ ├── ControlCenterDemo.xaml │ │ │ └── ControlCenterDemo.xaml.cs │ │ ├── GalaxyShuttles │ │ │ ├── Galaxy.png │ │ │ ├── GalaxyShuttleControl.xaml │ │ │ ├── GalaxyShuttleControl.xaml.cs │ │ │ ├── GalaxyShuttleDemo.xaml │ │ │ └── GalaxyShuttleDemo.xaml.cs │ │ ├── GlitchArtDemo │ │ │ ├── GlitchArtDemoPage.xaml │ │ │ ├── GlitchArtDemoPage.xaml.cs │ │ │ ├── GlitchArtWithManyWordsDemoPage.xaml │ │ │ ├── GlitchArtWithManyWordsDemoPage.xaml.cs │ │ │ ├── GlitchText.xaml │ │ │ ├── GlitchText.xaml.cs │ │ │ ├── GlitchText2.xaml │ │ │ ├── GlitchText2.xaml.cs │ │ │ ├── GlitchText3.xaml │ │ │ ├── GlitchText3.xaml.cs │ │ │ └── TextToBrushWrapper.cs │ │ ├── Gooey │ │ │ ├── ColorMatrixPipelineEffect.cs │ │ │ ├── GooeyDemo.xaml │ │ │ ├── GooeyDemo.xaml.cs │ │ │ ├── GooeyEllipseDemo2Page.xaml │ │ │ ├── GooeyEllipseDemo2Page.xaml.cs │ │ │ ├── GooeyEllipseDemoPage.xaml │ │ │ ├── GooeyEllipseDemoPage.xaml.cs │ │ │ ├── GooeyEllipsePixelShaderPage.xaml │ │ │ ├── GooeyEllipsePixelShaderPage.xaml.cs │ │ │ ├── GooeyFooter.xaml │ │ │ ├── GooeyFooter.xaml.cs │ │ │ ├── GooeyFooter2.xaml │ │ │ ├── GooeyFooter2.xaml.cs │ │ │ ├── TextMorph.xaml │ │ │ └── TextMorph.xaml.cs │ │ ├── GooeyButtonDemo │ │ │ ├── GooeyButtonDemoPage.xaml │ │ │ └── GooeyButtonDemoPage.xaml.cs │ │ ├── InnerShadow │ │ │ ├── InnerShadowDemo.xaml │ │ │ └── InnerShadowDemo.xaml.cs │ │ ├── LikeButtons │ │ │ ├── LikeButtonsDemo.xaml │ │ │ ├── LikeButtonsDemo.xaml.cs │ │ │ ├── MattHenleysLikeButton.xaml │ │ │ └── MattHenleysLikeButton.xaml.cs │ │ ├── LiquidFill │ │ │ ├── LiquidFill.xaml │ │ │ ├── LiquidFill.xaml.cs │ │ │ └── WaveCircle.cs │ │ ├── PopupUserControl │ │ │ ├── AppPopupExtensions.cs │ │ │ ├── IAppPopup.cs │ │ │ ├── PopupUserControlDemo.xaml │ │ │ ├── PopupUserControlDemo.xaml.cs │ │ │ ├── UpdatePopup.xaml │ │ │ └── UpdatePopup.xaml.cs │ │ ├── ThreeActionsWithOneClick │ │ │ ├── ThreeActionsWithOneClick.xaml │ │ │ └── ThreeActionsWithOneClick.xaml.cs │ │ ├── TransparentCube │ │ │ ├── TransparentCube.xaml │ │ │ └── TransparentCube.xaml.cs │ │ └── WalkingCat │ │ │ ├── WalkingCat.xaml │ │ │ └── WalkingCat.xaml.cs │ ├── DesignAndAnimationLab.csproj │ ├── Infrastructure │ │ ├── ExampleDefinition.cs │ │ ├── ExamplePage.xaml │ │ ├── ExamplePage.xaml.cs │ │ ├── NavigationHelper.cs │ │ ├── RelayCommand.cs │ │ └── SuspensionManager.cs │ ├── MainPage.xaml │ ├── MainPage.xaml.cs │ ├── Package.appxmanifest │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ └── Default.rd.xml │ ├── Shaders │ │ ├── CompileShaders.cmd │ │ ├── OpacityThreshold.bin │ │ ├── OpacityThreshold.hlsl │ │ ├── SmoothOpacityThreshold.bin │ │ └── SmoothOpacityThreshold.hlsl │ ├── Themes │ │ ├── BubbleButton.xaml │ │ ├── BubbleButtonStyle.xaml │ │ ├── Generic.xaml │ │ └── ProgressButton.xaml │ └── Thumbnails │ │ ├── AcrylicandBlur.png │ │ ├── BlendMixImage.png │ │ ├── BlendMixText.png │ │ ├── BubbleButton.png │ │ ├── ControlCenter.png │ │ ├── GalaxyShuttle.png │ │ ├── GlitchArt.png │ │ ├── GlitchArtManyWords.png │ │ ├── GooeyButton.png │ │ ├── GooeyEllipse.png │ │ ├── GooeyEllipse2.png │ │ ├── GooeyEllipsePixelShader.png │ │ ├── GooeyFooter.png │ │ ├── GooeyFooter2.png │ │ ├── PopupUserControl.png │ │ ├── TextMorph.png │ │ ├── ThreeActionsWithOneClick.png │ │ ├── TransparentCube.png │ │ ├── TwitterLikeButton.png │ │ └── WalkingCat.png ├── Settings.XamlStyler └── Thumbnails │ ├── BubbleButton.png │ ├── Glitch Art.gif │ ├── GooeyButton.gif │ └── TransparentCube.png ├── LICENSE └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /DesignAndAnimationLab/CodeMaid.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | True 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29519.181 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DesignAndAnimationLab", "DesignAndAnimationLab\DesignAndAnimationLab.csproj", "{3338AFD0-4006-40C6-8677-EB1B4D37E1B3}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM = Debug|ARM 11 | Debug|ARM64 = Debug|ARM64 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|ARM = Release|ARM 15 | Release|ARM64 = Release|ARM64 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Debug|ARM.ActiveCfg = Debug|ARM 21 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Debug|ARM.Build.0 = Debug|ARM 22 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Debug|ARM.Deploy.0 = Debug|ARM 23 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Debug|ARM64.ActiveCfg = Debug|ARM64 24 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Debug|ARM64.Build.0 = Debug|ARM64 25 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Debug|ARM64.Deploy.0 = Debug|ARM64 26 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Debug|x64.ActiveCfg = Debug|x64 27 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Debug|x64.Build.0 = Debug|x64 28 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Debug|x64.Deploy.0 = Debug|x64 29 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Debug|x86.ActiveCfg = Debug|x86 30 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Debug|x86.Build.0 = Debug|x86 31 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Debug|x86.Deploy.0 = Debug|x86 32 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Release|ARM.ActiveCfg = Release|ARM 33 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Release|ARM.Build.0 = Release|ARM 34 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Release|ARM.Deploy.0 = Release|ARM 35 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Release|ARM64.ActiveCfg = Release|ARM64 36 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Release|ARM64.Build.0 = Release|ARM64 37 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Release|ARM64.Deploy.0 = Release|ARM64 38 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Release|x64.ActiveCfg = Release|x64 39 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Release|x64.Build.0 = Release|x64 40 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Release|x64.Deploy.0 = Release|x64 41 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Release|x86.ActiveCfg = Release|x86 42 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Release|x86.Build.0 = Release|x86 43 | {3338AFD0-4006-40C6-8677-EB1B4D37E1B3}.Release|x86.Deploy.0 = Release|x86 44 | EndGlobalSection 45 | GlobalSection(SolutionProperties) = preSolution 46 | HideSolutionNode = FALSE 47 | EndGlobalSection 48 | GlobalSection(ExtensibilityGlobals) = postSolution 49 | SolutionGuid = {676DCC7E-B5C8-4197-BBFB-65F07B551E8E} 50 | EndGlobalSection 51 | EndGlobal 52 | -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | <?xml version="1.0" encoding="utf-16"?><Profile name="Copy of Built-in: Full Cleanup 1"><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><CSReorderTypeMembers>True</CSReorderTypeMembers><CSCodeStyleAttributes ArrangeVarStyle="True" ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" ArrangeArgumentsStyle="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeCodeBodyStyle="True" ArrangeTrailingCommas="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" /><CssAlphabetizeProperties>True</CssAlphabetizeProperties><JSStringLiteralQuotesDescriptor>True</JSStringLiteralQuotesDescriptor><CorrectVariableKindsDescriptor>True</CorrectVariableKindsDescriptor><VariablesToInnerScopesDescriptor>True</VariablesToInnerScopesDescriptor><StringToTemplatesDescriptor>True</StringToTemplatesDescriptor><JsInsertSemicolon>True</JsInsertSemicolon><RemoveRedundantQualifiersTs>True</RemoveRedundantQualifiersTs><OptimizeImportsTs>True</OptimizeImportsTs><OptimizeReferenceCommentsTs>True</OptimizeReferenceCommentsTs><PublicModifierStyleTs>True</PublicModifierStyleTs><ExplicitAnyTs>True</ExplicitAnyTs><TypeAnnotationStyleTs>True</TypeAnnotationStyleTs><RelativePathStyleTs>True</RelativePathStyleTs><AsInsteadOfCastTs>True</AsInsteadOfCastTs><RemoveCodeRedundanciesVB>True</RemoveCodeRedundanciesVB><Xaml.RedundantFreezeAttribute>True</Xaml.RedundantFreezeAttribute><Xaml.RemoveRedundantModifiersAttribute>True</Xaml.RemoveRedundantModifiersAttribute><Xaml.RemoveRedundantCollectionProperty>True</Xaml.RemoveRedundantCollectionProperty><Xaml.RemoveRedundantAttachedPropertySetter>True</Xaml.RemoveRedundantAttachedPropertySetter><Xaml.RemoveRedundantStyledValue>True</Xaml.RemoveRedundantStyledValue><Xaml.RemoveRedundantNamespaceAlias>True</Xaml.RemoveRedundantNamespaceAlias><Xaml.RemoveForbiddenResourceName>True</Xaml.RemoveForbiddenResourceName><Xaml.RemoveRedundantGridDefinitionsAttribute>True</Xaml.RemoveRedundantGridDefinitionsAttribute><Xaml.RemoveRedundantUpdateSourceTriggerAttribute>True</Xaml.RemoveRedundantUpdateSourceTriggerAttribute><Xaml.RemoveRedundantBindingModeAttribute>True</Xaml.RemoveRedundantBindingModeAttribute><Xaml.RemoveRedundantGridSpanAttribut>True</Xaml.RemoveRedundantGridSpanAttribut><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CssReformatCode>True</CssReformatCode><HtmlReformatCode>True</HtmlReformatCode><JsReformatCode>True</JsReformatCode><JsFormatDocComments>True</JsFormatDocComments><VBOptimizeImports>True</VBOptimizeImports><VBShortenReferences>True</VBShortenReferences><XMLReformatCode>True</XMLReformatCode><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><VBReformatCode>True</VBReformatCode><VBFormatDocComments>True</VBFormatDocComments><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor></Profile> 3 | Copy of Built-in: Full Cleanup 1 4 | Copy of Built-in: Full Cleanup 1 5 | True -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/BackEase.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | // 6 | 7 | using System; 8 | 9 | namespace DesignAndAnimationLab.AnimationTimelines 10 | { 11 | /// 12 | /// This class implements an easing function that backs up before going to the destination. 13 | /// 14 | public class BackEase : EasingFunctionBase 15 | { 16 | /// 17 | /// Specifies how much the function will pull back 18 | /// 19 | public double Amplitude { get; set; } = 1.0; 20 | 21 | protected override double EaseInCore(double normalizedTime) 22 | { 23 | var amp = Math.Max(0.0, Amplitude); 24 | return Math.Pow(normalizedTime, 3.0) - normalizedTime * amp * Math.Sin(Math.PI * normalizedTime); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/BounceEase.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | // 6 | 7 | using System; 8 | using DesignAndAnimationLab.Common; 9 | 10 | namespace DesignAndAnimationLab.AnimationTimelines 11 | { 12 | /// 13 | /// This class implements an easing function that can be used to simulate bouncing 14 | /// 15 | public class BounceEase : EasingFunctionBase 16 | { 17 | /// 18 | /// Specifies the number of bounces. This does not include the final half bounce. 19 | /// 20 | public int Bounces { get; set; } = 3; 21 | 22 | /// 23 | /// Specifies the amount of bounciness. This corresponds to the scale difference between a bounce and the next bounce. 24 | /// For example, Bounciness = 2.0 correspondes to the next bounce being twices as high and taking twice as long. 25 | /// 26 | public double Bounciness { get; set; } = 2.0; 27 | 28 | protected override double EaseInCore(double normalizedTime) 29 | { 30 | // The math below is complicated because we have a few requirements to get the correct look for bounce: 31 | // 1) The bounces should be symetrical 32 | // 2) Bounciness should control both the amplitude and the period of the bounces 33 | // 3) Bounces should control the number of bounces without including the final half bounce to get you back to 1.0 34 | // 35 | // Note: Simply modulating a expo or power curve with a abs(sin(...)) wont work because it violates 1) above. 36 | // 37 | 38 | // Constants 39 | var bounces = Math.Max(0.0, Bounces); 40 | var bounciness = Bounciness; 41 | 42 | // Clamp the bounciness so we dont hit a divide by zero 43 | if (bounciness < 1.0 || DoubleUtil.IsOne(bounciness)) 44 | { 45 | // Make it just over one. In practice, this will look like 1.0 but avoid divide by zeros. 46 | bounciness = 1.001; 47 | } 48 | 49 | var pow = Math.Pow(bounciness, bounces); 50 | var oneMinusBounciness = 1.0 - bounciness; 51 | 52 | // 'unit' space calculations. 53 | // Our bounces grow in the x axis exponentially. we define the first bounce as having a 'unit' width of 1.0 and compute 54 | // the total number of 'units' using a geometric series. 55 | // We then compute which 'unit' the current time is in. 56 | var sumOfUnits = 57 | (1.0 - pow) / oneMinusBounciness + pow * 0.5; // geometric series with only half the last sum 58 | var unitAtT = normalizedTime * sumOfUnits; 59 | 60 | // 'bounce' space calculations. 61 | // Now that we know which 'unit' the current time is in, we can determine which bounce we're in by solving the geometric equation: 62 | // unitAtT = (1 - bounciness^bounce) / (1 - bounciness), for bounce. 63 | var bounceAtT = Math.Log(-unitAtT * (1.0 - bounciness) + 1.0, bounciness); 64 | var start = Math.Floor(bounceAtT); 65 | var end = start + 1.0; 66 | 67 | // 'time' space calculations. 68 | // We then project the start and end of the bounce into 'time' space 69 | var startTime = (1.0 - Math.Pow(bounciness, start)) / (oneMinusBounciness * sumOfUnits); 70 | var endTime = (1.0 - Math.Pow(bounciness, end)) / (oneMinusBounciness * sumOfUnits); 71 | 72 | // Curve fitting for bounce. 73 | var midTime = (startTime + endTime) * 0.5; 74 | var timeRelativeToPeak = normalizedTime - midTime; 75 | var radius = midTime - startTime; 76 | var amplitude = Math.Pow(1.0 / bounciness, bounces - start); 77 | 78 | // Evaluate a quadratic that hits (startTime,0), (endTime, 0), and peaks at amplitude. 79 | return -amplitude / (radius * radius) * (timeRelativeToPeak - radius) * (timeRelativeToPeak + radius); 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/CircleEase.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | // 6 | 7 | using System; 8 | 9 | namespace DesignAndAnimationLab.AnimationTimelines 10 | { 11 | /// 12 | /// This class implements an easing function that gives a circular curve toward the destination. 13 | /// 14 | public class CircleEase : EasingFunctionBase 15 | { 16 | protected override double EaseInCore(double normalizedTime) 17 | { 18 | normalizedTime = Math.Max(0.0, Math.Min(1.0, normalizedTime)); 19 | return 1.0 - Math.Sqrt(1.0 - normalizedTime * normalizedTime); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/CubicEase.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | // 6 | 7 | namespace DesignAndAnimationLab.AnimationTimelines 8 | { 9 | /// 10 | /// This class implements an easing function that gives a cubic curve toward the destination 11 | /// 12 | public class CubicEase : EasingFunctionBase 13 | { 14 | protected override double EaseInCore(double normalizedTime) => normalizedTime * normalizedTime * normalizedTime; 15 | } 16 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/DoubleTimeline.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Windows.UI.Xaml; 3 | 4 | namespace DesignAndAnimationLab.AnimationTimelines 5 | { 6 | public class DoubleTimeline 7 | { 8 | private readonly TimelineProgresser _progresser; 9 | 10 | public DoubleTimeline(double from = 0, double to = 1, double seconds = 1, TimeSpan? beginTime = null, 11 | bool autoReverse = true, bool forever = true, EasingFunctionBase easingFunction = null) 12 | { 13 | _progresser = new TimelineProgresser(seconds, autoReverse) 14 | { 15 | EasingFunction = easingFunction, BeginTime = beginTime, Forever = forever 16 | }; 17 | From = from; 18 | To = to; 19 | Duration = new Duration(TimeSpan.FromSeconds(seconds)); 20 | AutoReverse = autoReverse; 21 | BeginTime = beginTime; 22 | Forever = forever; 23 | } 24 | 25 | public bool AutoReverse { get; } 26 | public TimeSpan? BeginTime { get; } 27 | public Duration Duration { get; } 28 | public bool Forever { get; } 29 | public double From { get; } 30 | public double To { get; } 31 | 32 | public double GetCurrentProgress(TimeSpan timeSpan) 33 | { 34 | var progress = _progresser.GetCurrentProgress(timeSpan); 35 | return From + (To - From) * progress; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/EasingFunctionBase.cs: -------------------------------------------------------------------------------- 1 | namespace DesignAndAnimationLab.AnimationTimelines 2 | { 3 | public abstract class EasingFunctionBase 4 | { 5 | /// 6 | /// Specifies the easing behavior. 7 | /// 8 | public EasingMode EasingMode { get; set; } = EasingMode.EaseOut; 9 | 10 | /// 11 | /// Transforms normalized time to control the pace of an animation. 12 | /// 13 | /// normalized time (progress) of the animation 14 | /// transformed progress 15 | /// Uses EasingMode in conjunction with EaseInCore to evaluate the easing function. 16 | public double Ease(double normalizedTime) 17 | { 18 | switch (EasingMode) 19 | { 20 | case EasingMode.EaseIn: 21 | return EaseInCore(normalizedTime); 22 | 23 | case EasingMode.EaseOut: 24 | // EaseOut is the same as EaseIn, except time is reversed & the result is flipped. 25 | return 1.0 - EaseInCore(1.0 - normalizedTime); 26 | 27 | case EasingMode.EaseInOut: 28 | default: 29 | // EaseInOut is a combination of EaseIn & EaseOut fit to the 0-1, 0-1 range. 30 | return normalizedTime < 0.5 31 | ? EaseInCore(normalizedTime * 2.0) * 0.5 32 | : (1.0 - EaseInCore((1.0 - normalizedTime) * 2.0)) * 0.5 + 0.5; 33 | } 34 | } 35 | 36 | /// 37 | /// Transforms normalized time to control the pace of an animation for the EaseIn EasingMode 38 | /// 39 | /// normalized time (progress) of the animation 40 | /// transformed progress 41 | /// 42 | /// You only have to specifiy your easing function for the 'EaseIn' case because the implementation 43 | /// of Ease will handle transforming normalizedTime & the result of this method to handle 'EaseOut' & 'EaseInOut'. 44 | /// 45 | protected abstract double EaseInCore(double normalizedTime); 46 | } 47 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/EasingMode.cs: -------------------------------------------------------------------------------- 1 | namespace DesignAndAnimationLab.AnimationTimelines 2 | { 3 | /// 4 | /// This enum defines the modes in which classes deriving from EasingFunctioBase 5 | /// can will perform their easing. 6 | /// 7 | public enum EasingMode 8 | { 9 | EaseIn, // the easing is performed at the start of the animation 10 | EaseOut, // the easing is performed at the end of the animation 11 | EaseInOut // the easing is performed both at the start and the end of the animation 12 | } 13 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/ElasticEase.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | // 6 | 7 | using System; 8 | using DesignAndAnimationLab.Common; 9 | 10 | namespace DesignAndAnimationLab.AnimationTimelines 11 | { 12 | /// 13 | /// This class implements an easing function that gives an elastic/springy curve 14 | /// 15 | public class ElasticEase : EasingFunctionBase 16 | { 17 | /// 18 | /// Specifies the number of oscillations 19 | /// 20 | public int Oscillations { get; set; } = 3; 21 | 22 | /// 23 | /// Specifies the amount of springiness 24 | /// 25 | public double Springiness { get; set; } = 3; 26 | 27 | protected override double EaseInCore(double normalizedTime) 28 | { 29 | var oscillations = Math.Max(0.0, Oscillations); 30 | var springiness = Math.Max(0.0, Springiness); 31 | double expo; 32 | if (DoubleUtil.IsZero(springiness)) 33 | { 34 | expo = normalizedTime; 35 | } 36 | else 37 | { 38 | expo = (Math.Exp(springiness * normalizedTime) - 1.0) / (Math.Exp(springiness) - 1.0); 39 | } 40 | 41 | return expo * Math.Sin((Math.PI * 2.0 * oscillations + Math.PI * 0.5) * normalizedTime); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/ExponentialEase.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | // 6 | 7 | using System; 8 | using DesignAndAnimationLab.Common; 9 | 10 | namespace DesignAndAnimationLab.AnimationTimelines 11 | { 12 | /// 13 | /// This class implements an easing function that gives an exponential curve 14 | /// 15 | public class ExponentialEase : EasingFunctionBase 16 | { 17 | /// 18 | /// Specifies the factor which controls the shape of easing. 19 | /// 20 | public double Exponent { get; set; } = 2; 21 | 22 | protected override double EaseInCore(double normalizedTime) 23 | { 24 | var factor = Exponent; 25 | if (DoubleUtil.IsZero(factor)) 26 | { 27 | return normalizedTime; 28 | } 29 | 30 | return (Math.Exp(factor * normalizedTime) - 1.0) / (Math.Exp(factor) - 1.0); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/PowerEase.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | // 6 | 7 | using System; 8 | 9 | namespace DesignAndAnimationLab.AnimationTimelines 10 | { 11 | /// 12 | /// This class implements an easing function that gives a polynomial curve of arbitrary degree. 13 | /// If the curve you desire is cubic, quadratic, quartic, or quintic it is better to use the 14 | /// specialized easing functions. 15 | /// 16 | public class PowerEase : EasingFunctionBase 17 | { 18 | /// 19 | /// Specifies the power for the polynomial equation. 20 | /// 21 | public double Power { get; set; } = 2; 22 | 23 | protected override double EaseInCore(double normalizedTime) 24 | { 25 | var power = Math.Max(0.0, Power); 26 | return Math.Pow(normalizedTime, power); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/QuadraticEase.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | // 6 | 7 | namespace DesignAndAnimationLab.AnimationTimelines 8 | { 9 | /// 10 | /// This class implements an easing function that gives a quadratic curve toward the destination 11 | /// 12 | public class QuadraticEase : EasingFunctionBase 13 | { 14 | protected override double EaseInCore(double normalizedTime) => normalizedTime * normalizedTime; 15 | } 16 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/QuarticEase.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | // 6 | 7 | namespace DesignAndAnimationLab.AnimationTimelines 8 | { 9 | /// 10 | /// This class implements an easing function that gives a quartic curve toward the destination 11 | /// 12 | public class QuarticEase : EasingFunctionBase 13 | { 14 | protected override double EaseInCore(double normalizedTime) => 15 | normalizedTime * normalizedTime * normalizedTime * normalizedTime; 16 | } 17 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/QuinticEase.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | // 6 | 7 | namespace DesignAndAnimationLab.AnimationTimelines 8 | { 9 | /// 10 | /// This class implements an easing function that gives a quintic curve toward the destination 11 | /// 12 | public class QuinticEase : EasingFunctionBase 13 | { 14 | protected override double EaseInCore(double normalizedTime) => 15 | normalizedTime * normalizedTime * normalizedTime * normalizedTime * normalizedTime; 16 | } 17 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/SineEase.cs: -------------------------------------------------------------------------------- 1 | // Licensed to the .NET Foundation under one or more agreements. 2 | // The .NET Foundation licenses this file to you under the MIT license. 3 | // See the LICENSE file in the project root for more information. 4 | 5 | // 6 | 7 | using System; 8 | 9 | namespace DesignAndAnimationLab.AnimationTimelines 10 | { 11 | /// 12 | /// This class implements an easing function that gives a Sine curve toward the destination. 13 | /// 14 | public class SineEase : EasingFunctionBase 15 | { 16 | protected override double EaseInCore(double normalizedTime) => 17 | 1.0 - Math.Sin(Math.PI * 0.5 * (1 - normalizedTime)); 18 | } 19 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/TimelineProgresser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Windows.UI.Xaml; 3 | 4 | namespace DesignAndAnimationLab.AnimationTimelines 5 | { 6 | public class TimelineProgresser 7 | { 8 | public TimelineProgresser(double seconds, bool autoReverse) 9 | { 10 | Duration = new Duration(TimeSpan.FromSeconds(seconds)); 11 | AutoReverse = autoReverse; 12 | } 13 | 14 | public bool AutoReverse { get; set; } 15 | public TimeSpan? BeginTime { get; set; } 16 | public Duration Duration { get; set; } = new Duration(TimeSpan.FromSeconds(1)); 17 | public EasingFunctionBase EasingFunction { get; set; } 18 | public bool Forever { get; set; } 19 | 20 | public double GetCurrentProgress(TimeSpan timeSpan) 21 | { 22 | var beginTimeTicks = 0l; 23 | 24 | if (BeginTime != null) 25 | { 26 | beginTimeTicks = BeginTime.Value.Ticks; 27 | } 28 | 29 | if (timeSpan.Ticks <= beginTimeTicks) 30 | { 31 | return 0; 32 | } 33 | 34 | var durationTicks = Duration.TimeSpan.Ticks; 35 | var scalingFactor = AutoReverse ? 2d : 1d; 36 | if (timeSpan.Ticks - beginTimeTicks > durationTicks * scalingFactor && Forever == false) 37 | { 38 | return 0; 39 | } 40 | 41 | var offsetFromBegin = (timeSpan.Ticks - beginTimeTicks) % (durationTicks * scalingFactor); 42 | 43 | if (offsetFromBegin > durationTicks) 44 | { 45 | offsetFromBegin = durationTicks * 2 - offsetFromBegin; 46 | } 47 | 48 | var progress = offsetFromBegin / durationTicks; 49 | 50 | if (EasingFunction != null) 51 | { 52 | progress = EasingFunction.Ease(progress); 53 | } 54 | 55 | return progress; 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/AnimationTimelines/Vector2Timeline.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Numerics; 3 | using Windows.UI.Xaml; 4 | 5 | namespace DesignAndAnimationLab.AnimationTimelines 6 | { 7 | public class Vector2Timeline 8 | { 9 | private readonly TimelineProgresser _progresser; 10 | 11 | public Vector2Timeline(Vector2 from, Vector2 to, double seconds = 1, TimeSpan? beginTime = null, 12 | bool autoReverse = true, bool forever = true, EasingFunctionBase easingFunction = null) 13 | { 14 | _progresser = new TimelineProgresser(seconds, autoReverse) 15 | { 16 | EasingFunction = easingFunction, BeginTime = beginTime, Forever = forever 17 | }; 18 | From = from; 19 | To = to; 20 | Duration = new Duration(TimeSpan.FromSeconds(seconds)); 21 | AutoReverse = autoReverse; 22 | Forever = forever; 23 | } 24 | 25 | public bool AutoReverse { get; } 26 | public Duration Duration { get; } 27 | public bool Forever { get; } 28 | public Vector2 From { get; } 29 | public Vector2 To { get; } 30 | 31 | public Vector2 GetCurrentValue(TimeSpan timeSpan) 32 | { 33 | var progress = (float)_progresser.GetCurrentProgress(timeSpan); 34 | return From + (To - From) * progress; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | 10 | 11 | /Assets/Fonts/Richasy_BiliBili.ttf#Richasy_BiliBili 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using Windows.ApplicationModel; 4 | using Windows.ApplicationModel.Activation; 5 | using Windows.UI.Xaml; 6 | using Windows.UI.Xaml.Controls; 7 | using Windows.UI.Xaml.Navigation; 8 | 9 | namespace DesignAndAnimationLab 10 | { 11 | /// 12 | /// 提供特定于应用程序的行为,以补充默认的应用程序类。 13 | /// 14 | public sealed partial class App : Application 15 | { 16 | /// 17 | /// 初始化单一实例应用程序对象。这是执行的创作代码的第一行, 18 | /// 已执行,逻辑上等同于 main() 或 WinMain()。 19 | /// 20 | public App() 21 | { 22 | InitializeComponent(); 23 | Suspending += OnSuspending; 24 | } 25 | 26 | /// 27 | /// 在应用程序由最终用户正常启动时进行调用。 28 | /// 将在启动应用程序以打开特定文件等情况下使用。 29 | /// 30 | /// 有关启动请求和过程的详细信息。 31 | protected override void OnLaunched(LaunchActivatedEventArgs e) 32 | { 33 | #if DEBUG 34 | if (Debugger.IsAttached) 35 | { 36 | DebugSettings.EnableFrameRateCounter = true; 37 | } 38 | #endif 39 | var rootFrame = Window.Current.Content as Frame; 40 | 41 | // 不要在窗口已包含内容时重复应用程序初始化, 42 | // 只需确保窗口处于活动状态 43 | if (rootFrame == null) 44 | { 45 | // 创建要充当导航上下文的框架,并导航到第一页 46 | rootFrame = new Frame(); 47 | 48 | rootFrame.NavigationFailed += OnNavigationFailed; 49 | 50 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) 51 | { 52 | //TODO: 从之前挂起的应用程序加载状态 53 | } 54 | 55 | // 将框架放在当前窗口中 56 | Window.Current.Content = rootFrame; 57 | } 58 | 59 | if (e.PrelaunchActivated == false) 60 | { 61 | if (rootFrame.Content == null) 62 | { 63 | // 当导航堆栈尚未还原时,导航到第一页, 64 | // 并通过将所需信息作为导航参数传入来配置 65 | // 参数 66 | rootFrame.Navigate(typeof(MainPage), e.Arguments); 67 | } 68 | 69 | // 确保当前窗口处于活动状态 70 | Window.Current.Activate(); 71 | } 72 | } 73 | 74 | /// 75 | /// 导航到特定页失败时调用 76 | /// 77 | /// 导航失败的框架 78 | /// 有关导航失败的详细信息 79 | private void OnNavigationFailed(object sender, NavigationFailedEventArgs e) => 80 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName); 81 | 82 | /// 83 | /// 在将要挂起应用程序执行时调用。 在不知道应用程序 84 | /// 无需知道应用程序会被终止还是会恢复, 85 | /// 并让内存内容保持不变。 86 | /// 87 | /// 挂起的请求的源。 88 | /// 有关挂起请求的详细信息。 89 | private void OnSuspending(object sender, SuspendingEventArgs e) 90 | { 91 | var deferral = e.SuspendingOperation.GetDeferral(); 92 | //TODO: 保存应用程序状态并停止任何后台活动 93 | deferral.Complete(); 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/BrushAssets/NoiseTexture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/BrushAssets/NoiseTexture.png -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/Fonts/Richasy_BiliBili.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/Fonts/Richasy_BiliBili.ttf -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/Images/heart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/Images/heart.png -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/Images/macOS-Catalina-Dark-Mode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/Images/macOS-Catalina-Dark-Mode.jpg -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/Images/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/Images/mask.png -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/Images/sea.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/Images/sea.jpg -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/Images/sea2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/Images/sea2.jpg -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/Images/tuna_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/Images/tuna_sprite.png -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/Images/wallpaper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/Images/wallpaper.jpg -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/StoreLogo.png -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DinoChan/uwp_design_and_animation_lab/7a5fb72bce667840860537a448120d981b742c3d/DesignAndAnimationLab/DesignAndAnimationLab/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/BlankPage1.xaml: -------------------------------------------------------------------------------- 1 |  12 | 13 | 14 | 15 | 16 | 22 | 26 | 27 | 28 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 请选择你最喜欢的角色(单选题) 48 | 49 | 50 | 53 | 56 | 57 | 61 | 62 | 66 | 70 | 71 | 72 | 76 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/BlankPage1.xaml.cs: -------------------------------------------------------------------------------- 1 | using DesignAndAnimationLab.Demos; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Runtime.InteropServices.WindowsRuntime; 7 | using System.Threading.Tasks; 8 | using Windows.Foundation; 9 | using Windows.Foundation.Collections; 10 | using Windows.UI.Input; 11 | using Windows.UI.Xaml; 12 | using Windows.UI.Xaml.Controls; 13 | using Windows.UI.Xaml.Controls.Primitives; 14 | using Windows.UI.Xaml.Data; 15 | using Windows.UI.Xaml.Input; 16 | using Windows.UI.Xaml.Media; 17 | using Windows.UI.Xaml.Media.Animation; 18 | using Windows.UI.Xaml.Navigation; 19 | 20 | // https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板 21 | 22 | namespace DesignAndAnimationLab 23 | { 24 | /// 25 | /// 可用于自身或导航至 Frame 内部的空白页。 26 | /// 27 | public sealed partial class BlankPage1 : Page 28 | { 29 | private Storyboard _progressStoryboard; 30 | private bool _isAnimateBegin; 31 | public BlankPage1() 32 | { 33 | this.InitializeComponent(); 34 | _progressStoryboard = CreateStoryboard(); 35 | } 36 | 37 | private void OnLikeButtonTapped(object sender, TappedRoutedEventArgs e) 38 | { 39 | if (LikeButton.State != ProgressState.Completed) 40 | LikeButton.State = ProgressState.Completed; 41 | else 42 | LikeButton.State = ProgressState.Idle; 43 | } 44 | 45 | 46 | 47 | private void OnGestureRecognizerTapped(object sender, Windows.UI.Input.TappedEventArgs e) 48 | { 49 | var progressButton = sender as ProgressButton; 50 | if (progressButton.State == ProgressState.Idle) 51 | progressButton.State = ProgressState.Completed; 52 | else 53 | progressButton.State = ProgressState.Idle; 54 | } 55 | 56 | 57 | 58 | private void OnGestureRecognizerHolding(object sender, Windows.UI.Input.HoldingEventArgs e) 59 | { 60 | var progressButton = sender as ProgressButton; 61 | if (e.HoldingState == HoldingState.Started) 62 | { 63 | if (!_isAnimateBegin) 64 | { 65 | _isAnimateBegin = true; 66 | (_progressStoryboard.Children[0] as DoubleAnimation).From = progressButton.Minimum; 67 | (_progressStoryboard.Children[0] as DoubleAnimation).To = progressButton.Maximum; 68 | Storyboard.SetTarget(_progressStoryboard.Children[0] as DoubleAnimation, progressButton); 69 | _progressStoryboard.Begin(); 70 | } 71 | } 72 | else 73 | { 74 | _isAnimateBegin = false; 75 | _progressStoryboard.Stop(); 76 | } 77 | } 78 | 79 | 80 | private Storyboard CreateStoryboard() 81 | { 82 | var animation = new DoubleAnimation 83 | { 84 | EnableDependentAnimation = true, 85 | Duration = TimeSpan.FromSeconds(2) 86 | }; 87 | 88 | Storyboard.SetTargetProperty(animation, nameof(ProgressButton.Value)); 89 | var storyboard = new Storyboard(); 90 | storyboard.Children.Add(animation); 91 | storyboard.Completed += OnProgressStoryboardCompleted; 92 | storyboard.FillBehavior = FillBehavior.Stop; 93 | return storyboard; 94 | } 95 | 96 | private async void OnProgressStoryboardCompleted(object sender, object e) 97 | { 98 | LikeButton.State = ProgressState.Completed; 99 | CoinButton.State = ProgressState.Completed; 100 | FavoriteButton.State = ProgressState.Completed; 101 | await Task.Delay( TimeSpan.FromSeconds(2)); 102 | var _updatePopup = new UpdatePopup(); 103 | _updatePopup.ShowPopup(); 104 | 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Common/Extensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Windows.UI.Composition; 3 | 4 | namespace DesignAndAnimationLab.Common 5 | { 6 | public static class Extensions 7 | { 8 | public static void BindCenterPoint(this Visual target) 9 | { 10 | var exp = target.Compositor.CreateExpressionAnimation( 11 | "Vector3(this.Target.Size.X / 2, this.Target.Size.Y / 2, 0f)"); 12 | target.StartAnimation("CenterPoint", exp); 13 | } 14 | 15 | public static void BindSize(this Visual target, Visual source) 16 | { 17 | var exp = target.Compositor.CreateExpressionAnimation("host.Size"); 18 | exp.SetReferenceParameter("host", source); 19 | target.StartAnimation("Size", exp); 20 | } 21 | 22 | public static ImplicitAnimationCollection CreateImplicitAnimation(this ImplicitAnimationCollection source, 23 | string Target, TimeSpan? Duration = null) 24 | { 25 | KeyFrameAnimation animation = null; 26 | switch (Target.ToLower()) 27 | { 28 | case "offset": 29 | case "scale": 30 | case "centerPoint": 31 | case "rotationAxis": 32 | animation = source.Compositor.CreateVector3KeyFrameAnimation(); 33 | break; 34 | 35 | case "size": 36 | animation = source.Compositor.CreateVector2KeyFrameAnimation(); 37 | break; 38 | 39 | case "opacity": 40 | case "blueRadius": 41 | case "rotationAngle": 42 | case "rotationAngleInDegrees": 43 | animation = source.Compositor.CreateScalarKeyFrameAnimation(); 44 | break; 45 | 46 | case "color": 47 | animation = source.Compositor.CreateColorKeyFrameAnimation(); 48 | break; 49 | } 50 | 51 | if (animation == null) 52 | { 53 | throw new ArgumentNullException("未知的Target"); 54 | } 55 | 56 | if (!Duration.HasValue) 57 | { 58 | Duration = TimeSpan.FromSeconds(0.2d); 59 | } 60 | 61 | animation.InsertExpressionKeyFrame(1f, "this.FinalValue"); 62 | animation.Duration = Duration.Value; 63 | animation.Target = Target; 64 | 65 | source[Target] = animation; 66 | return source; 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Common/Utils.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Graphics.Canvas; 2 | using Microsoft.Graphics.Canvas.Geometry; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Numerics; 7 | using System.Runtime.InteropServices.WindowsRuntime; 8 | using System.Threading.Tasks; 9 | using Windows.Storage; 10 | 11 | namespace DesignAndAnimationLab.Common 12 | { 13 | static class Utils 14 | { 15 | public static List GetEnumAsList() 16 | { 17 | return Enum.GetValues(typeof(T)).Cast().ToList(); 18 | } 19 | 20 | public static Matrix3x2 GetDisplayTransform(Vector2 outputSize, Vector2 sourceSize) 21 | { 22 | // Scale the display to fill the control. 23 | var scale = outputSize / sourceSize; 24 | var offset = Vector2.Zero; 25 | 26 | // Letterbox or pillarbox to preserve aspect ratio. 27 | if (scale.X > scale.Y) 28 | { 29 | scale.X = scale.Y; 30 | offset.X = (outputSize.X - sourceSize.X * scale.X) / 2; 31 | } 32 | else 33 | { 34 | scale.Y = scale.X; 35 | offset.Y = (outputSize.Y - sourceSize.Y * scale.Y) / 2; 36 | } 37 | 38 | return Matrix3x2.CreateScale(scale) * 39 | Matrix3x2.CreateTranslation(offset); 40 | } 41 | 42 | public static CanvasGeometry CreateStarGeometry(ICanvasResourceCreator resourceCreator, float scale, Vector2 center) 43 | { 44 | Vector2[] points = 45 | { 46 | new Vector2(-0.24f, -0.24f), 47 | new Vector2(0, -1), 48 | new Vector2(0.24f, -0.24f), 49 | new Vector2(1, -0.2f), 50 | new Vector2(0.4f, 0.2f), 51 | new Vector2(0.6f, 1), 52 | new Vector2(0, 0.56f), 53 | new Vector2(-0.6f, 1), 54 | new Vector2(-0.4f, 0.2f), 55 | new Vector2(-1, -0.2f), 56 | }; 57 | 58 | var transformedPoints = from point in points 59 | select point * scale + center; 60 | 61 | return CanvasGeometry.CreatePolygon(resourceCreator, transformedPoints.ToArray()); 62 | } 63 | 64 | public static float DegreesToRadians(float angle) 65 | { 66 | return angle * (float)Math.PI / 180; 67 | } 68 | 69 | static readonly Random random = new Random(); 70 | 71 | public static Random Random 72 | { 73 | get { return random; } 74 | } 75 | 76 | public static float RandomBetween(float min, float max) 77 | { 78 | return min + (float)random.NextDouble() * (max - min); 79 | } 80 | 81 | public static async Task ReadAllBytes(string filename) 82 | { 83 | var uri = new Uri("ms-appx:///" + filename); 84 | var file = await StorageFile.GetFileFromApplicationUriAsync(uri); 85 | var buffer = await FileIO.ReadBufferAsync(file); 86 | 87 | return buffer.ToArray(); 88 | } 89 | 90 | public static async Task TimeoutAfter(this Task task, TimeSpan timeout) 91 | { 92 | if (task == await Task.WhenAny(task, Task.Delay(timeout))) 93 | { 94 | return await task; 95 | } 96 | else 97 | { 98 | throw new TimeoutException(); 99 | } 100 | } 101 | 102 | public struct WordBoundary { public int Start; public int Length; } 103 | 104 | public static List GetEveryOtherWord(string str) 105 | { 106 | List result = new List(); 107 | 108 | for (int i = 0; i < str.Length; ++i) 109 | { 110 | if (str[i] == ' ') 111 | { 112 | int nextSpace = str.IndexOf(' ', i + 1); 113 | int limit = nextSpace == -1 ? str.Length : nextSpace; 114 | 115 | WordBoundary wb = new WordBoundary(); 116 | wb.Start = i + 1; 117 | wb.Length = limit - i - 1; 118 | result.Add(wb); 119 | i = limit; 120 | } 121 | } 122 | return result; 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Common/VisualExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Numerics; 3 | using Windows.UI.Xaml; 4 | using Windows.UI.Xaml.Hosting; 5 | 6 | namespace DesignAndAnimationLab.Common 7 | { 8 | public static class VisualExtensions 9 | { 10 | public static readonly DependencyProperty IsBindCenterPointProperty = 11 | DependencyProperty.RegisterAttached("IsBindCenterPoint", typeof(bool), typeof(VisualExtensions), 12 | new PropertyMetadata(false, (s, a) => 13 | { 14 | if (a.NewValue != a.OldValue) 15 | { 16 | if (s is UIElement ele) 17 | { 18 | if (a.NewValue is true) 19 | { 20 | ElementCompositionPreview.GetElementVisual(ele).BindCenterPoint(); 21 | } 22 | else 23 | { 24 | ElementCompositionPreview.GetElementVisual(ele).StopAnimation("CenterPoint"); 25 | } 26 | } 27 | } 28 | })); 29 | 30 | public static readonly DependencyProperty ScaleProperty = 31 | DependencyProperty.RegisterAttached("Scale", typeof(string), typeof(VisualExtensions), new PropertyMetadata( 32 | "1,1,1", (s, a) => 33 | { 34 | if (!Equals(a.NewValue, a.OldValue)) 35 | { 36 | if (s is UIElement element) 37 | { 38 | var newValue = a.NewValue as string; 39 | var arr = newValue.Replace(" ", string.Empty).Replace("f", string.Empty).Split(','); 40 | if (arr.Length == 3) 41 | { 42 | var v3 = new Vector3(float.Parse(arr[0]), float.Parse(arr[1]), float.Parse(arr[2])); 43 | var visual = ElementCompositionPreview.GetElementVisual(element); 44 | visual.Scale = v3; 45 | } 46 | else 47 | { 48 | throw new ArgumentException("数据不是Vector3"); 49 | } 50 | } 51 | } 52 | })); 53 | 54 | public static readonly DependencyProperty TransationsProperty = 55 | DependencyProperty.RegisterAttached("Transations", typeof(string), typeof(VisualExtensions), 56 | new PropertyMetadata(null, (s, a) => 57 | { 58 | if (!Equals(a.NewValue, a.OldValue)) 59 | { 60 | if (s is UIElement ele) 61 | { 62 | if (a.NewValue is string str) 63 | { 64 | var arr = str.Replace(" ", string.Empty).Split(','); 65 | if (arr.Length > 0) 66 | { 67 | var visual = ElementCompositionPreview.GetElementVisual(ele); 68 | visual.ImplicitAnimations = visual.Compositor.CreateImplicitAnimationCollection(); 69 | foreach (var item in arr) 70 | { 71 | visual.ImplicitAnimations.CreateImplicitAnimation(item); 72 | } 73 | 74 | return; 75 | } 76 | } 77 | 78 | ElementCompositionPreview.GetElementVisual(ele).ImplicitAnimations = null; 79 | } 80 | } 81 | })); 82 | 83 | public static bool GetIsBindCenterPoint(DependencyObject obj) => (bool)obj.GetValue(IsBindCenterPointProperty); 84 | 85 | public static string GetScale(DependencyObject obj) => (string)obj.GetValue(ScaleProperty); 86 | 87 | public static string GetTransations(DependencyObject obj) => (string)obj.GetValue(TransationsProperty); 88 | 89 | public static void SetIsBindCenterPoint(DependencyObject obj, bool value) => 90 | obj.SetValue(IsBindCenterPointProperty, value); 91 | 92 | public static void SetScale(DependencyObject obj, string value) => obj.SetValue(ScaleProperty, value); 93 | 94 | public static void SetTransations(DependencyObject obj, string value) => 95 | obj.SetValue(TransationsProperty, value); 96 | } 97 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Controls/GooeyButtonItem.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 49 | 50 | -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Controls/InnerShadowBox.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Controls/ProgressButton.Constants.cs: -------------------------------------------------------------------------------- 1 | namespace DesignAndAnimationLab 2 | { 3 | public partial class ProgressButton 4 | { 5 | private const string CompletedStateName = "Completed"; 6 | private const string FaultedStateName = "Faulted"; 7 | private const string GroupCommon = "CommonStates"; 8 | private const string IdleStateName = "Idle"; 9 | private const string InProgressStateName = "InProgress"; 10 | private const string ProgressStatesGroupName = "ProgressStates"; 11 | private const string StateDisabled = "Disabled"; 12 | private const string StateNormal = "Normal"; 13 | private const string StatePointerOver = "PointerOver"; 14 | private const string StatePressed = "Pressed"; 15 | } 16 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Controls/ProgressButton.Properties.cs: -------------------------------------------------------------------------------- 1 | using Windows.UI.Xaml; 2 | 3 | namespace DesignAndAnimationLab 4 | { 5 | public partial class ProgressButton 6 | { 7 | /// 8 | /// 标识 Content 依赖属性。 9 | /// 10 | public static readonly DependencyProperty ContentProperty = 11 | DependencyProperty.Register(nameof(Content), typeof(object), typeof(ProgressButton), 12 | new PropertyMetadata(default)); 13 | 14 | /// 15 | /// 标识 State 依赖属性。 16 | /// 17 | public static readonly DependencyProperty StateProperty = 18 | DependencyProperty.Register("State", typeof(ProgressState), typeof(ProgressButton), 19 | new PropertyMetadata(ProgressState.Idle, OnStateChanged)); 20 | 21 | /// 22 | /// 获取或设置Content的值 23 | /// 24 | public object Content 25 | { 26 | get => GetValue(ContentProperty); 27 | set => SetValue(ContentProperty, value); 28 | } 29 | 30 | public bool IsPointerOver { get; private set; } 31 | 32 | public bool IsPressed { get; private set; } 33 | 34 | /// 35 | /// 获取或设置State的值 36 | /// 37 | public ProgressState State 38 | { 39 | get => (ProgressState)GetValue(StateProperty); 40 | set => SetValue(StateProperty, value); 41 | } 42 | 43 | private static void OnStateChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 44 | { 45 | var target = obj as ProgressButton; 46 | var oldValue = (ProgressState)args.OldValue; 47 | var newValue = (ProgressState)args.NewValue; 48 | if (oldValue != newValue) 49 | { 50 | target.OnStateChanged(oldValue, newValue); 51 | } 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Controls/ProgressState.cs: -------------------------------------------------------------------------------- 1 | namespace DesignAndAnimationLab 2 | { 3 | public enum ProgressState 4 | { 5 | Idle, 6 | InProgress, 7 | Completed, 8 | Faulted 9 | } 10 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Demos/AcrylicAndBlur/AcrylicAndBlurDemo.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using Windows.UI; 4 | using Windows.UI.Xaml; 5 | using Windows.UI.Xaml.Controls; 6 | using Windows.UI.Xaml.Media; 7 | using Microsoft.Graphics.Canvas.Effects; 8 | using Microsoft.Toolkit.Uwp.Helpers; 9 | using Microsoft.Toolkit.Uwp.UI.Media; 10 | using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; 11 | 12 | // https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板 13 | 14 | namespace DesignAndAnimationLab.Demos 15 | { 16 | /// 17 | /// 可用于自身或导航至 Frame 内部的空白页。 18 | /// 19 | public sealed partial class AcrylicAndBlurDemo : Page, INotifyPropertyChanged 20 | { 21 | private Brush _customPipelineBrush; 22 | private Brush _customPipelineBrushDark; 23 | 24 | public AcrylicAndBlurDemo() 25 | { 26 | InitializeComponent(); 27 | CustomPipelineBrush = PipelineBuilder.FromHostBackdrop() 28 | .LuminanceToAlpha() 29 | .Opacity(0.4f) 30 | .Blend( 31 | PipelineBuilder.FromHostBackdrop(), 32 | BlendEffectMode.Multiply) 33 | .Blur(16) 34 | .Shade("#FF222222".ToColor(), 0.4f) 35 | .Blend( 36 | PipelineBuilder.FromTiles("/Assets/BrushAssets/NoiseTexture.png"), 37 | BlendEffectMode.Overlay, 38 | Placement.Background) 39 | .AsBrush(); 40 | 41 | HasBlur = true; 42 | HasLuminanceToAlpha = true; 43 | HasOpacity = true; 44 | HasShade = true; 45 | EffectOpacity = 0.4; 46 | BlurAmount = 16; 47 | ShadeColor = "#FF222222".ToColor(); 48 | ShadeIntensity = 0.4; 49 | UpdateCustomPipelineBrushDark(); 50 | } 51 | 52 | public double BlurAmount { get; set; } 53 | 54 | public Brush CustomPipelineBrush 55 | { 56 | get => _customPipelineBrush; 57 | set 58 | { 59 | _customPipelineBrush = value; 60 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CustomPipelineBrush))); 61 | } 62 | } 63 | 64 | public Brush CustomPipelineBrushDark 65 | { 66 | get => _customPipelineBrushDark; 67 | set 68 | { 69 | _customPipelineBrushDark = value; 70 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CustomPipelineBrushDark))); 71 | } 72 | } 73 | 74 | public double EffectOpacity { get; set; } 75 | public bool HasBlur { get; set; } 76 | public bool HasLuminanceToAlpha { get; set; } 77 | 78 | public bool HasOpacity { get; set; } 79 | public bool HasShade { get; set; } 80 | public Color ShadeColor { get; set; } 81 | 82 | public double ShadeIntensity { get; set; } 83 | 84 | public event PropertyChangedEventHandler PropertyChanged; 85 | 86 | private void OnAcceptCustomBrush(object sender, RoutedEventArgs e) 87 | { 88 | var builder = PipelineBuilder.FromHostBackdrop(); 89 | if (HasLuminanceToAlpha) 90 | { 91 | builder = builder.LuminanceToAlpha(); 92 | } 93 | 94 | if (HasOpacity) 95 | { 96 | builder = builder.Opacity((float)EffectOpacity); 97 | } 98 | 99 | builder = builder.Blend(PipelineBuilder.FromHostBackdrop(), BlendEffectMode.Multiply); 100 | 101 | if (HasBlur) 102 | { 103 | builder = builder.Blur((float)BlurAmount); 104 | } 105 | 106 | if (HasShade) 107 | { 108 | builder = builder.Shade(ShadeColor, (float)ShadeIntensity); 109 | } 110 | 111 | builder = builder.Blend(PipelineBuilder.FromTiles("/Assets/BrushAssets/NoiseTexture.png"), 112 | BlendEffectMode.Overlay, 113 | Placement.Background); 114 | 115 | CustomPipelineBrush = builder.AsBrush(); 116 | UpdateCustomPipelineBrushDark(); 117 | } 118 | 119 | private void UpdateCustomPipelineBrushDark() 120 | { 121 | var builder = PipelineBuilder.FromHostBackdrop(); 122 | if (HasLuminanceToAlpha) 123 | { 124 | builder = builder.LuminanceToAlpha(); 125 | } 126 | 127 | var opacity = Math.Min(1, EffectOpacity + 0.3); 128 | if (HasOpacity) 129 | { 130 | builder = builder.Opacity((float)opacity); 131 | } 132 | 133 | builder = builder.Blend(PipelineBuilder.FromHostBackdrop(), BlendEffectMode.Multiply); 134 | 135 | if (HasBlur) 136 | { 137 | builder = builder.Blur((float)BlurAmount); 138 | } 139 | 140 | if (HasShade) 141 | { 142 | builder = builder.Shade(ShadeColor, (float)ShadeIntensity); 143 | } 144 | 145 | builder = builder.Blend(PipelineBuilder.FromTiles("/Assets/BrushAssets/NoiseTexture.png"), 146 | BlendEffectMode.Overlay, 147 | Placement.Background); 148 | 149 | CustomPipelineBrushDark = builder.AsBrush(); 150 | } 151 | } 152 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Demos/AcrylicAndBlur/HostBackdropBlurBrush.cs: -------------------------------------------------------------------------------- 1 | using Windows.UI.Composition; 2 | using Windows.UI.Xaml; 3 | using Microsoft.Toolkit.Uwp.UI.Media; 4 | using Microsoft.Toolkit.Uwp.UI.Media.Pipelines; 5 | 6 | namespace DesignAndAnimationLab.Demos 7 | { 8 | public class HostBackdropBlurBrush : XamlCompositionEffectBrushBase 9 | { 10 | /// 11 | /// Identifies the dependency property. 12 | /// 13 | public static readonly DependencyProperty AmountProperty = DependencyProperty.Register( 14 | nameof(Amount), 15 | typeof(double), 16 | typeof(HostBackdropBlurBrush), 17 | new PropertyMetadata(0.0, OnAmountChanged)); 18 | 19 | /// 20 | /// The instance currently in use 21 | /// 22 | private EffectSetter amountSetter; 23 | 24 | /// 25 | /// Gets or sets the amount of gaussian blur to apply to the background. 26 | /// 27 | public double Amount 28 | { 29 | get => (double)GetValue(AmountProperty); 30 | set => SetValue(AmountProperty, value); 31 | } 32 | 33 | /// 34 | protected override PipelineBuilder OnPipelineRequested() => 35 | PipelineBuilder.FromHostBackdrop().Blur((float)Amount, out amountSetter); 36 | 37 | /// 38 | /// Updates the UI when changes 39 | /// 40 | /// The current instance 41 | /// 42 | /// The instance for 43 | /// 44 | private static void OnAmountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 45 | { 46 | if (d is HostBackdropBlurBrush brush && 47 | brush.CompositionBrush is CompositionBrush target) 48 | { 49 | brush.amountSetter?.Invoke(target, (float)brush.Amount); 50 | } 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Demos/BlendMixImage/BlendMixImage.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 15 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Demos/BlendMixImage/BlendMixImage.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Numerics; 3 | using Windows.UI; 4 | using Windows.UI.Composition; 5 | using Windows.UI.Xaml; 6 | using Windows.UI.Xaml.Controls; 7 | using Windows.UI.Xaml.Hosting; 8 | using Windows.UI.Xaml.Media; 9 | using Microsoft.Graphics.Canvas.Effects; 10 | 11 | //https://go.microsoft.com/fwlink/?LinkId=234236 上介绍了“用户控件”项模板 12 | 13 | namespace DesignAndAnimationLab.Demos 14 | { 15 | public sealed partial class BlendMixImage : UserControl 16 | { 17 | public BlendMixImage() 18 | { 19 | InitializeComponent(); 20 | 21 | ElementCompositionPreview.SetElementChildVisual(BackgroundElement, CreateVisual("sea.jpg")); 22 | ElementCompositionPreview.SetElementChildVisual(BackgroundElement2, CreateVisual("sea2.jpg")); 23 | } 24 | 25 | private (CompositionBrush compositionBrush, CompositionSurfaceBrush compositionSurfaceBrush) CreateBrush( 26 | string imageName, Color color) 27 | { 28 | var compositor = Window.Current.Compositor; 29 | var loadedSurface = LoadedImageSurface.StartLoadFromUri(new Uri("ms-appx:///Assets/Images/" + imageName)); 30 | var compositionSurfaceBrush = compositor.CreateSurfaceBrush(); 31 | compositionSurfaceBrush.Surface = loadedSurface; 32 | var compositionBrush = CreateBrush(compositionSurfaceBrush, compositor.CreateColorBrush(color), 33 | BlendEffectMode.Lighten); 34 | return (compositionBrush, compositionSurfaceBrush); 35 | } 36 | 37 | private CompositionBrush CreateBrush(CompositionBrush foreground, CompositionBrush background, 38 | BlendEffectMode blendEffectMode) 39 | { 40 | var compositor = Window.Current.Compositor; 41 | var effect = new BlendEffect 42 | { 43 | Mode = blendEffectMode, 44 | Foreground = new CompositionEffectSourceParameter("Main"), 45 | Background = new CompositionEffectSourceParameter("Tint") 46 | }; 47 | var effectFactory = compositor.CreateEffectFactory(effect); 48 | var compositionBrush = effectFactory.CreateBrush(); 49 | compositionBrush.SetSourceParameter("Main", foreground); 50 | compositionBrush.SetSourceParameter("Tint", background); 51 | 52 | return compositionBrush; 53 | } 54 | 55 | private SpriteVisual CreateVisual(string imageName) 56 | { 57 | var compositor = Window.Current.Compositor; 58 | var (foreground, foregroundBrush) = CreateBrush(imageName, Colors.Cyan); 59 | var (background, backgroundBrush) = CreateBrush(imageName, Colors.Red); 60 | foregroundBrush.Offset = new Vector2(10, 0); 61 | 62 | var brush = CreateBrush(foreground, background, BlendEffectMode.Darken); 63 | 64 | var imageVisual = compositor.CreateSpriteVisual(); 65 | imageVisual.Brush = brush; 66 | imageVisual.Size = new Vector2(800, 384); 67 | return imageVisual; 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Demos/BlendMixText/BlendMixText.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Demos/BlendMixText/BlendMixText.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Numerics; 2 | using Windows.UI; 3 | using Windows.UI.Composition; 4 | using Windows.UI.Xaml; 5 | using Windows.UI.Xaml.Controls; 6 | using Windows.UI.Xaml.Hosting; 7 | using Windows.UI.Xaml.Shapes; 8 | using DesignAndAnimationLab.Demos.GlitchArtDemo; 9 | using Microsoft.Graphics.Canvas.Effects; 10 | 11 | //https://go.microsoft.com/fwlink/?LinkId=234236 上介绍了“用户控件”项模板 12 | 13 | namespace DesignAndAnimationLab.Demos 14 | { 15 | public sealed partial class BlendMixText : UserControl 16 | { 17 | public BlendMixText() 18 | { 19 | InitializeComponent(); 20 | AddTextToRoot(BlendEffectMode.ColorBurn); 21 | AddTextToRoot(BlendEffectMode.ColorDodge); 22 | AddTextToRoot(BlendEffectMode.Darken); 23 | AddTextToRoot(BlendEffectMode.DarkerColor); 24 | AddTextToRoot(BlendEffectMode.Difference); 25 | AddTextToRoot(BlendEffectMode.Division); 26 | AddTextToRoot(BlendEffectMode.Exclusion); 27 | AddTextToRoot(BlendEffectMode.Exclusion); 28 | AddTextToRoot(BlendEffectMode.HardLight); 29 | AddTextToRoot(BlendEffectMode.HardMix); 30 | AddTextToRoot(BlendEffectMode.Lighten); 31 | AddTextToRoot(BlendEffectMode.LighterColor); 32 | AddTextToRoot(BlendEffectMode.LinearBurn); 33 | AddTextToRoot(BlendEffectMode.LinearDodge); 34 | AddTextToRoot(BlendEffectMode.LinearLight); 35 | AddTextToRoot(BlendEffectMode.Multiply); 36 | AddTextToRoot(BlendEffectMode.Overlay); 37 | AddTextToRoot(BlendEffectMode.PinLight); 38 | AddTextToRoot(BlendEffectMode.Screen); 39 | AddTextToRoot(BlendEffectMode.SoftLight); 40 | AddTextToRoot(BlendEffectMode.Subtract); 41 | AddTextToRoot(BlendEffectMode.VividLight); 42 | } 43 | 44 | private Compositor Compositor => Window.Current.Compositor; 45 | 46 | public TextToBrushWrapper CreateTextToBrushWrapper(string text, Color fontColor) 47 | { 48 | var result = new TextToBrushWrapper 49 | { 50 | Text = text, 51 | FontSize = 45, 52 | Width = 400, 53 | Height = 70, 54 | FontColor = fontColor 55 | }; 56 | result.Brush.VerticalAlignmentRatio = 0; 57 | return result; 58 | } 59 | 60 | private void AddTextToRoot(BlendEffectMode blendEffectMode) 61 | { 62 | var redBrushWrapper = CreateTextToBrushWrapper(blendEffectMode.ToString(), Colors.Red); 63 | var blueBrushWrapper = CreateTextToBrushWrapper(blendEffectMode.ToString(), Colors.Cyan); 64 | blueBrushWrapper.Brush.Offset = new Vector2(-4f, 0); 65 | var blueMaskBrush = CreateGradientBrush(); 66 | 67 | var textVisual = Compositor.CreateSpriteVisual(); 68 | textVisual.Brush = CreateBrush(blueBrushWrapper.Brush, redBrushWrapper.Brush, blendEffectMode); 69 | textVisual.Size = new Vector2(400, 70); 70 | var background = new Rectangle { Height = 70, Width = 400 }; 71 | 72 | ElementCompositionPreview.SetElementChildVisual(background, textVisual); 73 | Root.Children.Add(background); 74 | } 75 | 76 | private CompositionBrush CreateBrush(CompositionBrush foreground, CompositionBrush background, 77 | BlendEffectMode blendEffectMode) 78 | { 79 | var compositor = Window.Current.Compositor; 80 | var effect = new BlendEffect 81 | { 82 | Mode = blendEffectMode, 83 | Foreground = new CompositionEffectSourceParameter("Main"), 84 | Background = new CompositionEffectSourceParameter("Tint") 85 | }; 86 | var effectFactory = compositor.CreateEffectFactory(effect); 87 | var compositionBrush = effectFactory.CreateBrush(); 88 | compositionBrush.SetSourceParameter("Main", foreground); 89 | compositionBrush.SetSourceParameter("Tint", background); 90 | 91 | return compositionBrush; 92 | } 93 | 94 | private CompositionLinearGradientBrush CreateGradientBrush() 95 | { 96 | var gradientBrush = Compositor.CreateLinearGradientBrush(); 97 | gradientBrush.StartPoint = new Vector2(0.5f, 0); 98 | ; 99 | gradientBrush.EndPoint = new Vector2(0.5f, 1); 100 | 101 | var startGradientStop = Compositor.CreateColorGradientStop(); 102 | startGradientStop.Offset = 0.49f; 103 | startGradientStop.Color = Colors.White; 104 | var endGradientStop = Compositor.CreateColorGradientStop(); 105 | endGradientStop.Offset = 0.5f; 106 | endGradientStop.Color = Colors.Transparent; 107 | gradientBrush.ColorStops.Add(startGradientStop); 108 | gradientBrush.ColorStops.Add(endGradientStop); 109 | return gradientBrush; 110 | } 111 | } 112 | } -------------------------------------------------------------------------------- /DesignAndAnimationLab/DesignAndAnimationLab/Demos/BubbleButton/BubbleButtonDemo.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 10 |