vue横向文与下弦文圆形和椭圆公章

第一步:新建paintingSeal.js文件,文件内容如下:

"use strict";

let Seal = {

    //签章颜色定义

    colors: ['red', 'blue', '#000'],

    //签章字体定义

    fonts: ['宋体', 'YouYuan', 'KaiTi'],

    baseConf: {

        color: null,

        font: null,

    },

    commonMethod(cType, fType) {

        let color = null;

        color = this.colors[cType];

        if (color === undefined || color == 'undefined') {

            color = this.colors[0];

        }

        let font = this.fonts[fType];

        if (font === undefined || font == 'undefined') {

            font = this.fonts[0];

        }

        this.baseConf.color = color;

        this.baseConf.font = font;

    },

    /**

    *

    * @param company 公司名称

    * @param sType 横向文

    * @param seaNo 下弦文

    * @param cType 颜色 0.红  1. 蓝色 2.其他

    * @param fType 字体 0.宋体

    */

    companySeal: function (company, sType, seaNo, cType, fType) {

        var canvas = document.createElement("canvas");

        var context = canvas.getContext('2d');

        canvas.width = 200;

        canvas.height = 200;

        this.commonMethod(cType, fType);

        let width = canvas.width / 2;

        let height = canvas.height / 2;

        //画圆方法

        drawCircle()

        draw5Start(width, height)

        drawTitle();

        writeCompany()

        writeSeaNo()

        //返回图片base64

        return canvas.toDataURL();

        function drawCircle() {

            context.lineWidth = 5;

            context.strokeStyle = Seal.baseConf.color;

            context.beginPath();

            context.arc(width, height, 90, 0, Math.PI * 2); //宽、高、半径

            context.stroke();

        }

        function draw5Start(sx, sy) {

            context.save();

            context.fillStyle = Seal.baseConf.color;

            context.translate(sx, sy); //移动坐标原点

            context.rotate(Math.PI); //旋转

            context.beginPath(); //创建路径

            var dig = (Math.PI / 5) * 4;

            for (var i = 0; i < 5; i++) {

                //画五角星的五条边

                var x = Math.sin(i * dig);

                var y = Math.cos(i * dig);

                context.lineTo(x * 20, y * 20);

            }

            context.closePath();

            context.stroke();

            context.fill();

            context.restore();

        }

        function drawTitle() {

            context.font = '12px ' + Seal.baseConf.font;

            context.textBaseline = "middle"; //设置文本的垂直对齐方式

            context.textAlign = "center"; //设置文本的水平对对齐方式

            context.lineWidth = 1;

            context.strokeStyle = Seal.baseConf.color;

            context.strokeText(sType, width, height + 45);

        }

        function writeCompany() {

            context.translate(width, height); // 平移到此位置,

            context.font = '18px ' + Seal.baseConf.font;

            var count1 = company.length; // 字数

            var angle1 = (6 * Math.PI) / (5 * (count1 - 1)); // 字间角度

            var chars1 = company.split("");

            var c1;

            for (var i = 0; i < count1; i++) {

                c1 = chars1[i]; // 需要绘制的字符

                if (i == 0) {

                    context.rotate((19 * Math.PI) / 21);

                } else {

                    context.rotate(angle1);

                }

                context.save();

                context.translate(75, 0); // 平移到此位置,此时字和x轴垂直,公司名称和最外圈的距离

                context.rotate(Math.PI / 2); // 旋转90度,让字平行于x轴

                context.strokeText(c1, 0, 0); // 此点为字的中心点

                context.restore();

            }

        }

        function writeSeaNo() {

            context.translate(0, 0); // 平移到此位置,

            context.font = '12px ' + Seal.baseConf.font;

            var count = seaNo.length; // 字数

            var angle = (-3 * Math.PI) / (5 * (count - 1)); // 字间角度

            var chars = seaNo.split("");

            var c;

            for (var i = 0; i < count; i++) {

                c = chars[i]; // 需要绘制的字符

                if (i == 0) {

                    context.rotate((7 * Math.PI) / 10);

                } else {

                    context.rotate(angle);

                }

                context.save();

                context.translate(80, 0); // 平移到此位置,此时字和x轴垂直,公司名称和最外圈的距离

                context.rotate((Math.PI * 3) / 2); // 旋转90度,让字平行于x轴

                context.strokeText(c, 0, 0); // 此点为字的中心点

                context.restore();

            }

        }

    },

    /**

    *

    * @param company 公司名称

    * @param sType 横向文

    * @param seaNo 下弦文

    * @param cType 颜色 0.红  1. 蓝色 2.其他

    * @param fType 字体 0.宋体

    */

    companyEllipse: function (company, sType, seaNo, cType, fType) {

        //椭圆长轴半径

        var radiusX = 200;

        //短轴半径

        var radiusY = 125;

        this.commonMethod(cType, fType);

        var color = Seal.baseConf.color;

        var font = Seal.baseConf.font;

        var canvas = document.createElement("canvas");

        canvas.width = 200;

        canvas.height = 200;

        canvas.width = 2 * radiusX + 5;

        canvas.height = 2 * radiusY + 5;

        var context = canvas.getContext('2d');

        writeFont(true, company);

        writeFont(false, seaNo);

        writeTitle();

        drawEllipse();

        return canvas.toDataURL();

        function drawEllipse() {

            context.ellipse(radiusX + context.lineWidth + 1, radiusY + context.lineWidth + 1, radiusX, radiusY, 0, 0, Math.PI * 2);

            //背景透明

            context.fillStyle = "rgba(255, 255, 255, 0)";

            context.strokeStyle = color;

            context.lineWidth = 5;

            context.fill();

            context.stroke();

        }

        function writeFont(isTop, words) {

            var totalArcAng = 270;

            let f = ""

            //字体长度

            if (!isTop) {

                totalArcAng = 90;

                f = "20px " + font

            } else {

                f = "30px " + font

            }

            var fontTextLen = words.length;

            var radiusWidth = radiusX + context.lineWidth;

            var radiusHeight = radiusY + context.lineWidth;

            //从边线向中心的移动因子

            var minRat = 1.1;

            //起始角度

            var startAngle = isTop == true ? -90 - totalArcAng / 2 : 90 - totalArcAng / 2;

            var step = 0.5;

            var alCount = Math.ceil(totalArcAng / step) + 1;

            var angleArr = new Array(alCount);

            var arcLenArr = new Array(alCount);

            var num = 0;

            var accArcLen = 0;

            angleArr[num] = startAngle;

            arcLenArr[num] = accArcLen;

            num++;

            var angR = startAngle * Math.PI / 180;

            var lastX = radiusX * Math.cos(angR) + radiusWidth;

            var lastY = radiusY * Math.sin(angR) + radiusHeight;

            for (var i = startAngle + step; num < alCount; i += step) {

                angR = i * Math.PI / 180;

                var x = radiusX * Math.cos(angR) + radiusWidth;

                var y = radiusY * Math.sin(angR) + radiusHeight;

                accArcLen += Math.sqrt((lastX - x) * (lastX - x) + (lastY - y) * (lastY - y));

                angleArr[num] = i;

                arcLenArr[num] = accArcLen;

                lastX = x;

                lastY = y;

                num++;

            }

            var arcPer = accArcLen / fontTextLen;

            for (var i = 0; i < fontTextLen; i++) {

                var arcL = i * arcPer + arcPer / 2;

                var ang = 0;

                for (var p = 0; p < arcLenArr.length - 1; p++) {

                    if (arcLenArr[p] <= arcL && arcL <= arcLenArr[p + 1]) {

                        ang = (arcL >= ((arcLenArr[p] + arcLenArr[p + 1]) / 2)) ? angleArr[p + 1] : angleArr[p];

                        break;

                    }

                }

                angR = (ang * Math.PI / 180);

                var x = radiusX * Math.cos(angR) + radiusX;

                var y = radiusY * Math.sin(angR) + radiusY;

                var qxang = Math.atan2(radiusY * Math.cos(angR), -radiusX * Math.sin(angR));

                var fxang = qxang + Math.PI / 2;

                var subIndex = isTop == true ? i : fontTextLen - 1 - i;

                var c = words[subIndex];

                var w = 25; var h = 31;

                if (!isTop) {

                    w = 2; h = 10;

                }

                x += (h * minRat) * Math.cos(fxang);

                y += (h * minRat) * Math.sin(fxang);

                if (isTop) {

                    x += -w / 2 * Math.cos(qxang);

                    y += -w / 2 * Math.sin(qxang);

                } else {

                    x += w / 2 * Math.cos(qxang);

                    y += w / 2 * Math.sin(qxang);

                }

                context.save()

                context.translate(x, y);

                if (isTop == true) {

                    context.rotate((fxang * 180 / Math.PI - 90) * Math.PI / 180)

                } else {

                    context.rotate((fxang * 180 / Math.PI + 180 - 90) * Math.PI / 180)

                }

                context.translate(-x, -y)

                context.fillStyle = color;

                context.font = f;

                context.fillText(c, x, y);

                context.restore();

            }

        }

        function writeTitle() {

            context.fillStyle = color;

            context.font = 'bolder 24px ' + Seal.baseConf.font;

            context.textAlign = 'center';

            context.fillText(sType, radiusX, radiusY + 65);

            context.restore();

        }

    }

}

export default Seal

第二步:导入新建的js文件

import Seal from "当前文件路径(需要自己改哦,别直接复制运行哟)";

第三步:使用

圆形公章:

let src = Seal.companySeal(

        "公司名字",

        "横向文",

        "下弦文",

        0,

        0

      );

注:src为base64图片字符串,直接可用img标签加载

椭圆公章:

let src = Seal.companyEllipse(

        "公司名字",

        "横向文",

        "下弦文",

        0,

        0

      );

src和上面的一样哟,代码就到此为止了,大家可直接使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容