知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們在追求其視覺表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營銷的便利,運(yùn)營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!
您當(dāng)前位置>首頁 » 新聞資訊 » 小程序相關(guān) >
微信小程序分享海報(bào)開發(fā)總結(jié)
發(fā)表時(shí)間:2021-1-5
發(fā)布人:葵宇科技
瀏覽次數(shù):72
- 請求海報(bào)數(shù)據(jù)
- 加載圖片
- 初始化canvas
- 繪制文字
- 繪制區(qū)塊
- 微信小程序碼獲取
- 繪制圖片
- 導(dǎo)出圖片內(nèi)容
- 小程序碼解析
正常情況下,1px在屏幕上就顯示1px,但是在高清屏幕上,這個(gè)情況就不一樣了,以iPhone4S為例,它的devicePixelRatio為2,將看到100px的邏輯值等于200px的設(shè)備值。在元素的邏輯像素寬度上創(chuàng)建圖像,當(dāng)它們被繪制出來時(shí),它們會(huì)被設(shè)備像素按比例放大,并且會(huì)變得模糊。解決這個(gè)問題的方法是創(chuàng)建按devicePixelRatio縮放的圖像,然后使用CSS按相同的比例縮小.
canvas 的width 和 height控制元素位圖的屬性,如不設(shè)置默認(rèn)為width=300,height=150
// 獲取canvas
function getCanvas() {
return new Promise((resolve, reject) => {
Taro.createSelectorQuery()
.select('#myCanvas')
.fields({
node: true,
size: true
})
.exec(res => {
res ? resolve(res[0]) : reject(null);
});
});
}
/**
* 初始化canvas并返回 ctx
*
* @param {Object} res
* @returns {*}
*/
function setContext(res: Object): any {
let {canvas, width, height} = res;
const ctx = canvas.getContext('2d');
const dpr = Taro.getSystemInfoSync().pixelRatio;
// 防止重復(fù)放大處理
if (canvas.width !== width * dpr) {
// 設(shè)置畫布繪畫尺寸 = CSS尺寸 * 設(shè)備像素比率。
canvas.width = width * dpr;
canvas.height = height * dpr;
// 通過dpr縮放所有繪圖操作
ctx.scale(dpr, dpr);
}
return ctx;
}
let {node: canvas, width, height} = await getCanvas();
let ctx = setContext({canvas, width, height});
// 繪制前先清除,以防被原有圖案影響
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = '#ffffff';
復(fù)制代碼
canvas標(biāo)簽,微信對Canvas做了同層渲染的優(yōu)化,特別注意不要將canvas標(biāo)簽放到子組件,必須放到page頁,否則無法獲取的canvas對象
<Canvas type='2d' id='myCanvas' style='width: 414px; height: 736px;' />
復(fù)制代碼
微信小程序碼獲取
- 接口 A: 適用于需要的碼數(shù)量較少的業(yè)務(wù)場景
- 生成小程序碼,可接受 path 參數(shù)較長,生成個(gè)數(shù)受限,請謹(jǐn)慎使用。
- 接口 B:適用于需要的碼數(shù)量極多的業(yè)務(wù)場景
- 生成小程序碼,可接受頁面參數(shù)較短,生成個(gè)數(shù)不受限。
- 接口 C:適用于需要的碼數(shù)量較少的業(yè)務(wù)場景
- 生成二維碼,可接受 path 參數(shù)較長,生成個(gè)數(shù)受限。
我們使用的是接口B,需要注意的點(diǎn),
- scene參數(shù)只接收32的長度
- 小程序未發(fā)布時(shí),page參數(shù)必須為空,scene=xxxx,才可以獲取到二維碼
- 接口返回的數(shù)據(jù)需要為base64格式方便canvas繪制時(shí)使用
Taro.getImageInfo({
src: imgUrl
}).than(res => {
let { path } = res;
let imgtag = canvas.createImage();
imgtag.src = http://www.wxapp-union.com/path;
imgtag.onload = res => {
ctx.save();
ctx.drawImage(imgtag, 26, 615, 2 * 27, 2 * 27);
ctx.restore();
};
});
復(fù)制代碼
圖片裁剪
/**
* 畫圓
*
* @export
* @param {IDrawRound} options
* @example
* drawRound({
* ctx,
* r: 19,
* x: 22,
* y: 15,
* next() {
* ctx.fillStyle = '#F5F5F5';
* ctx.fill();
* }
* });
*/
export function drawRound(options: IDrawRound) {
let { ctx, r, x, y, next } = options;
ctx.save(); // 保存之前的
let cx = x + r; // 圓弧坐標(biāo)x
let cy = y + r; // 圓弧坐標(biāo) y
ctx.arc(cx, cy, r, 0, 2 * Math.PI);
if (typeof next === 'function') {
next();
}
ctx.restore(); // 返回上一狀態(tài)
}
// 繪制圓形頭像
drawRound({
ctx,
r: 27,
x: 26,
y: 615,
next() {
ctx.clip();
ctx.drawImage(imgtag, 26, 615, 2 * 27, 2 * 27); // 畫頭像
}
});
復(fù)制代碼
繪制圓角矩形
/**
* 繪制圓角矩形,需自行填充顏色
*
* @export
* @param {IDrawRound} options
*
* @example
* drawRoundRect({
* ctx,
* r: 13,
* x: 26,
* y: 80,
* w: 361,
* h: 361,
* next() {
* ctx.clip();
* ctx.drawImage(imgtag, 26, 80, 361, 361);
* }
* });
*/
export function drawRoundRect(options: IDrawRoundRect) {
let {ctx, x, y, w, h, r, next} = options;
ctx.save();
if (w < 2 * r) {
r = w / 2;
}
if (h < 2 * r) {
r = h / 2;
}
ctx.beginPath();
ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 3 / 2);
ctx.lineTo(w - r + x, y);
ctx.arc(w - r + x, r + y, r, Math.PI * 3 / 2, Math.PI * 2);
ctx.lineTo(w + x, h + y - r);
ctx.arc(w - r + x, h - r + y, r, 0, Math.PI * 1 / 2);
ctx.lineTo(r + x, h + y);
ctx.arc(r + x, h - r + y, r, Math.PI * 1 / 2, Math.PI);
ctx.closePath();
if (typeof next === 'function') {
next();
}
ctx.restore(); // 返回上一狀態(tài)
}
// 底部粉色圓角矩形
drawRoundRect({
ctx,
r: 15,
x: 26,
y: 687,
w: 147,
h: 23,
next() {
// 漸變填充
var grd = ctx.createLinearGradient(0, 0, 200, 0);
grd.addColorStop(0, '#E828FF');
grd.addColorStop(0.7, '#FF1D74');
grd.addColorStop(1, '#FFB050');
ctx.fillStyle = grd;
ctx.fill();
ctx.strokeStyle = grd;
ctx.stroke();
}
});
復(fù)制代碼
繪制文字
/**
* 繪制文字
*
* @export
* @param {*} ctx canvas的 2d 對象
* @param {string} t 繪制的文字
* @param {number} x
* @param {number} y
* @param {number} w 文字寬度
* @param {number} [l=30] 行高
* @param {number} [limit=2] 行數(shù)
*/
export function drawText(ctx: any, t: string, x: number, y: number, w: number, l:number = 30, limit:number = 2) {
// 參數(shù)說明
// ctx:canvas的 2d 對象,t:繪制的文字,x,y:文字坐標(biāo),w:文字最大寬度
let chr = t.split('');
let temp = '';
let row = [];
let limitIndex = 0;
let wordsNum = 0;
for (let a = 0; a < chr.length; a++) {
wordsNum++;
if (ctx.measureText(temp).width < w && ctx.measureText(temp + (chr[a])).width <= w) {
temp += chr[a];
}
else {
// 行數(shù)+1
limitIndex++;
if (limitIndex < limit) {
row.push(temp);
temp = chr[a];
}
else {
break;
}
}
}
// 最后一行超出最大字?jǐn)?shù)
if (limitIndex === limit && chr.length > wordsNum) {
temp = temp.substring(0, temp.length - 1) + '...';
}
row.push(temp);
for (let b = 0; b < row.length; b++) {
ctx.fillText(row[b], x, y + (b + 1) * l);// 每行字體y坐標(biāo)間隔30
}
};
復(fù)制代碼
繪制完成導(dǎo)出圖片
export async function draw() {
let { node: canvas, width, height } = await getCanvas();
let ctx = setContext({ canvas, width, height });
// 繪制前先清除,以防原有圖案被影響
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, 414, 736);
// 底部灰色塊
ctx.fillStyle = '#f5f5f5';
ctx.fillRect(0, 596, 414, 140);
// 底部粉色圓角矩形
drawRoundRect({
ctx,
r: 15,
x: 26,
y: 687,
w: 147,
h: 23,
next() {
// 漸變填充
var grd = ctx.createLinearGradient(0, 0, 200, 0);
grd.addColorStop(0, '#E828FF');
grd.addColorStop(0.7, '#FF1D74');
grd.addColorStop(1, '#FFB050');
ctx.fillStyle = grd;
ctx.fill();
ctx.strokeStyle = grd;
ctx.stroke();
}
});
// 推薦人
ctx.fillStyle = '#666666';
ctx.font = '13px/1.2 PingFangSC-Regular';
ctx.fillText(`${nickName}`, 93, 635);
// 推薦語
ctx.fillStyle = '#222222';
ctx.font = '15px/1.2 PingFangSC-Regular';
ctx.fillText(`${recommendation || '推薦你一個(gè)超值的變美項(xiàng)目'}`, 93, 660);
// 底部文字
ctx.fillStyle = '#ffffff';
ctx.font = '13px/1.2 PingFangSC-Regular';
ctx.fillText('長按識(shí)別小程序購物', 43, 703);
// 省略部分圖片繪制代碼
// 獲取圖片臨時(shí)路徑
let { tempFilePath } = await Taro.canvasToTempFilePath({ canvas } as any);
return Promise.resolve(tempFilePath);
};
復(fù)制代碼
以上導(dǎo)出的圖片地址可以直接給img標(biāo)簽賦值
const res = await Taro.saveImageToPhotosAlbum({
filePath: tempFilePath
});
if (res.errMsg === 'saveImageToPhotosAlbum:ok') {
Taro.showToast({
title: '保存圖片成功',
icon: 'success',
duration: 2000
});
}
復(fù)制代碼
小程序碼解析
小程序碼的解析后,在page里收到的參數(shù)在scene里
componentWillMount() {
let params = this.$router.params;
// 通過小程序碼進(jìn)入,參數(shù)在scene里
if (params.scene) {
let scene = decodeURIComponent(params.scene);
let {id} = query2parmas(scene);
this.setState({
goodsId: id
});
}
// 通過分享卡片進(jìn)入?yún)?shù)直接在params里
if (params.id) {
this.setState({
goodsId: params.id
});
}
}
相關(guān)案例查看更多
相關(guān)閱讀
- 云南網(wǎng)站建設(shè)高手
- 云南網(wǎng)站建設(shè)公司
- 小程序開發(fā)聯(lián)系方式
- 小程序開發(fā)
- 迪慶小程序開發(fā)
- 小程序被騙退款成功
- 云南網(wǎng)站建設(shè)列表網(wǎng)
- 云南小程序開發(fā)課程
- 北京小程序開發(fā)
- 前端技術(shù)
- 網(wǎng)站建設(shè)首選
- 小程序定制開發(fā)
- 云南建站公司
- 云南網(wǎng)站建設(shè)服務(wù)公司
- 云南網(wǎng)站建設(shè)方法
- 汽車報(bào)廢管理系統(tǒng)
- 昆明軟件定制公司
- 云南做百度小程序的公司
- 北京小程序制作
- 保山小程序開發(fā)
- 昆明做網(wǎng)站建設(shè)的公司排名
- 汽車報(bào)廢拆解管理系統(tǒng)
- 云南小程序開發(fā)費(fèi)用
- 云南小程序開發(fā)哪家好
- 云南網(wǎng)站建設(shè)選
- 微信分銷
- 霸屏推廣
- 云南網(wǎng)站建設(shè)百度官方
- web前端
- 網(wǎng)站小程序