irpas技术客

Web 图集应用,属于非游戏类的图集/雪碧图对象/JS雪碧图/前端图集/JS图集_李筱宝

网络投稿 4317

在非游戏领域其实也是存在很多细小的图标需求的。但是找遍全网却没有方便简洁的图集插件。

所以在此特写一个属于前端的图集插件,该插件使用非常简单。

首先准备需要打成图集的小图标若干

再使用国际标准的图集打包软件【texturepacker】,软件长这样

?然后将图片拖进软件内,

注意数据格式要选择【JSON(Array)】类型该插件才能解析成功,就是这个东西

接下来将生成的图集文件拖入工程内,比如我刚刚生成的文件分别是【asd.json 和 asd.png】

asd.json 是图集描述文件,里面记录着每个小图标的信息,位置大小等等

asd.png 是多个小图的合并生成的大图

json 文件长这样


好了准备工作做好了,接下来就来写代码

首先引入插件代码

然后在需要使用图集的【img】标签上添加属性【frame】

最后启动图集插件即可,如图所示

这是效果

?这是全部代码

/* * @Author: Summer * @LastEditors: Summer * @Description: * @Date: 2022-04-13 18:07:24 +0800 * @LastEditTime: 2022-04-15 08:52:08 +0800 * @FilePath: \test\atlas.js */ (function () { /** * 加载 Image 图片元素 * @param {*} url * @returns */ function loadImage(url) { return new Promise((resolve, reject) => { let image = new Image(); image.onerror = reject; image.onload = () => resolve(image); image.src = url; }) } /** * Canvas 转 Image * @param {*} canvas * @returns */ function createImageByCanvas(canvas) { return new Promise((resolve, reject) => canvas.toBlob(blob => { let image = new Image(); image.onerror = reject; image.onload = () => { URL.revokeObjectURL(image.src); resolve(image) } image.src = URL.createObjectURL(blob); })) } function createFrameByCanvas(canvas) { return new Promise(resolve => canvas.toBlob(blob => resolve(new Frame(blob)))); } class Frame { constructor(blob) { this.data = blob; this.image = new Image(); this.url = this.image.src = URL.createObjectURL(blob); Object.defineProperties(this, { data: { writable: false, configurable: false }, image: { writable: false, configurable: false }, url: { writable: false, configurable: false }, }) } get width() { return this.image.naturalWidth } get height() { return this.image.naturalHeight } } /** * 图集对象 */ window.Atlas = class Atlas { _frames = new Map(); constructor() { Object.defineProperty(this, "_frames", { writable: false, configurable: false }); document.body.addEventListener("DOMSubtreeModified", this.scanning.bind(this), false); } /** * 初始化图集数据 * @param {*} urls 图集的路径 */ async init(urls = {}) { let container = document.createElement("canvas"); let scene = document.createElement("canvas"); let s2d = scene.getContext("2d"); let c2d = container.getContext("2d"); for (let name in urls) { let atlas = await fetch(urls[name] + ".json").then(body => body.json()); let boot = await loadImage(urls[name] + ".png"); scene.width = boot.naturalWidth; scene.height = boot.naturalHeight; /// s2d.clearRect(0, 0, boot.naturalWidth, boot.naturalHeight); s2d.drawImage(boot, 0, 0, boot.naturalWidth, boot.naturalHeight); for (let { filename, sourceSize: { w: sw, h: sh }, spriteSourceSize: { x: sx, y: sy }, frame: { x, y, w, h }, rotated } of atlas.frames) { if (rotated) [w, h, sx, sy, sw, sh] = [h, w, sy, sx, sh, sw]; container.width = sw, container.height = sh; c2d.clearRect(0, 0, sw, sh); c2d.putImageData(s2d.getImageData(x, y, w, h), sx, sy, 0, 0, sw, sh); if (rotated) { let image = await createImageByCanvas(container); [sw, sh] = [sh, sw]; container.width = sw, container.height = sh; c2d.clearRect(0, 0, sw, sh); // 先位移坐标到中心 c2d.translate(sw / 2, sh / 2); // 旋转90度 c2d.rotate(-90 * Math.PI / 180); // 此时按照旋转后的尺寸 // 把定位中心移动到左上角 c2d.translate(-1 * sh / 2, -1 * sw / 2); // 绘制图片 c2d.drawImage(image, 0, 0, sh, sw, 0, 0, sh, sw) // 坐标系还原到初始 c2d.setTransform(1, 0, 0, 1, 0, 0); } this._frames.set(`${name}/${filename}`, await createFrameByCanvas(container)); } } return this; } /** * 获取图集中的某个图片元素 * @param {*} name 图集名称/图片名称 * @returns */ getFrame(name) { return this._frames.get(name) } /** * 获取图集中的某个图片地址 * @param {*} name 图集名称/图片名称 * @returns */ getFrameUrl(name) { return this._frames.get(name)?.url; } /** * 获取图集中所有的图片元素 * @returns */ getFrames() { return [...this._frames.values()] }; /** * 开始扫描文档中使用图集规则的【Image】元素, 进行图集映射 * 规则就是在 Img 标签添加属性【frame="图集名称/图片名称"】 */ scanning() { /// 扫描所有的 Image 节点,实现图集映射 for (let ele of document.body.querySelectorAll("img")) if (ele.getAttribute("frame") || ele.frame) { ele.src = this.getFrameUrl(ele.getAttribute("frame") || ele.frame) } } } })()


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #Web #图集应用 #