首页 > 其他分享 >Bootstrap Blazor自定义图片预览组件

Bootstrap Blazor自定义图片预览组件

时间:2024-11-06 14:19:02浏览次数:3  
标签:Task 预览 自定义 Bootstrap PreviewIndex private try ex Blazor

        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

相关文章

  • WinNTSetup 使用教程的框架,您可以根据自己的需求深入研究每个部分,特别是集成驱动、应
    WinNTSetupv5.3.5.2-InstallWindowsfromUSB-MSFNWinNTSetup官方原版多国语言版下载链接:https://www.mediafire.com/folder/53um6k2nmhvd5/https://www.mediafire.com/file/rbpu88tre4nxwbe/WinNTSetup_v5352.rar/fileWinNTSetupv5352初级使用教程大纲引言WinNTSet......
  • SpringBoot源码解析(二):启动流程之引导上下文DefaultBootstrapContext
     SpringBoot的启动流程可以分为几个重要的步骤,其中之一是引导上下文(BootstrapContext)。引导上下文是在SpringBoot应用程序启动时创建的第一个Spring应用程序上下文,它负责加载和初始化SpringBoot的核心组件和配置。默认的引导上下文是通过DefaultBootstrapContext类来实现......
  • 07LangChain实战课 - LLM模块使用与自定义模型调用
    LangChain实战课-LLM模块使用与自定义模型调用1.课程简介本节课聚焦于LangChain中的LLM(LargeLanguageModel)模块,探讨如何使用不同的大语言模型,包括开源模型和自定义模型。2.大语言模型的发展Transformer架构:Google在2018年提出的架构,是现代预训练模型的核心。基础......
  • pbootcms网站后台增加点击数自定义修改
    打开 /apps/admin/view/default/content/content.html 文件,在 {if([$mod])} 下方添加:<divclass="layui-form-item"><labelclass="layui-form-label">浏览量<spanclass="layui-text-red">*</span></label><......
  • PbootCMS 使用Ajax无刷新提交自定义表单
    <!--自定义表单(在线留言)--><formonsubmit="returnsubmsg(this);">联系人<inputtype="text"name="contacts"requiredid="contacts">手机<inputtype="text"name="mobile"requiredi......
  • SpringBoot项目使用AOP及自定义注解保存操作日志
    @目录概述:特色使用方式注意点代码第一步:pom引入AOP第二步:创建自定义注解、Bean实体、枚举、常量类第三步:Controller层方法使用自定义注解标识第四步:新建一个日志操作类LogAopAction,专门用来处理操作保存日志第五步:postman模拟调用接口,输出AOP中ProceedingJoinPoint获取目标方法,参......
  • 自定义注解实现权限校验
    自定义注解实现权限校验引入所需的依赖<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>版本号</version><relativePath/></parent><depen......
  • python: Parent-child form operations using ttkbootstrap
    #encoding:utf-8#版權所有2024©塗聚文有限公司#許可資訊查看:言語成了邀功的功臣,還需要行爲每日來值班嗎?#描述:主、子表單窗體傳值Parent-childformoperations#Author:geovindu,GeovinDu塗聚文.#IDE:PyCharm2023.1python3.11#OS:......
  • Blazor 使用 npm 依赖包
    使用node包时,经常会有 importinteractjsfrom'@interactjs/interactjs';这样类似的引用;这是node的语法,非node环境都不支持这种写法。所以Blazor要用node包,需要再用js封装一层。示例项目下面是一个node项目{"name":"test","version":"1.0.0","de......
  • 手把手教你编写自定义Categraf插件
    本文分享自天翼云开发者社区《手把手教你编写自定义Categraf插件》,作者:任****佳Categraf是一个监控采集Agent,类似Telegraf、Grafana-Agent、Datadog-Agent,希望对所有常见监控对象提供监控数据采集能力,采用All-in-one的设计,不但支持指标采集,也希望支持日志和调用链路的数据采......