欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

如何在微信小程序中使用多色icon - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設/小程序開發(fā)/軟件開發(fā)

知識

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!

您當前位置>首頁 » 新聞資訊 » 小程序相關 >

如何在微信小程序中使用多色icon

發(fā)表時間:2021-3-15

發(fā)布人:葵宇科技

瀏覽次數(shù):102

背景

在微信小程序開發(fā)過程中難免會遇到需要使用多色icon的場景,項目中的icon一般存放在iconfont上。

iconfont有三種引用方式(參考 https://www.iconfont.cn/help/detail?spm=a313x.7781069.1998910419.d8cf4382a&helptype=code )

  • unicode引用:因為是字體,所以不支持多色
  • font-class引用:本質(zhì)上還是使用的字體,所以多色圖標還是不支持的
  • symbol引用:支持多色,使用svg渲染

但是微信小程序iconfont并不支持  標簽,只支持以background形式渲染.svg文件?;诖耍梢允褂肗ode編寫腳本,將iconfont項目里的多色icon下載到項目中,生成

.arrow-down--colorful {
    background: url('./arrow-down.[hash].svg');
}

// 或者有CDN的可以
.arrow-down--colorful {
    background: url('//[cdn]/imgs/arrow-down.[hash].svg');
}

步驟

步驟一、 上傳icon至iconfont

注意在上傳時,帶顏色的圖標需要有固定后綴來區(qū)分。例如普通icon為icon-name,則帶顏色的icon需要為icon-name--colorful

步驟二、腳本下載icon_**.css

使用Node下載項目對應的css腳本,格式為:

@font-face {font-family: "iconfont";
  src: url('//at.alicdn.com/t/font_**.eot?t=1571134856668');
  src: url('//at.alicdn.com/t/font_385238_**.eot?t=1571134856668#iefix') format('embedded-opentype'),
  url('data:application/x-font-woff2;**') format('woff2'),
  url('//at.alicdn.com/t/font_**.woff?t=**') format('woff'),
  url('//at.alicdn.com/t/font_**.ttf?t=**') format('truetype'),
  url('//at.alicdn.com/t/font_385238_**.svg?t=**#iconfont') format('svg');
}

.iconfont {
  font-family: "iconfont" !important;
  ...
}

.icon-name:before {
  content: "\e600";
}

.icon-name--colorful:before {
  content: "\e653";
}

刪除其中無用的font格式,以及帶--colorful的css定義。使用腳本將其格式化為

@font-face {font-family: "iconfont";
  src: url('data:application/x-font-woff2;**') format('woff2');
}

.iconfont {
  font-family: "iconfont" !important;
  ...
}

.icon-name:before {
  content: "\e600";
}

步驟三、腳本下載icon_**.js

使用Node下載項目對應的js腳本,格式為:

!function(o){var t,l='<svg><symbol id="icon-name” viewBox="0 0 1024 1024"><path …>path>symbol>symbol id="icon-name—colorful” viewBox="0 0 1024 1024"><path …>path>symbol>svg>’,…}(window);

提取出其中帶顏色(id以--colorful結(jié)尾)的標簽,使用xml解析工具,得到

"..." fill="..." >path><path d="..." fill="..." >path>

注意:如果步驟一不能實現(xiàn)按照--colorful區(qū)分是否是多色icon,則需要分析各個path的顏色是否一致來區(qū)分是否是多色。

拼接上  標簽

function getHash(cont: string) {
  return cryptoNode
    .createHash('md5')
    .update(cont)
    .digest('hex')
    .substr(0, 8);
}

步驟四、生成hash值及圖片文件

最終得到的svgStr的hash值

function getHash(cont: string) {
  return cryptoNode
    .createHash('md5')
    .update(cont)
    .digest('hex')
    .substr(0, 8);
}

使用hash值是為了避免更換icon但是不換名字的場景

生成本地圖片文件

const hash = getHash(svgStr);
const fileName = `${iconId}.${hash}.svg`;
const filePath = `${stylePath}${fileName}`;
fs.writeFileSync(filePath, svgStr);

步驟五、將圖片上傳至CDN并刪除本地文件(可選)

如果有CDN資源可以將圖片上傳至CDN,可以節(jié)約打包出的項目體積

uploadFileToCDN(filePath);

/** 將pathWithHash文件上傳到CDN */
async function uploadFileToCDN(pathWithHash: string) {
  return new Promise((resolve, reject) => {
    exec(
      `${此處為上傳至CDN的命令行}`,
      (error: any, stdout: any, stderr: any) => {
        if (error) {
          console.error(`exec error: ${error}`);
          reject(error);
          return;
        }
        resolve('');
        /** 刪除文件 */
        fs.unlinkSync(pathWithHash);
      }
    );
  });
}

步驟六、生成完整的css內(nèi)容并寫入本地

給步驟二的css文件拼接上帶顏色圖片的css內(nèi)容

@font-face {font-family: "iconfont";
  src: url('data:application/x-font-woff2;**') format('woff2');
}

.iconfont {
  font-family: "iconfont" !important;
  ...
}

.icon-name:before {
  content: "\e600";
}

.icon-name--colorful:before {
  background: url('cdnUrl');
}

并寫入本地

fs.writeFileSync(cssPath, fileContent.replace(/"/g, "'"), 'utf8');

完整的腳本文件示例

const http = require('http');
const cryptoNode = require('crypto');
const { exec } = require('child_process');
const xml2js = require('xml2js');
const fs = require('fs');
const config = {
  url: '//at.alicdn.com/t/font_***.js'
};
// 上傳至CDN后的前綴
const cdnPath = '***';
/** 生成的css文件path */
const cssPath = 'src/styles/iconfont.scss';
const stylePath = 'src/styles/';

const { parseString } = xml2js;

// 替換iconfont.scss
const iconfontUrl = config.url.replace(/.*\/\//, 'http://');
const iconfontUrl_css = iconfontUrl.replace('.js', '.css');

let fileContent = '';

type IPath = {
  $: {
    [key: string]: string;
  };
};

type ISymbol = {
  $: {
    id: string;
    viewBox: string;
  };
  path: IPath[];
};

/** 讀取css文件,去掉遠程連接 */
async function generateFile() {
  const cssData = http://www.wxapp-union.com/await readRemoteFile(iconfontUrl_css);
  fileContent = cssData.replace(/[^,;]*at.alicdn.com.*\*\//g, '');
  // 替換掉woff
  fileContent = fileContent.replace(/[^)]*at.alicdn.com.*\),/g, ';');
  // 替換掉colorful
  fileContent = fileContent.replace(/[^}]*colorful[^}]*}/g, '');
  // 替換src
  fileContent = fileContent.replace('url(', 'src: url(');
  // 加換行
  fileContent = fileContent.replace('{font-family', '{\n  font-family');
  // 加換行
  fileContent = fileContent.replace(') format(', ')\n    format(');
  // 去除最后一個換行
  fileContent = fileContent.replace(/\n$/, '');
  // 有顏色的圖標生成background: url('cdnUrl')
  const fontXml = await fetchXml(iconfontUrl);
  fontXml.svg.symbol.forEach((item: ISymbol) => {
    const iconId = item.$.id;
    if (/colorful/.test(iconId)) {
      let svgStr = '';
      item.path.forEach((path: IPath) => {
        const keys = Object.keys(path.$);
        let attrStr = '';
        keys.forEach(k => {
          attrStr += `${k}="${path.$[k]}" `;
        });
        svgStr = `${svgStr}${attrStr}>`;
      });
      svgStr = `${svgStr}`;
      const hash = getHash(svgStr);
      const fileName = `${iconId}.${hash}.svg`;
      const filePath = `${stylePath}${fileName}`;
      fs.writeFileSync(filePath, svgStr);
      uploadFileToCDN(filePath);
      svgStr = `\n.${iconId} {\n  background: url('${cdnPath}${fileName}');\n}\n`;
      fileContent += svgStr;
    }
  });
}

function getHash(cont: string) {
  return cryptoNode
    .createHash('md5')
    .update(cont)
    .digest('hex')
    .substr(0, 8);
}

async function uploadAndUpdate() {
  // 寫文件
  fs.writeFileSync(cssPath, fileContent.replace(/"/g, "'"), 'utf8');
}

generateFile().then(() => {
  uploadAndUpdate();
});

function readRemoteFile(remoteUrl: string): Promise<string> {
  let _data = http://www.wxapp-union.com/'';
  return new Promise(resolve => {
    http.get(remoteUrl, (res: any) => {
      //數(shù)據(jù)
      res.on('data', function(chunk: string) {
        _data += chunk;
      });

      res.on('end', function() {
        resolve(_data);
      });
    });
  });
}

async function fetchXml(
  url: string
): Promise<{
  svg: {
    symbol: ISymbol[];
  };
}> {
  const data = http://www.wxapp-union.com/await readRemoteFile(url);
  const matches = String(data).match(/'(.+?)<\/svg>'/);
  return new Promise((resolve, reject) => {
    parseString(`${matches ? matches[1] : ''}`, (err: any, result: any) => {
      if (err) {
        reject(err);
      } else {
        resolve(result);
      }
    });
  });
}

/** 將pathWithHash文件上傳到CDN */
async function uploadFileToCDN(pathWithHash: string) {
  return new Promise((resolve, reject) => {
    exec(`${此處為上傳至CDN的命令行}`, (error: any, stdout: any, stderr: any) => {
      if (error) {
        console.error(`exec error: ${error}`);
        reject(error);
        return;
      }
      resolve('');
      /** 刪除文件 */
      fs.unlinkSync(pathWithHash);
      console.log(`stdout: ${stdout}`);
      console.error(`stderr: ${stderr}`);
    });
  });
}

再在 package.json 中的scripts中配置

"icon": "ts-node scripts/iconfont.ts"

則每次更新iconfont后,更新對應的url,再運行 npm run icon 即可

相關案例查看更多