UNPKG

@bscotch/stitch

Version:

Stitch: The GameMaker Studio 2 Asset Pipeline Development Kit.

90 lines 3.69 kB
import { pathy } from '@bscotch/pathy'; import { Spritely } from '@bscotch/spritely'; import { randomString } from '@bscotch/utility'; import { pascalCase } from 'change-case'; import { camelCase, snakeCase } from 'lodash-es'; import { assert } from '../utility/errors.js'; import paths from '../utility/paths.js'; /** * Given a source folder that is either a sprite or a * a folder containing sprites (where a 'sprite' is a folder * containing one or more immediate child PNGs that are * all the same size -- nesting is allowed), add or update * the game project sprites using those images. project.completely * replaces the existing images for that sprite. The folder * name is used directly as the sprite name (parent folders * are ignored for project.) */ export async function addSprites(project, sourceFolder, options) { const requestId = randomString(12, 'base64'); const [sprites, spineJsonFiles] = await Promise.all([ Spritely.from(sourceFolder, { excludeSpine: true }).then((ss) => ss.filter((s) => { if (options?.exclude) { const excludeRegex = new RegExp(options?.exclude); if (s.name.match(excludeRegex)) { return false; } } return true; })), pathy(sourceFolder).listChildrenRecursively({ async filter(path, siblings) { if (await path.isDirectory()) { return; } return (path.hasExtension('json') && siblings.find((s) => s.hasExtension('atlas')) && siblings.find((s) => s.hasExtension('png'))); }, transform(path) { return { path: path.absolute, }; }, }), ]); assert(sprites.length || spineJsonFiles.length, `No sprites found in ${sourceFolder}`); const casing = options?.case || 'keep'; const pathSep = casing == 'keep' ? options?.pathSeparator || '_' : ' '; const addingSprites = [...sprites, ...spineJsonFiles].map((sprite) => { const isSpine = !(sprite instanceof Spritely); let name = isSpine ? paths.dirname(sprite.path) : sprite.path; name = options?.flatten ? paths.relative(sourceFolder, name) : paths.subfolderName(name); name = name .replace(/[.\\/]/g, pathSep) .replace(/\s+/, pathSep) .trim(); const casedName = (casing == 'snake' && snakeCase(name)) || (casing == 'camel' && camelCase(name)) || (casing == 'pascal' && pascalCase(name)) || name; const fullName = `${options?.prefix || ''}${casedName}${options?.postfix || ''}`; return { name: fullName, path: sprite.path, isSpine, }; }); project.io.plugins.forEach((plugin) => { plugin.beforeSpritesAdded?.(project, { requestId: requestId, spriteSources: addingSprites, }); }); const addSpriteWaits = addingSprites.map((addingSprite) => { return addingSprite.isSpine ? project.resources.addSpineSprite(addingSprite.path, project.io, addingSprite.name) : project.resources.addSprite(addingSprite.path, project.io, addingSprite.name); }); await Promise.all(addSpriteWaits); project.io.plugins.forEach((plugin) => { plugin.afterSpritesAdded?.(project, { requestId: requestId, spriteSources: addingSprites, }); }); return project.save(); } //# sourceMappingURL=StitchProject.addSprites.js.map