微信小程序 畫布 組件

完整微信小程序(Java後端) 技術貼目錄清單頁面(必看)javascript

畫布組件,咱們能夠作一些繪圖和動畫效果。2.9.0 起支持一套新 Canvas 2D 接口(需指定 type 屬性),同時支持同層渲染,原有接口再也不維護。相關api:獲取 canvas 實例。html

屬性 類型 默認值 必填 說明 最低版本
type string   指定 canvas 類型,支持 2d (2.9.0) 和 webgl (2.7.0) 2.7.0
canvas-id string   canvas 組件的惟一標識符,若指定了 type 則無需再指定該屬性 1.0.0
disable-scroll boolean false 當在 canvas 中移動時且有綁定手勢事件時,禁止屏幕滾動以及下拉刷新 1.0.0
bindtouchstart eventhandle   手指觸摸動做開始 1.0.0
bindtouchmove eventhandle   手指觸摸後移動 1.0.0
bindtouchend eventhandle   手指觸摸動做結束 1.0.0
bindtouchcancel eventhandle   手指觸摸動做被打斷,如來電提醒,彈窗 1.0.0
bindlongtap eventhandle   手指長按 500ms 以後觸發,觸發了長按事件後進行移動不會觸發屏幕的滾動 1.0.0
binderror eventhandle   當發生錯誤時觸發 error 事件,detail = {errMsg} 1.0.0

Bug & Tipjava

  1. tip:canvas 標籤默認寬度300px、高度150px
  2. tip:同一頁面中的 canvas-id 不可重複,若是使用一個已經出現過的 canvas-id,該 canvas 標籤對應的畫布將被隱藏並再也不正常工做
  3. tip:請注意原生組件使用限制
  4. tip:開發者工具中默認關閉了 GPU 硬件加速,可在開發者工具的設置中開啓「硬件加速」提升 WebGL 的渲染性能
  5. tip: WebGL 支持經過 getContext(‘webgl’, { alpha: true }) 獲取透明背景的畫布
  6. tip: Canvas 2D(新接口)須要顯式設置畫布寬高 (默認爲 300x150)
  7. bug: 避免設置過大的寬高,在安卓下會有crash的問題

Canvas 2D 示例代碼node

在開發者工具中預覽效果web

index.wxmlcanvas

<canvas
  type="2d"
  id="canvas"
  style="width: 300px; height: 300px;"
></canvas>

index.js小程序

const app = getApp()

Page({
  data: {},

  onLoad: function () {
    this.position = {
      x: 150,
      y: 150,
      vx: 2,
      vy: 2
    }
    this.x = -100

    // 經過 SelectorQuery 獲取 Canvas 節點
    wx.createSelectorQuery()
      .select('#canvas')
      .fields({
        node: true,
        size: true,
      })
      .exec(this.init.bind(this))
  },

  init(res) {
    const width = res[0].width
    const height = res[0].height

    const canvas = res[0].node
    const ctx = canvas.getContext('2d')

    const dpr = wx.getSystemInfoSync().pixelRatio
    canvas.width = width * dpr
    canvas.height = height * dpr
    ctx.scale(dpr, dpr)

    const renderLoop = () => {
      this.render(canvas, ctx)
      canvas.requestAnimationFrame(renderLoop)
    }
    canvas.requestAnimationFrame(renderLoop)

    const img = canvas.createImage()
    img.onload = () => {
      this._img = img
    }
    img.src = './car.png'
  },

  render(canvas, ctx) {
    ctx.clearRect(0, 0, 300, 300)
    this.drawBall(ctx)
    this.drawCar(ctx)
  },

  drawBall(ctx) {
    const p = this.position
    p.x += p.vx
    p.y += p.vy
    if (p.x >= 300) {
      p.vx = -2
    }
    if (p.x <= 7) {
      p.vx = 2
    }
    if (p.y >= 300) {
      p.vy = -2
    }
    if (p.y <= 7) {
      p.vy = 2
    }

    function ball(x, y) {
      ctx.beginPath()
      ctx.arc(x, y, 5, 0, Math.PI * 2)
      ctx.fillStyle = '#1aad19'
      ctx.strokeStyle = 'rgba(1,1,1,0)'
      ctx.fill()
      ctx.stroke()
    }

    ball(p.x, 150)
    ball(150, p.y)
    ball(300 - p.x, 150)
    ball(150, 300 - p.y)
    ball(p.x, p.y)
    ball(300 - p.x, 300 - p.y)
    ball(p.x, 300 - p.y)
    ball(300 - p.x, p.y)
  },

  drawCar(ctx) {
    if (!this._img) return
    if (this.x > 350) {
      this.x = -100
    }
    ctx.drawImage(this._img, this.x++, 150 - 25, 100, 50)
    ctx.restore()
  }
})

運行效果:後端

在這裏插入圖片描述

WebGL 示例代碼微信小程序

在開發者工具中預覽效果api

<!-- canvas.wxml -->
  <canvas type="webgl" id="myCanvas"></canvas>
// canvas.js
Page({
  onReady() {
    const query = wx.createSelectorQuery()
    query.select('#myCanvas').node().exec((res) => {
      const canvas = res[0].node
      const gl = canvas.getContext('webgl')
      gl.clearColor(1, 0, 1, 1)
      gl.clear(gl.COLOR_BUFFER_BIT)
    })
  }
})

示例代碼(舊的接口)

在開發者工具中預覽效果 下載

<!-- canvas.wxml -->
<canvas style="width: 300px; height: 200px;" canvas-id="firstCanvas"></canvas>
<!-- 當使用絕對定位時,文檔流後邊的 canvas 的顯示層級高於前邊的 canvas -->
<canvas style="width: 400px; height: 500px;" canvas-id="secondCanvas"></canvas>
<!-- 由於 canvas-id 與前一個 canvas 重複,該 canvas 不會顯示,並會發送一個錯誤事件到 AppService -->
<canvas style="width: 400px; height: 500px;" canvas-id="secondCanvas" binderror="canvasIdErrorCallback"></canvas>
Page({
  canvasIdErrorCallback: function (e) {
    console.error(e.detail.errMsg)
  },
  onReady: function (e) {
    // 使用 wx.createContext 獲取繪圖上下文 context
    var context = wx.createCanvasContext('firstCanvas')

    context.setStrokeStyle("#00ff00")
    context.setLineWidth(5)
    context.rect(0, 0, 200, 200)
    context.stroke()
    context.setStrokeStyle("#ff0000")
    context.setLineWidth(2)
    context.moveTo(160, 100)
    context.arc(100, 100, 60, 0, 2 * Math.PI, true)
    context.moveTo(140, 100)
    context.arc(100, 100, 40, 0, Math.PI, false)
    context.moveTo(85, 80)
    context.arc(80, 80, 5, 0, 2 * Math.PI, true)
    context.moveTo(125, 80)
    context.arc(120, 80, 5, 0, 2 * Math.PI, true)
    context.stroke()
    context.draw()
  }
})
相關文章
相關標籤/搜索