如何在小程序中使用雪碧图

ByteCosmicRhapsody
• 阅读 10149

小程序对上传的代码有2M的大小限制,因此一般在小程序中使用icon的时候,要么是用icon-font,要么就是将icon图片上传到cdn再使用,而不会将图片放在本地。但是使用icon-font有一个问题,就是不能使用渐变色,因此,需要渐变色的icon都只能使用图片来完成。如果这样的icon少还可以手动一张张上传到cdn,但是多到10-20张,手动传就是一件耗时费力的事了。因此,我们需要把我们的icon整合起来,做成一张雪碧图,然后将其上传到cdn,最后将cdn的地址替换到css中。在小程序中我们借助gulp来将这一系列步骤自动化,下面谈谈具体的实施方案。

目录结构

为了使我们的源码能使用更多的现代特性,我们将目录分为了src和dist两大目录,src存放我们的源码,而dist则存放gulp处理过后给小程序执行的代码。如下所示:

如何在小程序中使用雪碧图

  • icons: 该目录存放所有的图片icons
  • style: 该目录存放共用的css,我们生成的雪碧图css也存放于此
  • gulpfile: gulp任务配置文件

gulp配置

先安装依赖包

 yarn add sprity sprity-sass gulp gulp-if gulp-sass gulp-rename gulp-replace -D

我们采用sprity这个库来处理雪碧图,而sprity-sass则是针对scss的一个处理器。gulp-sass则是将scss文件处理为css,gulp-rename将其命名为小程序特有的wxss文件。

首先打开gulpfile编写我们的雪碧图处理代码,如下:

const gulp = require('gulp');
const sass = require('gulp-sass');
const rename = require('gulp-rename');
const sprity = require('sprity');
const gulpif = require('gulp-if');

gulp.task('sprity', () => {
    return sprity.src({
        src: './src/icons/**/*.{png,jpg}', // icon存放目录
        style: '_icon.scss', // 生成的icon文件
        processor: 'sass', // 处理器
    })
    .pipe(
        gulpif('*.png', gulp.dest('./src/sprity/'),  // 生成的雪碧图存放路径
        gulp.dest('./src/sprity/')) // 生成的icon存放路径
    );
});

写完后,我们执行gulp sprity,可以发现我们sprity文件夹下生成了一张sprity.png和_icon.scss文件,其内容如下:

$buy-discount-card: -0px -0px 76px 76px;
$buy-product: -0px -76px 76px 76px;
$buy-service: -0px -152px 76px 76px;
$buy-times-card: -0px -228px 76px 76px;
$home: -0px -304px 76px 76px;
@mixin sprite-width($sprite) {
  width: nth($sprite, 3);
}
@mixin sprite-height($sprite) {
  height: nth($sprite, 4);
}
@function sprite-width($sprite) {
   @return nth($sprite, 3);
}
@function sprite-height($sprite) {
   @return nth($sprite, 4);
}
@mixin sprite-position($sprite) {
  $sprite-offset-x: nth($sprite, 1);
  $sprite-offset-y: nth($sprite, 2);
  background-position: $sprite-offset-x $sprite-offset-y;
}
@mixin sprite($sprite, $display: block) {
   @include sprite-position($sprite);
  background-repeat: no-repeat;
  overflow: hidden;
  display: $display;
  @include sprite-width($sprite);
  @include sprite-height($sprite);
}

.icon {
  background-image: url('../sprity/sprite.png');
}

如果不用上传到cdn,那么我们就可以直接引用这个文件了,其用法如下:

@import '_icon.scss'; // 引入生成的雪碧图文件
 
.icon-discount-card { // 编写icon
  @include sprite($buy-discount-card); // 此处的变量为_icon.scss前面几行定义的变量,这些变量的名称都是根据icon文件名来生成
}

.icon-home {
  @include sprite($home);
}

如上代码所示,我们就写好了我们的icon文件,到时候直接使用 icon icon-home即可。你可能会觉得还要自己手写图标会很麻烦,sprity也支持直接生成图标,不过得自己手动去写对应的模板,有兴趣的可以网上找一下相关资料,此处不展开。

雪碧图文件已经生成了,我们下一步要做的就是将其上传到cdn,这里我们的做法是使用node自带的spawn来执行shell命令,而这个shell命令会把我们的雪碧图上传到cdn上。在有赞内部,我们使用superman这个工具,如果读者是上传到别的cdn服务器,应该也会有相应的命令上传配置,建议找一下cdn的文档。gulp上传雪碧图代码如下:

const replace = require('gulp-replace');
const { spawn } = require('child_process');

