t-comm
Version:
专业、稳定、纯粹的工具库
294 lines (287 loc) • 9.47 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var _typeof = require('@babel/runtime/helpers/typeof');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof);
/**
/**
* 处理图片尺寸单位,将 px/rem 转换为纯数字
* @docgen
* @function handleImgUnit
*
* @param {number|string} size - 输入的尺寸值
* @return {number} 返回处理后的数值(px)
*
* @description
* 该函数用于处理图片尺寸,去除单位(px/rem)并转换为数字类型。
* - 纯数字:直接返回
* - px 单位:去除 'px' 后返回数字
* - rem 单位:乘以根元素的 fontSize 转换为 px 值
*
* @example
*
* handleImgUnit(3); // 3
* handleImgUnit('10'); // 10
* handleImgUnit('30px'); // 30
*
* // 假设 document.documentElement.style.fontSize = '50px'
* handleImgUnit('5rem'); // 250
*
* // 假设 document.documentElement.style.fontSize = '10px'
* handleImgUnit('5rem'); // 50
*/
var handleImgUnit = function handleImgUnit(size) {
if (!size || typeof size === 'number') {
return size;
}
if (size.indexOf('px') === -1 && size.indexOf('rem') === -1) {
return parseFloat(size);
}
if (size.indexOf('px') > -1) {
return parseFloat(size.replace('px', ''));
}
var baseFontSize = 50;
try {
baseFontSize = parseFloat(document.documentElement.style.fontSize.replace('px', ''));
if (isNaN(baseFontSize)) {
baseFontSize = 50;
}
} catch (e) {
console.log('err', e);
}
if (size.indexOf('rem') > -1) {
return parseFloat(size.replace('rem', '')) * baseFontSize;
}
};
var zhizhu = 'game.gtimg.cn';
var youtu = 'image.myqcloud.com';
var wxlogo = 'wx.qlogo.cn';
var thirdqq = 'thirdqq.qlogo.cn';
var thirdwx = 'thirdwx.qlogo.cn';
var qqlogo = 'q.qlogo.cn';
var ossweb = 'ossweb-img.qq.com';
var cdnMap = new Map([['igame-10037599.cos.ap-shanghai.myqcloud.com', 'igame-10037599.file.myqcloud.com'], ['image-1251917893.cos.ap-guangzhou.myqcloud.com', 'image-1251917893.file.myqcloud.com'], ['igame-10037599.image.myqcloud.com', 'igame-10037599.file.myqcloud.com'], ['gamelife-1251917893.cos.ap-guangzhou.myqcloud.com', 'gamelife-1251917893.igcdn.cn']]);
var isTencentPic = function isTencentPic(url) {
return url && (url.indexOf(zhizhu) !== -1 || url.indexOf(youtu) !== -1 || url.indexOf(wxlogo) !== -1 || url.indexOf(thirdqq) !== -1 || url.indexOf(qqlogo) !== -1 || url.indexOf(thirdwx) !== -1 || url.indexOf(ossweb) !== -1);
};
var startWithHttp = function startWithHttp(url) {
var http = /http:/;
return http.test(url);
};
/**
* 将图片地址由 http 替换为 https 协议
* @param url 图片地址
* @returns 新的地址
*/
var getHttpsUrl = function getHttpsUrl(inUrl) {
var url = inUrl;
if (startWithHttp(url) && isTencentPic(url)) {
url = url.replace('http', 'https');
}
return url;
};
/**
* 获取 cdn 链接
* @param {string} url 图片地址
* @returns 新的地址
*/
function getCdnUrl(inUrl) {
if (inUrl === void 0) {
inUrl = '';
}
var url = inUrl;
if (url) {
var domainStr = url.split('/');
if (domainStr && domainStr.length > 2) {
var domain = domainStr[2];
if (cdnMap.has(domain)) {
url = url.replace(domain, cdnMap.get(domain));
}
return url;
}
} else {
return url;
}
return '';
}
/**
* 处理并压缩图片 URL
* @docgen
* @function getCompressImgUrl
*
* @param {string|object} inUrl - 图片原始 URL,或包含 url/width/height 的对象
* @param {number} [inImageWidth=0] - 图片裁剪后的宽度(可选,默认为 0,表示不裁剪)
* @param {number} [inImageHeight=0] - 图片裁剪后的高度(可选,默认为 0,表示不裁剪)
* @return {string} 返回处理后的图片 URL
*
* @description
* 该函数用于处理腾讯云 COS 图片,实现按需加载和压缩。
* - 自动将 http 转为 https
* - 对腾讯云图片添加压缩参数
* - 自动调整图片尺寸为 2 倍(避免图片模糊)
* - 宽高按 10 取整(避免图片闪烁)
*
* @example
*
* // 基础用法
* const url = 'https://image-xxx.file.myqcloud.com/test.jpg';
* const compressed = getCompressImgUrl(url, 100, 100);
*
* // 使用对象参数
* const compressed2 = getCompressImgUrl({
* url: 'https://image-xxx.file.myqcloud.com/test.jpg',
* width: 100,
* height: 100
* });
*/
function getCompressImgUrl(inUrl, inImageWidth, inImageHeight) {
var _a;
if (inImageWidth === void 0) {
inImageWidth = 0;
}
if (inImageHeight === void 0) {
inImageHeight = 0;
}
var url = inUrl;
var imageWidth = inImageWidth;
var imageHeight = inImageHeight;
// 游戏内无法加载http,统一替换
url = (_a = url === null || url === void 0 ? void 0 : url.replace) === null || _a === void 0 ? void 0 : _a.call(url, 'http:', 'https:');
if (_typeof__default["default"](url) === 'object') {
imageWidth = url.width ? url.width : 0;
imageHeight = url.height ? url.height : 0;
url = url.url ? url.url : '';
}
url = getCompressTencentImgUrl(url, imageWidth, imageHeight);
return url;
}
function getCompressTencentImgSize(imageWidth, imageHeight) {
var width = 0;
var height = 0;
if (imageWidth && imageHeight) {
width = imageWidth > 0 ? imageWidth * 2 : 0;
height = imageHeight > 0 ? imageHeight * 2 : 0;
}
// width和height都按10取整,解决图片大小微微改变的时候,图片闪烁的问题
width = formatInt(width, 1, true);
height = formatInt(height, 1, true);
// 有时候图片没设置长宽,导致图片100%时图片过大,选择宽度优先
if (width > 200 && height > 200 && width === height) {
height = 0;
}
if (width < 10 && height < 10) {
width = 0;
height = 0;
}
return {
width: width,
height: height
};
}
function getCompressTencentImgUrl(url, imageWidth, imageHeight) {
// 如果是腾讯云的图片实现按需加载(1倍的时候感觉图片有点糊,放大到2倍)
var isCDN = Array.from(cdnMap.values()).some(function (item) {
return url === null || url === void 0 ? void 0 : url.includes(item);
});
var isTencentCloudPic = url && isCDN && url.indexOf('?') === -1;
if (!isTencentCloudPic) {
return url;
}
var _a = getCompressTencentImgSize(imageWidth, imageHeight),
width = _a.width,
height = _a.height;
if (width > 150 || height > 150) {
url = "".concat(url, "?imageMogr2/format/yjpeg/quality/80/thumbnail/!").concat(width > 0 ? width.toString() : '', "x").concat(height > 0 ? height.toString() : '', "r");
} else if (width > 0 || height > 0) {
url = "".concat(url, "?imageMogr2/thumbnail/!").concat(width > 0 ? width.toString() : '', "x").concat(height > 0 ? height.toString() : '', "r");
}
return url;
}
var formatInt = function formatInt(num, prec, ceil) {
if (prec === void 0) {
prec = 2;
}
if (ceil === void 0) {
ceil = true;
}
var len = String(num).length;
if (len <= prec) {
return num;
}
var mult = Math.pow(10, prec);
return ceil ? Math.ceil(num / mult) * mult : Math.floor(num / mult) * mult;
};
/**
* 处理图片 URL(换 CDN 域名 + 裁剪压缩)
* @docgen
* @function tinyImage
*
* @param {string} inUrl - 图片原始 URL
* @param {number} [width=0] - 图片裁剪后的宽度(可选,默认为 0,表示不裁剪)
* @param {number} [height=0] - 图片裁剪后的高度(可选,默认为 0,表示不裁剪)
* @return {string} 返回处理后的图片 URL
*
* @description
* 该函数是图片处理的综合方法,依次执行:
* 1. 将 http 转为 https
* 2. 替换为 CDN 域名
* 3. 添加压缩和裁剪参数
*
* @example
*
* const url = 'http://igame-10037599.cos.ap-shanghai.myqcloud.com/test.jpg';
* const optimized = tinyImage(url, 200, 200);
* // 结果:https 域名 + CDN + 压缩参数
*/
var tinyImage = function tinyImage(inUrl, imageWidth, imageHeight) {
if (imageWidth === void 0) {
imageWidth = 0;
}
if (imageHeight === void 0) {
imageHeight = 0;
}
var url = inUrl;
url = getHttpsUrl(url);
url = getCdnUrl(url);
url = getCompressImgUrl(url, imageWidth, imageHeight);
return url;
};
var supportsWebp = function supportsWebp(_a) {
var createImageBitmap = _a.createImageBitmap,
Image = _a.Image;
if (!createImageBitmap || !Image) return Promise.resolve(false);
return new Promise(function (resolve) {
// 加载一个1x1的空白图片,看下是否支持webP
var image = new Image();
image.onload = function () {
createImageBitmap(image).then(function () {
resolve(true);
})["catch"](function () {
resolve(false);
});
};
image.onerror = function () {
resolve(false);
};
image.src = 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=';
});
};
/**
* 判断当前浏览器是否支持 webp
* @returns {Promise<boolean> }是否支持
*/
var isSupportedWebp = function isSupportedWebp() {
var memo = null;
return function () {
if (!memo) {
memo = supportsWebp(window);
}
return memo;
};
};
exports.getCdnUrl = getCdnUrl;
exports.getCompressImgUrl = getCompressImgUrl;
exports.getHttpsUrl = getHttpsUrl;
exports.handleImgUnit = handleImgUnit;
exports.isSupportedWebp = isSupportedWebp;
exports.tinyImage = tinyImage;