allow screenshot from game as thumbnail header

This commit is contained in:
2026-02-07 12:48:13 +02:00
parent ab9c4d0508
commit 1978e82888
5 changed files with 42 additions and 2 deletions
+11 -1
View File
@@ -1,3 +1,5 @@
import sharp from 'sharp';
sharp.cache({ files : 0 });
const collection = 'games'; const collection = 'games';
/** /**
@@ -11,7 +13,7 @@ class GamesManager{
* @param {App} app Class initializer, основна апликация * @param {App} app Class initializer, основна апликация
*/ */
init(app){ init(app){
const {db, am} = app; const {db, am, config} = app;
/** /**
* Creates a new game definition, създаване на нова игрова дефиниция * Creates a new game definition, създаване на нова игрова дефиниция
@@ -69,6 +71,14 @@ class GamesManager{
project: { name:1, id:1, thumb: 1} project: { name:1, id:1, thumb: 1}
}); });
} }
this.setHeader = async function(ctx, id, file){
await sharp(file.path).resize({height: 500}).webp({quality: 75}).toFile(`${config.fs.repo}/thumb/${id}.webp`);
await sharp(file.path).webp({quality: 75}).toFile(`${config.fs.repo}/default/${id}.webp`);
let object = await this.read(id);
object.thumb = id;
await this.update(ctx, object);
}
} }
/** /**
@@ -1,4 +1,7 @@
import express from 'express'; import express from 'express';
import multipart from 'connect-multiparty';
const multipartMiddleware = multipart();
/** /**
* GamesController. API for the games manager, граничен клас за комуникация с модула за игрови дефиниции * GamesController. API for the games manager, граничен клас за комуникация с модула за игрови дефиниции
@@ -35,6 +38,19 @@ class GamesController{
} }
}); });
router.post('/:id/header', multipartMiddleware, async (req, res)=>{
try{
let id = parseInt(req.params.id);
await game.setHeader(req, id, req.files.file);
res.json({status: 'OK'});
am.audit(req, `game-header-set`, id);
}catch(err){
console.error(err);
res.status(500).json({status: 'ERR', err});
am.audit(req, `game-header-error`, id, {e: err});
}
});
/** /**
* API: POST /api/game/ List games by given criteria, търсене в игрови дефиниции * API: POST /api/game/ List games by given criteria, търсене в игрови дефиниции
* @function list * @function list
+11 -1
View File
@@ -17,7 +17,9 @@
<v-btn-toggle variant="tonal" v-model="store.prefs.xr.depthSense" class="ma-3" density="comfortable" color="green-darken-2"> <v-btn-toggle variant="tonal" v-model="store.prefs.xr.depthSense" class="ma-3" density="comfortable" color="green-darken-2">
<v-btn :value="true" icon="mdi-cube-outline"></v-btn> <v-btn :value="true" icon="mdi-cube-outline"></v-btn>
</v-btn-toggle> </v-btn-toggle>
<v-btn icon="mdi-walk" @click="control"></v-btn> <v-divider class="my-2"></v-divider>
<v-btn variant="tonal" icon="mdi-walk" @click="control" v-tooltip="`Pointer lock controls mode`" class="mx-1" size="small"></v-btn>
<v-btn variant="tonal" icon="mdi-image-frame" @click="setGameHeader" v-tooltip="`Capture screenshot as game header image`" class="mx-1" size="small"></v-btn>
</v-navigation-drawer> </v-navigation-drawer>
<div class="container my-3 position-relative game-designer-canvas"> <div class="container my-3 position-relative game-designer-canvas">
<div ref="target" @click="targetClick" <div ref="target" @click="targetClick"
@@ -54,5 +56,13 @@ export default {
cameraType: 'perspective', cameraType: 'perspective',
} }
}, },
methods:{
async setGameHeader(){
let screenshot = await this.engine.captureScreenshot();
let fd = new FormData();
fd.append('file', screenshot);
await this.$api.game.setHeader(this.modelValue.id, fd);
}
}
} }
</script> </script>
+1
View File
@@ -9,6 +9,7 @@ export default {
async mounted(){ async mounted(){
gameEngine = new GameEngine(); gameEngine = new GameEngine();
this.engine = gameEngine;
//this.gameEngine = gameEngine; //this.gameEngine = gameEngine;
await gameEngine.init(this.$refs.target, { await gameEngine.init(this.$refs.target, {
xr: true, xr: true,
+3
View File
@@ -61,6 +61,9 @@ export default {
}, },
async remove(id){ async remove(id){
return await $ax.delete(`/game/${id}`) return await $ax.delete(`/game/${id}`)
},
async setHeader(id, data){
return await $ax.post(`/game/${id}/header`, data);
} }
}, },
user:{ user:{