UI很忙?那我本身作雪碧图

引言

做为一名前端工程师(菜鸟),咱们在作项目的时候可能会用到不少小图片,须要咱们将这些小图片概括到一张图片上,也就是制做成雪碧图。讲道理,这个应该交给ui来作才对,可领导说ui很忙,让我本身想办法。因而本身就瞎捣鼓了一下,没想到效果还能够(自我感受良好0.0),由于是使用的float布局的,因此图片添加顺序不合适的话,会产生大量留白(珍惜头发)。css

预览

githup地址:github.com/moumoujiang… html

思路

  1. 图片上传预览 --> 合理的调整小图片的位置前端

  2. 将图片绘制到canvas上 --> 这张图不就至关与是雪碧图吗git

  3. 生成对应的样式 --> 灵机一动,与其一个个去找背景图位置,不如直接写出来github

    :总体代码都比较简单,惟一取巧的地方就是canvas区与图片区大小保持一致,使用小图片的offsetLeft - 图片区的offsetLeft来记录图片的位置(offsetTop同理),此时的位置刚好可做为canvas每次绘制小图片的位置,也是每张小图片的背景位置。canvas

图片上传预览

// 上传预览图片
    $(".selectImgInput").change(function(e) {
      for(let i=0;i<e.target.files.length;i++) {
        let file = e.target.files.item(i);
        //容许文件MIME类型 也能够在input标签中指定accept属性
        //console.log(/^image\/.*$/i.test(file.type));
        if(!(/^image\/.*$/i.test(file.type))) {
          continue;      //不是图片 就跳出这一次循环
        }
        //实例化FileReader API
        var freader = new FileReader();
        let img = document.createElement('img');
        freader.readAsDataURL(file);
        freader.onload=function(e) {
          // var img = '<img src="'+e.target.result+'" class="img" alt="'+file.name.split(".")[0]+ '" />';
          img.src = e.target.result
          img.alt = file.name.split(".")[0]
          img.className = 'img'
          $(".imgs").append(img);
        }
        freader.onloadend = function(e) {
          if($('.imgs').eq(0).height() < img.offsetTop + img.height) {
            $('.imgs').eq(0).height(img.offsetTop + img.height)
          }
        }
      }
    })
复制代码

将图片绘制到canvas上

这里咱们使用transparent来清空canvas画布,这样能够生成透明的图片bash

$(".product").click(function() {
      var drawW = $('.imgs')[0].offsetLeft;;
      var drawH = $('.imgs')[0].offsetTop;
      var canvas = document.getElementById("canvas")
      var ctx = canvas.getContext('2d')
      console.log($('.imgs').eq(0).height())
      var width = canvas.width = 400;
      var height = canvas.height = $('.imgs').eq(0).height() + 10;
      ctx.fillStyle = 'transparent';
      ctx.fillRect(0,0,width,height);
      var len = $('.img').length;
      var sccStyle = `
.sprites{
  display: inline-block;
  backGround: url(./sprites.png);
}
`;
      for(let i=0;i<len;i++) {
        var img = $('.img')[i]
        // console.log(img)
        var x = $('.img')[i].offsetLeft - drawW;
        var y = $('.img')[i].offsetTop - drawH;
        ctx.drawImage(img,0,0, img.width, img.height, x, y, img.width, img.height);
        var className = img.alt

    })
复制代码

生成对应的样式

知道了每张小图在canvas画布上的位置,即上文中的x, y;如不加以利用岂不天理难容?因而就有了css样式的这个部分。前端工程师

sccStyle += `
.sp_${className}{
  width: ${img.width}px;
  heihgt: ${img.height}px;
  background-position: ${x}px ${y}px;
}
`
      }
      html = `
<pre>
${sccStyle}
</pre>
`
      $(".css_sprites").html(html)
复制代码

下载雪碧图

在这里我是使用a标签进行下载的app

// 下载雪碧图
    $('.download').click(function(e) {
      var canvas = document.getElementById("canvas")
      var MIME_TYPE = "image/png";
      var imgURL = canvas.toDataURL(MIME_TYPE);

      var dlLink = document.createElement('a')
      dlLink.download = 'sprites';
      dlLink.href = imgURL;
      dlLink.dataset.downloadurl = [MIME_TYPE, dlLink.download, dlLink.href].join(':');

      document.body.appendChild(dlLink);
      dlLink.click();
      document.body.removeChild(dlLink);
    })
  })
复制代码

最后

这个代码都很是简单,没有什么复杂的逻辑,若是你们有什么更好的方案也能够本身尝试实现一个,别忘了@我,你们一块儿学习。写东西可能不实用,但更多的是相互学习处理业务的方法,对场景的考量。布局

相关文章
相关标签/搜索