网友真实露脸自拍10p,成人国产精品秘?久久久按摩,国产精品久久久久久无码不卡,成人免费区一区二区三区

小程序模板網

小程序利用Canvas繪制圖片和豎排文字

發布時間:2018-05-16 15:14 所屬欄目:小程序開發教程

閑暇時間抽個空寫了個三國殺武將手冊的小程序,中間有個需求設計的是合成武將皮膚圖、豎排的武將姓名、以及小程序碼,然后提供保存圖片到相冊,最終讓用戶可以分享到朋友圈或其他平臺。合成圖片應該按照 Canvas 的文檔來做都沒什么問題,主要是有個豎排文字的需求,這里和大家分享一下。

 

 

 

 

 

正文

首先放一張最終保存到相冊的圖片吧~

自我感覺良好,至少達到了我自己的預期吧~~~

下面讓我們一步一步來看看如何實現的吧。

整個圖片分為三個部分:

  1. 武將圖片
  2. 小程序碼
  3. 武將文字信息

先來看一下 wxml 里面的代碼,主要是放了一個 canvas 標簽,控制了一下高度和寬度屬性。


<view>
  <canvas class='share-canvas' style="width:100%;height:{{canvasHeight}}px" canvas-id="share_canvas"></canvas>
</view>

武將圖片


drawHeroImage: function (path) {
    var that = this;
    // 拿到canvas context
    let ctx = wx.createCanvasContext('share_canvas');
    // 為了保證圖片比例以及繪制的位置,先要拿到圖片的大小
    wx.getImageInfo({
      src: path,
      success: function (res) {
			
		  // 計算圖片占比信息	
        let maxWidth = Math.min(res.width, that.data.canvasWidth * 0.65);
        let radio = maxWidth / res.width;

        let offsetY = (that.data.canvasHeight - res.height * radio) / 2;
        console.log('offsetY=' + offsetY);
        that.setData({
          imageWidth: res.width * radio,
          imageHeight: res.height * radio,
          offsetY: offsetY,
        });
        
        // 繪制canvas背景,不屬于繪制圖片部分
        ctx.setFillStyle('white')
        ctx.fillRect(0, 0, that.data.canvasWidth, that.data.canvasHeight);
        // 繪制武將圖片,path是本地路徑,不可以傳網絡url,如果是網絡圖片需要先下載
        ctx.drawImage(path, 10, offsetY, res.width * radio, res.height * radio)
        // 繪制小程序碼
        that.drawQrCodeImage(ctx);
        // 繪制勢力漢字:吳
        that.drawInfluence(ctx, that.data.hero.HERO.INFLUENCE);
        // 繪制武將姓名:陸遜
        that.drawName(ctx, that.data.hero.HERO.NAME);
        // 繪制武將稱號:江陵侯
        that.drawHorner(ctx, that.data.hero.HERO.HORNER);
        // 最終調用draw函數,生成預覽圖
        // 一個坑點:只能調用一次,否則后面的會覆蓋前面的
        ctx.draw();
      }
    });
  }

小程序碼

小程序碼和武將圖片是一個類型,無非就是需要計算繪制的位置,這里就不再展示相關代碼了。

武將文字信息

從剛剛的代碼可以看出,我分了3個部分來繪制,其實  和 陸遜 應該是可以放到一起的,但是我在繪制的時候發現,空格在繪制的時候會引起異常,導致空格后面的文字無法繪制出來,所以我這里  和 陸遜 中間的空白是靠位置偏移來做的。

這里就展示一下如何繪制武將稱號的。


// 繪制武將稱號:江陵侯
drawHorner: function (ctx, text) {
	// 設置字號
    ctx.setFontSize(26);
    // 設置字體顏色
    ctx.setFillStyle("#000000");
    // 計算繪制起點
    let x = this.data.offsetX + 35;
    let y = this.data.offsetY + 10;
    console.log('drawHorner' + text);
    console.log(x);
    console.log(y);
    // 繪制豎排文字,這里是個Util函數,具體實現請繼續看
    Canvas.drawTextVertical(ctx, text, x, y);
  }

繪制豎排文字從網上找了個開源的代碼,需要看原理的請看 這里

當然我這里為了適用小程序做了些改動,函數原型是這樣子的:


CanvasRenderingContext2D.prototype.letterSpacingText = function (text, x, y, letterSpacing)

