- // ==UserScript==
- // @name 图片下载 | 页面所有图片打包下载 | 单张下载 | 图片预览放大,旋转,信息展示 | 简单有效,想要哪张点哪张
- // @namespace http://tampermonkey.net/
- // @description 简单纯洁的网页图片下载工具,侵入性小不影响原网页显示,可集中展示页面所有图片,可点击预览放大,可旋转,可查看图片信息(尺寸,格式,图片大小) | (Ctrl+鼠标右键)下载单个图片
- // @description:zh-CN 一个帮你快速捕获网页图片并打包下载、也可单张下载的小工具🔧
- // @author <shing0727@foxmail.com>
- // @version v4.1.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 *://*/*
- // @connect *
- // @grant GM_getValue
- // @grant GM_setValue
-
- // ==/UserScript==
-
-
- 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`);
- let str = $('#ccc_all_page_rename_val').val()
- str = str.length > 245 ? str.substring(0, 245) : str;
- saveAs(blob, `${str}.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) {
- try {
- 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 = decodeURIComponent(name + '.' + item.lastName)
- } catch (e) {
- console.log('e = ', e)
- }
- }
- // 更新节点显示信息
- function updateNodeItem(item) {
- try {
- $('.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
- }
- })
- } catch (e) {
- console.log(e)
- }
- }
-
- // 获取单张图片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(`<div id="ccc_notify">${msg}</div>`)
- 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);
- // 创建一个<a>标签用于下载
- 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);
- // 清理<a>标签
- 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 = $('<div>', { class: 'ccc_image_item ' + addCss, "data-imgsrc": item.src });
- var $img = $('<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 = $('<div>', { 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(`
- <div class="ccc_imgItem_ctrl">
- <div class="click_style" title="下载"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" t="1723013152119" class="icon" viewBox="0 0 1024 1024" version="1.1" p-id="6158" width="200" height="200"><path d="M862.39 161.61A222.53 222.53 0 0 0 704 96H320A224 224 0 0 0 96 320v384a224 224 0 0 0 224 224h384a224 224 0 0 0 224-224V320a222.53 222.53 0 0 0-65.61-158.39zM704 736a32 32 0 0 1-32 32H352a32 32 0 0 1-32-32 32 32 0 0 1 32-32h320a32 32 0 0 1 32 32z m-8.88-211.62L529.75 634.63a32 32 0 0 1-35.5 0L328.88 524.38A32 32 0 0 1 320 480a32 32 0 0 1 44.38-8.88l103.18 68.8a8 8 0 0 0 12.44-6.66V288a32 32 0 0 1 32-32 32 32 0 0 1 32 32v245.26a8 8 0 0 0 12.44 6.66l103.18-68.8A32 32 0 0 1 704 480a32 32 0 0 1-8.88 44.38z" fill="#ffffff" p-id="6159"/></svg></div>
- </div>
- <div class="ccc_imgItem_delete click_style" title="移除"><span></span></div>
- `)
- $(this).find('.ccc_imgItem_info').append(`
- <span class="ccc_more"> ···</span>
- `)
- })
-
- viewer && viewer.destroy();
- viewer = new Viewer(document.getElementById('ccc_image_container'));
- }
-
- const setLoading = (target, isLoading = true) => {
- if (isLoading) {
- $(target).append(
- `
- <div id="ccc_itemImgLoading">
- <div class="loader"></div>
- </div>
- `
- )
- } else {
- $(target).find('#ccc_itemImgLoading').remove();
- }
- }
-
- var ccc_currentVersion = 'v4.1.0';
- 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%E5%BC%A0%E4%B8%8B%E8%BD%BD-%E5%9B%BE%E7%89%87%E9%A2%84%E8%A7%88%E6%94%BE%E5%A4%A7-%E6%97%8B%E8%BD%AC-%E4%BF%A1%E6%81%AF%E5%B1%95%E7%A4%BA-%E7%AE%80%E5%8D%95%E6%9C%89%E6%95%88-%E6%83%B3%E8%A6%81%E5%93%AA%E5%BC%A0%E7%82%B9%E5%93%AA%E5%BC%A0'; // 脚本首页地址
- var online_update_url = 'https://update.greasyfork.org/scripts/492706/%E5%9B%BE%E7%89%87%E4%B8%8B%E8%BD%BD%20%7C%20%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%20%7C%20%E5%8D%95%E5%BC%A0%E4%B8%8B%E8%BD%BD%20%7C%20%E5%9B%BE%E7%89%87%E9%A2%84%E8%A7%88%E6%94%BE%E5%A4%A7,%E6%97%8B%E8%BD%AC,%E4%BF%A1%E6%81%AF%E5%B1%95%E7%A4%BA%20%7C%20%E7%AE%80%E5%8D%95%E6%9C%89%E6%95%88%EF%BC%8C%E6%83%B3%E8%A6%81%E5%93%AA%E5%BC%A0%E7%82%B9%E5%93%AA%E5%BC%A0.user.js'; // 脚本首页地址
- const loadUpdateTamp = () => {
- const extractVersion = (htmlString) => {
- // 使用正则表达式匹配 data-script-version 属性的值
- const versionMatch = htmlString.match(/data-script-version="([^"]+)"/);
- // 如果匹配成功,返回版本号;否则返回 null
- return versionMatch ? versionMatch[1] : null;
- }
-
- const isUpdateAvailable = (ccc_currentVersion, onlineVersion) => {
- const current = ccc_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(ccc_currentVersion, onlineVersion)
-
- if (hasUpdate) {
- GM_registerMenuCommand("有新版本啦~(♥ω", function () {
- window.open(online_update_url, '_blank');
- });
- $('#ccc_gotoUpdate').append(`
- <a href="${online_update_url}" target="_blank">有新版本啦,快去体验下吧~(♥ω</a>
- `)
- }
- }
- },
- 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(`
- <span>宽 ${w_min || 0} - ${w_max}</span>
- `)
- isView = true
- }
- if (h_min || $('#ccc_h_max').val()) {
- $('#ccc_view_filter_itembox').append(`
- <span>高 ${h_min || 0} - ${h_max}</span>
- `)
- 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()
- });
-
- 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(`<div class="loader"></div>`);
-
- $(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 = GM_getValue('ccc_main_icon_isshow', true);
- $(document).on('click', '#showhide_main_btn', function () {
- isShowMainIcon = !isShowMainIcon
- handleShowHide()
- })
-
- const handleShowHide = () => {
- let speed = 600
- $('#ccc_main_icon_container').css({
- transition: `all ${speed}ms`
- })
- GM_setValue('ccc_main_icon_isshow', isShowMainIcon);
- 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);
- }
- handleShowHide()
-
-
- $('#ccc_popUps_container').click(function (e) {
- e.stopPropagation()
- })
-
- document.getElementById('ccc_popUps_out').addEventListener("mousedown", function (event) {
- if (event.target.id === 'ccc_popUps_out') {
- let flag = document.querySelector('.ccc_all_pack_down_container').classList.contains('ccc_focus_rename');
- if (flag) return;
- 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()
- }
-
- // 检测是否移除icon
- var isRemoveIcon = GM_getValue('ccc_main_icon_isRemoveIcon', true);
- handleRemoveIcon(isRemoveIcon)
- GM_registerMenuCommand('(显示/移除)右下角图标', function () {
- isRemoveIcon = !isRemoveIcon
- GM_setValue('ccc_main_icon_isRemoveIcon', isRemoveIcon);
- handleRemoveIcon(isRemoveIcon)
- });
-
- // 处理是否显示右下角图片及注册油猴Menu
- function handleRemoveIcon(flag){
- if(flag === true){
- $('#ccc_main_icon_container').show()
- }else{
- $('#ccc_main_icon_container').hide()
- }
- }
-
- }
- // 初始声明事件
- 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)
- }
-
- // 获取textarea元素
- var textareaDom = document.getElementById('ccc_all_page_rename_val')
- // 监听focus事件
- textareaDom.addEventListener('focus', function () {
- document.querySelector('.ccc_all_pack_down_container').classList.add('ccc_focus_rename');
- });
- // 监听blur事件
- textareaDom.addEventListener('blur', function () {
- setTimeout(() => {
- document.querySelector('.ccc_all_pack_down_container').classList.remove('ccc_focus_rename');
- }, 100);
- });
- var ccc_domain = window.location.href.replace(/^https?:\/\//i, "");
- var ccc_zipFileName = `【${document.title}】【${ccc_domain}】`
- $(textareaDom).val(ccc_zipFileName)
- }
- // 打包下载loading
- function isTopLoading(flag, total) {
- if (flag) {
- if ($('#ccc_load_tip_style').length) {
- $('#ccc_load_tip_style').remove();
- }
- $('body').append(`
- <div id="ccc_load_tip_style">
- <div>稍等片刻,正在打包下载...</div>
- <div class="ccc_schedule_container">
- <div class="ccc_schedule_bg"><div class="ccc_schedule_curr"></div></div>
- <div class="ccc_schedule_text"><span id="curr_ing">0</span>/${total}</div>
- </div>
- </div>
- `)
- $('#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) => {
- try {
- if ($('#curr_ing').length) {
- $('#curr_ing').text(curr)
- let w = ((curr / total) * 100).toFixed(1) + '%'
- $('.ccc_schedule_curr').css('width', w)
- }
- } catch (e) {
- console.log(e)
- }
- }
-
-
- // 初始化加载页面
- const init = () => {
- window.addEventListener("load", function () {
- if (window.self !== window.top) return;
- setTimeout(() => {
- loadCss()
- loadElementDOM()
- loadAllImgUrls();
- loadMainOperations();
- initEvents();
- // loadUpdateTamp()
- }, 300);
- });
- };
- (function () {
- init();
- })();
-
- const loadElementDOM = () => {
- $("body").append(`
-
- <!-- 主体Icom -->
- <div id="ccc_main_icon_container">
- <div id="showhide_main_btn" class="none_select">»</div>
- <div id="open_popUps_icon" title="ALT + Q">
- <span class="pop_title_num none_select">0</span>
- <svg t="1719977292759" class="icon" viewBox="0 0 1248 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
- p-id="9887" width="256" height="256">
- <path
- d="M0 159.430165V865.420028c0 65.985105 13.006679 78.509585 76.517343 78.509585h867.120413c62.977707 0 76.504653-12.029592 76.504653-78.458827v-706.040621c0-64.322788-11.991524-78.446138-76.504653-78.446138H76.504653C13.247779 80.984027 0 92.214184 0 159.430165z m900.02414 601.479609H120.638537c85.184232-127.389321 236.670806-339.721774 275.157887-339.721774 37.268895 0 163.693818 171.561272 220.796312 231.950332 0 0 73.484566-100.665353 111.984336-100.665353 39.261137 0 170.114676 207.358192 171.38362 208.398726zM671.017758 316.33513c0-53.295662 42.065504-96.439769 94.092221-96.439768s94.092222 43.144107 94.092222 96.439768-42.065504 96.439769-94.092222 96.439769-94.092222-43.144107-94.092221-96.439769zM478.39201 33.652403L329.265673 4.631647c-49.488829-9.631287-69.132087-6.167069-81.212437 29.020756z m702.792123 136.741441l-116.742877-22.714104c0 2.905882 0.076137 5.799076 0.076136 8.654201v710.050485c0 32.992552-2.131826 70.236068-27.536092 95.767228-24.706346 24.820551-60.503265 26.90162-92.099979 26.901619h-70.439099l149.824256 29.18572c61.873725 12.042282 77.405604 2.804367 89.435196-62.44475l128.379097-693.693793c11.699667-63.206117 2.537889-79.372467-60.909327-91.706606z"
- p-id="9888" fill="#333333"></path>
- </svg>
- </div>
- </div>
-
- <!-- 弹窗 -->
- <div id="ccc_popUps_out">
- <div id="ccc_popUps_container">
- <div id="ccc_popUps_top">
- <div id="ccc_title_ctrl">
- <div class="ccc_title_text">网页图片列表 (共 <span class="pop_title_num">0</span> 张)</div>
- <div id="ccc_filter_out">
- <svg id="ccc_filter_btn" class="click_style" t="1719976985515" class="icon"
- viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6880"
- width="256" height="256">
- <path
- d="M577.499296 1023.99875a99.999878 99.999878 0 0 1-47.999942-11.999985l-131.999839-72.999911a99.999878 99.999878 0 0 1-51.999936-87.999893V431.999473a19.999976 19.999976 0 0 0-7.99999-15.999981L32.499961 171.99979l-3.999995-3.999995C0.5 138.99983-6.499991 96.999882 9.499989 59.999927S60.499927 0 100.499878 0h821.998997c39.999951 0 75.999907 22.999972 91.999887 59.999927s8.999989 77.999905-17.999978 107.999868l-3.999995 3.999995-307.999624 246.999699a19.999976 19.999976 0 0 0-6.999991 15.99998v488.999403a99.999878 99.999878 0 0 1-99.999878 99.999878zM84.499897 111.999863l302.999631 241.999705a98.999879 98.999879 0 0 1 37.999953 77.999905v418.999488a19.999976 19.999976 0 0 0 9.999988 17.999978l131.999839 71.999912a19.999976 19.999976 0 0 0 29.999963-17.999978V434.999469a99.999878 99.999878 0 0 1 36.999955-77.999905l303.999629-244.999701a19.999976 19.999976 0 0 0-15.99998-31.999961H100.499878a19.999976 19.999976 0 0 0-15.999981 31.999961z m881.998924 28.999965z"
- fill="#333333" p-id="6881"></path>
- <path
- d="M983.4988 520.999364H757.499076a39.999951 39.999951 0 0 1 0-79.999902h225.999724a39.999951 39.999951 0 0 1 0 79.999902zM983.4988 670.999181H757.499076a39.999951 39.999951 0 0 1 0-79.999902h225.999724a39.999951 39.999951 0 0 1 0 79.999902zM983.4988 819.998999H757.499076a39.999951 39.999951 0 0 1 0-79.999902h225.999724a39.999951 39.999951 0 0 1 0 79.999902z"
- fill="#333333" p-id="6882"></path>
- </svg>
- <div id="ccc_filter_container">
- <div>宽:<input id="ccc_w_min" class="ccc_filter_input" type="text"
- placeholder="0"><span>-</span><input id="ccc_w_max" class="ccc_filter_input"
- type="text" placeholder="∞">
- </div>
- <div>高:<input id="ccc_h_min" class="ccc_filter_input" type="text"
- placeholder="0"><span>-</span><input id="ccc_h_max" class="ccc_filter_input"
- type="text" placeholder="∞">
- </div>
- <div>
- <div id="refilter_btn" class="click_style">重置</div>
- </div>
- </div>
- </div>
- <div class="ccc_view_filter">
- <span style="font-weight: bold;">筛选条件:</span>
- <div id="ccc_view_filter_itembox">
- </div>
- </div>
- </div>
- <div class="ccc_popUps_top_right">
- <div id="ccc_gotoUpdate"></div>
- <div id="ccc_fetch_pageImgs_text">
- <div id="ccc_fetch_btn" class="click_style none_select">刷新抓取</div>
- <div class="ccc_fetch_tips none_select">(非首屏载入网页的图片,需刷新抓取)</div>
- </div>
- <div class="ccc_all_pack_down_container">
- <div id="ccc_all_pack_down_btn" class="none_select click_style"><span
- class="pop_title_num">0</span>打包下载
- </div>
- <!-- 🖊✍ -->
- <div id="ccc_all_page_rename"><span class="ccc_all_page_rename_icon">✍</span>
- <div class="ccc_all_page_rename_out">
- <div class="ccc_all_page_rename_container">
- <div class="ccc_all_page_rename_container_tips_font">重命名压缩包文件名称:</div>
- <textarea id="ccc_all_page_rename_val" maxlength="255"></textarea>
- </div>
- </div>
- </div>
- </div>
- <div id="ccc_close_popUps" class="none_select" title="Esc">❌</div>
- </div>
- </div>
- <div id="load_mask">图片加载中...</div>
-
- <div id="ccc_image_container">
- <!-- <div class="ccc_image_item"></div> -->
- </div>
- </div>
- </div>
-
- `)
- }
- 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;
- display: none;
- }
-
- #open_popUps_icon {
- position: relative;
- width: 30px;
- height: 30px;
- cursor: pointer;
- }
-
- #open_popUps_icon>svg {
- width: 100%;
- height: 100%;
- }
-
- #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: 10px;
- border-radius: 30px;
- }
-
- #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 {
- position: relative;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding-bottom: 10px;
- margin-bottom: 10px;
- z-index: 10;
- }
-
- .pop_title_num {
- color: red;
- }
-
- .ccc_popUps_top_right {
- display: flex;
- align-items: center;
- justify-content: flex-end;
- }
-
- #ccc_all_pack_down_btn, #ccc_all_page_screenShot {
- 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_page_screenShot{
- margin-right: 20px;
- background-color: #666666;
- }
-
- #ccc_all_page_screenShot: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;
- line-height: 10px;
- border-radius: 30px;
- margin-right: 2px;
- }
-
- #ccc_close_popUps {
- cursor: pointer;
- filter: grayscale(100%);
- font-size: 12px;
- margin-left: 30px;
- }
-
- #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: 14px;
- }
-
- #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;
- }
-
- .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_imgItem_info:hover .ccc_more {
- color: rgb(24, 144, 255)
- }
-
- .ccc_imgItem_info:hover {
- cursor: pointer;
- }
-
- .ccc_more>.loader {
- width: 12px;
- height: 12px;
- border: 2px solid #f3f3f3;
- border-top: 2px solid #3498db;
- }
-
-
- #ccc_load_tip_style {
- position: fixed;
- width: 210px;
- 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: 20%;
- transition: all 0.3s ease;
- }
-
- #curr_ing {
- color: #67C23A;
- }
-
- #ccc_fetch_pageImgs {
- display: flex;
- width: 20px;
- height: 20px;
- margin: auto 20px;
- }
-
- #ccc_fetch_pageImgs>svg {
- width: 100%;
- height: 100%;
- }
- #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;
- }
-
- .ccc_all_pack_down_container{
- display: flex;
- background-color: #666666;
- border-radius: 4px;
- transition: all 0.3s;
- cursor: pointer;
-
- }
-
- .ccc_all_pack_down_container:hover {
- box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.3);
- }
-
- .ccc_all_pack_down_container> #ccc_all_pack_down_btn{
- margin-right: 0;
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
- background-color: initial;
- }
-
- .ccc_all_pack_down_container>#ccc_all_pack_down_btn:hover{
- background-color: #333333;
- }
- #ccc_all_page_rename{
- position: relative;
- width: 20px;
- display: flex;
- align-items: center;
- justify-content: center;
- border-top-right-radius: 4px;
- border-bottom-right-radius: 4px;
- border-left: 1px solid #555;
- color: #eee;
-
- }
- #ccc_all_page_rename>.ccc_all_page_rename_icon{
- position: absolute;
- top: 45%;
- left: 50%;
- transform: translate(-50%, -50%);
- box-sizing: border-box;
- font-size: 12px;
- transition: all 0.3s;
- }
- .ccc_all_pack_down_container>#ccc_all_page_rename:hover .ccc_all_page_rename_icon, .ccc_focus_rename .ccc_all_page_rename_icon{
- font-size: 55px !important;
- z-index: 999 !important;
- }
- .ccc_all_pack_down_container>#ccc_all_page_rename:hover, .ccc_focus_rename #ccc_all_page_rename{
- background-color: #eee;
- color: red;
- }
- .ccc_all_page_rename_out{
- /* display: none; */
- visibility:hidden;
- position: absolute;
- top: 100%;
- padding: 10px 50px 50px 50px;
- cursor: initial;
- }
- .ccc_all_page_rename_container{
- opacity: 0;
- width: 0;
- /* width: 340px; */
- padding: 10px;
- border-radius: 10px;
- color: #333;
- /* background-color: #f5f5f5; */
- cursor: initial;
- box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.3);
- background-color: rgba(255, 255, 255, 0.6); /* 设置半透明背景 */
- backdrop-filter: blur(10px); /* 应用背景模糊效果 */
- -webkit-backdrop-filter: blur(10px); /* 兼容老版本Safari */
- transition: all 0.3s;
- }
- .ccc_all_pack_down_container>#ccc_all_page_rename:hover .ccc_all_page_rename_out, .ccc_focus_rename .ccc_all_page_rename_out{
- display: block;
- visibility: visible;
- }
- .ccc_all_pack_down_container>#ccc_all_page_rename:hover .ccc_all_page_rename_container, .ccc_focus_rename .ccc_all_page_rename_container{
- width: 340px;
- opacity: 1;
- }
-
- .ccc_all_page_rename_container_tips_font{
- font-size: 13px;
- font-weight: 550;
- letter-spacing: 0.5px;
- margin-bottom: 5px;
- white-space: nowrap;
- }
- #ccc_all_page_rename_val{
- max-width: 100%;
- min-width: 100%;
- min-height: 100px;
- box-sizing: border-box;
- border: none;
- outline: none; /* 可选:移除聚焦时的轮廓 */
- padding: 4px 6px;
- border-radius: 6px;
- box-shadow: 0 0 10px 1px rgba(0, 0, 0, 0.1);
- background-color: rgba(255, 255, 255, 0.7); /* 设置半透明背景 */
-
- }
- `
- );
- }