• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

excaliburjs / Excalibur / 14804036802

02 May 2025 09:58PM UTC coverage: 5.927% (-83.4%) from 89.28%
14804036802

Pull #3404

github

web-flow
Merge 5c103d7f8 into 0f2ccaeb2
Pull Request #3404: feat: added Graph module to Math

234 of 8383 branches covered (2.79%)

229 of 246 new or added lines in 1 file covered. (93.09%)

13145 existing lines in 208 files now uncovered.

934 of 15759 relevant lines covered (5.93%)

4.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/engine/Graphics/TiledAnimation.ts
1
import { ImageFiltering } from './Filtering';
2
import { ImageWrapConfiguration } from './ImageSource';
3
import { SourceView, Sprite } from './Sprite';
4
import { ImageWrapping } from './Wrapping';
5
import { Animation, AnimationOptions } from './Animation';
6
import { GraphicOptions } from './Graphic';
7
import { TiledSprite } from './TiledSprite';
8
import { watch } from '../Util/Watch';
9
import { Future } from '../Util/Future';
10

11
export interface TiledAnimationOptions {
12
  /**
13
   * Animation to tile
14
   */
15
  animation: Animation;
16
  /**
17
   * Optionally override source view on frame graphics
18
   */
19
  sourceView?: Partial<SourceView>;
20
  /**
21
   * Optionally override filtering options
22
   */
23
  filtering?: ImageFiltering;
24
  /**
25
   * Default wrapping is Repeat for TiledAnimation
26
   */
27
  wrapping?: ImageWrapConfiguration | ImageWrapping;
28
  /**
29
   * Total width in pixels for the tiling to take place
30
   */
31
  width: number;
32
  /**
33
   * Total height in pixels for the tiling to take place
34
   */
35
  height: number;
36
}
37

38
export class TiledAnimation extends Animation {
UNCOV
39
  private _ready = new Future<void>();
×
UNCOV
40
  public ready = this._ready.promise;
×
UNCOV
41
  private _tiledWidth: number = 0;
×
UNCOV
42
  private _tiledHeight: number = 0;
×
UNCOV
43
  private _sourceView: Partial<SourceView> = {};
×
44
  constructor(options: GraphicOptions & Omit<AnimationOptions, 'frames'> & TiledAnimationOptions) {
UNCOV
45
    super({
×
46
      ...options,
47
      frames: options.animation.frames.slice(),
48
      strategy: options.animation.strategy,
49
      frameDuration: options.animation.frameDuration,
50
      speed: options.animation.speed,
51
      reverse: options.animation.isReversed
52
    });
UNCOV
53
    this._sourceView = { ...options.sourceView };
×
UNCOV
54
    this._tiledWidth = options.width;
×
UNCOV
55
    this._tiledHeight = options.height;
×
56

UNCOV
57
    const promises: Promise<void>[] = [];
×
UNCOV
58
    for (let i = 0; i < this.frames.length; i++) {
×
UNCOV
59
      const graphic = this.frames[i].graphic;
×
UNCOV
60
      if (graphic && graphic instanceof Sprite) {
×
UNCOV
61
        const tiledSprite = new TiledSprite({
×
62
          image: graphic.image,
63
          width: options.width,
64
          height: options.height,
65
          sourceView: { ...graphic.sourceView },
66
          wrapping: options.wrapping,
67
          filtering: options.filtering
68
        });
UNCOV
69
        this.frames[i].graphic = tiledSprite;
×
70

71
        // There is a new calc'd sourceView when ready
UNCOV
72
        tiledSprite.ready.then(() => {
×
UNCOV
73
          tiledSprite.sourceView = { ...tiledSprite.sourceView, ...this._sourceView };
×
74
        });
UNCOV
75
        promises.push(tiledSprite.ready);
×
76
      }
77
    }
UNCOV
78
    Promise.all(promises).then(() => this._ready.resolve());
×
79
  }
80

81
  public static fromAnimation(animation: Animation, options?: Omit<TiledAnimationOptions, 'animation'>): TiledAnimation {
82
    return new TiledAnimation({
×
83
      width: animation.width,
84
      height: animation.height,
85
      ...options,
86
      animation
87
    });
88
  }
89

90
  private _updateSourceView() {
91
    for (let i = 0; i < this.frames.length; i++) {
×
92
      const graphic = this.frames[i].graphic;
×
93
      if (graphic && graphic instanceof Sprite) {
×
94
        graphic.sourceView = { ...graphic.sourceView, ...this._sourceView };
×
95
      }
96
    }
97
  }
98

99
  get sourceView(): Partial<SourceView> {
100
    return watch(this._sourceView, () => this._updateSourceView());
×
101
  }
102

103
  set sourceView(sourceView: Partial<SourceView>) {
104
    this._sourceView = watch(sourceView, () => this._updateSourceView());
×
105
    this._updateSourceView();
×
106
  }
107

108
  private _updateWidthHeight() {
109
    for (let i = 0; i < this.frames.length; i++) {
×
110
      const graphic = this.frames[i].graphic;
×
111
      if (graphic && graphic instanceof Sprite) {
×
112
        graphic.sourceView.height = this._tiledHeight || graphic.height;
×
113
        graphic.destSize.height = this._tiledHeight || graphic.height;
×
114
        graphic.sourceView.width = this._tiledWidth || graphic.width;
×
115
        graphic.destSize.width = this._tiledWidth || graphic.width;
×
116
      }
117
    }
118
  }
119

120
  get width() {
UNCOV
121
    return this._tiledWidth;
×
122
  }
123

124
  get height() {
UNCOV
125
    return this._tiledHeight;
×
126
  }
127

128
  override set width(width: number) {
129
    this._tiledWidth = width;
×
130
    this._updateWidthHeight();
×
131
  }
132

133
  override set height(height: number) {
134
    this._tiledHeight = height;
×
135
    this._updateWidthHeight();
×
136
  }
137
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc