欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

微信小程序海報(bào)繪制示例講解

 更新時(shí)間:2024年05月04日 10:46:57   作者:零一行者  
這篇文章主要介紹了微信小程序海報(bào)繪制示例,海報(bào)分享功能在許多應(yīng)用中應(yīng)該是很常見(jiàn)的,因?yàn)樗鳛橐环N常用的應(yīng)用推廣和拉新的方式,下面我們來(lái)通過(guò)案例學(xué)習(xí)如何繪制

前言

海報(bào)分享功能在許多應(yīng)用中應(yīng)該是很常見(jiàn)的,因?yàn)樗鳛橐环N常用的應(yīng)用推廣和拉新的方式。

接下來(lái)看個(gè)實(shí)際的案例,如下:

把任務(wù)拆解下:

  • 如何繪制海報(bào)
  • 如何把繪制后的海報(bào)保存到相冊(cè)

繪制海報(bào)

canvas 來(lái)繪制海報(bào)。 這里需要了解基本的 canvas api,不熟悉可以先去了解下相關(guān) Canvas API

定義 canvas 元素

<template>
  <view class="poster-container">
    <canvas class="poster" canvas-id="posterId"></canvas>
    <button class="btn" @click="onSave">保存至相冊(cè)</button>
  </view>
</template>

獲取 canvas 上下文對(duì)象

const context = uni.createCanvasContext('posterId');

繪制背景圖片

圖片支持遠(yuǎn)程圖片和本地圖片,網(wǎng)絡(luò)圖片要通過(guò) getImageInfo / downloadFile 先下載。

context.drawImage('/static/poster.png', 0, 0, 320, 410); // 繪制背景圖片

繪制頭像和昵稱(chēng)

const avatarLeft = 185;
const avatarTop = 18;
const avatarWidth = 16;
const avatarHeight = 16;
context.drawImage(
  '/static/avatar.png',
  avatarLeft,
  avatarTop,
  avatarWidth,
  avatarHeight
);

從設(shè)計(jì)上來(lái)看頭像和昵稱(chēng)是對(duì)齊的。

直接按照設(shè)計(jì)稿距離來(lái)設(shè)定看看效果

const nickName = '墻頭草中的頂尖的';
const nameLeft = avatarLeft + avatarWidth + 7;
context.setFillStyle('#ffffff');
context.setFontSize(12);
context.fillText(nickName, nameLeft, 21, 96);

實(shí)際效果如下:

發(fā)現(xiàn)與預(yù)期效果對(duì)應(yīng)不上,思考下這是為什么? 文字設(shè)置距離偏移的參考基線(xiàn)不是文字的頂部。

怎么驗(yàn)證我的說(shuō)法呢?可以 x 值設(shè)置為 0

const nickName = '墻頭草中的頂尖的';
const nameLeft = avatarLeft + avatarWidth + 7;
context.setFillStyle('#ffffff');
context.setFontSize(12);
context.fillText(nickName, nameLeft, 0, 96); // 修改為 0

再看看效果:

發(fā)現(xiàn)參考點(diǎn)幾乎是文字的底部,這就驗(yàn)證了上面的結(jié)論。

怎么解決這個(gè)問(wèn)題呢?

  • 獲取文本行的高度
  • 更改偏移的參考點(diǎn)

通常知道文本行實(shí)際占用的高度,需要知道其 line-height,上面并不知道其 line-height 值。canvas 本身并不直接支持line-height屬性,顯然沒(méi)辦法獲得相對(duì)準(zhǔn)確的行高。

只能采用第二種方式,從 canvas 提供 API 來(lái)看,可以更改文本相行對(duì)齊的點(diǎn)。

const nickName = '墻頭草中的頂尖的';
const nameLeft = avatarLeft + avatarWidth + 7;
context.setFillStyle('#ffffff');
context.setFontSize(12);
context.setTextBaseline('top'); // 更改基線(xiàn)對(duì)齊點(diǎn)
context.fillText(nickName, nameLeft, 21, 96);

再來(lái)看看效果如下:

接下來(lái)實(shí)現(xiàn)二維碼區(qū)域,主要白色背景 + 二維碼 + 文案

白色背景區(qū)域

const rectWidth = 300;
const rectHeight = 89;
const rectLeft = 10;
const rectTop = 311;
context.setFillStyle('#ffffff');
context.fillRect(rectLeft, rectTop, rectWidth, rectHeight);

效果如下:

繪制二維碼

const qrcodeLeft = 20;
const qrcodeTop = rectTop + 10;
const qrcodeWidth = 68;
const qrcodeHeight = 68;
context.drawImage(
  '/static/qrcode.png',
  qrcodeLeft,
  qrcodeTop,
  qrcodeWidth,
  qrcodeHeight
);

二維碼這里直接采用現(xiàn)成圖片。實(shí)際上前端可以通過(guò) weapp.qrcode.esm.js 在前端生成二維碼,再把它繪制上去。

繪制多行文本

const startX = qrcodeLeft + qrcodeWidth + 15;
const text1 = '與志同道合的,他們一起成長(zhǎng)';
context.setFillStyle('#161413');
context.setFontSize(14);
context.setTextBaseline('top');
context.fillText(text1, startX, rectTop + 29);
const text2 = '掃碼即可進(jìn)入“Get一下”社區(qū)';
context.font = 'bold 14px Arial';
context.fillText(text2, startX, rectTop + 51);

