整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          .NET CORE(C#) WPF 值得推薦的動畫菜單設(shè)計

          信公眾號:Dotnet9,網(wǎng)站:Dotnet9,問題或建議:請網(wǎng)站留言, 如果對您有所幫助:歡迎贊賞。

          .NET CORE(C#) WPF 值得推薦的動畫菜單設(shè)計

          閱讀導(dǎo)航

          1. 本文背景
          2. 代碼實(shí)現(xiàn)
          3. 本文參考
          4. 源碼

          1. 本文背景

          YouTube上老外的一個設(shè)計,站長覺得不錯,分享給大家作為參考,抽屜菜單的動畫做的非常不錯。

          運(yùn)行起始界面:



          站長運(yùn)行操作一遍,錄制了動畫大家看看:



          2. 代碼實(shí)現(xiàn)

          使用 .NET CORE 3.1 創(chuàng)建名為 “AnimatedMenu” 的WPF模板項(xiàng)目,添加1個Nuget庫:MaterialDesignThemes,版本為最新預(yù)覽版3.1.0-ci948。

          解決方案主要文件目錄組織結(jié)構(gòu):

          • AnimatedMenu
          • App.xaml
          • MainWindow.xaml
          • MainWindow.xaml.cs

          2.1 引入樣式

          文件【App.xaml】,在 StartupUri 中設(shè)置啟動的視圖【MainWindow.xaml】,并在【Application.Resources】節(jié)點(diǎn)增加 MaterialDesignThemes庫的樣式文件:

          <Application.Resources>
              <ResourceDictionary>
                  <ResourceDictionary.MergedDictionaries>
                      <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Dark.xaml" />
                      <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
                      <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Blue.xaml" />
                      <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Blue.xaml" />
                  </ResourceDictionary.MergedDictionaries>
              </ResourceDictionary>
          </Application.Resources>

          2.2 演示窗體

          文件【MainWindow.xaml】,布局代碼、動畫代碼都在此文件中,源碼如下:

          <Window x:Class="AnimatedMenu.MainWindow"
                  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                  xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
                  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                  mc:Ignorable="d" MouseLeftButtonDown="MoveWindow_MouseLeftButtonDown"
                  Height="600" Width="1024" WindowStyle="None" WindowStartupLocation="CenterScreen">
              <WindowChrome.WindowChrome>
                  <WindowChrome CaptionHeight="0"/>
              </WindowChrome.WindowChrome>
              <Window.Resources>
                  <Storyboard x:Key="OpenMenu">
                      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="GridMain">
                          <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="250"/>
                      </DoubleAnimationUsingKeyFrames>
                      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="GridMain">
                          <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="50"/>
                      </DoubleAnimationUsingKeyFrames>
                      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="StackPanelMenu">
                          <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="250"/>
                      </DoubleAnimationUsingKeyFrames>
                      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="listViewItem">
                          <EasingDoubleKeyFrame KeyTime="0" Value="-250"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="-250"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.7" Value="0"/>
                      </DoubleAnimationUsingKeyFrames>
                      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="listViewItem1">
                          <EasingDoubleKeyFrame KeyTime="0" Value="-250"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="-250"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.9" Value="0"/>
                      </DoubleAnimationUsingKeyFrames>
                      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="listViewItem2">
                          <EasingDoubleKeyFrame KeyTime="0" Value="-250"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="-250"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:1.1" Value="0"/>
                      </DoubleAnimationUsingKeyFrames>
                      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="listViewItem3">
                          <EasingDoubleKeyFrame KeyTime="0" Value="-250"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="-250"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:1.3" Value="0"/>
                      </DoubleAnimationUsingKeyFrames>
                      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="listViewItem4">
                          <EasingDoubleKeyFrame KeyTime="0" Value="-250"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="-250"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="0"/>
                      </DoubleAnimationUsingKeyFrames>
                      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="button">
                          <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
                      </DoubleAnimationUsingKeyFrames>
                      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="button">
                          <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="1"/>
                      </DoubleAnimationUsingKeyFrames>
                  </Storyboard>
                  <Storyboard x:Key="CloseMenu">
                      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="GridMain">
                          <EasingDoubleKeyFrame KeyTime="0" Value="250"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
                      </DoubleAnimationUsingKeyFrames>
                      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="GridMain">
                          <EasingDoubleKeyFrame KeyTime="0" Value="50"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
                      </DoubleAnimationUsingKeyFrames>
                      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="StackPanelMenu">
                          <EasingDoubleKeyFrame KeyTime="0" Value="250"/>
                          <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0"/>
                      </DoubleAnimationUsingKeyFrames>
                  </Storyboard>
              </Window.Resources>
              <Window.Triggers>
                  <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="ButtonOpenMenu">
                      <BeginStoryboard Storyboard="{StaticResource OpenMenu}"/>
                  </EventTrigger>
                  <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="ButtonCloseMenu">
                      <BeginStoryboard x:Name="CloseMenu_BeginStoryboard" Storyboard="{StaticResource CloseMenu}"/>
                  </EventTrigger>
              </Window.Triggers>
              <Grid Background="#FF3580BF">
                  <StackPanel x:Name="StackPanelMenu" Width="250" HorizontalAlignment="Left" Margin="-250 0 0 0" RenderTransformOrigin="0.5,0.5">
                      <StackPanel.RenderTransform>
                          <TransformGroup>
                              <ScaleTransform/>
                              <SkewTransform/>
                              <RotateTransform/>
                              <TranslateTransform/>
                          </TransformGroup>
                      </StackPanel.RenderTransform>
                      <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Height="100" HorizontalAlignment="Center">
                          <Button Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}" Background="{x:Null}" BorderBrush="{x:Null}" Padding="0" Width="50" Height="50" Margin="10">
                              <materialDesign:PackIcon Kind="Settings" Width="40" Height="40"/>
                          </Button>
                          <Button x:Name="button" Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}" BorderBrush="{x:Null}" Padding="0" Width="80" Height="80" Margin="10" RenderTransformOrigin="0.5,0.5">
                              <Button.RenderTransform>
                                  <TransformGroup>
                                      <ScaleTransform/>
                                      <SkewTransform/>
                                      <RotateTransform/>
                                      <TranslateTransform/>
                                  </TransformGroup>
                              </Button.RenderTransform>
                              <Button.Background>
                                  <ImageBrush ImageSource="https://img.dotnet9.com/logo.png" Stretch="UniformToFill"/>
                              </Button.Background>
                          </Button>
                          <Button Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}" Background="{x:Null}" BorderBrush="{x:Null}" Padding="0" Width="50" Height="50" Margin="10">
                              <materialDesign:PackIcon Kind="InformationOutline" Width="40" Height="40"/>
                          </Button>
                      </StackPanel>
                      <ListView>
                          <ListViewItem x:Name="listViewItem" Height="60" RenderTransformOrigin="0.5,0.5">
                              <ListViewItem.RenderTransform>
                                  <TransformGroup>
                                      <ScaleTransform/>
                                      <SkewTransform/>
                                      <RotateTransform/>
                                      <TranslateTransform/>
                                  </TransformGroup>
                              </ListViewItem.RenderTransform>
                              <StackPanel Orientation="Horizontal" Margin="10 0">
                                  <materialDesign:PackIcon Kind="Home" Width="30" Height="30" VerticalAlignment="Center" Margin="5"/>
                                  <TextBlock Text="主頁" Margin="10" VerticalAlignment="Center"/>
                              </StackPanel>
                          </ListViewItem>
                          <ListViewItem x:Name="listViewItem1" Height="60" RenderTransformOrigin="0.5,0.5">
                              <ListViewItem.RenderTransform>
                                  <TransformGroup>
                                      <ScaleTransform/>
                                      <SkewTransform/>
                                      <RotateTransform/>
                                      <TranslateTransform/>
                                  </TransformGroup>
                              </ListViewItem.RenderTransform>
                              <StackPanel Orientation="Horizontal" Margin="10 0">
                                  <materialDesign:PackIcon Kind="AccountSearch" Width="30" Height="30" VerticalAlignment="Center" Margin="5"/>
                                  <TextBlock Text="搜索" Margin="10" VerticalAlignment="Center"/>
                              </StackPanel>
                          </ListViewItem>
                          <ListViewItem x:Name="listViewItem2" Height="60" RenderTransformOrigin="0.5,0.5">
                              <ListViewItem.RenderTransform>
                                  <TransformGroup>
                                      <ScaleTransform/>
                                      <SkewTransform/>
                                      <RotateTransform/>
                                      <TranslateTransform/>
                                  </TransformGroup>
                              </ListViewItem.RenderTransform>
                              <StackPanel Orientation="Horizontal" Margin="10 0">
                                  <materialDesign:PackIcon Kind="Wechat" Width="30" Height="30" VerticalAlignment="Center" Margin="5"/>
                                  <TextBlock Text="微信" Margin="10" VerticalAlignment="Center"/>
                              </StackPanel>
                          </ListViewItem>
                          <ListViewItem x:Name="listViewItem3" Height="60" RenderTransformOrigin="0.5,0.5">
                              <ListViewItem.RenderTransform>
                                  <TransformGroup>
                                      <ScaleTransform/>
                                      <SkewTransform/>
                                      <RotateTransform/>
                                      <TranslateTransform/>
                                  </TransformGroup>
                              </ListViewItem.RenderTransform>
                              <StackPanel Orientation="Horizontal" Margin="10 0">
                                  <materialDesign:PackIcon Kind="Qqchat" Width="30" Height="30" VerticalAlignment="Center" Margin="5"/>
                                  <TextBlock Text="QQ" Margin="10" VerticalAlignment="Center"/>
                              </StackPanel>
                          </ListViewItem>
                          <ListViewItem x:Name="listViewItem4" Height="60" RenderTransformOrigin="0.5,0.5">
                              <ListViewItem.RenderTransform>
                                  <TransformGroup>
                                      <ScaleTransform/>
                                      <SkewTransform/>
                                      <RotateTransform/>
                                      <TranslateTransform/>
                                  </TransformGroup>
                              </ListViewItem.RenderTransform>
                              <StackPanel Orientation="Horizontal" Margin="10 0">
                                  <materialDesign:PackIcon Kind="Facebook" Width="30" Height="30" VerticalAlignment="Center" Margin="5"/>
                                  <TextBlock Text="臉書" Margin="10" VerticalAlignment="Center"/>
                              </StackPanel>
                          </ListViewItem>
                      </ListView>
                  </StackPanel>
                  <Grid x:Name="GridMain" Background="#FFFBFBFB" Width="1024" RenderTransformOrigin="0.5,0.5">
                      <Grid.RenderTransform>
                          <TransformGroup>
                              <ScaleTransform/>
                              <SkewTransform/>
                              <RotateTransform/>
                              <TranslateTransform/>
                          </TransformGroup>
                      </Grid.RenderTransform>
                      <Grid.ColumnDefinitions>
                          <ColumnDefinition Width="*"/>
                          <ColumnDefinition Width="250"/>
                      </Grid.ColumnDefinitions>
          
                      <Grid Grid.Column="1" Background="#FF3580BF">
                          <Image Height="150" VerticalAlignment="Top" Source="https://dotnet9.com/wp-content/uploads/2017/04/About-Header.jpg" Stretch="UniformToFill"/>
                          <Ellipse Height="100" Width="100" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="20 100" Stroke="White">
                              <Ellipse.Fill>
                                  <ImageBrush ImageSource="https://img.dotnet9.com/logo.png" Stretch="UniformToFill"/>
                              </Ellipse.Fill>
                          </Ellipse>
                          <TextBlock Text="Dotnet9" Foreground="White" FontSize="28" FontFamily="Nirmala UI Semilight" Margin="10 100" VerticalAlignment="Top"/>
                          <StackPanel Margin="0 150">
                              <Grid Height="60" Margin="20 50 20 0">
                                  <Grid.ColumnDefinitions>
                                      <ColumnDefinition Width="*"/>
                                      <ColumnDefinition Width="*"/>
                                  </Grid.ColumnDefinitions>
                                  <Grid.RowDefinitions>
                                      <RowDefinition Height="30"/>
                                      <RowDefinition Height="30"/>
                                  </Grid.RowDefinitions>
                                  <TextBlock Text="追隨者" VerticalAlignment="Bottom" Foreground="#FFFBFBFB" Margin="5,0,5,5"/>
                                  <TextBlock Text="1.5K" VerticalAlignment="Top" Foreground="#FFFBFBFB" Grid.Row="1" Margin="10 0"/>
          
                                  <TextBlock Text="跟隨" VerticalAlignment="Bottom" Foreground="#FFFBFBFB" Margin="5,0,5,5" Grid.Column="1"/>
                                  <TextBlock Text="2.3K" VerticalAlignment="Top" Foreground="#FFFBFBFB" Grid.Row="1" Margin="10 0" Grid.Column="1"/>
                              </Grid>
          
                              <TextBlock TextWrapping="Wrap" Margin="10" Foreground="#FFFBFBFB" FontSize="14">
                                  <Run Text="網(wǎng)名:沙漠盡頭的狼"/>
                                  <LineBreak/>
                                  <LineBreak/>
                                  <Run Text="網(wǎng)站:https://dotnet9.com"/>
                                  <LineBreak/>
                                  <Run Text="    Dotnet9的博客 - 一個熱衷于互聯(lián)網(wǎng)分享精神的個人博客站點(diǎn)"/>
                                  <LineBreak/>
                                  <LineBreak/>
                                  <Run Text="座右銘:時間如流水,只能流去不流回。"/>
                              </TextBlock>
                          </StackPanel>
                      </Grid>
                      <Grid>
                          <Grid.RowDefinitions>
                              <RowDefinition Height="40"/>
                              <RowDefinition Height="50"/>
                              <RowDefinition Height="*"/>
                              <RowDefinition Height="*"/>
                              <RowDefinition Height="*"/>
                          </Grid.RowDefinitions>
                          <Grid.ColumnDefinitions>
                              <ColumnDefinition Width="*"/>
                              <ColumnDefinition Width="*"/>
                              <ColumnDefinition Width="*"/>
                          </Grid.ColumnDefinitions>
          
                          <Button x:Name="ButtonCloseMenu" Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}" Width="30" Height="30" Padding="0" Background="{x:Null}" BorderBrush="{x:Null}" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="5" Click="ButtonCloseMenu_Click" Visibility="Collapsed">
                              <materialDesign:PackIcon Kind="Menu" Foreground="#FF3580BF"/>
                          </Button>
                          <Button x:Name="ButtonOpenMenu" Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}" Width="30" Height="30" Padding="0" Background="{x:Null}" BorderBrush="{x:Null}" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="5" Click="ButtonOpenMenu_Click">
                              <materialDesign:PackIcon Kind="Menu" Foreground="#FF3580BF"/>
                          </Button>
          
          
                          <TextBlock Text="照片" Foreground="#FF3580BF" FontSize="30" FontWeight="Bold" Margin="5" Grid.Row="1"/>
          
                          <Grid Margin="5" Grid.Row="2" Grid.Column="0">
                              <Grid.Effect>
                                  <DropShadowEffect BlurRadius="20" Color="#FFEEEEEE" ShadowDepth="1"/>
                              </Grid.Effect>
                              <Image Source="https://dotnet9.com/wp-content/uploads/2019/12/wpf.png" Stretch="UniformToFill"/>
                              <StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right" VerticalAlignment="Bottom">
                                  <materialDesign:PackIcon Kind="Heart" Foreground="#FFFBFBFB"/>
                                  <TextBlock Text="25" Foreground="#FFFBFBFB"/>
                              </StackPanel>
                          </Grid>
                          <Grid Margin="5" Grid.Row="2" Grid.Column="1">
                              <Grid.Effect>
                                  <DropShadowEffect BlurRadius="20" Color="#FFEEEEEE" ShadowDepth="1"/>
                              </Grid.Effect>
                              <Image Source="https://dotnet9.com/wp-content/uploads/2019/12/winform.png" Stretch="UniformToFill"/>
                              <StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right" VerticalAlignment="Bottom">
                                  <materialDesign:PackIcon Kind="Heart" Foreground="#FFFBFBFB"/>
                                  <TextBlock Text="50" Foreground="#FFFBFBFB"/>
                              </StackPanel>
                          </Grid>
                          <Grid Margin="5" Grid.Row="2" Grid.Column="2">
                              <Grid.Effect>
                                  <DropShadowEffect BlurRadius="20" Color="#FFEEEEEE" ShadowDepth="1"/>
                              </Grid.Effect>
                              <Image Source="https://dotnet9.com/wp-content/uploads/2019/12/asp-net-core.png" Stretch="UniformToFill"/>
                              <StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right" VerticalAlignment="Bottom">
                                  <materialDesign:PackIcon Kind="Heart" Foreground="#FFFBFBFB"/>
                                  <TextBlock Text="18" Foreground="#FFFBFBFB"/>
                              </StackPanel>
                          </Grid>
                          <Grid Margin="5" Grid.Row="3" Grid.Column="0">
                              <Grid.Effect>
                                  <DropShadowEffect BlurRadius="20" Color="#FFEEEEEE" ShadowDepth="1"/>
                              </Grid.Effect>
                              <Image Source="https://img.dotnet9.com/Xamarin.Forms.png" Stretch="UniformToFill"/>
                              <StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right" VerticalAlignment="Bottom">
                                  <materialDesign:PackIcon Kind="Heart" Foreground="#FFFBFBFB"/>
                                  <TextBlock Text="32" Foreground="#FFFBFBFB"/>
                              </StackPanel>
                          </Grid>
                          <Grid Margin="5" Grid.Row="3" Grid.Column="1">
                              <Grid.Effect>
                                  <DropShadowEffect BlurRadius="20" Color="#FFEEEEEE" ShadowDepth="1"/>
                              </Grid.Effect>
                              <Image Source="https://dotnet9.com/wp-content/uploads/2019/12/front-end.png" Stretch="UniformToFill"/>
                              <StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right" VerticalAlignment="Bottom">
                                  <materialDesign:PackIcon Kind="Heart" Foreground="#FFFBFBFB"/>
                                  <TextBlock Text="32" Foreground="#FFFBFBFB"/>
                              </StackPanel>
                          </Grid>
                      </Grid>
                  </Grid>
                  <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Height="40" HorizontalAlignment="Right" Margin="10">
                      <Button Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}" Width="30" Height="30" Padding="0" Background="{x:Null}" BorderBrush="{x:Null}">
                          <materialDesign:PackIcon Kind="Bell"/>
                      </Button>
                      <Button x:Name="ButtonClose" Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}" Width="30" Height="30" Padding="0" Background="{x:Null}" BorderBrush="{x:Null}" Click="ButtonClose_Click">
                          <materialDesign:PackIcon Kind="Close"/>
                      </Button>
                  </StackPanel>
              </Grid>
          </Window>

          簡單說明下:

          1. "StackPanelMenu" 作為左側(cè)菜單容器,默認(rèn)是顯示在窗體外,距離窗體左邊緣-250,點(diǎn)擊左上角菜單按鈕圖標(biāo)可控制此容器的顯示與隱藏,注:菜單開關(guān)由兩個按鈕組成 "ButtonOpenMenu" 和 "ButtonCloseMenu"。
          2. 左側(cè)菜單項(xiàng)使用 "ListView" 進(jìn)行布局,實(shí)際開發(fā)需要運(yùn)用模板,使用MVVM做成動態(tài)菜單,方便擴(kuò)展。
          3. 中間的5張演示照片,也和2類似。直接使用Grid進(jìn)行的布局,實(shí)際上都需要做成模板。
          4. 抽屜菜單動畫見 Window.Resouces 中的動畫代碼,展開抽屜菜單動畫是 "OpenMenu",左側(cè)菜單向右、向下移動,右側(cè)展示區(qū)域及個人信息概況界面同時也是向右、向下移動;關(guān)閉抽屜菜單動畫是 "CloseMenu",動畫移動方向與展開時相反(說的是廢話),這段動畫代碼值得好好學(xué)習(xí)、復(fù)用。

          文件【MainWindow.xaml.cs】,后臺關(guān)閉窗體、抽屜菜單按鈕切換、窗體移動等事件處理:

          private void ButtonClose_Click(object sender, RoutedEventArgs e)
          {
              Application.Current.Shutdown();
          }
          
          private void ButtonOpenMenu_Click(object sender, RoutedEventArgs e)
          {
              ButtonOpenMenu.Visibility = Visibility.Collapsed;
              ButtonCloseMenu.Visibility = Visibility.Visible;
          }
          
          private void ButtonCloseMenu_Click(object sender, RoutedEventArgs e)
          {
              ButtonOpenMenu.Visibility = Visibility.Visible;
              ButtonCloseMenu.Visibility = Visibility.Collapsed;
          }
          
          private void MoveWindow_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
          {
              DragMove();
          }

          代碼已全部奉上...

          3.本文參考

          1. 視頻一:C# WPF Material Design UI: Animated Menu,配套源碼:AnimatedMenu1。
          2. C# WPF開源控件庫《MaterialDesignInXAML》

          4.源碼

          效果圖實(shí)現(xiàn)代碼在文中已經(jīng)全部給出,站長方便演示,文中的圖片使用的本站外鏈圖片,代碼可直接Copy,按解決方案目錄組織代碼文件即可運(yùn)行。

          演示Demo下載


          除非注明,文章均由 Dotnet9 整理發(fā)布,歡迎轉(zhuǎn)載。轉(zhuǎn)載請注明本文地址:https://dotnet9.com/7669.html歡迎掃描下方二維碼關(guān)注 Dotnet9 的微信公眾號,本站會及時推送最新技術(shù)文章


          時間如流水,只能流去不流回!

          點(diǎn)擊《【閱讀原文】》,本站還有更多技術(shù)類文章等著您哦!!!

          果圖

          動態(tài)圖沒法彰顯它原本的魅力,可以自行下載后觀看!

          代碼過長需要文檔版源碼來我的前端群581549454,已上傳到群文件

          CSS3源碼:

          @charset "utf-8";

          html, body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, p, blockquote, th, td, textarea { margin: 0; padding: 0; font-size: 14px; line-height: 24px; color: #000; font-family: 'microsoft yahei',verdana,Tahoma; }

          ol, ul, li { list-style: none; line-height: 22px; }

          ol, ul { zoom: 1; }

          h1, h2, h3, h4, h5, h6 { font-size: 100%; }

          img { border: none; max-width: 100%; }

          a, a:link, a:visited { cursor: pointer; text-decoration: none;}

          a:hover { cursor: pointer; }

          .table { border-collapse: collapse; border-spacing: 0; }

          .table td { border: solid 1px #666; }

          .clear { clear: both; float: none; overflow: hidden; height: 0; font-size: 0; }

          .clearFix:after { clear: both; display: block; visibility: hidden; height: 0; line-height: 0; content: "."; }

          .clearFix { zoom: 1; }

          * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }

          :after, :before { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }

          .font { font: 14px/24px "Comic Sans MS"; }

          :focus { outline: none; }

          .css3pie { -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; behavior: url(css3pie/PIE.htc); }

          /*------------------------------------------------------------------------------------------------------------------------------------------------*/

          body{ font-size: 14px; font-family: "黑體-簡","黑體","微軟雅黑", Arial, Gotham, "Helvetica Neue", Helvetica, sans-serif; width: 100%; margin: 0 auto; background-color: #313131; overflow-x: hidden; }

          .wrap{width:100%;height:1000px;}

          .wrap p{font-size: 48px;text-align: center;color: #fff;padding-top: 280px;line-height: 60px;}

          .logo{

          text-align: center;

          vertical-align: middle;

          background: #357dd7;

          margin-left: 45%;

          top: 20%;

          z-index: 11;

          width: 240px;

          height: 240px;

          overflow: hidden;

          position: relative;

          }

          .logo:hover{

          box-shadow: 0px 0px 10px #333;

          }

          .logo h1{

          display: table-cell;

          vertical-align: middle;

          width: 240px;

          height: 240px;

          }

          .logo a{width: 240px;height: 240px;overflow: hidden;}

          .logo a:before{

          content: '';

          position: absolute;

          left: -230%;

          top: 0px;

          width: 200%;

          height: 120%;

          background: #1f415f;

          z-index: 1;

          transform:skew(30deg, 0);

          -webkit-transform:skew(30deg, 0);

          -ms-transform:skew(30deg, 0);

          -moz-transform:skew(30deg, 0);

          -o-transform:skew(30deg, 0);

          transition:all .5s;

          -moz-transition:all .5s;

          -webkit-transition:all .5s;

          -o-transition:all .5s;

          }

          .logo a:hover{

          background: #357dd7;

          }

          .logo a:hover:before {

          left: -60px;

          }

          .logo img {

          position: relative;

          z-index: 1;

          }

          /*一級導(dǎo)航*/

          .nav-main{

          position: fixed;

          top: 0;

          z-index: 12;

          height: 100%;

          width: 100px;

          color: #fff;

          background: #111213;

          }

          .nav-main a{color: #fff;}

          .nav-box{

          position: relative;

          perspective: 200px;

          -webkit-perspective: 200px;

          transform-style: preserve-3d;

          -webkit-transform-style: preserve-3d;

          height: 100%;

          z-index: 99;

          }

          .nav-ul li a{

          display: block;

          width: 100px;

          height: 100px;

          overflow: hidden;

          text-align: center;

          position: relative;

          transition: all .5s;

          -moz-transition: all .5s;

          -webkit-transition: all .5s;

          -o-transition: all .5s;

          }

          .nav-ul li a:before{

          content: '';

          position: absolute;

          left: -240px;

          top: 0px;

          width: 200px;

          height: 100%;

          background: #629feb;

          z-index: 1;

          transform: skew(30deg, 0);

          -webkit-transform: skew(30deg, 0);

          -ms-transform: skew(30deg, 0);

          -moz-transform: skew(30deg, 0);

          -o-transform: skew(30deg, 0);

          transition: all .5s;

          -moz-transition: all .5s;

          -webkit-transition: all .5s;

          -o-transition: all .5s;

          }

          .nav-ul li a:hover{background: #357dd7;}

          .nav-ul li a:hover:before{left: -30px;}

          .nav-ul li a:after{

          content: '';

          position: absolute;

          width: 100%;

          height: 30px;

          left: 0;

          top: 20px;

          z-index: 1;

          }

          .nav-ul li a span{

          display: block;

          margin-top: 60px;

          perspective: ;

          position: relative;

          z-index: 1;

          }

          .nav-slide{

          position: fixed;

          left: 100px;

          top: 0;

          width: 240px;

          height: 100%;

          background: #252829;

          transform: rotateY(120deg);

          -webkit-transform: rotateY(120deg);

          -moz-transform: rotateY(120deg);

          -o-transform: rotateY(120deg);

          -ms-transform: rotateY(120deg);

          z-index: 99;

          visibility: hidden;

          transform-origin: 0 0;

          -webkit-transform-origin: 0 0;

          -moz-transform-origin: 0 0;

          -o-transform-origin: 0 0;

          -ms-transform-origin: 0 0;

          backface-visibility: hidden;

          -webkit-backface-visibility: hidden;

          transition: all .5s;

          -webkit-transition: all .5s;

          -moz-transition: all .5s;

          -o-transition: all .5s;

          transition-timing-function: cubic-bezier(.08, .72, .71, .96);

          -webkit-transition-timing-function: cubic-bezier(.08, .72, .71, .96);

          }

          .nav-slide.hover{

          transform: rotateY(0deg);

          -webkit-transform: rotateY(0deg);

          -moz-transform: rotateY(0deg);

          -o-transform: rotateY(0deg);

          -ms-transform: rotateY(0deg);

          z-index: 15;

          visibility: visible;

          }

          /*二級菜單*/

          .nav-slide-o li a{

          line-height: 50px;

          display: block;

          padding: 0 20px;

          font-size: 14px;

          overflow: hidden;

          text-align: left;

          position: relative;

          transition: all .5s;

          -webkit-transition: all .5s;

          -moz-transition: all .5s;

          -o-transition: all .5s;

          }

          .nav-slide-o li a:before{

          content: '';

          position: absolute;

          left: -230%;

          top: 0px;

          width: 200%;

          height: 100%;

          background: #629feb;

          z-index: 1;

          transform: skew(30deg, 0);

          -webkit-transform: skew(30deg, 0);

          -moz-transform: skew(30deg, 0);

          -o-transform: skew(30deg, 0);

          -ms-transform: skew(30deg, 0);

          transition: all .5s;

          -webkit-transition: all .5s;

          -moz-transition: all .5s;

          -o-transition: all .5s;

          }

          .nav-slide-o li a:hover{background: #357dd7;}

          .nav-slide-o li a:hover:before{left: -60px;}

          .nav-slide-o li a span{position: relative;z-index: 1;}

          .nav-slide-o {display: none;}

          itbook 是一款產(chǎn)品文檔構(gòu)建工具,也可以用于構(gòu)建個人博客,默認(rèn)情況下電腦端訪問時左側(cè)菜單是展開狀態(tài),可偏偏有人想要實(shí)現(xiàn)默認(rèn)折疊效果,于是誕生了這篇文章!

          善良的我選擇幫助別人

          可能是網(wǎng)上關(guān)于 Gitbook 的教程相對來說有些落后,加上寫文章時分享了不少關(guān)于 ,因此關(guān)注我的粉絲好友中有不少是來源于 Gitbook.

          所以上個月有個好友問我能不能配置 Gitbook 默認(rèn)折疊的效果,心里有些犯難,作為 gitbook 的忠實(shí)粉絲,我都不知道 gitbook 還有這方面的配置?!

          但是,善良的我總是有求必應(yīng),不忍心拒絕小白用戶,于是我便抱著試一試的心態(tài)開始研究一下如何默認(rèn)折疊?

          當(dāng)然,解決問題前還是要先復(fù)現(xiàn)一下問題,然后在命令行中熟練敲入了 gitbook serve 命令來啟動本地服務(wù)器,為了排除緩存等影響,特意打開了 Chrome 瀏覽器的無痕模式,果不其然默認(rèn)左側(cè)菜單是展開的!

          不能復(fù)現(xiàn)的問題都不是我的問題,拒絕解決此類問題,搞不好是你自己環(huán)境搭建問題呢!

          驀然回首官方文檔已走

          問題復(fù)現(xiàn)后就要開始尋求解決之道,雖然印象中并沒有相關(guān)配置,但是難保記憶混亂遺漏了某些配置項(xiàng),所以還是先看看官方文檔怎么說的吧!

          但是,當(dāng)你在瀏覽器中輸入 gitbook 官方文檔 時,并找不到想象中的官方文檔而是新版官網(wǎng),不信你自己去搜一下,肯定是新版官網(wǎng).

          當(dāng)你自以為找到了官網(wǎng)時,點(diǎn)擊進(jìn)去查看文檔部分,很遺憾,這是新版文檔并不是老版文檔,你還會繼續(xù)百度一下尋求可用鏈接期待找到官方文檔.

          為了節(jié)省寶貴時間,這里推薦訪問個人維護(hù)的 gitbook 文檔

          目前提供了中英文兩個語言版本的文檔,相信可以滿足大多數(shù)用戶的需求了,選擇任意一種語言后點(diǎn)擊進(jìn)入翻閱相關(guān)設(shè)置.

          實(shí)際上,官方文檔也并沒有什么用,因?yàn)楦揪蜎]有提到過如何更改相關(guān)配置使其默認(rèn)折疊而非展開狀態(tài).

          官方不再維護(hù)舊版文檔,費(fèi)盡心機(jī)找到舊版文檔也無濟(jì)于事,因?yàn)椴]有提及到相關(guān)配置,所以猜測很可能并未提供有關(guān)配置項(xiàng)!

          百度一下你就知道了嗎

          俗話說:"互聯(lián)網(wǎng)上絕大多數(shù)問題別人都已經(jīng)遇到過并提供了解決方案,我們唯一要做的就是找到它!"

          這也是面向搜索編程的核心思想,遇到默認(rèn)折疊問題應(yīng)該也不會例外,那就搜索一下吧!

          雖然百度搜索出現(xiàn)了一些相關(guān)文章,但是卻不是我們想要的效果,大多數(shù)是基于 gitbook 插件實(shí)現(xiàn)的目錄折疊效果,并不是默認(rèn)折疊左側(cè)菜單效果.

          不管是換關(guān)鍵詞重新搜索還是谷歌搜索,均未發(fā)現(xiàn)有關(guān)默認(rèn)折疊左側(cè)菜單的解決方案,難不成面向搜索失敗了,要做解決問題的第一人嗎?!

          多次重復(fù)搜索操作均為找到解決方案,由此可見真的很少有人想要默認(rèn)折疊左側(cè)菜單,我也是很佩服提出該問題的小伙伴骨骼驚奇啊!

          自力更生找尋蛛絲馬跡

          既然依靠別人無法解決問題,那么只能自力更生獨(dú)自解決問題,是時候考驗(yàn)真正的技術(shù)了!

          為了排除無關(guān)干擾,不能再用自己的 gitbook 項(xiàng)目了,畢竟文件太多不方便后續(xù)調(diào)試,那么不妨重新創(chuàng)建一個測試項(xiàng)目.

          • 創(chuàng)建測試項(xiàng)目
          • 初始化測試項(xiàng)目
          • 啟動測試項(xiàng)目

          雖然一片空白,并沒有什么實(shí)質(zhì)性內(nèi)容,但是大道至簡,對于我們復(fù)現(xiàn)并測試問題來說,足夠了!

          打開 Chrome 瀏覽器并按下 F12 開啟調(diào)試模式,鼠標(biāo)選中左側(cè)的 Elements 元素選項(xiàng)卡并點(diǎn)亮左側(cè)的小鼠標(biāo),然后在頁面上找到左側(cè)圖標(biāo)按鈕,于是選中元素高亮了.

          單獨(dú)摘錄 Html 關(guān)鍵代碼如下:

          稍微熟悉前端的小伙伴可能很輕松就能明白 a 標(biāo)簽的 class 屬性表示的含義,見名知意,可以這么解釋:

          • btn 應(yīng)該是控制外觀的樣式,表現(xiàn)得像是按鈕效果.
          • pull-left 應(yīng)該是控制元素的位置,拉倒左邊.
          • js-toolbar-action 應(yīng)該是控制元素的行為,js 工具欄行為動作.

          由此可見,點(diǎn)擊該圖標(biāo)實(shí)現(xiàn)左側(cè)菜單折疊/展開效果應(yīng)該是 .js-toolbar-action 在起作用,也就是說某一段 js 肯定是針對該 class進(jìn)行了監(jiān)聽!

          此時,點(diǎn)擊右側(cè)的 Event Listeners 選項(xiàng)卡查看該元素已監(jiān)聽的 click 事件,定位到是哪一個具體的 js 文件在起作用.

          果不其然,元素上存在 click 點(diǎn)擊事件監(jiān)聽并且發(fā)現(xiàn)執(zhí)行監(jiān)聽的邏輯代碼出現(xiàn)在 theme.js 文件,點(diǎn)擊進(jìn)入文件查看具體內(nèi)容.

          壓縮后的 js 代碼不具備可讀性,點(diǎn)擊左下方的 {} 圖標(biāo)可以進(jìn)行代碼格式化,但是可能不是單純的壓縮而是進(jìn)行了丑化或者混淆代碼之類的邏輯,格式化后的代碼仍然不可讀!

          終于發(fā)現(xiàn)了蛛絲馬跡,修改的代碼邏輯就隱藏在 theme.js 文件中,只要找到相關(guān)源碼重新編譯輸出 theme.js文件并替換應(yīng)該就能實(shí)現(xiàn)默認(rèn)折疊效果!

          不要擔(dān)心黎明前的黑暗

          根據(jù)目前已掌握的線索,可以肯定的是有用線索主要有兩個:

          • 監(jiān)聽元素 .js-toolbar-action
          • 輸出文件 theme.js

          一個是源碼文件,另一個是輸出文件,想要在龐大的 gitbook 項(xiàng)目中迅速定位到相關(guān)代碼邏輯,個人能力有限,并不熟悉前端開發(fā)調(diào)試流程,因此采用最簡單粗暴傻瓜式搜索方式進(jìn)行排查!

          如果讀者對于現(xiàn)代前端開發(fā)流程比較屬性的話,大概過一遍項(xiàng)目結(jié)構(gòu)應(yīng)該就可以調(diào)試定位問題了,用不著像我這樣傻瓜式搜索排查!

          • 查看當(dāng)前 gitbook 版本
          • 找到 gitbook 安裝位置

          gitbook 一般安裝在 ~/.gitbook/versions/3.2.3 目錄,其中 ~ 表示用戶家目錄.

          選擇一款熟悉的編輯器并打開 Gitbook 安裝目錄,這里以 sublime 編輯器為例,選中項(xiàng)目后右鍵全局搜索關(guān)鍵字 js-toolbar-action 期望找到相關(guān)源碼文件.

          全局搜索后主要出現(xiàn)兩個文件包含 js-toolbar-action 關(guān)鍵字,一個是輸出文件 theme.js ,另一個是源碼文件 toolbar.js .

          可想而知,源碼文件肯定是經(jīng)過編譯處理后統(tǒng)一打包輸出,因此不僅僅要找到源碼文件還要掌握如何編譯.

          定位到當(dāng)前 gitbook 目錄后借助全局搜索功能定位到具體的文件路徑,起作用的是 gitbook-plugin-theme-default 項(xiàng)目,其實(shí)這就是 Gitbook 的默認(rèn)主題.

          源碼在哪

          /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default/src/js/theme/toolbar.js :

          粗略看一下,上述代碼是實(shí)現(xiàn)觸發(fā)左側(cè)圖標(biāo)折疊/展開菜單的邏輯實(shí)現(xiàn),這里只是具體實(shí)現(xiàn)還不知道誰是使用者,也就是說這種邏輯是在哪里調(diào)用的?

          只能繼續(xù)順藤摸瓜,往上翻看,根據(jù)基本開發(fā)常識,在該文件的同級目錄中存在如下文件,其中的 index.js 應(yīng)該就是入口文件:

          打開 index.js 文件,根據(jù)注釋我們可以看到 init() 函數(shù)是入門函數(shù),其中 sidebar.init() 和 sidebar.toggle() 函數(shù)無不說明 sidebar.js 和 toolbar.js 關(guān)系密切,完全有理由猜想 sidebar.js 是 toolbar.js 的使用者!

          打開 sidebar.js 文件并查看 init() 初始化函數(shù)和 toggle() 觸發(fā)函數(shù),可以驗(yàn)證我們的猜想,這里就是控制中心!

          : 非手機(jī)端初始化上次狀態(tài),默認(rèn)展開側(cè)邊欄,如果是手機(jī)端則折疊側(cè)邊欄.其中 toggleSidebar() 接收兩個參數(shù),第一次參數(shù)表示是展開還是折疊,第二個參數(shù)暫不可知.

          「: 第一個參數(shù)確實(shí)表示狀態(tài)而第二個參數(shù)表示是否有動畫效果,不用看具體代碼邏輯而是看注釋就能猜出大概邏輯了.

          通過上述分析,我們可以得知 init() 初始化函數(shù)決定了默認(rèn)行為是折疊還是展開,同時 gitbook.storage.set('sidebar', isOpen()) 和 gitbook.storage.get('sidebar', true) 應(yīng)該是設(shè)置和獲取是否展開菜單的標(biāo)志!

          由此,如果想要默認(rèn)折疊左側(cè)菜單,那么只需要設(shè)置成 gitbook.storage.set('sidebar', false) 應(yīng)該就會生效!

          如何編譯

          說干就干,于是乎在 init() 函數(shù)插入 gitbook.storage.set('sidebar', false) 默認(rèn)折疊邏輯,接著看一下是否需要重新編譯才能生效?

          接著切換到測試項(xiàng)目再次運(yùn)行 gitbook serve 啟動本地服務(wù)器,發(fā)現(xiàn)并沒有任何變化,很有可能改變源碼文件需要重新編譯才會生效或者說更改的源碼項(xiàng)目也沒有生效?

          : 該源碼文件所在的項(xiàng)目是 gitbook-plugin-theme-default ,根據(jù) gitbook 插件命名規(guī)范我們知道,gitbook-plugin-* 一般是功能性插件,這一類的插件有 gitbook-plugin-readmore 閱讀更多插件和 gitbook-plugin-copyright版權(quán)保護(hù)插件等等.

          但是如果插件名以 gitbook-plugin-theme 開頭的話,這一類插件就是主題插件,比如 gitbook-plugin-theme-default 就是默認(rèn)主題.

          除此之外,只要遵守該命名規(guī)則的插件引入時無需添加 gitbook-plugin- 前綴,可以直接在 gitbook.json 文件中引入剩余的簡稱作為插件名.

          摘錄自 Gitbook 項(xiàng)目的配置文件,可以佐證上述規(guī)則的正確性.

          作為普通的 nodejs 包,開發(fā)規(guī)范規(guī)定了 package.json 提供了插件的配置信息,而 Gitbook 插件除了是標(biāo)準(zhǔn)的 nodejs 包之外還有自己的約束,主要體現(xiàn)在提供了 gitbook 節(jié)點(diǎn)屬性:

          默認(rèn)主題僅僅提供了兩個配置項(xiàng),分別是 styles 樣式文件位置和 showLevel 是否顯示層級配置.

          再一次驗(yàn)證了猜想的正確性,真的需要修改源碼才能實(shí)現(xiàn)默認(rèn)折疊左側(cè)菜單的效果,緊著繼續(xù)在 package.json 中找到項(xiàng)目源碼的托管地址,看一下有沒有提供二次開發(fā)文檔.

          令人遺憾的是,項(xiàng)目介紹空空如也,除了一張主題預(yù)覽圖,別的什么都沒有?!

          既然沒有二次開發(fā)文檔,那就看看項(xiàng)目源碼有沒有別的蛛絲馬跡教我們?nèi)绾尉幾g?

          繞了這么多,其實(shí)還不是因?yàn)楸容^菜,人家都提供給源碼都不會編譯,留下來沒有技術(shù)的眼淚!

          視角再一次切換到源碼目錄,除了 js 和 less 目錄外,竟然還有一個 build.sh 構(gòu)建腳本!

          這一刻,仿佛看到了九點(diǎn)鐘升起的太陽,未來是你們的也是我們的!

          這一段腳本中除了看不懂 browserify,uglifyjs,lessc -clean-css 命令外,剩下部分都很簡單,大致是編譯源碼文件并輸出到 _assets 目錄.

          編譯 js 的命令主要有以下兩條,而我們關(guān)心的 theme.js 僅涉及到一條,除此之外沒有任何別的依賴,這一點(diǎn)非常好!

          接下來的重點(diǎn)就是如何運(yùn)行 browserify src/js/theme/index.js | uglifyjs -mc > _assets/website/theme.js 命令了!

          搖身一變重新編譯源碼

          browserify src/js/theme/index.js | uglifyjs -mc > _assets/website/theme.js

          百度一下 browserify

          再一次打開熟悉的瀏覽器輸入關(guān)鍵字 browserify 后出現(xiàn)一系列相關(guān)文章,很好奇為啥排名第一個都不會是官網(wǎng)呢?不管怎么樣,找到 browserify 的 github 項(xiàng)目地址也是不錯的!

          這里并不關(guān)心 browserify 到底是什么,只在乎如何安裝基本環(huán)境而已!

          如果是 mac 電腦,全局安裝需要管理員權(quán)限,應(yīng)該運(yùn)行 sudo npm install -g browserify ,如果嫌棄安裝速度慢也可以運(yùn)行 cnpm install -g browserify ,前提是已安裝 cnpm 命令.

          谷歌一下 uglifyjs

          不吹不黑,少走一點(diǎn)彎路,直接就找到了 github 項(xiàng)目網(wǎng)址,同樣的也不關(guān)心項(xiàng)目介紹,直接翻看如何安裝部分.

          重新編譯 others

          涉及到 browserify src/js/theme/index.js | uglifyjs -mc > _assets/website/theme.js 命令的兩個插件均已安裝完畢,理所應(yīng)當(dāng)開始重新編譯源碼了,但是竟然報錯了?

          當(dāng)出現(xiàn)報錯時,開始懷疑人生,難道推論不正確,難道環(huán)境沒有安裝成功嗎,為啥提示找不到 mousetrap 模塊?

          算了吧,與其費(fèi)盡心思猜測為啥無法加載 mousetrap 模塊,不如繼續(xù)安裝剩余依賴,最大可能性排除環(huán)境問題.

          那就先把 src/build.sh 構(gòu)建腳本涉及到的其他命令全部安裝一遍,然后再試一下吧!

          除了編譯 Js 的命令外,還有編譯 Css 的命令,關(guān)于構(gòu)建腳本 build.sh 的其他內(nèi)容就是基本的復(fù)制粘貼之類的操作了.

          這里省略面向搜索編程的中間過程,安裝命令如下:

          當(dāng)我再一次運(yùn)行構(gòu)建腳本時,滿心期待會編譯成功,沒想到現(xiàn)實(shí)再一次打臉,這時候錯誤更多了呢,真的是沒想到!

          那就繼續(xù)擴(kuò)大安裝環(huán)境范圍,這時候?qū)φ麄€ gitbook-plugin-theme-default 進(jìn)行 npm install 安裝相關(guān)依賴,這一次會發(fā)生什么情況呢?

          讓我們拭目以待!

          命令行沒有了亂七八糟的輸出,世界變得安靜了!

          linux 命令行哲學(xué)告訴我們,沒有消息就是好消息,全部安裝項(xiàng)目環(huán)境后再次運(yùn)行 src/build.sh 腳本命令行瞬間安靜了!

          懷著忐忑不安的心,切換到測試項(xiàng)目運(yùn)行 gitbook serve 命令后,那一瞬間,感覺世界都靜止了,奇跡就這么發(fā)生了?

          終于成功了,實(shí)現(xiàn)默認(rèn)折疊效果了嗎?

          為了驗(yàn)證是否成功實(shí)現(xiàn)默認(rèn)折疊失效,做一次反向測試,既然默認(rèn)折疊左側(cè)菜單設(shè)置的是 false,如果設(shè)置成 true 的話,默認(rèn)應(yīng)該是展開狀態(tài).

          重新編譯后再次啟動本地測試項(xiàng)目,如果是展開狀態(tài),那就說明成功不是偶然而是靠技巧和努力!

          • 重新編譯源碼

          /Users/snowdreams1006/.gitbook/versions/3.2.3/node_modules/gitbook-plugin-theme-default

          • 啟動本地項(xiàng)目

          /Users/snowdreams1006/Documents/workspace/test

          苦心人天不負(fù),不是曇花一現(xiàn)的巧合而是貨真價實(shí)的現(xiàn)實(shí),就這么實(shí)現(xiàn)了默認(rèn)折疊左側(cè)菜單功能!

          懶人直達(dá)以及回顧總結(jié)

          如果你是 Gitbook 普通用戶或者懶得折騰,那么推薦你直接替換掉 theme.js 文件:

          • 查看正在使用的 gitbook 版本信息
          • 打開正在使用的 gitbook 安裝位置
          • 新文件替換掉原來的 _assets/website/theme.js 文件
          • 切換到測試項(xiàng)目驗(yàn)證默認(rèn)折疊是否已生效

          如果你不怕麻煩,喜歡折騰,那么不妨體驗(yàn)一下如何重新編譯源碼文件.

          • 查看正在使用的 gitbook 版本信息
          • 打開正在使用的 gitbook 安裝位置
          • 安裝 theme-default 默認(rèn)主題項(xiàng)目所需依賴
          • 安裝 build.sh 構(gòu)建腳本所需依賴
          • 運(yùn)行 build.sh 構(gòu)建腳本重新編譯
          • 切換到測試項(xiàng)目驗(yàn)證默認(rèn)折疊是否已生效

          值得注意的是,實(shí)現(xiàn)默認(rèn)折疊左側(cè)菜單功能僅僅需要添加一行代碼,但是也很有可能和項(xiàng)目中已引入插件存在沖突,畢竟 sidebar 的狀態(tài)也可以被未知代碼所更改!Copy// Prepare sidebar: state and toggle buttonfunction init() { // Close sidebar as default state gitbook.storage.set('sidebar', false); // Open sidebar as default state // gitbook.storage.set('sidebar', true); // Init last state if not mobile if (!platform.isMobile()) { toggleSidebar(gitbook.storage.get('sidebar', true), false); } // Close sidebar after clicking a link on mobile $(document).on('click', '.book-summary li.chapter a', function(e) { if (platform.isMobile()) toggleSidebar(false, false); });}

          最后希望本文對你有所幫助,面向搜索編程變得不可用時,自力更生也未嘗不可,如果大家在使用 Gitbook 中遇到任何問題,歡迎留言評論告訴我,當(dāng)然我也不一定保證解決,萬一哪天心血來潮翻看一下源碼就解決了呢!


          主站蜘蛛池模板: 精品午夜福利无人区乱码一区| 美日韩一区二区三区| AA区一区二区三无码精片| 亚洲AV无码一区二区三区系列| 相泽南亚洲一区二区在线播放| 人妻体内射精一区二区三区| 亚洲一区二区高清| 日韩精品中文字幕无码一区 | 国产精品一区二区综合| 无码国产精品一区二区免费模式| 国产精品资源一区二区| 99精品国产高清一区二区| 国精产品一区一区三区| 一区二区三区四区视频在线| 亚洲欧美日韩中文字幕在线一区 | 国产色欲AV一区二区三区| 蜜臀AV在线播放一区二区三区| 久久精品国产免费一区| 国产一区麻豆剧传媒果冻精品| 日本美女一区二区三区| 国产一区二区三区日韩精品 | 亚洲一区二区女搞男| 久久综合一区二区无码 | 一色一伦一区二区三区| 国产精品福利一区二区久久| 亚洲欧洲一区二区| 人妻少妇久久中文字幕一区二区| 亚洲日本一区二区三区在线| 视频一区精品自拍| 久久精品国产一区| 91秒拍国产福利一区| 无码国产精品一区二区免费| tom影院亚洲国产一区二区 | 日韩精品一区在线| 无码人妻AⅤ一区二区三区水密桃| 美女视频黄a视频全免费网站一区| 波多野结衣中文字幕一区二区三区 | 国产精品一区二区三区高清在线| 怡红院一区二区在线观看| 国产主播福利精品一区二区| 精品国产一区二区三区AV性色|