HTML版图像精灵制作工具

公司项目性能调优,要把小图标合成一张大图片,以减少服务器请求。也就是要制作传说中的CSS图像精灵

上百张图片,美工mm在photoshop里一个个的拖,太慢太累。也不是很复杂的工作,不如写个程序来做吧。

看Demo点这里


思路

  1. 选择磁盘上的小图标,支持多选。
  2. 把选中的小图标一张张的绘制到canvas上。
    简单起见,纵向排列,每个小图标占一行,也就是最终canvas上绘制了老长老长的内容。
  3. canvas导出png图片。

Show Me the Code

1. 支持多选的file input

<input type="file" 
       accept="image/gif,image/jpg,image/jpeg,image/png,image/bmp"
       multiple>
  • type="file"指定该input为文件选择框
  • accept限制可选文件类型
  • multiple表示支持多选

2. 绘制图标到canvas上

canvas上绘制图片,要用到这个方法:

CanvasRenderingContext2d.drawImage(image, dx, dy)
  • 参数image是绘制到canvas上的元素
    支持HTMLImageElementSVGImageElementHTMLCanvasElement等。
    在这次的程序中,我传入的是一个HTMLImageElement,即dom元素img
  • 参数dx指定小图标左上角在canvas X轴上的位置
  • 参数dy指定小图标左上角在canvas Y轴上的位置

有了这个方法,我们就可以把一个img元素绘制到canvas上了。但是怎么把fileInput选中的文件转成img元素呢?

读取选中的文件

fileInput选完文件后会触发change事件,事件监听器里,通过files属性可以得到选中的文件。

fileInput.addEventListener('change', () => {
    let selectedFiles = fileInput.files;
    ...
});

这里要注意一下:
selectedFiles不是Array对象,而是FileList对象。
如果你想用Array的方法操作,例如想按文件名排个序什么的,可以用下面的方法将它转化为Array对象。

let selectedFiles = Array.prototype.slice.call(selectedFiles);

转化成img元素

要使用到FileReader去读取文件内容,以DataURL的形式输出,设置给img.src
selectedFiles中的一个File对象为例。

let fileReader = new FileReader();
let img = document.createElement('img');
fileReader.onload = () => {
    img.src = fileReader.result;
    img.onload = () => {
        // onload触发以后才能读到img的宽和高
        console.log(`${file.name}: ${img.width}px * ${img.height}`);
    };
};
fileReader.readAsDataURL(file);

3.canvas导出图片

简单的话,chrome右键canvas->图片另存为...就可以了。
但这样不够直观,我想加一个导出图片的按钮。

首先来定义一个导出按钮。

<a id="exportBtn" class="button" download="compressed.png">导出图像精灵</a>

download="compressed.png"这个属性可以让链接点击后,下载文件,并且以compressed.png为文件名保存。

前面说到FileReader读取文件内容,可以以DataURL形式输出。
canvas.toDataURL(type, encoderOptions)也可以把canvas的内容以DataURL形式输出。
Canvas绘制完所有图标后,将DataURL设置给导出按钮的href即可。

exportBtn.href = canvas.toDataURL('png');

相关资料

猜你喜欢

转载自blog.csdn.net/github_39212680/article/details/78496811