zoukankan      html  css  js  c++  java
  • nodejs iconfont处理

    做前端优化,iconfont可以替换掉很多图片,减少请求,并有很好的兼容性,颜色大小也有很好的自由度。现在网上已经有很多公开的iconfont供我们使用。但是每个项目有不同的应用场景,网上的并不能满足所有的需求。设计在出ps的有很多svg的图标。

    在线的矢量图标库,我们熟知的,http://www.iconfont.cn/,国内功能很强大且图标内容很丰富的矢量图标库。

    可是我们自己做项目,每次都要上传iconfont,再下载最新的,要操作好多。表示本人是个懒人,操作了几遍就感觉生命在浪费。

    最近在整理,nodejs gulp相关的插件,编写符合业务活动开发的gulp脚本,加快开发,并且前端优化。

    所以就想着nodejs有没网络字体处理

    font-carrier https://github.com/purplebamboo/font-carrier

    用起来很简单,首先定义好适合项目的文件目录格式

    //api参数说明
    icon({
        isWatch: true, //是否启动watch,监控更改
        template: __dirname + "/_fonts_demo.tmpl", //产生的预览html模版
        path: './qnk/font', //项目的font目录
      fontName: 'iconfont', //字体文字
      beginNum: 0xe001 //字体开始的最小值
    })

    //基于 模块chokidar 进行文件监控 path+'/*.svg'文件
    //在svg文件新增,修改,删除的,会调用font.setSvg,更新字体信息,并更新对应的json配置,用于下次的恢复svg与unicode关系
    //会实时生成 {fontName}.html 进行字体效果预览,该文件通过template生成,使用的模版语言是handlebars

    下面看主要代码,现在的代码没有封装模块,主要是功能还有些欠缺

    现在的功能是实时发布 矢量图标库,开发的时候,还是需要通过查看{fontName}.html,进行html编写

    后期进一步结合项目情况,生成项目可以用的html模版,iconfont配置变量,在html的时候只需要根据svg文件名,编写,如{{我的红包}}

    var fontCarrier = require('font-carrier')
    var chokidar = require('chokidar');
    var sysPath = require('path');
    var Handlebars = require('handlebars');
    var fs = require('fs');
    var glob = require('glob')
    
    
    //makeWatch ready前会有add响应,所以增加参数进行屏蔽
    var makeWatch = function (flies, done) {
        var files = [];
        var _isdone = -1;
        var watcher = chokidar.watch(flies, {
            ignored: /[/\]./,
            persistent: true
        });
        watcher.on('add', path => {
            if (_isdone == -1) {
                files.push(path);
            } else if (_isdone == 1) {
                done('add', path);
            }
        }).on('change', path => {
            if (_isdone == 1) {
                done('change', path);
            }
        }).on('unlink', path => {
            if (_isdone == 1) {
                done('remove', path);
            }
        }).on('ready', function() {
            _isdone = 1;
            done('ready', files);
        })
        return watcher;
    };
    
    //defaults默认数值
    var defaults = {
        beginNum: 0xe001,
        template: '<style>@font-face {font-family: "{{fontName}}";src: url("{{fontName}}.eot?t={{now}}"); src: url("{{fontName}}.eot?t={{now}}#iefix") format("embedded-opentype"),url("{{fontName}}.woff?t={{now}}") format("woff"),url("{{fontName}}.ttf?t={{now}}") format("truetype"),url("{{fontName}}.svg?t={{now}}#{{fontName}}") format("svg");}/n
    .{{fontName}} {font-family:"{{fontName}}" !important;font-size:16px;font-style:normal;-webkit-font-smoothing: antialiased;-webkit-text-stroke- 0.2px;-moz-osx-font-smoothing: grayscale;}</style>/n
    <ul class="icon_lists clear">{{#each data}}<li><i class="icon {{../fontName}}">&#x{{val}};</i><div class="name">{{name}}</div><div class="code">&amp;#x{{val}};</div></li>{{/each}}</ul>',
        fontName: 'iconfont'
    };
    
    //通过现有的json配置 和 文件夹实际的svg目录,进行数据修正,获取正确的beginNum
    var getExistsFontMap = function (map, dirPath, beginNum) {
        var files = glob.sync(dirPath + '/*.svg');
        var fileMap = {};
        var res = {};
        files.forEach(function (f) {
            fileMap[sysPath.basename(f, '.svg')] = f;
        })
        for (var key in map) {
            if (!fileMap[key])
                delete map[key];
        }
        var _bNum;
        for (var key in map) {
            _bNum = map[key];
            break;
        }
        _bNum = _bNum || beginNum;
        for (var key in map) {
            if (map[key] >= _bNum) {
                _bNum = map[key] + 1;
            }
        }
        for (var key in fileMap) {
            res[key] = map[key] || _bNum++;
        }
        return {
            fontMap: res,
            beginNum: _bNum
        }
    }
    
    //模块主方法
    var icon = function (opts) {
        var font = fontCarrier.create();//创建字体
        var bNum = opts.beginNum || defaults.beginNum;
        var template;
        var fontMap = {};
        if (opts.template) {
            template = Handlebars.compile(fs.readFileSync(opts.template).toString());
        } else {
            template = Handlebars.compile(defaults.template);
        }
        var path = opts.path;
        if (!path) {
            throw new Error('must set path option.')
        }
        var fontPath = path;
        var fontName = opts.fontName || defaults.fontName;
        var dirPath = fontPath + '/svg';
        var jsonPath = dirPath + '/' + fontName + '.json';
        
        //字体信息保存
        var save = function (action) {
            //字体保存
            font.output({
                path: fontPath + '/' + fontName
            })
            //配置保存
            fs.writeFileSync(jsonPath, JSON.stringify(fontMap));
            var tab = [];
            for (var key in fontMap) {
                tab.push({name: key, val: fontMap[key].toString(16)})
            }
            //预览文件保存
            fs.writeFile(fontPath + '/' + fontName + '.html', template({data: tab, fontName: fontName, now: +new Date}), (err) => {
                if (err) throw err;
            });
        };
        var setSvg = function (flie, key) {
            fs.readFile(flie, (err, data) => {
                if (err) {
                    throw err;
                }
                font.setSvg('&#x' + key.toString(16) + ';', data.toString());
                save();
            });
        };
        
        var fileExists = fs.existsSync(jsonPath);
        var map = {};
        if (fileExists) {
            map = JSON.parse(fs.readFileSync(jsonPath).toString());
        }
        var res = getExistsFontMap(map, dirPath, bNum);
        fontMap = res.fontMap;
        bNum = res.beginNum;
        for (var fileName in fontMap) {
            font.setSvg('&#x' + fontMap[fileName].toString(16) + ';', fs.readFileSync(dirPath + '/' + fileName + '.svg').toString());
        }
        save();
        
        //watch 文件修改逻辑
        if (opts.isWatch) {
            return makeWatch(dirPath + '/*.svg', function (action, flie) {
                if (action == 'ready') {
                } else if (action == 'change' || action == 'add') {
                    var fileName = sysPath.basename(flie, '.svg');
                    var n = fontMap[fileName] = fontMap[fileName] || bNum++;
                    //**文件存在busy状态,延时1秒读取文件,不能解决根本问题
                    setTimeout(function () {
                        setSvg(flie, n);
                    }, 1000);
                } else if (action == 'remove') {
                    var fileName = sysPath.basename(flie, '.svg');
                    font.setSvg('&#x' + fontMap[fileName].toString(16) + ';', '');
                    delete fontMap[fileName];
                    save(action);
                }
            })
        }
    };
    icon({
        isWatch: true,
        template: __dirname + "/_fonts_demo.tmpl",
        path: './v3-mobile-snail-com/qnk/font'
    })
  • 相关阅读:
    ArcGIS Server 10.2 安装教程
    leaflet 使用kriging.js实现前端自定义插值
    气象科普 -降水
    前端开发者如何用JS开发后台
    Spring的简单介绍
    Hibernate与jsp技术结合的小例子
    Servlet_001 我的第一个servlet程序
    Hibernate一级缓存和三种状态
    github提交代码
    MySql索引原理以及查询优化
  • 原文地址:https://www.cnblogs.com/legu/p/5817622.html
Copyright © 2011-2022 走看看