class Share {
constructor(options = {} as any) {
(<any>this).picArr = [];
}
public createPic() {
let _this: any = this;
if (!_this.sharepic) {
_this.sharepic = document.createElement('div');
_this.sharepic.className = 'draw-img-cover';
_this.sharepic.innerHTML = `<div class="share-pic-box">\
<div class="close"></div>\
<div class="share-pic-box"><div id="shareCanvas"></div></div>\
<p class="save-share-card">保存图片分享</p>\
</div>`;
let data = { zid: (<any>window).zid, a: 'GetEditorInfo', c: 'Author_Ajax' };
jsonp('/Mbase/index.php', data).then(function (result: any) {
if (result.status === 0) {
_this.drawCanvas(result.data);
}
});
document.body.appendChild(_this.sharepic);
_this.sharepic.addEventListener('click', function (e: any) {
if (e.target.tagName !== 'IMG') {
_this.sharepic.style.display = 'none';
}
});
}
_this.sharepic.style.display = 'block';
}
public drawCanvas(data: any) {
let _this = this;
// 生成图片
let shareBox = document.createElement('canvas');
let ctx = shareBox.getContext('2d');
let cw = document.body.offsetWidth;
let ratio = cw / 750;
(<any>_this).sharepic.querySelectorAll('.share-pic-box').forEach(function (item: any) {
item.style.width = 540 * ratio + 'px';
item.style.height = 960 * ratio + 'px';
});
ratio = 1.44;
shareBox.width = 540;
shareBox.height = 960;
// ctx.rect(0, 0, shareBox.width, shareBox.height);
// ctx.fillStyle = '#fff';
ctx.fill();
// 背景图
(<any>_this).picArr.push({
src: '/bg.png',
x: 0 * ratio,
y: 0 * ratio,
w: shareBox.width,
h: shareBox.height
});
(<any>_this).picArr.push({
src: data.img,
type: 'circle',
r: 44 * ratio,
cx: 188 * ratio, // 圆心x
cy: 276 * ratio, // 圆心y
x: 144 * ratio,
y: 232 * ratio,
w: 88 * ratio,
h: 88 * ratio
});
// icon v
if (data.desc.length > 0) {
(<any>_this).picArr.push({
src: 'icon_V@2x.png',
x: 212 * ratio,
y: 300 * ratio,
w: 20 * ratio,
h: 20 * ratio
});
}
// 二维码
(<any>_this).picArr.push({
src: data.codeImg,
x: 251 * ratio,
y: 543 * ratio,
w: 94 * ratio,
h: 94 * ratio
});
let len = (<any>_this).picArr.length;
/**
* 递归函数 canvas画图
*
* @param {*} n 图片提前存储在数据中,按序加载图片绘制
*/
function drawPics(n: any) {
let item = (<any>_this).picArr[n];
if (n < len) {
let img = new Image();
img.crossOrigin = '*'; // 跨域处理
img.src = item.src;
img.onload = function () {
if (item.type === 'circle') {
_this.getCirclePic(ctx, item.cx, item.cy, item.r, img, item.x, item.y, item.w, item.h);
} else {
ctx.drawImage(img, item.x, item.y, item.w, item.h);
}
drawPics(n + 1); // 递归
};
} else {
// 分享描述
_this.drawMultiLineTextOnCanvas(ctx, {
x: 68 * ratio,
y: 100 * ratio,
color: '#fff',
line: 3,
width: 239 * ratio,
fontSize: 22 * ratio,
lineHeight: 30 * ratio,
align: 'left',
baseline: 'normal',
text: data.descript
});
_this.drawMultiLineTextOnCanvas(ctx, {
x: (188 - data.title.length * 12) * ratio,
y: 357 * ratio,
color: '#222',
line: 1,
fontSize: 24 * ratio,
lineHeight: 0 * ratio,
align: 'left',
baseline: 'normal',
text: data.title
});
_this.drawMultiLineTextOnCanvas(ctx, {
x: (188 - (data.level.length + data.desc.length + 1) * 6) * ratio,
y: 382 * ratio,
color: '#666',
line: 1,
width: 200 * ratio,
fontSize: 14 * ratio,
lineHeight: 20 * ratio,
align: 'left',
baseline: 'normal',
text: `${data.level} ${data.desc}`
});
// 分割线
_this.drawMultiLineTextOnCanvas(ctx, {
x: 129 * ratio,
y: 445 * ratio,
color: '#F0F0F0',
line: 1,
width: 10 * ratio,
fontSize: 18 * ratio,
lineHeight: 20 * ratio,
align: 'left',
baseline: 'normal',
text: '|'
});
_this.drawMultiLineTextOnCanvas(ctx, {
x: 244 * ratio,
y: 445 * ratio,
color: '#F0F0F0',
line: 1,
width: 10 * ratio,
fontSize: 18 * ratio,
lineHeight: 20 * ratio,
align: 'left',
baseline: 'normal',
text: '|'
});
// 文章
_this.drawMultiLineTextOnCanvas(ctx, {
x: 59 * ratio,
y: 463 * ratio,
color: '#999',
line: 1,
width: 200 * ratio,
fontSize: 14 * ratio,
lineHeight: 20 * ratio,
align: 'left',
baseline: 'normal',
text: '文章'
});
_this.drawMultiLineTextOnCanvas(ctx, {
x: 51 * ratio,
y: 434 * ratio,
color: '#222',
line: 1,
width: 100 * ratio,
fontSize: 24 * ratio,
lineHeight: 20 * ratio,
align: 'left',
baseline: 'normal',
text: data.docNum
});
// 粉丝
_this.drawMultiLineTextOnCanvas(ctx, {
x: 174 * ratio,
y: 463 * ratio,
color: '#999',
line: 1,
width: 200 * ratio,
fontSize: 14 * ratio,
lineHeight: 20 * ratio,
align: 'left',
baseline: 'normal',
text: '粉丝'
});
_this.drawMultiLineTextOnCanvas(ctx, {
x: 158 * ratio,
y: 434 * ratio,
color: '#222',
line: 1,
width: 100 * ratio,
fontSize: 24 * ratio,
lineHeight: 20 * ratio,
align: 'left',
baseline: 'normal',
text: data.fansNum
});
// 获赞
_this.drawMultiLineTextOnCanvas(ctx, {
x: 289 * ratio,
y: 463 * ratio,
color: '#999',
line: 1,
width: 200 * ratio,
fontSize: 14 * ratio,
lineHeight: 20 * ratio,
align: 'left',
baseline: 'normal',
text: '获赞'
});
_this.drawMultiLineTextOnCanvas(ctx, {
x: 273 * ratio,
y: 434 * ratio,
color: '#222',
line: 1,
width: 100 * ratio,
fontSize: 24 * ratio,
lineHeight: 20 * ratio,
align: 'left',
baseline: 'normal',
text: data.likeNum
});
let sharePic = shareBox.toDataURL('image/jpeg', 1.2);
if (sharePic) {
document.getElementById('shareCanvas').innerHTML = '<img src="' + sharePic + '" />';
}
}
}
drawPics(0);
(<any>_this).sharepic.querySelectorAll('.save-share-card').forEach(function (item: any) {
item.addEventListener('click', function (e: any) {
let fileName = 'share.jpg';
let alink = document.createElement("a");
alink.href = shareBox.toDataURL('image/jpeg', 1.2);
alink.download = fileName;
alink.click();
})
});
}
// 绘制圆形头像
public getCirclePic(ctx: any, x: number, y: number, r: number, pic: HTMLImageElement, dx: number, dy: number, dWidth: number, dHeight: number) {
// x:圆心x轴位置
// y:圆心x轴位置
// r:圆半径
// pic:图片
// dx:图片左上角x轴位置
// dy:图片左上角y轴位置
// dWidth:图片的宽
// dHeight:图片的高
ctx.save();
ctx.beginPath();
ctx.arc(x, y, r, 0, 2 * Math.PI, false);
ctx.fill();
ctx.clip();
ctx.drawImage(pic, dx, dy, dWidth, dHeight);
ctx.restore();
}
// 把需要绘制的文字根据参数改成多行,然后逐行绘制
public getCanvasMultiLineText(ctx: any, text: string, width: number, fontSize: number) {
ctx.font = fontSize + 'px arial';
if (text === '') {
return;
}
let textArr = text.trim().split('');
let textLen = textArr.length;
let line = '';
let lineArr = [];
for (let i = 0; i < textLen; i++) {
let word = line + textArr[i];
let metrics = ctx.measureText(word);
if (metrics.width > width && i > 0) {
lineArr.push(line);
line = textArr[i];
} else {
line = word;
}
if (i === textLen - 1) {
lineArr.push(line);
}
}
return lineArr;
}
// 逐行绘制文本
public drawMultiLineTextOnCanvas(ctx: any, options: any) {
let str = options.text;
if (str === undefined) {
return;
}
let textLineArr = this.getCanvasMultiLineText(ctx, options.text, options.width, options.fontSize);
let lineLen = textLineArr.length;
for (let i = 0; i < lineLen; i++) {
if (i < options.line) {
let text = textLineArr[i].trim();
if (i === options.line - 1) {
let textLen = text.length;
if (lineLen > options.line) {
text = text.substring(0, textLen - 1) + '...';
}
}
ctx.save();
ctx.fillStyle = options.color;
ctx.font = options.fontSize + 'px arial';
ctx.textAlign = options.align;
ctx.textBaseline = options.baseline;
ctx.fillText(text, options.x, options.y + (i * options.lineHeight));
ctx.restore();
}
}
};
}
export default Share;
canvs 画分享海报
最新推荐文章于 2024-06-04 16:47:58 发布
本文将介绍如何利用JavaScript和TypeScript的canvas API来创建吸引人的分享海报。内容包括canvas的基本用法,绘制图形、文字以及图片的方法,以及在实际项目中如何优化和适配不同屏幕尺寸。
摘要由CSDN通过智能技术生成