// ==UserScript== // @name 图片下载 | 页面所有图片打包下载 | 单张下载 | 图片预览放大,旋转,信息展示 | 简单有效,想要哪张点哪张 // @namespace http://tampermonkey.net/ // @description 简单纯洁的网页图片下载工具,侵入性小不影响原网页显示,可集中展示页面所有图片,可点击预览放大,可旋转,可查看图片信息(尺寸,格式,图片大小) | (Ctrl+鼠标右键)下载单个图片 // @description:zh-CN 一个帮你快速捕获网页图片并打包下载、也可单张下载的小工具🔧 // @author // @version v4.0.0 // @license GPLv3 // @icon https://s21.ax1x.com/2024/05/14/pkmNM0s.png // @require https://code.jquery.com/jquery-3.6.0.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.6.0/jszip.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.6/viewer.min.js // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_download // @grant GM_registerMenuCommand // @match *://*/* // @downloadURL none // ==/UserScript== // 待做 // --1.检查版本更新(提示) // --2.下载进度条 // --3.刷新获取图片 // 4.页面svg标签转图片 // 5.用户自定义配置(状态) var currentVersion = 'v4.0.0'; var isPackLoad = false // 多图片打包下载 const downloadPackZipImgs = (all_imgs = []) => { if (!all_imgs.length || isPackLoad) return; isPackLoad = true isTopLoading(true, all_imgs.length) const zip = new JSZip(); var currNum = 0; let total = all_imgs.length Promise.all( all_imgs.map((item, index) => { if (item.blob) { zip.file(item.imgName, item.blob, { binary: true }); realTimeSchedule(++currNum, total) return Promise.resolve() } return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: item.src, responseType: "blob", onload: function (response) { if (response.status === 200) { let blob = response.response; item.blob = blob if (blob.size > (1024 * 1024)) { item.size = (blob.size / (1024 * 1024)).toFixed(1) + 'MB' } else if (blob.size < (1024 * 1024) && blob.size > 1024) { item.size = (blob.size / 1024).toFixed(1) + 'KB' } else { item.size = blob.size + '字节' } setItemImgsName(item) updateNodeItem(item) const filename = item.imgName; zip.file(filename, blob, { binary: true }); } else { console.error("请求报错,状态码: " + response.status); } realTimeSchedule(++currNum, total) resolve(); }, onerror: function (e) { console.error("请求失败: " + e.message); realTimeSchedule(++currNum, total) resolve(); }, }); }); }) ) .then(() => { let domain = window.location.href.replace(/^https?:\/\//i, ""); zip.generateAsync({ type: "blob" }).then((blob) => { saveAs(blob, `【${document.title}】【${domain}】.zip`); }); }).finally(() => { isPackLoad = false isTopLoading(false) }) } // 指定数组元素对象属性去重、去除宽高小于1的 function removeDuplicatesByProperty(arr = [], property) { const seenIds = new Set(); return arr.filter(item => { const isUnique = !seenIds.has(item[property]); if (isUnique) { seenIds.add(item[property]); } return isUnique; }); } // 根据blob设置图片后缀名 function setItemImgsName(item) { let { src = "", blob = {} } = item let name = src.match(/\/([^\/?#]+)(?:[?#]|$)/)[1].split('.')[0] if (blob?.type && blob?.type.includes('image')) { item.lastName = blob.type.match(/^image\/([a-zA-Z0-9]+)/)[1] item.isImg = true } else { item.isImg = false } item.imgName = name + '.' + item.lastName } // 更新节点显示信息 function updateNodeItem(item) { $('.ccc_image_item').each(function () { if ($(this).attr('data-imgsrc') == item.src) { let info = '' let imgDom = $(this).children('img')[0] if (imgDom.naturalWidth || imgDom.naturalHeight) { info = imgDom.naturalWidth + ' x ' + imgDom.naturalHeight item.width = imgDom.naturalWidth item.height = imgDom.naturalHeight } if (item.lastName) { info += (' | ' + item.lastName.toUpperCase()) } if (item.size) { info += (' | ' + item.size) } $(this).find('.ccc_imgItem_info').text(info) item.isFullInfo = true } }) } // 获取单张图片blob const getSingleBlob = (item) => { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: item.src, responseType: "blob", onload: function (response) { if (response.status === 200) { let blob = response.response; item.blob = blob if (blob.size > (1024 * 1024)) { item.size = (blob.size / (1024 * 1024)).toFixed(1) + 'MB' } else if (blob.size < (1024 * 1024) && blob.size > 1024) { item.size = (blob.size / 1024).toFixed(1) + 'KB' } else { item.size = blob.size + '字节' } setItemImgsName(item) updateNodeItem(item) resolve(item); } else { console.error("请求报错,状态码: " + response.status); } }, onerror: function (e) { console.error("请求失败: " + e.message); reject(); }, }); }) } // 根据svg元素返回{src,blob} const getSvgAsFile = (svgElement) => { // 将 SVG 元素序列化为字符串 const svgString = new XMLSerializer().serializeToString(svgElement); // 创建一个包含 SVG 数据的 Blob 对象 const blob = new Blob([svgString], { type: 'image/svg+xml;charset=utf-8' }); // 创建一个 URL 对象 const src = URL.createObjectURL(blob); return { src, blob, } } // 获取页面所有图片 const loadAllImgUrls = async () => { all_imgs = [] document.querySelectorAll("img").forEach((item) => { let src = item?.src || item.getAttribute("srcset"); if (!src) return; if (origin_all_imageUrls.some(n => { if (n.src === src) { all_imgs.push(n) return true } else { false } })) return; let imgName = getImageFileNameFromUrl(src) let lastName = '' if (imgName.includes('.')) { let last = imgName.split('.').pop() if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg', 'tiff', 'tif', 'avif'].includes(last)) { lastName = last } } all_imgs.push({ src, imgName, lastName, width: item.naturalWidth, height: item.naturalHeight, }); }); // 获取SVG标签图片 // document.querySelectorAll("svg").forEach((svgDom, index) => { // let {src, blob} = getSvgAsFile(svgDom) // const { width, height } = svgDom.getBoundingClientRect(); // all_imgs.push({ // src, // blob, // imgName: `svg_${index}.svg`, // lastName: 'svg', // width, // height // }); // }) resetImgsObj(all_imgs) } const reFetchImgs = () => { loadAllImgUrls() let w_min = parseInt($('#ccc_w_min').val()) || 0 let w_max = parseInt($('#ccc_w_max').val()) || 99999 let h_min = parseInt($('#ccc_h_min').val()) || 0 let h_max = parseInt($('#ccc_h_max').val()) || 99999 all_imageUrls = valid_all_imageUrls.filter(item => { if (item.width < w_min || item.width > w_max) return false if (item.height < h_min || item.height > h_max) return false return true }) reRender() showNotify('已刷新') } // 显示通知 var notifyTimer = null; function showNotify(msg) { if (notifyTimer) { clearTimeout(notifyTimer) $('#ccc_notify').remove() } $('#ccc_popUps_container').append(`
${msg}
`) setTimeout(() => { $('#ccc_notify').addClass('active') }, 16); notifyTimer = setTimeout(() => { $('#ccc_notify').remove() }, 1000); } // 获取图片名称 function getImageFileNameFromUrl(url) { // 正则表达式匹配最后一个'/'和第一个'?'之间的内容(如果存在) // 或者最后一个'/'和字符串结尾之间的内容(如果不存在查询参数) const regex = /\/([^?\/]+?)(?:\?|$|@)/; const match = url.match(regex); if (match && match[1]) { // match[1] 是文件名(不包括查询参数及其后面的部分) return match[1]; } return "default.jpg"; } // 获取图片扩展名 function getImageExtension(url) { var extension = url.match(/\.(jpg|jpeg|png|gif|bmp|webp|svg|tiff|tif|avif)$/i); if (extension) { return ''; } if (url.includes("data:image/png")) { return '.png' } if (url.includes("data:image/gif")) { return '.gif' } return '.jpg' } function deepClone(source) { if (!source && typeof source !== 'object') { throw new Error('error arguments', 'deepClone') } const targetObj = source.constructor === Array ? [] : {} Object.keys(source).forEach(keys => { if (source[keys] && typeof source[keys] === 'object') { targetObj[keys] = deepClone(source[keys]) } else { targetObj[keys] = source[keys] } }) return targetObj } var origin_all_imageUrls = []; // 所有图片 var valid_all_imageUrls = []; // 有效图片 = 所有图片 - 移除图片 var all_imageUrls = []; // 筛选后的图片 // 初始化加载图片数据 const resetImgsObj = (imgsObj = []) => { imgsObj = removeDuplicatesByProperty(imgsObj, 'src') if (imgsObj.length) { origin_all_imageUrls = deepClone(imgsObj) valid_all_imageUrls = deepClone(imgsObj) all_imageUrls = deepClone(imgsObj) $('.pop_title_num').text(all_imageUrls.length) $('#load_mask').css('display', 'none') $('#open_popUps_icon>.pop_title_num').css('display', 'block') reRender() } else { } } // blob图片下载 const blobDownload = (item = {}) => { let { blob, imgName } = item // 创建一个Blob UFRL const url = window.URL.createObjectURL(blob); // 创建一个标签用于下载 const a = document.createElement("a"); a.href = url; a.download = imgName; // 设置下载的文件名 a.style.display = "none"; // 触发点击事件 document.body.appendChild(a); a.click(); // 释放URL对象 window.URL.revokeObjectURL(url); // 清理标签 document.body.removeChild(a); } // 渲染图片列表 var viewer = null; const reRender = () => { // // 去除宽高小于1 // all_imageUrls = all_imageUrls.filter(item => { // return item.width > 1 && item.height > 1 // }) $('.pop_title_num').text(all_imageUrls.length) var $newElements = $(); all_imageUrls.forEach(item => { let addCss = item.isFullInfo === true ? 'hide_more' : '' var $el = $('
', { class: 'ccc_image_item ' + addCss, "data-imgsrc": item.src }); var $img = $('', { src: item.src, alt: item.imgName, title: '预览' }); let info = ''; if (item.width || item.height) { info = item.width + ' x ' + item.height } if (item.lastName) { let s = (item.width || item.height) ? ' | ' : '' info += (s + item.lastName.toUpperCase()) } if (item.size) { info += (' | ' + item.size) } var $infoBox = $('
', { text: info, class: 'ccc_imgItem_info' }); $img.appendTo($el); $infoBox.appendTo($el); $newElements = $.merge($newElements, $el); }); $('#ccc_image_container').empty().append($newElements); $('.ccc_image_item').each(function () { $(this).append(`
`) $(this).find('.ccc_imgItem_info').append(` ··· `) }) viewer && viewer.destroy(); viewer = new Viewer(document.getElementById('ccc_image_container')); } const setLoading = (target, isLoading = true) => { if (isLoading) { $(target).append( `
` ) } else { $(target).find('#ccc_itemImgLoading').remove(); } } var hasUpdate = false; var onlineVersion = null; // 线上版本号 var online_homeUrl = 'https://greasyfork.org/zh-CN/scripts/492706-%E5%9B%BE%E7%89%87%E4%B8%8B%E8%BD%BD-%E9%A1%B5%E9%9D%A2%E6%89%80%E6%9C%89%E5%9B%BE%E7%89%87%E6%89%93%E5%8C%85%E4%B8%8B%E8%BD%BD-%E5%8D%95%E4%B8%AA%E5%9B%BE%E7%89%87%E4%B8%8B%E8%BD%BD-%E6%83%B3%E8%A6%81%E5%93%AA%E5%BC%A0%E7%82%B9%E5%93%AA%E5%BC%A0-%E7%AE%80%E5%8D%95%E6%9C%89%E6%95%88'; // 脚本首页地址 const loadUpdateTamp = () => { const extractVersion = (htmlString) => { // 使用正则表达式匹配 data-script-version 属性的值 const versionMatch = htmlString.match(/data-script-version="([^"]+)"/); // 如果匹配成功,返回版本号;否则返回 null return versionMatch ? versionMatch[1] : null; } const isUpdateAvailable = (currentVersion, onlineVersion) => { const current = currentVersion.replace('v', '').split('.').map(Number); const online = onlineVersion.replace('v', '').split('.').map(Number); for (let i = 0; i < Math.max(current.length, online.length); i++) { const currentPart = current[i] || 0; // 如果当前版本号部分不存在,则默认为 0 const onlinePart = online[i] || 0; // 如果线上版本号部分不存在,则默认为 0 if (onlinePart > currentPart) { return true; // 如果线上版本号更高,则需要更新 } else if (onlinePart < currentPart) { return false; // 如果线上版本号更低,则不需要更新 } // 如果当前部分的版本号相等,继续比较下一部分 } // 如果所有部分的版本号都相等,则不需要更新 return false; } GM_xmlhttpRequest({ method: "GET", url: online_homeUrl, onload: function (res) { if (res.status === 200) { onlineVersion = extractVersion(res.response) hasUpdate = isUpdateAvailable(currentVersion, onlineVersion) console.log('线上版本号 = ', onlineVersion) console.log('当前版本号 = ', currentVersion) console.log('是否有更新 = ', hasUpdate) if (hasUpdate) { GM_registerMenuCommand("有新版本啦~(♥ω", function () { window.open(online_homeUrl, '_blank'); }); $('#ccc_gotoUpdate').append(`
有新版本啦,快去体验下吧~(♥ω `) } } }, onerror: function (e) { console.error(e); }, }); } // 渲染展示筛选条件 function renderViewFilter() { let w_min = $('#ccc_w_min').val() let w_max = $('#ccc_w_max').val() || '∞' let h_min = $('#ccc_h_min').val() let h_max = $('#ccc_h_max').val() || '∞' let isView = false $('#ccc_view_filter_itembox').empty(); if (w_min || $('#ccc_w_max').val()) { $('#ccc_view_filter_itembox').append(` 宽 ${w_min || 0} - ${w_max} `) isView = true } if (h_min || $('#ccc_h_max').val()) { $('#ccc_view_filter_itembox').append(` 高 ${h_min || 0} - ${h_max} `) isView = true } if (isView) { $('.ccc_view_filter').css({ display: 'flex' }) } else { $('.ccc_view_filter').css({ display: 'none' }) } } // 主要交互操作逻辑 const loadMainOperations = () => { GM_registerMenuCommand("打开图片列表(ALT + Q)", function () { handleOpenPopPus() }); // GM_registerMenuCommand("检查更新",function(){ // window.open('https://greasyfork.org/zh-CN/scripts/492706-%E5%9B%BE%E7%89%87%E4%B8%8B%E8%BD%BD-%E9%A1%B5%E9%9D%A2%E6%89%80%E6%9C%89%E5%9B%BE%E7%89%87%E6%89%93%E5%8C%85%E4%B8%8B%E8%BD%BD-%E5%8D%95%E4%B8%AA%E5%9B%BE%E7%89%87%E4%B8%8B%E8%BD%BD-%E6%83%B3%E8%A6%81%E5%93%AA%E5%BC%A0%E7%82%B9%E5%93%AA%E5%BC%A0-%E7%AE%80%E5%8D%95%E6%9C%89%E6%95%88', '_blank'); // }); var isOpenPop = false; // 处理打开弹窗 const handleOpenPopPus = () => { isOpenPop = true; document.querySelector('#ccc_popUps_out').style.display = 'block'; setLayout(); } // 处理关闭弹窗 const handleClosePop = () => { isOpenPop = false document.querySelector('#ccc_popUps_out').style.display = 'none'; } // 关闭弹窗 document.querySelector('#ccc_close_popUps').onclick = function () { handleClosePop() } // 快捷键事件 document.addEventListener('keydown', function (event) { // 按alt + ` 显隐弹窗 if (event.altKey && (event.key === 'Q' || event.key === 'q')) { isOpenPop ? handleClosePop() : handleOpenPopPus() } // Esc键-关闭弹窗 if (event.key === 'Escape' || event.key === 'Esc') { handleClosePop() } }); const setLayout = () => { reRender() //渲染图片 let container_h = ccc_popUps_container.offsetHeight - 30; ccc_image_container.style.height = (container_h - ccc_popUps_top.offsetHeight - 30) + 'px'; } var isShowFilter = false; // 显示筛选 const showHideFilter = (is, key) => { isShowFilter = is let speed = 300 key === 'leave' && (speed = 500) if (key === 'enter') { $('#ccc_filter_container').stop(); $('#ccc_filter_container').css('opacity', 1) return; } if (isShowFilter) { $('#ccc_filter_container').fadeIn(speed); } else { $('#ccc_filter_container').fadeOut(speed); } } $('#ccc_filter_btn').click(function (e) { e.stopPropagation(); // 阻止事件冒泡 isShowFilter = !isShowFilter showHideFilter(isShowFilter) }) $('#ccc_filter_container').click(function (e) { e.stopPropagation(); // 阻止事件冒泡 }) $(document).click(function (e) { showHideFilter(false) }) $('#ccc_filter_container').mouseleave(function () { showHideFilter(false, 'leave') }); $('#ccc_filter_container').mouseenter(function () { showHideFilter(true, 'enter') }); // 筛选input触发 $('.ccc_filter_input').on('input', function () { let w_min = parseInt($('#ccc_w_min').val()) || 0 let w_max = parseInt($('#ccc_w_max').val()) || 99999 let h_min = parseInt($('#ccc_h_min').val()) || 0 let h_max = parseInt($('#ccc_h_max').val()) || 99999 all_imageUrls = valid_all_imageUrls.filter(item => { if (item.width < w_min || item.width > w_max) return false if (item.height < h_min || item.height > h_max) return false return true }) reRender() renderViewFilter() }); // 重置筛选触发 $("#refilter_btn").click(function () { $('#ccc_w_min').val('') $('#ccc_w_max').val('') $('#ccc_h_min').val('') $('#ccc_h_max').val('') all_imageUrls = valid_all_imageUrls reRender() renderViewFilter() }) // 点击按钮下载单张图片 $('#ccc_image_container').on('click', '.ccc_imgItem_ctrl svg', function () { let url = $(this).closest('.ccc_image_item').attr('data-imgsrc') let item = all_imageUrls.filter(item => item.src === url)[0] if (item.lock) return; item.lock = true let target = $(this).closest('.ccc_image_item') setLoading(target, true) if (item.lastName && item.blob) { blobDownload(item) item.lock = false setLoading(target, false) } else { getSingleBlob(item).then(res => { blobDownload(res) item.lock = false setLoading(target, false) }) } }) // 移除图片 $('#ccc_image_container').on('click', '.ccc_imgItem_delete', function () { let url = $(this).closest('.ccc_image_item').attr('data-imgsrc') valid_all_imageUrls = valid_all_imageUrls.filter(item => item.src !== url) all_imageUrls = all_imageUrls.filter(item => item.src !== url) reRender() }) // 显示更多 $('#ccc_image_container').on('click', '.ccc_imgItem_info', function () { let url = $(this).closest('.ccc_image_item').attr('data-imgsrc') let item = all_imageUrls.filter(item => item.src === url)[0] if (item.lock) return; item.lock = true $(this).find('.ccc_more').empty().append(`
`); $(this).closest('.ccc_image_item').find('.ccc_imgItem_ctrl>div').css('cursor', 'no-drop').removeClass('click_style') getSingleBlob(item).then(res => { }).finally(() => { $(this).find('.ccc_more').remove(); $(this).css('cursor', 'initial') $(this).closest('.ccc_image_item').find('.ccc_imgItem_ctrl>div').css('cursor', 'pointer').addClass('click_style') item.lock = false }) }) // 显隐主体icon var isShowMainIcon = true $(document).on('click', '#showhide_main_btn', function () { isShowMainIcon = !isShowMainIcon let speed = 600 $('#ccc_main_icon_container').css({ transition: `all ${speed}ms` }) if (isShowMainIcon) { $('#ccc_main_icon_container').css({ 'right': '20px', }) $('#showhide_main_btn').css({ left: 'auto', right: '0', opacity: '0', }).text('»') } else { $('#ccc_main_icon_container').css({ 'right': '-30px', }) $('#showhide_main_btn').css({ right: 'auto', left: '-40px', opacity: '1', }).text('«') } setTimeout(() => { $('#ccc_main_icon_container').css({ transition: 'none' }) }, speed); }) $('#ccc_popUps_container').click(function (e) { e.stopPropagation() }) $('#ccc_popUps_out').click(function (e) { handleClosePop() }) // 声明拖动事件 function bindHandleDrag() { let isMove = false let mouseToEleY; let mainContainerDom = document.querySelector('#ccc_main_icon_container') let iconDom = document.querySelector('#open_popUps_icon') let isOpen = true; // 拖动处理 mainContainerDom.addEventListener("mousedown", function (e) { isMove = true // 获取鼠标相对于元素的位置 mouseToEleY = e.clientY - mainContainerDom.getBoundingClientRect().top; }); // 当鼠标移动时 window.addEventListener('mousemove', (e) => { if (!isMove) return document.body.style.userSelect = 'none'; iconDom.style.cursor = 'grabbing' // 防止默认的拖动选择文本行为 e.preventDefault(); let newTop = e.clientY - mouseToEleY; // 防止元素超出视口下方 let maxTop = window.innerHeight - mainContainerDom.offsetHeight; if (newTop < 0) { newTop = 0; } else if (newTop > maxTop) { newTop = maxTop; } mainContainerDom.style.top = `${newTop}px`; mainContainerDom.style.bottom = 'auto'; isOpen = false; }) // 当鼠标松开时 document.querySelector('#open_popUps_icon').addEventListener('mouseup', () => { isOpen && handleOpenPopPus() // 打开弹窗 }); window.addEventListener('mouseup', () => { isMove = false; iconDom.style.cursor = 'pointer' isOpen = true document.body.style.userSelect = 'auto'; }); } bindHandleDrag(); // 刷新抓取 document.querySelector('#ccc_fetch_btn').onclick = () => { reFetchImgs() } } // 初始声明事件 const initEvents = () => { // ctrl+右键 下载图片 document.addEventListener("mousedown", function (event) { if (event.ctrlKey && event.button === 2) { event.preventDefault(); var targetElement = event.target; const getUrl = (dom) => { return dom.getAttribute("src") || dom.getAttribute("srcset") || ""; }; if (targetElement) { let url = getUrl(targetElement); let srcArr = []; if (url) { srcArr = [url]; } else { let arrDom = targetElement.querySelectorAll("img"); arrDom.forEach((item) => { srcArr.push(getUrl(item)); }); } srcArr.forEach((url) => { let item = { src: url } getSingleBlob(item).then(res => { blobDownload(res) }) }); } } }); document.querySelector('#ccc_all_pack_down_btn').onclick = function () { downloadPackZipImgs(all_imageUrls) } } // 打包下载loading function isTopLoading(flag, total) { if (flag) { if ($('#ccc_load_tip_style').length) { $('#ccc_load_tip_style').remove(); } $('body').append(`
稍等片刻,正在打包下载...
0/${total}
`) $('#ccc_all_pack_down_btn').css('cursor', 'no-drop').removeClass('click_style') } else { $('#ccc_load_tip_style').length && $('#ccc_load_tip_style').css('right', '-280px') $('#ccc_all_pack_down_btn').css('cursor', 'pointer').addClass('click_style') setTimeout(() => { $('#ccc_load_tip_style').remove(); }, 800); } } // 实时计算进度条 const realTimeSchedule = (curr, total) => { if ($('#curr_ing').length) { $('#curr_ing').text(curr) let w = ((curr / total) * 100).toFixed(1) + '%' $('.ccc_schedule_curr').css('width', w) } } // 初始化加载页面 const init = () => { window.addEventListener("load", function () { if (window.self !== window.top) return; setTimeout(() => { loadCss() loadElementDOM() loadAllImgUrls(); loadMainOperations(); initEvents(); loadUpdateTamp() }, 500); }); }; (function () { init(); })(); const loadElementDOM = () => { $("body").append(`
»
0
网页图片列表 (共 0 张)
宽:-
高:-
重置
筛选条件:
刷新抓取
(非首屏载入网页的图片,需刷新抓取)
打包下载0
图片加载中...
`) } const loadCss = () => { GM.addStyle( ` /*! * Viewer.js v1.10.5 * https://fengyuanchen.github.io/viewerjs * * Copyright 2015-present Chen Fengyuan * Released under the MIT license * * Date: 2022-04-05T08:21:00.150Z */ .viewer-zoom-in::before, .viewer-zoom-out::before, .viewer-one-to-one::before, .viewer-reset::before, .viewer-prev::before, .viewer-play::before, .viewer-next::before, .viewer-rotate-left::before, .viewer-rotate-right::before, .viewer-flip-horizontal::before, .viewer-flip-vertical::before, .viewer-fullscreen::before, .viewer-fullscreen-exit::before, .viewer-close::before { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARgAAAAUCAYAAABWOyJDAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAQPSURBVHic7Zs/iFxVFMa/0U2UaJGksUgnIVhYxVhpjDbZCBmLdAYECxsRFBTUamcXUiSNncgKQbSxsxH8gzAP3FU2jY0kKKJNiiiIghFlccnP4p3nPCdv3p9778vsLOcHB2bfveeb7955c3jvvNkBIMdxnD64a94GHMfZu3iBcRynN7zAOI7TG15gHCeeNUkr8zaxG2lbYDYsdgMbktBsP03jdQwljSXdtBhLOmtjowC9Mg9L+knSlcD8TNKpSA9lBpK2JF2VdDSR5n5J64m0qli399hNFMUlpshQii5jbXTbHGviB0nLNeNDSd9VO4A2UdB2fp+x0eCnaXxWXGA2X0au/3HgN9P4LFCjIANOJdrLr0zzZ+BEpNYDwKbpnQMeAw4m8HjQtM6Z9qa917zPQwFr3M5KgA6J5rTJCdFZJj9/lyvGhsDvwFNVuV2MhhjrK6b9bFiE+j1r87eBl4HDwCF7/U/k+ofAX5b/EXBv5JoLMuILzf3Ap6Z3EzgdqHMCuF7hcQf4HDgeoHnccncqdK/TvSDWffFXI/exICY/xZyqc6XLWF1UFZna4gJ7q8BsRvgd2/xXpo6P+D9dfT7PpECtA3cnWPM0GXGFZh/wgWltA+cDNC7X+AP4GzjZQe+k5dRxuYPeiuXU7e1qwLpDz7dFjXKRaSwuMLvAlG8zZlG+YmiK1HoFqT7wP2z+4Q45TfEGcMt01xLoNZEBTwRqD4BLpnMLeC1A41UmVxsXgXeBayV/Wx20rpTyrpnWRft7p6O/FdqzGrDukPNtkaMoMo3FBdBSQMOnYBCReyf05s126fU9ytfX98+mY54Kxnp7S9K3kj6U9KYdG0h6UdLbkh7poFXMfUnSOyVvL0h6VtIXHbS6nOP+s/Zm9mvyXW1uuC9ohZ72E9uDmXWLJOB1GxsH+DxPftsB8B6wlGDN02TAkxG6+4D3TWsbeC5CS8CDFce+AW500LhhOW2020TRjK3b21HEmgti9m0RonxbdMZeVzV+/4tF3cBpP7E9mKHNL5q8h5g0eYsCMQz0epq8gQrwMXAgcs0FGXGFRcB9wCemF9PkbYqM/Bas7fxLwNeJPdTdpo4itQti8lPMqTpXuozVRVXPpbHI3KkNTB1NfkL81j2mvhDp91HgV9MKuRIqrykj3WPq4rHyL+axj8/qGPmTqi6F9YDlHOvJU6oYcTsh/TYSzWmTE6JT19CtLTJt32D6CmHe0eQn1O8z5AXgT4sx4Vcu0/EQecMydB8z0hUWkTd2t4CrwNEePqMBcAR4mrBbwyXLPWJa8zrXmmLEhNBmfpkuY2102xxrih+pb+ieAb6vGhuA97UcJ5KR8gZ77K+99xxeYBzH6Q3/Z0fHcXrDC4zjOL3hBcZxnN74F+zlvXFWXF9PAAAAAElFTkSuQmCC"); background-repeat: no-repeat; background-size: 280px; color: transparent; display: block; font-size: 0; height: 20px; line-height: 0; width: 20px; } .viewer-zoom-in::before { background-position: 0 0; content: "Zoom In"; } .viewer-zoom-out::before { background-position: -20px 0; content: "Zoom Out"; } .viewer-one-to-one::before { background-position: -40px 0; content: "One to One"; } .viewer-reset::before { background-position: -60px 0; content: "Reset"; } .viewer-prev::before { background-position: -80px 0; content: "Previous"; } .viewer-play::before { background-position: -100px 0; content: "Play"; } .viewer-next::before { background-position: -120px 0; content: "Next"; } .viewer-rotate-left::before { background-position: -140px 0; content: "Rotate Left"; } .viewer-rotate-right::before { background-position: -160px 0; content: "Rotate Right"; } .viewer-flip-horizontal::before { background-position: -180px 0; content: "Flip Horizontal"; } .viewer-flip-vertical::before { background-position: -200px 0; content: "Flip Vertical"; } .viewer-fullscreen::before { background-position: -220px 0; content: "Enter Full Screen"; } .viewer-fullscreen-exit::before { background-position: -240px 0; content: "Exit Full Screen"; } .viewer-close::before { background-position: -260px 0; content: "Close"; } .viewer-container { bottom: 0; direction: ltr; font-size: 0; left: 0; line-height: 0; overflow: hidden; position: absolute; right: 0; -webkit-tap-highlight-color: transparent; top: 0; -ms-touch-action: none; touch-action: none; -webkit-touch-callout: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none } .viewer-container::-moz-selection, .viewer-container *::-moz-selection { background-color: transparent; } .viewer-container::selection, .viewer-container *::selection { background-color: transparent; } .viewer-container:focus { outline: 0; } .viewer-container img { display: block; height: auto; max-height: none !important; max-width: none !important; min-height: 0 !important; min-width: 0 !important; width: 100%; } .viewer-canvas { bottom: 0; left: 0; overflow: hidden; position: absolute; right: 0; top: 0 } .viewer-canvas > img { height: auto; margin: 15px auto; max-width: 90% !important; width: auto; } .viewer-footer { bottom: 0; left: 0; overflow: hidden; position: absolute; right: 0; text-align: center; } .viewer-navbar { background-color: rgba(0, 0, 0, 50%); overflow: hidden; } .viewer-list { box-sizing: content-box; height: 50px; margin: 0; overflow: hidden; padding: 1px 0 } .viewer-list > li { color: transparent; cursor: pointer; float: left; font-size: 0; height: 50px; line-height: 0; opacity: 0.5; overflow: hidden; transition: opacity 0.15s; width: 30px } .viewer-list > li:focus, .viewer-list > li:hover { opacity: 0.75; } .viewer-list > li:focus { outline: 0; } .viewer-list > li + li { margin-left: 1px; } .viewer-list > .viewer-loading { position: relative } .viewer-list > .viewer-loading::after { border-width: 2px; height: 20px; margin-left: -10px; margin-top: -10px; width: 20px; } .viewer-list > .viewer-active, .viewer-list > .viewer-active:focus, .viewer-list > .viewer-active:hover { opacity: 1; } .viewer-player { background-color: #000; bottom: 0; cursor: none; display: none; left: 0; position: absolute; right: 0; top: 0; z-index: 1 } .viewer-player > img { left: 0; position: absolute; top: 0; } .viewer-toolbar > ul { display: inline-block; margin: 0 auto 5px; overflow: hidden; padding: 6px 3px } .viewer-toolbar > ul > li { background-color: rgba(0, 0, 0, 50%); border-radius: 50%; cursor: pointer; float: left; height: 24px; overflow: hidden; transition: background-color 0.15s; width: 24px } .viewer-toolbar > ul > li:focus, .viewer-toolbar > ul > li:hover { background-color: rgba(0, 0, 0, 80%); } .viewer-toolbar > ul > li:focus { box-shadow: 0 0 3px #fff; outline: 0; position: relative; z-index: 1; } .viewer-toolbar > ul > li::before { margin: 2px; } .viewer-toolbar > ul > li + li { margin-left: 1px; } .viewer-toolbar > ul > .viewer-small { height: 18px; margin-bottom: 3px; margin-top: 3px; width: 18px } .viewer-toolbar > ul > .viewer-small::before { margin: -1px; } .viewer-toolbar > ul > .viewer-large { height: 30px; margin-bottom: -3px; margin-top: -3px; width: 30px } .viewer-toolbar > ul > .viewer-large::before { margin: 5px; } .viewer-tooltip { background-color: rgba(0, 0, 0, 80%); border-radius: 10px; color: #fff; display: none; font-size: 12px; height: 20px; left: 50%; line-height: 20px; margin-left: -25px; margin-top: -10px; position: absolute; text-align: center; top: 50%; width: 50px; } .viewer-title { color: #ccc; display: inline-block; font-size: 12px; line-height: 1.2; margin: 0 5% 5px; max-width: 90%; opacity: 0.8; overflow: hidden; text-overflow: ellipsis; transition: opacity 0.15s; white-space: nowrap } .viewer-title:hover { opacity: 1; } .viewer-button { -webkit-app-region: no-drag; background-color: rgba(0, 0, 0, 50%); border-radius: 50%; cursor: pointer; height: 80px; overflow: hidden; position: absolute; right: -40px; top: -40px; transition: background-color 0.15s; width: 80px } .viewer-button:focus, .viewer-button:hover { background-color: rgba(0, 0, 0, 80%); } .viewer-button:focus { box-shadow: 0 0 3px #fff; outline: 0; } .viewer-button::before { bottom: 15px; left: 15px; position: absolute; } .viewer-fixed { position: fixed; } .viewer-open { overflow: hidden; } .viewer-show { display: block; } .viewer-hide { display: none; } .viewer-backdrop { background-color: rgba(0, 0, 0, 50%); } .viewer-invisible { visibility: hidden; } .viewer-move { cursor: move; cursor: -webkit-grab; cursor: grab; } .viewer-fade { opacity: 0; } .viewer-in { opacity: 1; } .viewer-transition { transition: all 0.3s; } @-webkit-keyframes viewer-spinner { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes viewer-spinner { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .viewer-loading::after { -webkit-animation: viewer-spinner 1s linear infinite; animation: viewer-spinner 1s linear infinite; border: 4px solid rgba(255, 255, 255, 10%); border-left-color: rgba(255, 255, 255, 50%); border-radius: 50%; content: ""; display: inline-block; height: 40px; left: 50%; margin-left: -20px; margin-top: -20px; position: absolute; top: 50%; width: 40px; z-index: 1; } @media (max-width: 767px) { .viewer-hide-xs-down { display: none; } } @media (max-width: 991px) { .viewer-hide-sm-down { display: none; } } @media (max-width: 1199px) { .viewer-hide-md-down { display: none; } } // -------------- my-style ------------ .viewer-backdrop{ background-color: rgba(0, 0, 0, 0.75) !important; } #ccc_main_icon_container { position: fixed; bottom: 50px; right: 20px; opacity: 0.3; z-index: 88888; } #open_popUps_icon { position: relative; width: 30px; height: 30px; cursor: pointer; } #open_popUps_icon>svg { width: 100%; height: 100%; box-shadow: 0 0 12px 2px rgba(255, 255, 255, 1); } #open_popUps_icon>.pop_title_num { position: absolute; top: 0; right: 0; transform: translate(50%, -50%); padding: 2px 4px; background-color: red; color: #ffffff; font-size: 8px; border-radius: 30px; display: none; } #showhide_main_btn { position: absolute; display: flex; align-items: center; justify-content: center; height: 30px; width: 20px; font-size: 26px; line-height: 30px; top: 0; right: 0; transform: translate(100%, 0%); cursor: pointer; transition: all 0.3s; font-weight: bold; background-image: linear-gradient(to right, #ffffff, #333333); -webkit-background-clip: text; color: transparent; opacity: 0; } #ccc_main_icon_container:hover { opacity: 1; } #ccc_main_icon_container:hover #showhide_main_btn { opacity: 1 !important; } #showhide_main_btn:hover { text-shadow: -0 -0 0 #333, 0 -0 0 #333, -0 0 0 #333, 0 0 0 #333; } /* 滚动条整体样式 */ #ccc_image_container::-webkit-scrollbar { width: 6px; /* 宽度 */ height: 6px; /* 高度(对于垂直滚动条) */ } /* 滚动条滑块 */ #ccc_image_container::-webkit-scrollbar-thumb { background: #aaa; border-radius: 6px; } /* 滚动条滑块:hover状态样式 */ #ccc_image_container::-webkit-scrollbar-thumb:hover { background: #888; } /* 滚动条轨道 */ #ccc_image_container::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 6px; } /* 滚动条轨道:hover状态样式 */ #ccc_image_container::-webkit-scrollbar-track:hover { background: #ddd; } /* 滚动条轨道:active状态样式 */ #ccc_image_container::-webkit-scrollbar-track-piece:active { background: #eee; } /* 滚动条:角落样式(即两个滚动条交汇处) */ #ccc_image_container::-webkit-scrollbar-corner { background: #535353; } .none_select { user-select: none; /* 禁止选中 */ -webkit-user-select: none; /* 对 Safari 和旧版 Chrome 的支持 */ -moz-user-select: none; /* 对 Firefox 的支持 */ -ms-user-select: none; /* 对 Internet Explorer 的支持 */ } #ccc_popUps_out { position: fixed; background-color: rgba(0, 0, 0, 0.6); width: 100vw; height: 100vh; top: 0; left: 0; z-index: 88888; display: none; } #ccc_popUps_container { position: absolute; width: 75vw; height: 75vh; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #ffffff; border-radius: 8px; box-shadow: 0px 1px 4px 0 rgba(0, 0, 0, 0.2); padding: 15px; } #ccc_popUps_top { display: flex; align-items: center; justify-content: space-between; padding-bottom: 10px; margin-bottom: 10px; } .pop_title_num { color: red; } .ccc_popUps_top_right { display: flex; align-items: center; justify-content: flex-end; } #ccc_all_pack_down_btn { position: relative; cursor: pointer; background-color: #666666; color: #fff; padding: 6px 10px; font-size: 12px; display: flex; align-items: center; justify-content: center; border-radius: 4px; margin-right: 30px; transition: all 0.3s; } #ccc_all_pack_down_btn:hover { background-color: #333333; box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.3); } #ccc_all_pack_down_btn>.pop_title_num { position: absolute; top: 0; right: 0; transform: translate(50%, -50%); padding: 2px 4px; background-color: red; color: #ffffff; font-size: 10px; border-radius: 30px; } #ccc_close_popUps { cursor: pointer; filter: grayscale(100%); font-size: 12px; } #ccc_close_popUps:hover { filter: grayscale(0%); } #ccc_image_container { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 10px; box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1); padding: 10px; overflow: auto; align-content: start; } .ccc_image_item { position: relative; height: 120px; background-color: #f5f5f5; display: flex; align-items: center; justify-content: center; border-radius: 3px; padding: 1px; box-sizing: border-box; box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.1); } .ccc_image_item:hover { box-shadow: 0 0 6px 1px rgba(0, 0, 0, 0.3); } .ccc_image_item img { max-width: 100%; max-height: 100%; object-fit: contain; cursor: zoom-in; } .ccc_imgItem_info, .ccc_imgItem_ctrl, .ccc_imgItem_delete { position: absolute; background-color: rgba(0, 0, 0, 0.6); color: #fff; box-sizing: border-box; font-size: 10px; display: flex; align-items: center; opacity: 0; transition: all 0.3s; } .ccc_imgItem_info { left: 0; top: 0; padding: 3px 5px; border-bottom-right-radius: 5px; flex-wrap: wrap; max-width: 80%; line-height: 14px; } .ccc_imgItem_ctrl { right: 0; bottom: 0; color: #fff; padding: 3px 6px; border-top-left-radius: 5px; } .ccc_imgItem_delete { right: 0; top: 0; padding: 8px; background-color: transparent; cursor: pointer; transition: all 0.3s; } .ccc_imgItem_delete>span { width: 14px; height: 3px; border-radius: 6px; background-color: rgba(255, 0, 0, 1); } .ccc_imgItem_ctrl>div { width: 17px; height: 17px; cursor: pointer; transition: all 0.3s; } .ccc_imgItem_ctrl svg { width: 100%; height: 100%; } .ccc_image_item:hover .ccc_imgItem_info, .ccc_image_item:hover .ccc_imgItem_ctrl, .ccc_image_item:hover .ccc_imgItem_delete { opacity: 1; } .viewer-container { z-index: 99999 !important; } #ccc_title_ctrl { display: flex; align-items: center; } #ccc_title_ctrl>.ccc_title_text{ font-size: 15px; } #ccc_filter_out { position: relative; top: 1px; display: flex; width: 18px; height: 18px; margin-left: 20px; } #ccc_filter_out svg { width: 100%; height: 100%; cursor: pointer; transition: all 0.3s; } .ccc_view_filter{ /* display: flex; */ align-items: center; font-size: 12px; /* background-color: #fafafa; */ /* padding: 10px 14px; */ border-radius: 4px; margin-left: 14px; display: none; } #ccc_view_filter_itembox{ display: flex; flex-wrap: wrap; align-items: center; max-width: 400px; } #ccc_view_filter_itembox>span{ display: inline-flex; align-items: center; justify-content: center; padding: 3px 8px; font-size: 11px; border-radius: 4px; box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.3); background-color: #f5f5f5; margin-left: 8px; } #ccc_view_filter_itembox>span:first-of-type{ margin-left: 0; } #ccc_filter_container { position: absolute; top: 50%; left: 40px; transform: translate(0, -50%); padding: 10px 15px; background: #fff; border: 1px solid #555; box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.6); border-radius: 6px; z-index: 9; display: none; width: 160px; font-size: 14px; /* opacity: 0; */ } #ccc_filter_container::before, #ccc_filter_container::after { position: absolute; content: ''; top: 50%; } #ccc_filter_container::before { left: -23px; margin-top: -13px; border: 13px solid transparent; border-right: 12px solid #fff; z-index: 2; } #ccc_filter_container::after { left: -26px; margin-top: -13px; border: 13px solid transparent; border-right: 13px solid #555; z-index: 1; } #ccc_filter_container>div { width: 100%; display: flex; align-items: center; margin: 6px auto; align-items: center; justify-content: center; } #ccc_filter_container>div>span { width: 10%; text-align: center; display: block; } #ccc_filter_container>div input { width: 35%; height: 18px; font-size: 13px; text-align: center; } #ccc_filter_container>div input::placeholder { text-align: center; line-height: 18px; } #refilter_btn { width: 40px; height: 20px; font-size: 10px; display: flex; align-items: center; justify-content: center; border-radius: 2px; box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.2); color: #ffffff; background-color: #666666; letter-spacing: 1px; cursor: pointer; transition: all 0.3s; } #refilter_btn:hover { background-color: #333333; box-shadow: 0 0 4px 1px rgba(0, 0, 0, 0.2); } #ccc_w_max::placeholder, #ccc_h_max::placeholder { position: relative; top: 5px; font-size: 26px; } #load_mask{ position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 18px; letter-spacing: 1px; padding: 10px 20px; border-radius: 4px; color: #fff; background-color: rgba(0, 0, 0, 0.6); z-index: 100; } #ccc_itemImgLoading{ position: absolute; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background-color: rgba(0, 0, 0, 0.5); z-index: 10; } .loader { width: 30px; height: 30px; border: 3px solid #f3f3f3; /* 边框的颜色 */ border-top: 3px solid #3498db; /* 上边框颜色,旋转时的主要颜色 */ border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .ccc_more{ cursor: pointer; display: inline-block; margin-left: 4px; } .ccc_more:hover{ color: rgb(24, 144, 255) } .ccc_more>.loader{ width: 10px; height: 10px; border: 2px solid #f3f3f3; border-top: 2px solid #3498db; } .ccc_imgItem_info:hover .ccc_more{ color: rgb(24, 144, 255) } .ccc_imgItem_info:hover{ cursor: pointer; } .hide_more .ccc_more { display: none; } .hide_more .ccc_imgItem_info: hover{ cursor: initial; } #ccc_load_tip_style{ position: fixed; padding: 12px 24px; top: 20px; right: 20px; color: #333; background-color: #fff; box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 10px 5px; border-radius: 5px; transition: all 0.5s ease-in-out 0s, transform 0.5s ease-in-out 0s; font-family: 'Damion', cursive; font-weight: 600; text-align: center; z-index: 999999; } #ccc_gotoUpdate{ position: relative; margin-right: 20px; line-height: 24px; } #ccc_gotoUpdate>a{ text-decoration: none; cursor: pointer; color: #909090; font-size: 12px; transition: all 0.3s ease; } #ccc_gotoUpdate:hover>a{ color: #007fff; } #ccc_gotoUpdate::before{ content: ''; position: absolute; left: 0; bottom: 0; height: 1px; width: 0; background-color: #007fff; transition: all 0.3s ease; } #ccc_gotoUpdate:hover::before{ width: 100%; } .ccc_schedule_container{ margin-top: 5px; display: flex; align-items: center; } .ccc_schedule_text{ text-align: center; font-size: 14px; white-space: nowrap; padding-left: 10px; } .ccc_schedule_bg{ position: relative; flex-grow: 1; height: 4px; border-radius: 2px; background-color: #ddd; margin: 2px auto; overflow: hidden; } .ccc_schedule_curr{ height: 100%; background-color: #67C23A; width: 0%; transition: all 0.3s ease; } #curr_ing{ color: #67C23A; } #ccc_fetch_pageImgs_text{ position: relative; font-size: 14px; margin-right: 20px; } #ccc_fetch_btn{ cursor: pointer; padding: 3px 0; transition: all 0.1s ease; } #ccc_fetch_pageImgs_text>.ccc_fetch_tips{ position: absolute; /* color: #F56C6C; */ color: #999999; font-size: 11px; top: 100%; right: 0; width: 0%; text-align: right; letter-spacing: 1px; opacity: 0; white-space: nowrap; /* 确保文本不会换行 */ overflow: hidden; /* 隐藏超出div的文本 */ text-overflow: ellipsis; /* 超出部分显示省略号 */ transition: all 0.4s ease; } #ccc_fetch_btn:hover{ color: #007fff; } #ccc_fetch_btn:hover + .ccc_fetch_tips{ width: 400%; opacity: 1; } #ccc_fetch_btn:active{ transform: translate3d(0, 1px, 0); } .click_style:active { transform: scale(0.9); } #ccc_notify{ position: absolute; top: 30px; left: 50%; transform: translate(-50%, 0); background-color: rgb(226, 244, 219); color: #67C23A; padding: 8px 20px; border-radius: 4px; font-size: 14px; letter-spacing: 1px; z-index: 8; opacity: 0; transition: all 0.3s ease; } #ccc_notify.active{ top: 70px; opacity: 1; } ` ); }