看看最后的效果:

左上角的部分沒(méi)有繪制,思路同頭像和昵稱(chēng)一樣。 接下來(lái)只要把圖片保存到相冊(cè)即可。

保存到相冊(cè)

在小程序中,提供方法支持如下:

const onSave = () => {
  // 轉(zhuǎn)換為臨時(shí)路徑
  uni.canvasToTempFilePath({
    canvasId: 'posterId',
    success: (res) => {
      // 保存圖片到相冊(cè)
      uni.saveImageToPhotosAlbum({
        filePath: res.tempFilePath,
        success: () => {
          uni.showToast({
            title: '保存成功',
            icon: 'none',
          });
        },
        fail: () => {
          uni.showToast({
            title: '保存失敗',
            icon: 'none',
          });
        },
      });
    },
  });
};

這里基本上把一個(gè)海報(bào)繪制

擴(kuò)展

在繪制名稱(chēng)時(shí),用戶(hù)名稱(chēng)長(zhǎng)短不一至,如果名字過(guò)長(zhǎng)時(shí)會(huì)出現(xiàn)什么效果呢

const nickName = '墻頭草中的頂尖的墻頭草中的頂尖的';
const nameLeft = avatarLeft + avatarWidth + 7;
context.setFillStyle('#ffffff');
context.setFontSize(12);
context.fillText(nickName, nameLeft, 21, 96);

從效果來(lái)看,發(fā)現(xiàn)文字直接重疊。如果希望超出的部分能夠通過(guò)省略號(hào)來(lái)省略,是可以的

const nickName = '墻頭草中的頂尖的墻頭草中的頂尖的';
const nameLeft = avatarLeft + avatarWidth + 7;
context.setFillStyle('#ffffff');
context.setFontSize(12);
context.fillText(nickName, nameLeft, 21, 96);
let text = '';
const textArr = nickName.split('');
const ellipsisWidth = context.measureText('...').width; // 省略號(hào)的寬度
for (let i = 0; i < textArr.length; i++) {
  const temp = text + textArr[i];
  const metrics = context.measureText(temp);
  if (metrics.width + ellipsisWidth > 96) {
    text = text + '...';
    break;
  }
  text = temp;
}
context.fillText(text, nameLeft, 21, 96);

上面主要是通過(guò) measureText 方法獲得文字對(duì)應(yīng)寬度,針對(duì)超出的部分采用省略號(hào)替代。當(dāng)然,如果希望完整地顯示名字,也可以使用換行的方式。具體的實(shí)現(xiàn)方式,就留給大家自己思考和實(shí)現(xiàn)了。

處理后效果如下:

頭像實(shí)現(xiàn)圓角

默認(rèn)采用圓角頭像,如果用戶(hù)上傳的頭像沒(méi)有進(jìn)行裁剪處理,導(dǎo)致圖片出現(xiàn)非圓角情況,那么在海報(bào)上呈現(xiàn)的效果可能會(huì)有所差異。

先使用一個(gè)非圓角的圖片,代碼修改如下:

const avatarLeft = 185;
const avatarTop = 18;
const avatarWidth = 16;
const avatarHeight = 16;
context.drawImage(
  '/static/avatar-rect.png',
  avatarLeft,
  avatarTop,
  avatarWidth,
  avatarHeight
);

效果如下:

現(xiàn)在對(duì)圖片處理一下:

const avatarLeft = 185;
const avatarTop = 18;
const avatarWidth = 16;
const avatarHeight = 16;
context.beginPath();
context.arc(
  avatarLeft + avatarWidth / 2,
  avatarTop + avatarHeight / 2,
  avatarWidth / 2,
  0,
  2 * Math.PI
);
context.closePath();
context.clip();
// 繪制圓形頭像
context.drawImage(
  '/static/avatar-rect.png',
  avatarLeft,
  avatarTop,
  avatarWidth,
  avatarHeight
);

效果如下:

圓角是實(shí)現(xiàn)了,發(fā)現(xiàn)其他區(qū)域內(nèi)容都被裁剪了。 這是為什么? clip()改變了繪畫(huà)環(huán)境。ctx()調(diào)用后,所裁剪的區(qū)域就是 clip ()后的繪制環(huán)境,clip()之后的繪畫(huà)只能在裁剪區(qū)域中渲染,不能訪(fǎng)問(wèn)畫(huà)布上的其他區(qū)域。

怎么處理這個(gè)問(wèn)題呢 ? 通過(guò) save()restore().

context.save(); // 暫存
context.beginPath();
context.arc(
  avatarLeft + avatarWidth / 2,
  avatarTop + avatarHeight / 2,
  avatarWidth / 2,
  0,
  2 * Math.PI
);
context.closePath();
context.clip();
// 繪制圓形頭像
context.drawImage(
  '/static/avatar-rect.png',
  avatarLeft,
  avatarTop,
  avatarWidth,
  avatarHeight
);
context.restore(); // 恢復(fù)

效果如下:

總結(jié)

  • 通過(guò) canvas + 小程序提供 API 實(shí)現(xiàn)海報(bào)繪制、保存海報(bào)到相冊(cè)
  • 優(yōu)化特殊情況下名稱(chēng)和頭像的展示方式。

以上就是微信小程序海報(bào)繪制示例講解的詳細(xì)內(nèi)容,更多關(guān)于小程序海報(bào)繪制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論