gulp.task('cdn', () => {
    const reg = /\/\/img\.yzcdn\.cn(.+)\.png/g; // 匹配上传的路径
    const sm = spawn('superman', ['cdn', './src/sprity/sprite.png']); // 执行上传命令
    sm.stdout.on('data', (data) => {
        const d =  reg.exec(data);
        if(d && d.length > 0) { // 根据返回值来匹配
            gulp.src(['./src/sprity/_icon.scss'])
                .pipe(replace(/\.\.\/sprity\/sprite\.png/g, d[0])) // 替换本地雪碧图
                .pipe(gulp.dest('./src/style/'));
        }
    });
});

以上步骤做完后,基本就大功告成了。如果更进一步,我们可以把生成的scss的px改为微信建议的rpx,代码如下:

if(d && d.length > 0) { // 根据返回值来匹配
    gulp.src(['./src/sprity/_icon.scss'])
        .pipe(replace(/\.\.\/sprity\/sprite\.png/g, d[0])) // 替换本地雪碧图
        .pipe(replace(/(-?)(\d+)px/g, ($1, $2, $3) => {
            return $2 + parseInt($3) * 2 + 'rpx';
        }))
        .pipe(gulp.dest('./src/style/'));
}

以上,我们就完成了在小程序中使用雪碧图,为了能让我们一边写代码,一边能看到相应的输出,我们可以通过gulp来watch我们的文件,当检测到变化时就重新生成一份代码到dist中。

点赞
收藏
评论区
推荐文章
橘子橙 橘子橙
4年前
vue-element-admin项目打包后,iconfont图标出现乱码
使用vueelementadmin或者vueelementtemplate开发的项目,打包到线上,就出现了图标乱码,f12后能看到icon元素为.eliconclose:before{content:"□"}的情况(如下)
CuterCorley CuterCorley
4年前
uni-app入门教程(9)字体库、自定义组件、打包和新闻实战
前言本文主要介绍了4方面内容:在uniapp项目中使用iconfont提供的图标字体库,美化页面;实现自定义组件,并且可以自定义属性和实现父子组件之间的消息传递;微信小程序预览和真机测试,APP端云打包和本地打包;新闻列表和详情实战练习。一、使用iconfont字体库uniapp中可以使用iconfont()提供的图标字体。大致过程如下:
浩浩 浩浩
4年前
【Flutter实战】图片和Icon
3.5图片及ICON3.5.1图片Flutter中,我们可以通过Image组件来加载并显示图片,Image的数据源可以是asset、文件、内存以及网络。ImageProviderImageProvider是一个抽象类,主要定义了图片数据获取的接口load(),从不同的数据源获取图片需要实现不同的ImageProvi
Stella981 Stella981
3年前
Shodan的http.favicon.hash语法详解与使用技巧
  在Shodan搜索中有一个关于网站icon图标的搜索语法,http.favicon.hash,我们可以使用这个语法来搜索出使用了同一icon图标的网站,不知道怎么用的朋友请参考我上一篇(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fmia
Easter79 Easter79
3年前
Taro小程序自定义顶部导航栏
微信自带的顶部导航栏是无法支持自定义icon和增加元素的,在开发小程序的时候自带的根本满足不了需求,分享一个封装好的组件,支持自定义icon、扩展dom,适配安卓、ios、h5,全面屏。我用的是京东的Taro多端编译框架写的小程序,原生的也可以适用,用到的微信/taro的api做调整就行,实现效果如下。!在这里插入图片描述(https://i
Stella981 Stella981
3年前
PhoneGap设置Icon
参考:http://cordova.apache.org/docs/en/latest/config\_ref/images.html通过config.xml中的<icon标签来设置Icon<iconsrc"res/ios/icon.png"platform"ios"width"57"height"57"densi
Wesley13 Wesley13
3年前
Vant Weapp 有赞小程序UI库 ICON 组件的本地图标路径支持
dist或lib组件文件夹下面的:wxs/utils.wxsvarbemrequire('./bem.wxs').bem;varmemoizerequire('./memoize.wxs').memoize;functionisSrc(url){returnurl.indexO
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
Unity横屏
Android下发现Unity里面的Player设置,并不能完全有效,比如打开了自动旋转,启动的时候还是会横屏,修改XML添加以下代码<applicationandroid:icon"@drawable/ic\_launcher"                    android:label"@string/app\_name"
Stella981 Stella981
3年前
JOptionPane修改图标
1.在Linux平台下.JOptionPane会显示Java默认的图标,在window平台不显示图标,如何替换这个图标了?2JOptionPane.setIcon(Icon)修改的是内容区域的icon,而不是左上角的Icon.所以需要通过修改Jdialog/Frame的图标来达到修改默认图标的问题.3.代码:if(JOptio
使用taro+canvas实现微信小程序的图片分享功能 | 京东云技术团队
业务场景二轮充电业务中,用户充电完成后在订单详情页展示订单相关信息,用户点击分享按钮唤起微信小程序分享菜单,将生成的图片海报分享给微信好友或者下载到本地,好友可通过扫描海报中的二维码加群领取优惠。使用场景及功能:微信小程序生成海报图片分享好友下载图片使用技