JSDM

HTML

 
1
<div> <a href="https://github.com/niezhiliang/canvas-draw-seal" target="_blanl">github</a></div>
2
<div style="text-align: center">
3
    <img id="img"/>
4
</div>
5
6
<div style="text-align: center">
7
    <img id="img2"/>
8
</div>
9
10
11
<div style="text-align: center">
12
    <img id="img3"/>
13
</div>
14
15
<div style="text-align: center">
16
    <img id="img4"/>
17
</div>
18

CSS

xxxxxxxxxx
1
 
1
? ?
? ?
必须是有效的URL
+ 添加另一个资源

JS

xxxxxxxxxx
461
 
1
"use strict";
2
3
var FXQ = {
4
5
    //签章颜色定义
6
    colors: ['red','blue','#000'],
7
8
//签章字体定义
9
    fonts: ['SimSun','YouYuan','KaiTi'],
10
11
12
    baseConf: {
13
        color: null,
14
        font: null,
15
    },
16
17
    commonMethod: function(cType,fType) {
18
19
        var color = null;
20
        color = this.colors[cType];
21
        if (color === undefined || color == 'undefined') {
22
            color = this.colors[0];
23
        }
24
25
        var font = this.fonts[fType];
26
        if (font === undefined || font == 'undefined') {
27
            font = this.fonts[0];
28
        }
29
30
        this.baseConf.color = color;
31
        this.baseConf.font = font;
32
33
    },
34
35
    /**
36
     *
37
     * @param company 公司名称
38
     * @param cType 颜色 0.红  1. 蓝色 2.其他
39
     * @param fType 字体 0.宋体
40
     * @param sType 签章类型 0.公章 1.合同专用章
41
     * @param seaNo  这个是签章的序列号
42
     */
43
    companySeal: function (company,cType,fType,sType,seaNo) {
44
45
        //获取canvans doc对象
46
       // var canvas = document.getElementById('canvas');
47
        var canvas = document.createElement("canvas");
48
49
        var context = canvas.getContext('2d');
50
        canvas.width = 300;
51
        canvas.height = 300;
52
53
        this.commonMethod(cType,fType);
54
55
        var width = canvas.width/2;
56
        var height = canvas.height/2;
57
58
        //画圆方法
59
        drawCircle()
60
61
        draw5Start(30,0)
62
63
        drawTitle();
64
65
        writeSerNo(seaNo)
66
67
        writeFont(company)
68
69
        //返回图片base64
70
        return canvas.toDataURL();
71
72
73
74
        /**
75
         * 画圆的方法
76
         * color : 圆边框的颜色
77
         * lineWidth: 线条宽度
78
         */
79
        function drawCircle() {
80
            context.translate(0,0);
81
            context.lineWidth = 5;
82
            context.strokeStyle=FXQ.baseConf.color;
83
            context.beginPath();
84
            context.arc(width,height,110,0,Math.PI*2);
85
            context.stroke();
86
            context.save();
87
            var data = canvas.toDataURL("image/jpeg")
88
            console.log(canvas);
89
        }
90
91
        /**
92
         * 绘制五角星
93
         * @param sx
94
         * @param sy
95
         * @param radius
96
         * @param color
97
         * @param rotato
98
         */
99
        function draw5Start() {
100
            context.save();
101
            context.fillStyle=FXQ.baseConf.color;
102
            //移动坐标原点  中心点开始绘制
103
            context.translate(width,height);
104
            //旋转
105
            context.rotate(Math.PI);
106
            context.beginPath();
107
            var dig = Math.PI/5*4
108
            for (var i = 0; i < 5; i++) {
109
                var x = Math.sin(i*dig);
110
                var y = Math.cos(i*dig);
111
                context.lineTo(x*30,y*30);
112
            }
113
            context.closePath();
114
            context.stroke();
115
            context.fill();
116
            context.restore();
117
        }
118
119
120
        /**
121
         * 绘制公章标题
122
         */
123
        function drawTitle() {
124
125
            var title = '';
126
            if (sType != 0) {
127
128
                title = '合同专用章';
129
            }
130
131
            // 绘制印章名称
132
            context.font = 'bolder 20px '+FXQ.baseConf.font;
133
            context.textBaseline = 'middle';//设置文本的垂直对齐方式
134
            context.textAlign = 'center'; //设置文本的水平对对齐方式
135
            context.lineWidth=1;
136
            context.fillStyle = FXQ.baseConf.color;
137
            context.fillText(title,width,height+65);
138
        }
139
140
        /**
141
         * 绘制公司名称
142
         */
143
        function writeFont() {
144
            context.font = 'bolder 30px '+FXQ.baseConf.font;
145
            var count = company.length;// 字数
146
            var angle = -4*Math.PI/(3*(count - 1));// 字间角度
147
            var chars = company.split("");
148
            var trueChars = chars.reverse();
149
            var c;
150
            for (var i = 0; i < count; i++){
151
                c = trueChars[i];// 需要绘制的字符
152
                if(i==0)
153
                    context.rotate(5*Math.PI/6.1);
154
                else
155
                    context.rotate(angle);
156
                context.save();
157
                context.translate(95, 0);// 平移到此位置,此时字和x轴垂直,第一个参数是与圆外边的距离,越大距离越近
158
                context.rotate(Math.PI/2);// 旋转90度,让字平行于x轴
159
                context.fillText(c,0, 5);// 此点为字的中心点
160
                context.restore();
161
            }
162
163
        }
164
165
        /**
166
         * 绘制签章序列号
167
         * @param serNo
168
         */
169
        function writeSerNo(serNo) {
170
            context.translate(width, height);
171
            context.font = 'bolder 8px '+FXQ.baseConf.font;
172
            var count = serNo.length;// 字数
173
            var angle = -2 * Math.PI / (6 * (count - 1));// 字间角度
174
            var chars = serNo.split("");
175
176
            for (var i = 0; i < count; i++) {
177
                var c = chars[i];// 需要绘制的字符
178
                if (i == 0)
179
                    context.rotate(10 * Math.PI / 5.95);
180
                else
181
                    context.rotate(angle);
182
                context.save();
183
                context.translate(-95, 5);// 平移到此位置,此时字和x轴垂直,第一个参数是与圆外边的距离,越大距离越近
184
                context.rotate(Math.PI / 2);// 旋转90度,让字平行于x轴
185
                context.fillStyle = FXQ.baseConf.color;
186
                context.fillText(c, 0, 5);// 此点为字的中心点
187
                context.restore();
188
            }
189
        }
190
    },
191
    /**
192
     * 绘制个人签章
193
     * @param name 姓名
194
     * @param cType 字体颜色
195
     * @param fType 字体
196
     * @param type 类型
197
     */
198
    personal: function (name,cType,fType,type,border) {
199
        this.commonMethod(cType,fType);
200
        var color = FXQ.baseConf.color;
201
        var font = FXQ.baseConf.font;
202
        //获取canvans doc对象
203
        //var canvas = document.getElementById('canvas');
204
        var canvas = document.createElement("canvas");
205
        var context = canvas.getContext('2d');
206
        canvas.width = 120;
207
        canvas.height = 120;
208
        var length = name.length;
209
        //长方形前面
210
        if (type == 0) {
211
            console.log(context.width)
212
            //要边框
213
            if (border == 0) {
214
                context.rect(5, 5, 100, 50);
215
                context.strokeStyle = color;
216
                context.lineWidth = 4
217
                context.stroke();
218
            }
219
            // 绘制印章名称
220
            context.font = '30px '+font;
221
            if (length > 3)
222
            {
223
                context.font = '24px '+font;
224
            }
225
            context.textBaseline = 'middle';//设置文本的垂直对齐方式
226
            context.textAlign = 'center'; //设置文本的水平对对齐方式
227
            context.lineWidth=1;
228
            context.fillStyle = color;
229
            context.textAlign = 'center'; //设置文本的水平对对齐方式
230
            context.fillText(name,55,30);
231
232
        } else {//正方形
233
            var personal = '';
234
            switch (name.length) {
235
                case 3:
236
                    name += '印';
237
                    break;
238
                case 2:
239
                    name += '之印';
240
                default:
241
                    break;
242
243
            }
244
            var names = name.split('');
245
            personal = names[2]+names[0]+names[3]+names[1];
246
            //要边框
247
            if (border == 0) {
248
                context.rect(2,2,108,108);
249
                context.strokeStyle=color;
250
                context.lineWidth=2
251
                context.stroke();
252
            }
253
254
            // 绘制印章名称
255
            context.font = '40px '+font;
256
            context.fillStyle = color;
257
            this.wrapText(context,personal,8,45,80,40)
258
259
        }
260
        //返回图片base64
261
        return canvas.toDataURL();
262
    },
263
    //椭圆签章
264
    companyEllipse: function (company,serNo,fType,cType) {
265
266
        //椭圆长轴半径
267
        var radiusX = 140;
268
        //短轴半径
269
        var radiusY = 90;
270
        this.commonMethod(cType,fType);
271
        var color = FXQ.baseConf.color;
272
        var font = FXQ.baseConf.font;
273
274
        //var canvas = document.getElementById('canvas');
275
        var canvas = document.createElement("canvas");
276
277
        canvas.width = 300;
278
        canvas.height = 300;
279
280
        canvas.width = 2 * radiusX + 5;
281
        canvas.height = 2 * radiusY + 5;
282
283
        var context = canvas.getContext('2d');
284
285
        writeFont(true,company);
286
        writeFont(false,serNo);
287
        writeTitle();
288
        drawEllipse();
289
290
        function writeFont(isTop,words) {
291
292
            var totalArcAng = 180;
293
            font = "20px "+font
294
295
            //字体长度
296
            if (!isTop) {
297
                totalArcAng = 60;
298
                font = "10px "+font
299
            }
300
            var fontTextLen = words.length;
301
302
            var radiusWidth = radiusX + context.lineWidth;
303
            var radiusHeight = radiusY + context.lineWidth;
304
305
            //从边线向中心的移动因子
306
            var minRat = 0.9;
307
            //起始角度
308
            var startAngle = isTop == true ? -90 -totalArcAng/2 : 90 - totalArcAng/2;
309
            var step = 0.5;
310
            var alCount = Math.ceil(totalArcAng / step) + 1;
311
            var angleArr = new Array(alCount);
312
            var arcLenArr = new Array(alCount);
313
            var num = 0;
314
            var accArcLen = 0;
315
            angleArr[num] = startAngle;
316
            arcLenArr[num] = accArcLen;
317
            num++;
318
            var angR = startAngle * Math.PI / 180;
319
            var lastX = radiusX * Math.cos(angR) + radiusWidth;
320
            var lastY = radiusY * Math.sin(angR) + radiusHeight;
321
322
            for (var i = startAngle + step; num < alCount; i+=step) {
323
                angR = i * Math.PI / 180;
324
                var x = radiusX * Math.cos(angR) + radiusWidth;
325
                var y = radiusY * Math.sin(angR) + radiusHeight;
326
                accArcLen += Math.sqrt((lastX - x) * (lastX - x) + (lastY - y) * (lastY - y));
327
                angleArr[num] = i;
328
                arcLenArr[num] = accArcLen;
329
                lastX = x;
330
                lastY = y;
331
                num++;
332
            }
333
334
            var arcPer = accArcLen / fontTextLen;
335
            for (var i = 0; i < fontTextLen; i++) {
336
                var arcL = i * arcPer + arcPer / 2;
337
                var ang = 0;
338
339
                for (var p = 0; p < arcLenArr.length - 1; p++) {
340
                    if (arcLenArr[p] <= arcL && arcL <= arcLenArr[p + 1]) {
341
                        ang = (arcL >= ((arcLenArr[p] + arcLenArr[p + 1]) /2)) ? angleArr[p + 1] : angleArr[p];
342
                        break;
343
                    }
344
                }
345
                angR = (ang * Math.PI / 180);
346
                var x = radiusX * Math.cos(angR) + radiusX;
347
                var y = radiusY * Math.sin(angR) + radiusY;
348
                var qxang = Math.atan2(radiusY * Math.cos(angR),-radiusX * Math.sin(angR));
349
                var fxang = qxang + Math.PI / 2;
350
351
                var subIndex = isTop == true ? i : fontTextLen - 1 -i;
352
                var c = words[subIndex];
353
                var w = 25; var h = 31;
354
355
                if (!isTop) {
356
                    w = 2; h = 10;
357
                }
358
359
                x += (h * minRat) * Math.cos(fxang);
360
                y += (h * minRat) * Math.sin(fxang);
361
                if (isTop) {
362
                    x += -w / 2 * Math.cos(qxang);
363
                    y += -w / 2 * Math.sin(qxang);
364
                } else {
365
                    x += w / 2 * Math.cos(qxang);
366
                    y += w / 2 * Math.sin(qxang);
367
                }
368
369
                context.save()
370
                context.translate(x,y);
371
                if (isTop == true) {
372
                    context.rotate((fxang * 180 / Math.PI - 90) * Math.PI / 180)
373
                } else {
374
                    context.rotate((fxang * 180 / Math.PI + 180 -90)* Math.PI / 180)
375
                }
376
                context.translate(-x,-y)
377
                context.fillStyle = color;
378
                context.font = font;
379
                context.fillText(c,x,y);
380
                context.restore();
381
            }
382
        }
383
384
        function writeTitle() {
385
            context.fillStyle = color;
386
            context.font = '20px SimSun';
387
            context.textAlign = 'center';
388
            context.fillText('合同专用章',radiusX,radiusY+20);
389
            context.restore();
390
        }
391
392
        function drawEllipse() {
393
            context.ellipse(radiusX + context.lineWidth+1,radiusY + context.lineWidth+1,radiusX,radiusY,0,0,Math.PI*2);
394
            //背景透明
395
            context.fillStyle = "rgba(255, 255, 255, 0)";
396
            context.strokeStyle = color;
397
            context.lineWidth = 3;
398
            context.fill();
399
            context.stroke();
400
        }
401
402
        //返回图片base64
403
        return canvas.toDataURL();
404
    },
405
    /**
406
     * 字体换行
407
     * */
408
    wrapText: function (ctx,text, x, y, maxWidth, lineHeight) {
409
        if (typeof text != 'string' || typeof x != 'number' || typeof y != 'number') {
410
            return;
411
        }
412
413
        var context = ctx;
414
        var canvas = context.canvas;
415
416
        if (typeof maxWidth == 'undefined') {
417
            maxWidth = (canvas && canvas.width) || 112;
418
        }
419
        if (typeof lineHeight == 'undefined') {
420
            lineHeight = (canvas && parseInt(window.getComputedStyle(canvas).lineHeight)) || parseInt(window.getComputedStyle(document.body).lineHeight);
421
        }
422
423
        // 字符分隔为数组
424
        var arrText = text.split('');
425
        var line = '';
426
427
        for (var n = 0; n < arrText.length; n++) {
428
            var testLine = line + arrText[n];
429
            var metrics = context.measureText(testLine);
430
            var testWidth = metrics.width;
431
            if (testWidth > maxWidth && n > 0) {
432
                context.fillText(arrText[0], x, y);
433
                context.fillText(arrText[1], x+50, y);
434
                line = arrText[n];
435
                y += lineHeight;
436
            } else {
437
                line = testLine;
438
            }
439
        }
440
        context.fillText(arrText[2], x, y+10);
441
        context.fillText(arrText[3], x+50, y+10);
442
    }
443
};
444
445
446
447
448
449
//var base64 = FXQ.companySeal('浙江葫芦娃网络集团有限公司',0,0,0,'2018-12-19')
450
    //FXQ.companySeal('某某某网络集团有限公司',0,0,0,'1234xyz')
451
    var base64 = FXQ.companyEllipse('某某某网络集团有限公司','1234567899876',0,0)
452
    //var base64 = FXQ.personal("李易峰",0,0,0,0);
453
    //FXQ.personal("赵丽颖",0,0,0,1);
454
    //var base64 = FXQ.personal("易烊千玺",1,1,1,0);
455
    //FXQ.personal("王源",0,1,1,0);
456
    //var base64 = FXQ.personal("李易峰",0,1,1,0);
457
    //FXQ.personal("王俊凯",0,1,1,1);
458
    document.getElementById('img').src=base64;
459
    document.getElementById('img2').src=FXQ.companySeal('浙江葫芦娃网络集团有限公司',0,0,0,'2018-12-19');
460
document.getElementById('img3').src=FXQ.companySeal('某某某网络集团有限公司',0,0,1,'1234xyz');
461
document.getElementById('img4').src=FXQ.personal("赵丽颖",0,0,0,0);
必须是有效的URL
+ 添加另一个资源
Close

文件管理 点击文件查看URL

图片

  1. 暂无文件

CSS

  1. 暂无文件

JavaScript

  1. 暂无文件

其他

  1. 暂无文件
拖动文件到上面的区域或者:
加载中 ..................