Viewer.js自定义工具栏与界面扩展
Viewer.js 提供了强大的工具栏自定义功能,允许开发者根据具体需求添加、修改或移除工具栏按钮。通过灵活的配置选项,可以创建完全符合项目需求的图像查看器界面。文章详细介绍了内置按钮类型与配置方法、自定义按钮的实现、CSS样式定制、响应式布局以及移动端优化等核心功能。
自定义工具栏按钮的实现方法
Viewer.js 提供了强大的工具栏自定义功能,允许开发者根据具体需求添加、修改或移除工具栏按钮。通过灵活的配置选项,您可以创建完全符合项目需求的图像查看器界面。
内置按钮类型与配置
Viewer.js 内置了11种标准工具栏按钮,每种按钮都有特定的功能:
| 按钮标识符 | 功能描述 | 默认显示 |
|---|---|---|
zoom-in |
放大图像 | ✓ |
zoom-out |
缩小图像 | ✓ |
one-to-one |
1:1比例显示 | ✓ |
reset |
重置图像 | ✓ |
prev |
上一张图片 | ✓ |
play |
自动播放 | ✓ |
next |
下一张图片 | ✓ |
rotate-left |
向左旋转 | ✓ |
rotate-right |
向右旋转 | ✓ |
flip-horizontal |
水平翻转 | ✓ |
flip-vertical |
垂直翻转 | ✓ |
基本配置语法
自定义工具栏主要通过 toolbar 选项进行配置,支持多种配置格式:
// 完全隐藏工具栏
new Viewer(element, {
toolbar: false
});
// 根据屏幕宽度响应式显示
new Viewer(element, {
toolbar: 2 // 仅在屏幕宽度 > 768px 时显示
});
// 自定义单个按钮的显示状态
new Viewer(element, {
toolbar: {
zoomIn: true,
zoomOut: false, // 隐藏缩小按钮
play: {
show: true,
size: 'large' // 设置按钮大小
}
}
});
添加自定义按钮
要为工具栏添加全新的自定义按钮,需要在配置对象中定义新的按钮键名,并提供相应的点击处理函数:
const viewer = new Viewer(document.getElementById('gallery'), {
toolbar: {
// 保留内置按钮
zoomIn: true,
zoomOut: true,
// 添加下载按钮
download: function() {
const image = viewer.image;
const a = document.createElement('a');
a.href = image.src;
a.download = image.alt || 'image';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
},
// 添加分享按钮
share: function() {
if (navigator.share) {
navigator.share({
title: viewer.image.alt,
url: viewer.image.src
});
} else {
alert('分享功能在当前浏览器中不可用');
}
}
}
});
按钮样式自定义
每个自定义按钮都可以通过CSS进行样式定制。Viewer.js 会自动为按钮生成相应的CSS类名:
/* 自定义下载按钮样式 */
.viewer-download {
background-color: #4CAF50;
color: white;
border-radius: 50%;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s;
}
.viewer-download:hover {
background-color: #45a049;
}
/* 使用FontAwesome图标 */
.viewer-download::before {
content: "\f019"; /* 下载图标 */
font-family: 'Font Awesome 5 Free';
font-weight: 900;
}
/* 自定义分享按钮样式 */
.viewer-share {
background-color: #2196F3;
color: white;
}
.viewer-share::before {
content: "\f064"; /* 分享图标 */
font-family: 'Font Awesome 5 Free';
font-weight: 900;
}
响应式按钮配置
Viewer.js 支持根据屏幕尺寸动态显示或隐藏按钮:
new Viewer(element, {
toolbar: {
zoomIn: 4, // 仅在屏幕宽度 > 1200px 时显示
zoomOut: 3, // 仅在屏幕宽度 > 992px 时显示
play: 2, // 仅在屏幕宽度 > 768px 时显示
download: true, // 始终显示
share: {
show: 4, // 仅在屏幕宽度 > 1200px 时显示
size: 'small'
}
}
});
按钮大小控制
支持三种预定义的按钮尺寸:
new Viewer(element, {
toolbar: {
zoomIn: {
show: true,
size: 'small' // small, medium, large
},
play: {
show: true,
size: 'large'
},
download: {
show: true,
size: 'medium' // 默认值
}
}
});
完整示例:自定义图片编辑器工具栏
下面是一个完整的自定义工具栏示例,包含图片编辑功能:
const viewer = new Viewer(document.getElementById('image-gallery'), {
toolbar: {
// 标准功能按钮
zoomIn: true,
zoomOut: true,
oneToOne: true,
reset: true,
// 导航按钮
prev: true,
next: true,
// 自定义编辑按钮
crop: function() {
// 裁剪功能实现
console.log('裁剪图片');
},
filter: function() {
// 滤镜功能
console.log('应用滤镜');
},
annotate: function() {
// 标注功能
console.log('添加标注');
},
// 高级功能
save: function() {
// 保存编辑后的图片
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const img = viewer.image;
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
ctx.drawImage(img, 0, 0);
canvas.toBlob(function(blob) {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'edited-' + (img.alt || 'image');
a.click();
URL.revokeObjectURL(url);
});
}
}
});
按钮配置流程图
以下流程图展示了自定义按钮的配置决策过程:
flowchart TD
A[开始工具栏配置] --> B{配置类型?}
B -->|布尔值| C[显示/隐藏整个工具栏]
B -->|数字| D[响应式显示配置]
B -->|对象| E[详细按钮配置]
C --> F[完成配置]
D --> G[根据屏幕尺寸显示]
G --> F
E --> H{按钮键值类型?}
H -->|布尔值| I[显示/隐藏该按钮]
H -->|数字| J[响应式显示该按钮]
H -->|字符串| K[设置按钮尺寸]
H -->|函数| L[设置点击处理器]
H -->|对象| M[完整按钮配置]
I --> F
J --> F
K --> F
L --> F
M --> N[配置显示条件]
N --> O[配置按钮尺寸]
O --> P[配置点击处理器]
P --> F
通过上述方法,您可以灵活地定制Viewer.js的工具栏,创建出既美观又功能丰富的图像查看体验。无论是简单的按钮隐藏显示,还是复杂的自定义功能添加,Viewer.js都提供了完善的API支持。
添加下载功能等自定义操作
Viewer.js提供了强大的工具栏自定义能力,允许开发者添加各种自定义操作按钮,其中下载功能是最常见的需求之一。通过灵活的配置选项,我们可以轻松地为图片查看器添加下载按钮,并实现个性化的下载逻辑。
自定义工具栏配置基础
Viewer.js的工具栏配置通过toolbar选项进行控制,该选项支持多种配置格式:
// 布尔值配置 - 显示或隐藏整个工具栏
toolbar: true // 显示默认工具栏
toolbar: false // 隐藏工具栏
// 数字配置 - 响应式显示
toolbar: 2 // 仅在屏幕宽度大于768px时显示
toolbar: 3 // 仅在屏幕宽度大于992px时显示
toolbar: 4 // 仅在屏幕宽度大于1200px时显示
// 对象配置 - 精细化控制每个按钮
toolbar: {
zoomIn: true, // 显示放大按钮
zoomOut: false, // 隐藏缩小按钮
download: function() { // 自定义下载按钮
// 下载逻辑
}
}
实现下载功能
添加下载功能需要创建一个自定义按钮并实现下载逻辑。以下是完整的实现示例:
const viewer = new Viewer(document.getElementById('gallery'), {
toolbar: {
// 保留部分默认按钮
zoomIn: true,
zoomOut: true,
oneToOne: true,
reset: true,
// 自定义下载按钮
download: {
show: true, // 始终显示
size: 'medium', // 按钮大小:small, medium, large
click: function() {
// 获取当前查看的图片
const currentImage = viewer.image;
const imageUrl = currentImage.src;
const imageName = currentImage.alt || 'download';
// 创建下载链接
const link = document.createElement('a');
link.href = imageUrl;
link.download = `${imageName}.${getFileExtension(imageUrl)}`;
link.style.display = 'none';
// 添加到文档并触发点击
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
},
// 其他自定义按钮示例
share: {
show: true,
click: function() {
// 分享功能实现
shareImage(viewer.image.src);
}
}
}
});
// 辅助函数:获取文件扩展名
function getFileExtension(url) {
return url.split('.').pop().split('?')[0];
}
// 分享功能示例
function shareImage(imageUrl) {
if (navigator.share) {
navigator.share({
title: '分享图片',
url: imageUrl
});
} else {
// 备用分享方案
prompt('复制链接分享:', imageUrl);
}
}
自定义按钮样式
为了让下载按钮与其他工具栏按钮风格一致,需要添加相应的CSS样式:
/* 下载按钮样式 */
.viewer-download {
background-color: rgba(0, 0, 0, 0.5);
border-radius: 50%;
color: #fff;
cursor: pointer;
display: inline-block;
font-size: 0.75rem;
height: 1.5rem;
line-height: 1.5rem;
margin: 0 0.25rem;
text-align: center;
width: 1.5rem;
transition: background-color 0.15s;
}
.viewer-download:hover {
background-color: rgba(0, 0, 0, 0.8);
}
/* 使用FontAwesome图标 */
.viewer-download::before {
content: "\f019"; /* 下载图标 */
font-family: 'Font Awesome 5 Free';
font-weight: 900;
}
/* 或者使用SVG背景 */
.viewer-download {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: center;
background-size: 60%;
}
高级下载功能实现
对于更复杂的下载需求,可以实现以下高级功能:
// 高级下载处理器
const advancedDownloadHandler = {
show: true,
size: 'medium',
click: function() {
const image = viewer.image;
const originalUrl = getOriginalImageUrl(image);
// 创建高质量下载
downloadHighQualityImage(originalUrl, image.alt);
}
};
// 获取原始高质量图片URL
function getOriginalImageUrl(imageElement) {
// 检查data-original属性(常见于懒加载)
const dataOriginal = imageElement.getAttribute('data-original');
if (dataOriginal) return dataOriginal;
// 检查srcset中的高质量版本
const srcset = imageElement.getAttribute('srcset');
if (srcset) {
const sources = srcset.split(',').map(src => src.trim());
const largestSource = sources.reduce((largest, current) => {
const currentSize = parseInt(current.split(' ')[1]) || 0;
const largestSize = parseInt(largest.split(' ')[1]) || 0;
return currentSize > largestSize ? current : largest;
});
return largestSource.split(' ')[0];
}
// 默认返回当前src
return imageElement.src;
}
// 高质量图片下载
function downloadHighQualityImage(url, filename) {
fetch(url)
.then(response => response.blob())
.then(blob => {
const blobUrl = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = blobUrl;
link.download = filename || 'image';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(blobUrl);
})
.catch(error => {
console.error('下载失败:', error);
// 降级方案:直接下载当前图片
const fallbackLink = document.createElement('a');
fallbackLink.href = url;
fallbackLink.download = filename || 'image';
document.body.appendChild(fallbackLink);
fallbackLink.click();
document.body.removeChild(fallbackLink);
});
}
响应式工具栏配置
根据不同设备屏幕尺寸动态显示下载按钮:
const responsiveToolbar = {
// 基础按钮始终显示
zoomIn: true,
zoomOut: true,
// 下载按钮响应式配置
download: {
show: window.innerWidth > 768 ? 1 : 0, // 大屏显示,小屏隐藏
click: downloadHandler
},
// 其他功能按钮
print: {
show: window.innerWidth > 992 ? 1 : 0, // 超大屏才显示打印按钮
click: printHandler
}
};
// 窗口大小变化时更新工具栏
window.addEventListener('resize', () => {
viewer.update({
toolbar: responsiveToolbar
});
});
自定义操作按钮的最佳实践
- 一致性设计:自定义按钮的样式应该与默认按钮保持一致
- 无障碍访问:为按钮添加适当的ARIA标签和键盘支持
- 错误处理:实现完善的错误处理和降级方案
- 性能考虑:大量图片下载时考虑使用Web Worker
- 用户体验:提供下载进度反馈和成功提示
// 完整的下载功能实现示例
function createDownloadButton(viewerInstance) {
return {
show: true,
size: 'medium',
click: function() {
try {
const image = viewerInstance.image;
if (!image || !image.src) {
throw new Error('没有可下载的图片');
}
showDownloadProgress(); // 显示进度提示
const downloadUrl = image.src;
const fileName = image.alt || `image_${Date.now()}`;
// 使用fetch确保获取原始质量图片
fetch(downloadUrl)
.then(response => {
if (!response.ok) throw new Error('下载失败');
return response.blob();
})
.then(blob => {
const url = URL.createObjectURL(blob);
downloadFile(url, fileName);
URL.revokeObjectURL(url);
showDownloadSuccess(); // 显示成功提示
})
.catch(error => {
console.error('下载错误:', error);
// 降级到直接下载
downloadFile(downloadUrl, fileName);
});
} catch (error) {
console.error('下载处理错误:', error);
showDownloadError(error.message);
}
}
};
}
function downloadFile(url, filename) {
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
通过上述方法,我们可以为Viewer.js添加强大而灵活的下载功能,同时保持与原生工具栏的无缝集成和一致的用户体验。
CSS样式自定义与主题定制
Viewer.js提供了灵活的CSS样式系统,允许开发者完全自定义查看器的外观和主题。通过深入理解其CSS架构,您可以创建符合品牌风格的独特图片查看体验。
CSS类名结构与覆盖机制
Viewer.js采用BEM(Block Element Modifier)命名规范,所有CSS类名都以.viewer-前缀开头,确保良好的封装性和可扩展性。主要的结构类名包括:
| 类名 | 描述 | 用途 |
|---|---|---|
.viewer-container |
查看器主容器 | 控制整体布局和定位 |
.viewer-canvas |
图片画布区域 | 管理图片显示和缩放 |
.viewer-toolbar |
工具栏容器 | 工具栏样式控制 |
.viewer-navbar |
导航栏 | 缩略图导航样式 |
.viewer-footer |
底部信息栏 | 标题和状态信息显示 |
/* 自定义主题示例:深色模式 */
.viewer-container {
background-color: #1a1a1a;
}
.viewer-toolbar > ul > li {
background-color: rgba(255, 255, 255, 0.1);
border
Kimi-K2.5Kimi K2.5 是一款开源的原生多模态智能体模型,它在 Kimi-K2-Base 的基础上,通过对约 15 万亿混合视觉和文本 tokens 进行持续预训练构建而成。该模型将视觉与语言理解、高级智能体能力、即时模式与思考模式,以及对话式与智能体范式无缝融合。Python00- QQwen3-Coder-Next2026年2月4日,正式发布的Qwen3-Coder-Next,一款专为编码智能体和本地开发场景设计的开源语言模型。Python00
xw-cli实现国产算力大模型零门槛部署,一键跑通 Qwen、GLM-4.7、Minimax-2.1、DeepSeek-OCR 等模型Go06
PaddleOCR-VL-1.5PaddleOCR-VL-1.5 是 PaddleOCR-VL 的新一代进阶模型,在 OmniDocBench v1.5 上实现了 94.5% 的全新 state-of-the-art 准确率。 为了严格评估模型在真实物理畸变下的鲁棒性——包括扫描伪影、倾斜、扭曲、屏幕拍摄和光照变化——我们提出了 Real5-OmniDocBench 基准测试集。实验结果表明,该增强模型在新构建的基准测试集上达到了 SOTA 性能。此外,我们通过整合印章识别和文本检测识别(text spotting)任务扩展了模型的能力,同时保持 0.9B 的超紧凑 VLM 规模,具备高效率特性。Python00
KuiklyUI基于KMP技术的高性能、全平台开发框架,具备统一代码库、极致易用性和动态灵活性。 Provide a high-performance, full-platform development framework with unified codebase, ultimate ease of use, and dynamic flexibility. 注意:本仓库为Github仓库镜像,PR或Issue请移步至Github发起,感谢支持!Kotlin08
VLOOKVLOOK™ 是优雅好用的 Typora/Markdown 主题包和增强插件。 VLOOK™ is an elegant and practical THEME PACKAGE × ENHANCEMENT PLUGIN for Typora/Markdown.Less00