Bootstrap Blazor的官方虽然有提供图片预览组件ImagePreviewer,但是,它是置于窗口顶层的,而且是全屏显示,如果业务中有在预览组件中添加其它功能的需求,它是不支持扩展的。
为此,我参考官方的源码,自己写了一个自定义图片预览组件,文件的源码在下面,可自行查阅和扩展。支持左右切换、缩放(含鼠标滚轮缩放)和旋转图片,实现的效果如下:
ImagePreviewCustom.razor文件内容如下:
<div class="fyy-previewer">
<div class="fyy-viewer-canvas" id="fyy-viewer-canvas-id">
<img src="@GetShowImageUrl()" draggable="false" class="fyy-viewer-img" id="fyy-viewer-img-id" style="transform: scale(@ScaleValue) rotate(@(RotateValue)deg); margin: 0; object-fit:contain;" @onmousewheel="(e) => onm ouseWheelToScaleImage(e.DeltaY)">
</div>
<div class="fyy-viewer-btn fyy-viewer-actions">
<div class="fyy-viewer-actions-inner">
@if (ShowButtons)
{
<i class="icon-circle fa-solid fa-angle-left" @onclick="() => OnClickToPrevImage()"></i>
<i class="icon-circle fa-solid fa-angle-right" @onclick="() => OnClickToNextImage()"></i>
}
<i class="icon-circle minus-icon fa-solid fa-magnifying-glass-minus" @onclick="() => OnClickToMinusImage()"></i>
<i class="icon-circle plus-icon fa-solid fa-magnifying-glass-plus" @onclick="() => OnClickToPlusImage()"></i>
<i class="icon-circle rotate-left fa-solid fa-rotate-left" @onclick="() => OnClickToRotateLeft()"></i>
<i class="icon-circle rotate-right fa-solid fa-rotate-right" @onclick="() => OnClickToRotateRight()"></i>
</div>
</div>
</div>
ImagePreviewCustom.razor.cs内容如下:
using Microsoft.AspNetCore.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics.CodeAnalysis;
namespace Fyy.Components
{
/// <summary>
/// 自定义图片预览
/// </summary>
public partial class ImagePreviewCustom
{
[Inject]
[NotNull]
private MessageBox? _MsgBox { get; set; }
/// <summary>
/// 获得/设置 预览大图链接集合 默认 null
/// </summary>
[Parameter]
[NotNull]
#if NET6_0_OR_GREATER
[EditorRequired]
#endif
public List<string>? PreviewList { get; set; }
/// <summary>
/// 获得/设置 预览大图当前链接集合点开的索引 默认为 0
/// </summary>
[Parameter]
[NotNull]
public int PreviewIndex { get; set; } = 0;
/// <summary>
/// 是否显示左右切换按钮
/// </summary>
private bool ShowButtons => PreviewList.Count > 1;
/// <summary>
/// 当前暂时的图片
/// </summary>
/// <returns></returns>
private string? GetShowImageUrl() => PreviewList[PreviewIndex];
/// <summary>
/// 缩放倍数
/// </summary>
private double ScaleValue { get; set; } = 1;
/// <summary>
/// 旋转角度
/// </summary>
private long RotateValue { get; set; } = 0;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
try
{
if (firstRender)
{
onl oadData();
}
await base.OnAfterRenderAsync(firstRender);
}
catch (Exception ex)
{
_MsgBox.Show(ex.Message, AlertTypes.Error);
}
}
private void onl oadData()
{
if (PreviewIndex < 0 || PreviewIndex >= PreviewList.Count)
{
throw new ArgumentOutOfRangeException();
}
}
/// <summary>
/// 切换到前一张图片
/// </summary>
/// <returns></returns>
private Task OnClickToPrevImage()
{
try
{
if (PreviewIndex == 0)
{
PreviewIndex = PreviewList.Count - 1;
}
else
{
PreviewIndex--;
}
StateHasChanged();
}
catch (Exception ex)
{
_MsgBox.Show(ex.Message, AlertTypes.Error);
}
return Task.CompletedTask;
}
/// <summary>
/// 切换到后一张图片
/// </summary>
/// <returns></returns>
private Task OnClickToNextImage()
{
try
{
if (PreviewIndex == PreviewList.Count - 1)
{
PreviewIndex = 0;
}
else
{
PreviewIndex++;
}
StateHasChanged();
}
catch (Exception ex)
{
_MsgBox.Show(ex.Message, AlertTypes.Error);
}
return Task.CompletedTask;
}
/// <summary>
/// 缩小图片
/// </summary>
/// <returns></returns>
private Task OnClickToMinusImage()
{
try
{
if (ScaleValue <= 0)
{
ScaleValue = 1;
}
else
{
ScaleValue -= 0.01;
}
StateHasChanged();
}
catch (Exception ex)
{
_MsgBox.Show(ex.Message, AlertTypes.Error);
}
return Task.CompletedTask;
}
/// <summary>
/// 放大图片
/// </summary>
/// <returns></returns>
private async Task OnClickToPlusImage()
{
try
{
if (ScaleValue <= 0)
{
ScaleValue = 1;
}
else
{
ScaleValue += 0.01;
}
StateHasChanged();
}
catch (Exception ex)
{
_MsgBox.Show(ex.Message, AlertTypes.Error);
}
}
/// <summary>
/// 逆时针旋转图片
/// </summary>
/// <returns></returns>
private Task OnClickToRotateLeft()
{
try
{
RotateValue -= 90;
StateHasChanged();
}
catch (Exception ex)
{
_MsgBox.Show(ex.Message, AlertTypes.Error);
}
return Task.CompletedTask;
}
/// <summary>
/// 逆时针旋转图片
/// </summary>
/// <returns></returns>
private Task OnClickToRotateRight()
{
try
{
RotateValue += 90;
StateHasChanged();
}
catch (Exception ex)
{
_MsgBox.Show(ex.Message, AlertTypes.Error);
}
return Task.CompletedTask;
}
private async Task onm ouseWheelToScaleImage(double delta)
{
try
{
if (delta > 0)
{
if (ScaleValue <= 0)
{
ScaleValue = 1;
}
else
{
ScaleValue += 0.01;
}
}
else
{
if (ScaleValue <= 0)
{
ScaleValue = 1;
}
else
{
ScaleValue -= 0.01;
}
}
StateHasChanged();
}
catch (Exception ex)
{
_MsgBox.Show(ex.Message, AlertTypes.Error);
}
}
}
}
ImagePreviewCustom.razor.css文件内容如下:
.fyy-previewer {
height: 50vh;
}
.fyy-viewer-canvas {
width: 100%;
height: calc(100% - 38px);
overflow: auto;
border: 1px solid #ccc;
position: relative;
display: flex;
align-items: center;
}
.fyy-viewer-img {
display: block;
transition: transform 0.3s ease;
}
.fyy-viewer-btn {
position: absolute;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
}
.fyy-viewer-actions {
left: 50%;
bottom: 2px;
transform: translateX(-50%);
width: 400px;
height: 36px;
cursor: default;
}
.fyy-viewer-actions-inner {
font-size: 0rem;
}
.icon-circle {
font-size: 1.5rem;
width: 36px;
height: 36px;
margin-left: 5px;
margin-right: 5px;
border-radius: 50%;
border: 1px solid darkgray;
line-height: 36px;
align-content: center;
text-align: center;
background-color: darkgray;
opacity: .8;
}
.icon-circle:hover {
opacity: 1;
}
弹出预览窗口的方式如下(这个是我在项目中用的,可作为参考):
[Inject]
[NotNull]
private DialogService _DialogService { get; set; }
private Task OnImageClick(List<string> previewList, int previewIndex)
{
try
{
if (previewIndex >= previewList.Count)
{
previewIndex = 0;
}
_DialogService.Show(new DialogOption()
{
Title = "图片预览",
ShowCloseButton = false,
Size = BootstrapBlazor.Components.Size.ExtraExtraLarge,
BodyTemplate = BootstrapDynamicComponent.CreateComponent<ImagePreviewCustom>(new Dictionary<string, object?>
{
[nameof(ImagePreviewCustom.PreviewList)] = previewList,
[nameof(ImagePreviewCustom.PreviewIndex)] = previewIndex
}).Render()
});
}
catch (Exception ex)
{
}
return Task.CompletedTask;
}
标签:Task,预览,自定义,Bootstrap,PreviewIndex,private,try,ex,Blazor
From: https://blog.csdn.net/weixin_50478033/article/details/143569004