UNPKG

@osbjs/osbjs

Version:

a minimalist osu! storyboarding framework

102 lines (84 loc) 3.57 kB
import { IColor, Component, Sprite, OsbVector2, SubtitleCollection, Layer, Origin, Parameter, TextureGenerator, ILyricsOptions, IFontOptions } from '@osbjs/osbjs' export class MyLyrics extends Component { name = 'MyLyrics' folderPath: string osbFolderPath: string options = { fadeDuration: 200, opacity: 1, fontName: 'Arial', fontSize: 72, fontScale: 1, perCharacter: false, y: 400, additive: true, color: { r: 255, g: 255, b: 255, }, } private _textureGenerator: TextureGenerator private _subtitleCollection: SubtitleCollection constructor(folderPath: string, osbFolderPath: string, subtitlePath: string, options?: MyLyricsOptions, registerFontOptions?: IFontOptions) { super() this.folderPath = folderPath this.osbFolderPath = osbFolderPath this.options = { ...this.options, ...options } this._textureGenerator = new TextureGenerator(folderPath, osbFolderPath, { fontName: this.options.fontName, fontSize: this.options.fontSize }) if (registerFontOptions) this._textureGenerator.registerFont(registerFontOptions.fontPath, registerFontOptions.family) this._subtitleCollection = new SubtitleCollection(subtitlePath) } override generate() { if (this.options.perCharacter) { this._generatePerChar() } else { this._generatePerLine() } } private _generatePerChar() { this._subtitleCollection.subtitles.forEach((subtitle) => { let letterY = this.options.y subtitle.text.split('\n').forEach((line) => { let lineWidth = 0, lineHeight = 0 for (let i = 0; i < line.length; i++) { const letter = line[i] let { width, height } = this._textureGenerator.getTextDimensions(letter, {}, true) lineWidth += width * this.options.fontScale lineHeight = Math.max(lineHeight, height * this.options.fontScale) } let letterX = 320 - lineWidth * 0.5 for (let i = 0; i < line.length; i++) { const letter = line[i] let texture = this._textureGenerator.generateTexture(letter, this.options.color, {}, true) let position = new OsbVector2(letterX, letterY) let sprite = new Sprite(texture.osbPath, Layer.Background, Origin.TopLeft, position) sprite.ScaleAtTime(subtitle.startTime, this.options.fontScale) sprite.Fade(subtitle.startTime - this.options.fadeDuration, subtitle.startTime, 0, this.options.opacity) sprite.Fade(subtitle.endTime - this.options.fadeDuration, subtitle.endTime, this.options.opacity, 0) if (this.options.additive) sprite.Parameter(subtitle.startTime - this.options.fadeDuration, subtitle.endTime, Parameter.AdditiveBlending) this.registerComponents(sprite) letterX += texture.width * this.options.fontScale } letterY += lineHeight }) }) } private _generatePerLine() { this._subtitleCollection.subtitles.forEach((line) => { let texture = this._textureGenerator.generateTexture(line.text, this.options.color) let position = new OsbVector2(320, this.options.y) let sprite = new Sprite(texture.osbPath, Layer.Background, Origin.Center, position) sprite.ScaleAtTime(line.startTime, this.options.fontScale) sprite.Fade(line.startTime - this.options.fadeDuration, line.startTime, 0, this.options.opacity) sprite.Fade(line.endTime - this.options.fadeDuration, line.endTime, this.options.opacity, 0) if (this.options.additive) sprite.Parameter(line.startTime - this.options.fadeDuration, line.endTime, Parameter.AdditiveBlending) this.registerComponents(sprite) }) } } export interface MyLyricsOptions extends ILyricsOptions { // your options here }