服务端渲染canvas动画

更新时间: 2024-12-02 15:14:52

前面已经可以传图片和视频了,今天尝试一下nodejs去渲染canvas动画并传递给客户端

# 思路

服务端安装node-canvas,在服务端渲染好canvas动画,再将canvas.toBuffer()将canvas的图像转成二进制传给客户端,然后客户端将图片渲染出来

效果如下,没有写得太花哨:

# 服务端代码

const express = require('express')
const {createServer} = require('node:http')
const {Server} = require('socket.io')  
const { createCanvas } = require('canvas')

const app = express() 
const server = createServer(app)
const io = new Server(server,{
    cors: {
      origin: "*"
    }
})

io.on('connection', (socket) => {
    const canvas = createCanvas(600, 600)
    const ctx = canvas.getContext('2d')  
    let interval = null 

    let left = 0
    const draw = () => {
        ctx.clearRect(0, 0, 600, 600)
        ctx.fillRect(left, 100, 20, 20)
        left += 2
        if(left > 600) {
            left = 0
        }
        socket.emit('img', canvas.toBuffer())
    }
    draw()

    socket.on('start',() => {
        if(interval){
            clearInterval(interval)
            interval = null
        }
        interval = setInterval(() => {
            draw()
        },25)
    })

    socket.on('stop',() => {
        if(interval) {
            clearInterval(interval)
            interval = null
        }
    })
})

server.listen(3000, () => {
    console.log('server running at http://localhost:3000')
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

# 客户端代码

<template>
  <div class="main">
    <button @click="start">开始</button>
    <button @click="stop">停止</button>
    <div class="img-wrapper">
      <img :src="imageSrc" alt="">
    </div>
  </div>
</template>

<script setup>
  import {ref, onMounted} from "vue"
  import {io} from  "socket.io-client/dist/socket.io.js" 
  let socket = null
  const imageSrc = ref('')

  onMounted(() => {

    socket = io("http://192.168.2.122:3000")

    socket.on('img',(data) => {
      const blob = new Blob([data])
      imageSrc.value = URL.createObjectURL(blob)
    })
  })

  function start() {
   socket.emit('start')
  }

  function stop() {
    socket.emit('stop')
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34