背景:
在一些场景中,在浏览器端进行生成与绘制图片性能比较差,那么就需要服务器端来完成这些逻辑,该例子是一个简单的demo,基于node作为应用服务器,使用canvas作为绘制容器生成图片
正文:
在浏览器cancas上进行鼠标事件,上下左右的操作,将事件行为传递到node服务上,当node服务接收到信号,根据当前的信号提供的逻辑生成那个时刻的位置的图片,当生成完成图片之后图片的URL会返回到html上,最终会展示到html页面中,从而达到的云渲染的效果。
从实现过程中,分解为两个文件,分布是server.js、canvas-main.html
server.js:
var express = require('express');
var app = express();
const path = require('path');
var port = 90;
// 设置静态资源目录
const staticDir = path.join(__dirname, 'images');
// 使用express.static()中间件来指定静态资源目录
app.use(express.static(staticDir));
const { createCanvas } = require('canvas');
var fs = require("fs"); // 引入fs模块
const canvas = createCanvas(200, 200);
const ctx = canvas.getContext('2d');
var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
var radius = 50;
var x = canvas.width / 2;
var y = canvas.height - radius - 20;
var dateStr = (new Date()).valueOf();
function drawCircle() {
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.fillStyle = "#FF0000";
ctx.fill();
ctx.closePath();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawCircle();
dateStr = (new Date()).valueOf();
genfile(canvas,dateStr);
}
function moveCircle(dx, dy) {
x += dx;
y += dy;
draw();
}
// 键盘事件监听
function keyDown(key) {
switch(key) {
case 'ArrowUp':
moveCircle(0, -5);
break;
case 'ArrowDown':
moveCircle(0, 5);
break;
case 'ArrowLeft':
moveCircle(-5, 0);
break;
case 'ArrowRight':
moveCircle(5, 0);
break;
default:
break;
}
}
// 初始绘制
draw();
// 这个函数就是动画的一帧
function genfile(canvas, count) {
var image = canvas.toDataURL("images/png");
var path = './images/'+ count +'.png';
var base64 = image.replace(/^data:image\/\w+;base64,/, "");
var dataBuffer = new Buffer(base64, 'base64'); //把base64码转成buffer对象,
console.log('dataBuffer是否是Buffer对象:'+Buffer.isBuffer(dataBuffer)); // 输出是否是buffer对象
fs.writeFile(path,dataBuffer,function(err){//用fs写入文件
if(err){
console.log(err);
}else{
console.log('写入成功!');
}
});
}
// 2.2 监听 web 服务器的 request 事件
app.on("request", (req, res) => {
// 3.1 获取到客户端请求的 ur1 地址
const url = req.url;
console.log(url);
// 3.2 把 请求的 url 地址,映射为本地文件的存放路径
const fpath = path.join(__dirname, url);
console.log(__dirname); //__dirname就是当前js文件所在的目录
// 4.1 根据”映射”过来的文件路径读取文件
fs.readFile(fpath, "utf-8", (err, dataStr) => {
// 4.2 读取文件失败后,向客户端响应固定的“错误消息”
if (err) return res.end("404 Not fount.");
//4 读取文件成功后,将“读取成功的内容”响应给客户端
res.end(dataStr);
});
});
app.get('/', (req, res) => {
fs.readFile('canvas-main.html', function(err, data) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write(data);
res.end();
});
});
app.get('/getData', (req, res) => {
const name = req.query.name;
console.log(`进入请求接口`);
keyDown(name);
res.end(""+dateStr);
});
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});
canvas-main.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>可通过键盘移动的圆形</title>
<style>
#myCanvas {
border: 1px solid #000;
position: absolute;
top: 0;
left: 0;
display: block;
margin: 0 auto;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="400" height="400"></canvas>
<script>
var xhr = new XMLHttpRequest();
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var image = new Image();
image.onload = function() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(image, 0, 0);
}
//image.src = 'images/1701856421918.png';
function moveCircle2(value) {
console.log(value);
console.log("open request");
// 使用 fetch API 调用 HTTP 接口
fetch("http://localhost:90/getData?name="+value)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// 处理获取到的数据
console.log('/'+data+'.png');
image.src = '/'+data+'.png';
})
.catch(error => {
// 处理错误
console.error('There has been a problem with your fetch operation:', error);
});
}
// 键盘事件监听
function keyDown(e) {
switch(e.key) {
case 'ArrowUp':
moveCircle2('ArrowUp');
break;
case 'ArrowDown':
moveCircle2('ArrowDown');
break;
case 'ArrowLeft':
moveCircle2('ArrowLeft');
break;
case 'ArrowRight':
moveCircle2('ArrowRight');
break;
default:
break;
}
}
// 绑定键盘事件
document.addEventListener('keydown', keyDown);
// 初始绘制
//draw();
</script>
</body>
</html>
代码包参考:https://download.csdn.net/download/HWTwilight/88734290?spm=1001.2014.3001.5503