最近在研究webview2,發現通過這個控件借用css和js來實現一些UI上的動畫效果簡直太方便了,最終效果如圖:
1. 首先選好背景圖片和logo圖片:
可以在這個網站,觀察各種參數的效果:Neumorphism/Soft UI CSS shadow generator
選定合適參數之後,在figma上根據參數繪製背景圖片,或者直接從figma上找一個好看的導出,導出一定要選png格式這樣纔有半透明效果:
2. MainWindow.xaml之中添加webview2控件,並設好佈局
我是用wpf的,webview使用入門可以看這裏:WPF 應用中的 WebView2 入門 - Microsoft Edge Development | Microsoft Learn
winform可以看WinForms 應用中的 WebView2 入門 - Microsoft Edge Development | Microsoft Learn
代碼如下,LoginBG爲窗口背景,window屬性需要ResizeMode="NoResize" AllowsTransparency="True" Background="#00ffffff"這幾項以實現透明效果。
<Window x:Class="TestWeb.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestWeb"
mc:Ignorable="d"
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
Title="MainWindow" Height="680" Width="680" WindowStyle="None" WindowStartupLocation="CenterScreen" ResizeMode="NoResize" AllowsTransparency="True" Background="#00ffffff" MouseLeftButtonDown="Window_MouseLeftButtonDown">
<Grid>
<Image Source="Resource\LoginBG.png" Stretch="Fill" Opacity="0.9"/>
<Image Source="Resource\Logo.png" Margin="254,87,254,467"/>
<TextBlock HorizontalAlignment="Center" Margin="0,252,0,0" TextWrapping="Wrap" Text="Software Name" VerticalAlignment="Top" FontSize="36" Height="56" Width="460" TextAlignment="Center"/>
<wv2:WebView2 Grid.Row="1" Name="webView1" Margin="50,320,50,50" />
</Grid>
</Window>
window添加一個Window_MouseLeftButtonDown事件以實現鼠標拖動窗口效果。
說明一下,此處必須把LoginBG.png放在本地端,而不能放在webview2裏再設定webview2爲半透明,如果那樣,webview裏的html內容將會變成可以看但不能點擊。
Logo.png可以放在html裏,但是加載的時候會有一些延遲,不如放在本地,先顯示logo再顯示輸入框和按鈕。
3. 本地代碼
MainWindow.xaml.cs代碼如下:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//加載login.html
webView1.Source = new Uri("file:///" + System.Environment.CurrentDirectory + "\\App\\login.html");
//給webview2控件設定透明度
webView1.DefaultBackgroundColor = System.Drawing.Color.Transparent;
//接受web發來的事件
webView1.WebMessageReceived += WebView_WebMessageReceived;
InitializeAsync();
}
void WebView_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs args)
{
HandleWebMessage(args);
}
void HandleWebMessage(CoreWebView2WebMessageReceivedEventArgs args)
{
string message = args.TryGetWebMessageAsString();
//此處處理web發來的Quit事件
if (message.Contains("bQuit"))
{
System.Windows.Application.Current.Shutdown();
}
}
async void InitializeAsync()
{
await webView1.EnsureCoreWebView2Async(null);
//禁止鼠標右鍵菜單
await webView1.CoreWebView2.ExecuteScriptAsync("window.addEventListener('contextmenu', window => {window.preventDefault();});");
//禁止鼠標左鍵拖動選擇
await webView1.CoreWebView2.ExecuteScriptAsync("window.addEventListener('selectstart', window => {window.preventDefault();});");
//禁止拖動文件到窗口
await webView1.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(
"window.addEventListener('dragover',function(e){e.preventDefault();},false);" +
"window.addEventListener('drop',function(e){" +
"e.preventDefault();" +
"console.log(e.dataTransfer);" +
"console.log(e.dataTransfer.files[0])" +
"}, false);");
}
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.DragMove();
}
}
4. login.html設計
首先在601 Buttons made with CSS (uiverse.io) 找一個好看的button的css
然後在92 Inputs made with CSS (uiverse.io) 找一個input輸入框css
最終login.html類似:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
/* 按鈕的樣式 */
button {
width: 10em;
height: 3em;
border-radius: 30em;
font-size: 15px;
font-family: inherit;
border: none;
position: relative;
overflow: hidden;
z-index: 1;
box-shadow: 6px 6px 12px #c5c5c5,
-6px -6px 12px #ffffff;
}
button::before {
content: '';
width: 0;
height: 3em;
border-radius: 30em;
position: absolute;
top: 0;
left: 0;
background-image: linear-gradient(to right, #0fd850 0%, #f9f047 100%);
transition: .5s ease;
display: block;
z-index: -1;
}
button:hover::before {
width: 10em;
}
/* 輸入框的樣式 */
.input {
width: 330px;
height: 30px;
padding: 10px;
outline: none;
background: #e8e8e8;
box-shadow: 5px 5px 17px #c8c8c8,
-5px -5px 17px #ffffff;
border: none;
border-radius: 10px;
transition: all .5s;
}
.input:focus {
background: #e8e8e8;
box-shadow: inset 5px 5px 17px #c8c8c8,
inset -5px -5px 17px #ffffff;
}
</style>
</head>
<body>
<div>
<div style="height: 20px;"></div>
<div style="text-align: center;height: 80px;">
<input placeholder="UserName" class="input" type="text">
</div>
<div style="text-align: center;height: 80px;">
<input placeholder="PassWord" class="input" type="password">
</div>
<div style="text-align: center;height: 70px;">
<button id="bLogin" style="margin: 20px 20px 0px 0px;">登錄</button>
<button id="bQuit" style="margin: 20px 0px 0px 20px;">退出</button>
</div>
</div>
<script>
"use strict";
//獲取dom 綁定事件 一步執行
function AddClickToButton(buttonName)
{
document.getElementById(buttonName).addEventListener('click',(e)=>{
window.chrome.webview.postMessage(buttonName);
});
}
AddClickToButton("bQuit"); //向本地端發送bQuit事件
AddClickToButton("bLogin");
</script>
</body>
</html>
至此這個混合了webview和本地控件的登錄界面就做好了。