原諒我不是很會 js ,完全不懂這是個什么語法,看了一會沒弄懂,感覺像是給類添加新的屬性,不管他。

不管白貓黑貓,能抓到耗子就是好貓

改造后的函數像下面的樣子:

canvas.js


/**
* @author zhangxinxu(.com)
* @licence MIT
* @description http://www.zhangxinxu.com/wordpress/?p=7362
*/
function drawTextVertical(context, text, x, y) {
  var arrText = text.split('');
  var arrWidth = arrText.map(function (letter) {
    return 26;
    // 這里為了找到那個空格的 bug 做了許多努力,不過似乎是白費力了
    // const metrics = context.measureText(letter);
    // console.log(metrics);
    // const width = metrics.width;
    // return width;
  });
  
  var align = context.textAlign;
  var baseline = context.textBaseline;

  if (align == 'left') {
    x = x + Math.max.apply(null, arrWidth) / 2;
  } else if (align == 'right') {
    x = x - Math.max.apply(null, arrWidth) / 2;
  }
  if (baseline == 'bottom' || baseline == 'alphabetic' || baseline == 'ideographic') {
    y = y - arrWidth[0] / 2;
  } else if (baseline == 'top' || baseline == 'hanging') {
    y = y + arrWidth[0] / 2;
  }

  context.textAlign = 'center';
  context.textBaseline = 'middle';

  // 開始逐字繪制
  arrText.forEach(function (letter, index) {
    // 確定下一個字符的縱坐標位置
    var letterWidth = arrWidth[index];
    // 是否需要旋轉判斷
    var code = letter.charCodeAt(0);
    if (code <= 256) {
      context.translate(x, y);
      // 英文字符,旋轉90°
      context.rotate(90 * Math.PI / 180);
      context.translate(-x, -y);
    } else if (index > 0 && text.charCodeAt(index - 1) < 256) {
      // y修正
      y = y + arrWidth[index - 1] / 2;
    }
    context.fillText(letter, x, y);
    // 旋轉坐標系還原成初始態
    context.setTransform(1, 0, 0, 1, 0, 0);
    // 確定下一個字符的縱坐標位置
    var letterWidth = arrWidth[index];
    y = y + letterWidth;
  });
  // 水平垂直對齊方式還原
  context.textAlign = align;
  context.textBaseline = baseline;
}

module.exports = {
  drawTextVertical: drawTextVertical
}

繪制網絡圖片

由于網絡圖片無法直接繪制,所以需要先下載到本地,然后再按住本地圖片繪制的流程走一遍。


downloadHeroImage: function () {
    // 微信不支持非https的圖片下載,這里了個替換
    let url = this.data.hero.HERO.ICON.replace(/http/, "https");
    var that = this;
    wx.downloadFile({
      url: url,
      success: function (res) {
        // 下載成功后拿到圖片的路徑,然后開始繪制
        var path = res.tempFilePath;
        that.drawHeroImage(path);
      }, fail: function (res) {
        console.log(res)
      }
    });
  }

保存圖片

說了這么多,自然少不了最終的一步,將繪制到 canvas 的圖片保存到手機相冊,這里需要用戶授權,你需要自己處理。

用的是微信給我們提供的接口 wx.canvasToTempFilePath 。需要我們傳入起點坐標 (x, y)和畫布大小 (width, height) 以及 canvasId 。


saveShareImage: function () {
    wx.showLoading({
      title: '正在保存圖片..',
    });
    let that = this;
    wx.canvasToTempFilePath({
      x: 0,
      y: 0,
      width: that.data.canvasWidth,
      height: that.data.canvasHeight,
      canvasId: 'share_canvas',
      success: function (res) {
        wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success(res) {
            console.log(res);
            wx.showToast({
              title: '保存到相冊成功',
              duration: 1500,
            })
          },
          fail(res) {
            console.log(res)
            wx.showToast({
              title: '保存到相冊失敗',
              icon: 'fail'
            })
          },
          complete(res) {
            console.log(res)
          }
        })
      }
    })
  }


易優小程序(企業版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://www.xiuhaier.com/wxmini/doc/course/24422.html 復制鏈接 如需定制請聯系易優客服咨詢:800182392 點擊咨詢
QQ在線咨詢
AI智能客服 ×