@@ -284,36 +284,11 @@ export default class PixiStage {
284284 // Load mouth texture (reuse if already loaded)
285285 this . loadAsset ( mouthTextureUrls [ mouthState ] , ( ) => {
286286 const texture = this . assetLoader . resources [ mouthTextureUrls [ mouthState ] ] . texture ;
287- if ( ! texture ) {
287+ const sprite = currentFigure ?. children ?. [ 0 ] as PIXI . Sprite ;
288+ if ( ! texture || ! sprite ) {
288289 return ;
289290 }
290- const originalWidth = texture . width ;
291- const originalHeight = texture . height ;
292- const scaleX = this . stageWidth / originalWidth ;
293- const scaleY = this . stageHeight / originalHeight ;
294- const targetScale = Math . min ( scaleX , scaleY ) ;
295- const figureSprite = new PIXI . Sprite ( texture ) ;
296- figureSprite . scale . x = targetScale ;
297- figureSprite . scale . y = targetScale ;
298- figureSprite . anchor . set ( 0.5 ) ;
299- figureSprite . position . y = this . stageHeight / 2 ;
300- const targetWidth = originalWidth * targetScale ;
301- const targetHeight = originalHeight * targetScale ;
302- currentFigure . setBaseY ( this . stageHeight / 2 ) ;
303- if ( targetHeight < this . stageHeight ) {
304- currentFigure . setBaseY ( this . stageHeight / 2 + this . stageHeight - targetHeight / 2 ) ;
305- }
306- if ( presetPosition === 'center' ) {
307- currentFigure . setBaseX ( this . stageWidth / 2 ) ;
308- }
309- if ( presetPosition === 'left' ) {
310- currentFigure . setBaseX ( targetWidth / 2 ) ;
311- }
312- if ( presetPosition === 'right' ) {
313- currentFigure . setBaseX ( this . stageWidth - targetWidth / 2 ) ;
314- }
315- currentFigure . pivot . set ( 0 , this . stageHeight / 2 ) ;
316- currentFigure . addChild ( figureSprite ) ;
291+ sprite . texture = texture ;
317292 } ) ;
318293 }
319294
@@ -337,38 +312,11 @@ export default class PixiStage {
337312 // Load eye texture (reuse if already loaded)
338313 this . loadAsset ( blinkTextureUrls [ blinkState ] , ( ) => {
339314 const texture = this . assetLoader . resources [ blinkTextureUrls [ blinkState ] ] . texture ;
340-
341- if ( ! texture ) {
315+ const sprite = currentFigure ?. children ?. [ 0 ] as PIXI . Sprite ;
316+ if ( ! texture || ! sprite ) {
342317 return ;
343318 }
344-
345- const originalWidth = texture . width ;
346- const originalHeight = texture . height ;
347- const scaleX = this . stageWidth / originalWidth ;
348- const scaleY = this . stageHeight / originalHeight ;
349- const targetScale = Math . min ( scaleX , scaleY ) ;
350- const figureSprite = new PIXI . Sprite ( texture ) ;
351- figureSprite . scale . x = targetScale ;
352- figureSprite . scale . y = targetScale ;
353- figureSprite . anchor . set ( 0.5 ) ;
354- figureSprite . position . y = this . stageHeight / 2 ;
355- const targetWidth = originalWidth * targetScale ;
356- const targetHeight = originalHeight * targetScale ;
357- currentFigure . setBaseY ( this . stageHeight / 2 ) ;
358- if ( targetHeight < this . stageHeight ) {
359- currentFigure . setBaseY ( this . stageHeight / 2 + this . stageHeight - targetHeight / 2 ) ;
360- }
361- if ( presetPosition === 'center' ) {
362- currentFigure . setBaseX ( this . stageWidth / 2 ) ;
363- }
364- if ( presetPosition === 'left' ) {
365- currentFigure . setBaseX ( targetWidth / 2 ) ;
366- }
367- if ( presetPosition === 'right' ) {
368- currentFigure . setBaseX ( this . stageWidth - targetWidth / 2 ) ;
369- }
370- currentFigure . pivot . set ( 0 , this . stageHeight / 2 ) ;
371- currentFigure . addChild ( figureSprite ) ;
319+ sprite . texture = texture ;
372320 } ) ;
373321 }
374322
@@ -447,6 +395,84 @@ export default class PixiStage {
447395 }
448396 }
449397
398+ public addSpineBg ( key : string , url : string ) {
399+ const spineId = `spine-${ url } ` ;
400+ const loader = this . assetLoader ;
401+ // 准备用于存放这个背景的 Container
402+ const thisBgContainer = new WebGALPixiContainer ( ) ;
403+
404+ // 是否有相同 key 的背景
405+ const setBgIndex = this . backgroundObjects . findIndex ( ( e ) => e . key === key ) ;
406+ const isBgSet = setBgIndex >= 0 ;
407+
408+ // 已经有一个这个 key 的背景存在了
409+ if ( isBgSet ) {
410+ // 挤占
411+ this . removeStageObjectByKey ( key ) ;
412+ }
413+
414+ // 挂载
415+ this . backgroundContainer . addChild ( thisBgContainer ) ;
416+ const bgUuid = uuid ( ) ;
417+ this . backgroundObjects . push ( {
418+ uuid : bgUuid ,
419+ key : key ,
420+ pixiContainer : thisBgContainer ,
421+ sourceUrl : url ,
422+ sourceType : 'live2d' ,
423+ sourceExt : this . getExtName ( url ) ,
424+ } ) ;
425+
426+ // 完成图片加载后执行的函数
427+ const setup = ( ) => {
428+ const spineResource : any = this . assetLoader . resources ?. [ spineId ] ;
429+ // TODO:找一个更好的解法,现在的解法是无论是否复用原来的资源,都设置一个延时以让动画工作正常!
430+ setTimeout ( ( ) => {
431+ if ( spineResource && this . getStageObjByUuid ( bgUuid ) ) {
432+ const bgSpine = new Spine ( spineResource . spineData ) ;
433+ const transY = spineResource ?. spineData ?. y ?? 0 ;
434+ /**
435+ * 重设大小
436+ */
437+ const originalWidth = bgSpine . width ; // TODO: 视图大小可能小于画布大小,应提供参数指定视图大小
438+ const originalHeight = bgSpine . height ; // TODO: 视图大小可能小于画布大小,应提供参数指定视图大小
439+ const scaleX = this . stageWidth / originalWidth ;
440+ const scaleY = this . stageHeight / originalHeight ;
441+ logger . debug ( 'bgSpine state' , bgSpine . state ) ;
442+ // TODO: 也许应该使用 setAnimation 播放初始动画
443+ if ( bgSpine . spineData . animations . length > 0 ) {
444+ // 播放首个动画
445+ bgSpine . state . setAnimation ( 0 , bgSpine . spineData . animations [ 0 ] . name , true ) ;
446+ }
447+ const targetScale = Math . max ( scaleX , scaleY ) ;
448+ const bgSprite = new PIXI . Sprite ( ) ;
449+ bgSprite . addChild ( bgSpine ) ;
450+ bgSprite . scale . x = targetScale ;
451+ bgSprite . scale . y = targetScale ;
452+ bgSprite . anchor . set ( 0.5 ) ;
453+ bgSprite . position . y = this . stageHeight / 2 ;
454+ thisBgContainer . setBaseX ( this . stageWidth / 2 ) ;
455+ thisBgContainer . setBaseY ( this . stageHeight / 2 ) ;
456+ thisBgContainer . pivot . set ( 0 , this . stageHeight / 2 ) ;
457+
458+ // 挂载
459+ thisBgContainer . addChild ( bgSprite ) ;
460+ }
461+ } , 0 ) ;
462+ } ;
463+
464+ /**
465+ * 加载器部分
466+ */
467+ this . cacheGC ( ) ;
468+ if ( ! loader . resources ?. [ url ] ) {
469+ this . loadAsset ( url , setup , spineId ) ;
470+ } else {
471+ // 复用
472+ setup ( ) ;
473+ }
474+ }
475+
450476 /**
451477 * 添加立绘
452478 * @param key 立绘的标识,一般和立绘位置有关
@@ -566,7 +592,6 @@ export default class PixiStage {
566592
567593 // 完成图片加载后执行的函数
568594 const setup = ( ) => {
569- console . log ( this . assetLoader . resources ) ;
570595 const spineResource : any = this . assetLoader . resources ?. [ spineId ] ;
571596 // TODO:找一个更好的解法,现在的解法是无论是否复用原来的资源,都设置一个延时以让动画工作正常!
572597 setTimeout ( ( ) => {
@@ -576,14 +601,12 @@ export default class PixiStage {
576601 /**
577602 * 重设大小
578603 */
579- console . log ( figureSpine ) ;
580604 const originalWidth = figureSpine . width ;
581605 const originalHeight = figureSpine . height ;
582606 const scaleX = this . stageWidth / originalWidth ;
583607 const scaleY = this . stageHeight / originalHeight ;
584608 // 我也不知道为什么啊啊啊啊
585609 figureSpine . y = - ( scaleY * transY ) / 2 ;
586- console . log ( figureSpine . state ) ;
587610 figureSpine . state . setAnimation ( 0 , '07' , true ) ;
588611 const targetScale = Math . min ( scaleX , scaleY ) ;
589612 const figureSprite = new PIXI . Sprite ( ) ;
0 commit comments