【NodeJS】基于Node生成图片的尝试

背景:

在一些场景中,在浏览器端进行生成与绘制图片性能比较差,那么就需要服务器端来完成这些逻辑,该例子是一个简单的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

基于Node.js的代码生成器是一种工具,它可以根据预定义的模板和规则自动生成代码。这些生成器通常用于加快开发过程,减少重复性工作,并提高代码的一致性和可维护性。 Node.js作为一个强大的后端开发框架,拥有丰富的生态系统和大量的第三方库,使得基于Node.js的代码生成器具有很高的灵活性和可扩展性。下面是一些常见的基于Node.js的代码生成器: 1. Yeoman:Yeoman是一个流行的代码生成器,它提供了一个可扩展的脚手架工具,可以帮助开发者快速创建项目结构、生成模块、配置文件等。Yeoman支持大量的生成器插件,可以满足各种不同的项目需求。 2. NestJS CLI:NestJS是一个基于Node.js的框架,用于构建高效、可扩展的服务器端应用程序。NestJS CLI是官方提供的命令行工具,可以通过简单的命令来生成控制器、服务、模块等代码文件,加速项目开发。 3. Express Generator:Express是一个流行的Node.js Web应用框架,而Express Generator是官方提供的脚手架工具,可以快速生成Express项目的基本结构和文件。通过Express Generator,开发者可以快速创建路由、中间件、视图等代码文件。 4. Sequelize CLI:Sequelize是一个强大的Node.js ORM(对象关系映射)库,用于操作数据库。Sequelize CLI是Sequelize官方提供的命令行工具,可以生成模型、迁移文件等数据库相关的代码,简化数据库操作的开发过程。 这些基于Node.js的代码生成器都提供了丰富的命令和选项,可以根据开发者的需求进行定制和扩展。通过使用这些工具,开发者可以快速生成符合规范的代码,提高开发效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯癫的老码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值