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

2020-11-19  本文已影响0人  賣女孩的小火柴

第一步:新建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和上面的一样哟,代码就到此为止了,大家可直接使用。

上一篇下一篇

猜你喜欢

热点阅读