Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Dynamic Poster Generation in WeChat Mini Programs Using Painter

Tech Apr 18 38

Creating dynamic posters in WeChat Mini Programs often involves complex Canvas API operations. Painter simplifies this by utilizing a JSON-based configuration approach, similar to CSS, to render elements onto a <canvas> and export an image directly.

Entegration

  1. Clone or download the repository from GitHub.
  2. Copy the components/painter directory into your project's components folder (e.g., your-miniprogram/components/painter).

Core Concepts

Unlike tradisional web Canvas libraries that manipulate the drawing context direct, Painter generates an image file based on a provided JSON schema. This resulting image is then displayed using the standard <image> component.

Component Registration

Include the component in your page's JSON configuration file.

// pages/poster/poster. { "usingComponents": { "painter": "/components/painter/painter" } }

Layout and Data Binding

The WXML template requires both the <painter> component (which remains invisible) and an <image> component to display the output.

<view>
  <painter 
    palette="{{posterSchema}}" 
    bind:imgOK="onImageReady" 
  />
  <image src="{{outputImageUrl}}" />
</view>
  • palette: Accepts the JSON data structure defining the poster layout.
  • bind:imgOK: Triggered when the image is successfully generated, returning the file path.
  • src: Binds to the generated image's local path.

Page Logic

Construct the JSON schema in the JavaScript file and handle the image generation callback.

// pages/poster/poster.js
Page({
  data: {
    posterSchema: {},
    outputImageUrl: '',
    canvasWidth: 600,
    canvasHeight: 800
  },

  onImageReady(e) {
    const { path } = e.detail;
    this.setData({ outputImageUrl: path });
  },

  buildSchema() {
    return {
      width: `${this.data.canvasWidth}px`,
      height: `${this.data.canvasHeight}px`,
      background: '#e0e0e0',
      views: [
        {
          type: 'text',
          text: 'Hello World',
          css: {
            fontSize: '80px',
            color: '#333333'
          }
        }
      ]
    };
  },

  onLoad() {
    this.setData({ posterSchema: this.buildSchema() });
  }
});

The palette object requires three primary fields:

  • width: Canvas width (e.g., '600px').
  • height: Canvas height (e.g., `'800px'').
  • views: An array of elements to render.

Fixing Aspect Ratio

The native <image> component defaults to 320px by 240px, which may distort the generated poster. To maintain the correct proportions, bind the canvas dimensions directly to the image element's style.

<image
  src="{{outputImageUrl}}"
  style="width: {{canvasWidth}}rpx; height: {{canvasHeight}}rpx"
/>

Supported Elements

The views array supports various element types, defined by the type and css properties.

Text

Set type to "text" and provide the string via the text property.

views: [
  {
    type: 'text',
    text: 'Main Title',
    css: {
      top: '150px',
      left: '80px',
      fontSize: '60px',
      color: 'blue',
      rotate: '15'
    }
  },
  {
    type: 'text',
    text: 'Subtitle',
    css: {
      top: '250px',
      left: '80px',
      fontSize: '40px',
      color: 'gray'
    }
  }
]

Image

Set type to "image" and provide the source via url. Network URLs require the domain to be whitelisted in the Mini Program backend.

views: [
  {
    type: 'image',
    url: '/assets/images/banner.png',
    css: {
      top: '50px',
      right: '30px',
      width: '200px' // Height scales automatically
    }
  }
]

Rectangle

Set type to "rect". Both width and height are mandatory. Use color to fill the shape (not backgroundColor). Circular shapes can be achieved using borderRadius.

views: [
  {
    type: 'rect',
    css: {
      width: '400px',
      height: '200px',
      color: 'green',
      borderRadius: '100px'
    }
  }
]

QR Code

Set type to "qrcode". The content property holds the encoded data. Dimensions are required.

views: [
  {
    type: 'qrcode',
    content: 'https://example.com/invite',
    css: {
      width: '250px',
      height: '250px',
      color: 'darkblue'
    }
  }
]

Related Articles

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

SBUS Signal Analysis and Communication Implementation Using STM32 with Fus Remote Controller

Overview In a recent project, I utilized the SBUS protocol with the Fus remote controller to control a vehicle's basic operations, including movement, lights, and mode switching. This article is aimed...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.