notes.dt.in.th

Sometimes we want to draw web elements onto a perspective photo. There are several articles that teaches you how to do this:

These articles are from 2015 era. The examples has a lot of custom code, uses jQuery and CoffeeScript.

But it’s 2022, don’t we already have npm package for this? As it turns out, yes. The library in question is projection-3d-2d. However, this library gives you a 3x3 matrix, but we need a 4x4 matrix to use with matrix3d(). The following code can be used to turn the resulting matrix from projection-3d-2d into a 4x4 matrix suitable for use with matrix3d().

// Width and height of your element
const w = 1200
const h = 800
const points3d = [
  [0, 0],
  [w, 0],
  [w, h],
  [0, h],
]

// The target points on the photo to project onto
const points2d = [
  [70, 543],
  [916, 65],
  [1578, 185],
  [1170, 990],
]

// Calculate the matrix
const projectionCalculator = new ProjectionCalculator2d(points3d, points2d)
const m = projectionCalculator.resultMatrix

// Create the parameters for matrix3d
const matrix = [
  ...[m[0][0], m[1][0], 0, m[2][0]],
  ...[m[0][1], m[1][1], 0, m[2][1]],
  ...[0, 0, 1, 0],
  ...[m[0][2], m[1][2], 0, m[2][2]],
]

Make sure to set the transform-origin to top left.

See example: https://stackblitz.com/edit/vitejs-vite-ndobdk?file=src/App.svelte