Added clip.
435
spine-ts/spine-webgl/example/assets/chibi-stickers-pma.atlas
Normal file
@ -0,0 +1,435 @@
|
|||||||
|
chibi-stickers-pma.png
|
||||||
|
size: 512, 128
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
scale: 0.5
|
||||||
|
common/angry-mark
|
||||||
|
bounds: 278, 85, 42, 41
|
||||||
|
common/big-purple-fear
|
||||||
|
bounds: 2, 54, 134, 72
|
||||||
|
common/big-tear
|
||||||
|
bounds: 138, 93, 33, 82
|
||||||
|
rotate: 90
|
||||||
|
common/eye-3
|
||||||
|
bounds: 226, 25, 15, 26
|
||||||
|
common/eye-closed-happy
|
||||||
|
bounds: 267, 7, 25, 9
|
||||||
|
rotate: 90
|
||||||
|
common/eye-dafault
|
||||||
|
bounds: 203, 20, 22, 21
|
||||||
|
rotate: 90
|
||||||
|
common/eye-equal
|
||||||
|
bounds: 308, 43, 25, 15
|
||||||
|
common/eye-fire
|
||||||
|
bounds: 278, 57, 26, 28
|
||||||
|
rotate: 90
|
||||||
|
common/eye-half-open
|
||||||
|
bounds: 138, 2, 26, 16
|
||||||
|
common/eye-heart
|
||||||
|
bounds: 308, 60, 26, 23
|
||||||
|
common/eye-reverse-v
|
||||||
|
bounds: 166, 2, 26, 16
|
||||||
|
common/eye-sideway-v
|
||||||
|
bounds: 336, 60, 21, 23
|
||||||
|
common/eye-slant-close
|
||||||
|
bounds: 194, 2, 23, 16
|
||||||
|
common/eye-small-dot
|
||||||
|
bounds: 119, 2, 15, 15
|
||||||
|
common/eye-sparkle
|
||||||
|
bounds: 372, 97, 30, 29
|
||||||
|
common/eye-star
|
||||||
|
bounds: 404, 99, 29, 27
|
||||||
|
common/eye-twirl
|
||||||
|
bounds: 226, 2, 21, 23
|
||||||
|
rotate: 90
|
||||||
|
common/eye-u
|
||||||
|
bounds: 2, 2, 24, 17
|
||||||
|
common/eye-x
|
||||||
|
bounds: 176, 20, 25, 22
|
||||||
|
common/lamp
|
||||||
|
bounds: 138, 44, 47, 65
|
||||||
|
rotate: 90
|
||||||
|
common/mouth-3
|
||||||
|
bounds: 89, 2, 15, 28
|
||||||
|
rotate: 90
|
||||||
|
common/mouth-bracket
|
||||||
|
bounds: 322, 85, 34, 11
|
||||||
|
common/mouth-doubt
|
||||||
|
bounds: 243, 34, 26, 15
|
||||||
|
common/mouth-fangs
|
||||||
|
bounds: 205, 52, 39, 14
|
||||||
|
rotate: 90
|
||||||
|
common/mouth-line
|
||||||
|
bounds: 435, 96, 36, 7
|
||||||
|
common/mouth-neutral
|
||||||
|
bounds: 245, 51, 27, 12
|
||||||
|
common/mouth-o-tall
|
||||||
|
bounds: 221, 53, 22, 33
|
||||||
|
common/mouth-open-smile
|
||||||
|
bounds: 138, 20, 36, 22
|
||||||
|
common/mouth-rectangle
|
||||||
|
bounds: 435, 105, 35, 21
|
||||||
|
common/mouth-reverse-v
|
||||||
|
bounds: 473, 95, 27, 10
|
||||||
|
common/mouth-s
|
||||||
|
bounds: 28, 8, 41, 11
|
||||||
|
common/mouth-smile-little
|
||||||
|
bounds: 117, 19, 33, 19
|
||||||
|
rotate: 90
|
||||||
|
common/mouth-toungue-sticking-out
|
||||||
|
bounds: 245, 65, 31, 21
|
||||||
|
common/mouth-u
|
||||||
|
bounds: 472, 107, 36, 19
|
||||||
|
common/mouth-v
|
||||||
|
bounds: 251, 5, 27, 14
|
||||||
|
rotate: 90
|
||||||
|
common/mouth-x
|
||||||
|
bounds: 335, 38, 21, 20
|
||||||
|
common/purple-fear-lines
|
||||||
|
bounds: 322, 98, 48, 28
|
||||||
|
common/shadow
|
||||||
|
bounds: 2, 21, 113, 31
|
||||||
|
common/small-dash
|
||||||
|
bounds: 404, 88, 9, 20
|
||||||
|
rotate: 90
|
||||||
|
common/small-drop-line
|
||||||
|
bounds: 71, 2, 16, 17
|
||||||
|
common/small-purple-fear
|
||||||
|
bounds: 222, 88, 54, 38
|
||||||
|
common/tear
|
||||||
|
bounds: 274, 36, 20, 19
|
||||||
|
|
||||||
|
chibi-stickers-pma_2.png
|
||||||
|
size: 1024, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
scale: 0.5
|
||||||
|
erikari/arm
|
||||||
|
bounds: 981, 164, 28, 90
|
||||||
|
erikari/arm-shoulder-decoration
|
||||||
|
bounds: 790, 149, 32, 43
|
||||||
|
erikari/back-hair
|
||||||
|
bounds: 258, 113, 158, 141
|
||||||
|
erikari/back-hair-long
|
||||||
|
bounds: 2, 34, 220, 254
|
||||||
|
rotate: 90
|
||||||
|
erikari/blush
|
||||||
|
bounds: 981, 133, 29, 18
|
||||||
|
rotate: 90
|
||||||
|
erikari/body
|
||||||
|
bounds: 584, 115, 70, 98
|
||||||
|
erikari/bracelet
|
||||||
|
bounds: 1011, 221, 33, 11
|
||||||
|
rotate: 90
|
||||||
|
erikari/collar
|
||||||
|
bounds: 390, 48, 61, 62
|
||||||
|
erikari/ear
|
||||||
|
bounds: 258, 2, 34, 42
|
||||||
|
erikari/eyebrow
|
||||||
|
bounds: 453, 98, 20, 12
|
||||||
|
erikari/hair-front
|
||||||
|
bounds: 258, 46, 130, 65
|
||||||
|
erikari/hair-side
|
||||||
|
bounds: 656, 149, 43, 132
|
||||||
|
rotate: 90
|
||||||
|
erikari/hat-border
|
||||||
|
bounds: 418, 215, 254, 39
|
||||||
|
erikari/hat-top
|
||||||
|
bounds: 674, 194, 160, 60
|
||||||
|
erikari/head-base
|
||||||
|
bounds: 836, 129, 143, 125
|
||||||
|
erikari/leg
|
||||||
|
bounds: 2, 4, 28, 101
|
||||||
|
rotate: 90
|
||||||
|
erikari/leg-decoration
|
||||||
|
bounds: 770, 134, 36, 13
|
||||||
|
erikari/skirt
|
||||||
|
bounds: 418, 112, 164, 101
|
||||||
|
erikari/strawberries-decoration
|
||||||
|
bounds: 656, 91, 112, 56
|
||||||
|
|
||||||
|
chibi-stickers-pma_3.png
|
||||||
|
size: 512, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
scale: 0.5
|
||||||
|
harri/arm
|
||||||
|
bounds: 147, 21, 28, 90
|
||||||
|
rotate: 90
|
||||||
|
harri/back-hair
|
||||||
|
bounds: 2, 107, 158, 141
|
||||||
|
harri/back-hair-long
|
||||||
|
bounds: 147, 51, 40, 80
|
||||||
|
rotate: 90
|
||||||
|
harri/beard
|
||||||
|
bounds: 2, 2, 10, 11
|
||||||
|
harri/blush
|
||||||
|
bounds: 265, 103, 29, 18
|
||||||
|
harri/body
|
||||||
|
bounds: 307, 94, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
harri/body-decoration
|
||||||
|
bounds: 407, 97, 70, 67
|
||||||
|
harri/ear
|
||||||
|
bounds: 229, 57, 34, 42
|
||||||
|
rotate: 90
|
||||||
|
harri/eyebrow
|
||||||
|
bounds: 494, 226, 22, 12
|
||||||
|
rotate: 90
|
||||||
|
harri/hair-front
|
||||||
|
bounds: 2, 15, 143, 90
|
||||||
|
harri/head-base
|
||||||
|
bounds: 162, 123, 143, 125
|
||||||
|
harri/leg
|
||||||
|
bounds: 162, 93, 28, 101
|
||||||
|
rotate: 90
|
||||||
|
harri/sword
|
||||||
|
bounds: 307, 166, 185, 82
|
||||||
|
|
||||||
|
chibi-stickers-pma_4.png
|
||||||
|
size: 1024, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
scale: 0.5
|
||||||
|
luke/arm
|
||||||
|
bounds: 930, 224, 28, 90
|
||||||
|
rotate: 90
|
||||||
|
luke/arm-shoulder-decoration
|
||||||
|
bounds: 581, 112, 31, 27
|
||||||
|
rotate: 90
|
||||||
|
luke/back-hair
|
||||||
|
bounds: 173, 111, 158, 141
|
||||||
|
luke/blush
|
||||||
|
bounds: 151, 68, 29, 18
|
||||||
|
rotate: 90
|
||||||
|
luke/body
|
||||||
|
bounds: 700, 123, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
luke/eyebrow
|
||||||
|
bounds: 2, 2, 27, 12
|
||||||
|
luke/face-cover
|
||||||
|
bounds: 2, 99, 169, 153
|
||||||
|
luke/glasses-shadow
|
||||||
|
bounds: 2, 16, 147, 81
|
||||||
|
luke/hair-decoration
|
||||||
|
bounds: 478, 145, 130, 107
|
||||||
|
luke/hair-front
|
||||||
|
bounds: 700, 195, 122, 57
|
||||||
|
luke/head-base
|
||||||
|
bounds: 333, 127, 143, 125
|
||||||
|
luke/leg
|
||||||
|
bounds: 478, 115, 28, 101
|
||||||
|
rotate: 90
|
||||||
|
luke/shield
|
||||||
|
bounds: 610, 148, 88, 104
|
||||||
|
luke/skirt
|
||||||
|
bounds: 930, 191, 81, 31
|
||||||
|
luke/sword
|
||||||
|
bounds: 824, 181, 104, 71
|
||||||
|
|
||||||
|
chibi-stickers-pma_5.png
|
||||||
|
size: 512, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
scale: 0.5
|
||||||
|
mario/arm
|
||||||
|
bounds: 244, 2, 28, 90
|
||||||
|
mario/back-hair
|
||||||
|
bounds: 2, 101, 168, 148
|
||||||
|
mario/back-hair-long
|
||||||
|
bounds: 151, 6, 86, 91
|
||||||
|
rotate: 90
|
||||||
|
mario/beard
|
||||||
|
bounds: 2, 6, 147, 93
|
||||||
|
mario/blush
|
||||||
|
bounds: 492, 220, 29, 18
|
||||||
|
rotate: 90
|
||||||
|
mario/body
|
||||||
|
bounds: 317, 111, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
mario/ear
|
||||||
|
bounds: 456, 207, 34, 42
|
||||||
|
mario/eyebrow
|
||||||
|
bounds: 417, 164, 32, 17
|
||||||
|
mario/hair-front
|
||||||
|
bounds: 317, 183, 137, 66
|
||||||
|
mario/head-base
|
||||||
|
bounds: 172, 124, 143, 125
|
||||||
|
mario/leg
|
||||||
|
bounds: 172, 94, 28, 101
|
||||||
|
rotate: 90
|
||||||
|
|
||||||
|
chibi-stickers-pma_6.png
|
||||||
|
size: 1024, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
scale: 0.5
|
||||||
|
misaki/arm
|
||||||
|
bounds: 609, 95, 28, 90
|
||||||
|
misaki/back-hair
|
||||||
|
bounds: 194, 105, 158, 141
|
||||||
|
misaki/back-hair-long
|
||||||
|
bounds: 2, 51, 190, 195
|
||||||
|
misaki/belt
|
||||||
|
bounds: 741, 190, 76, 26
|
||||||
|
misaki/blush
|
||||||
|
bounds: 844, 228, 29, 18
|
||||||
|
misaki/body
|
||||||
|
bounds: 641, 176, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
misaki/ear
|
||||||
|
bounds: 144, 7, 34, 42
|
||||||
|
misaki/eyebrow
|
||||||
|
bounds: 194, 54, 30, 12
|
||||||
|
misaki/glasses
|
||||||
|
bounds: 194, 68, 141, 35
|
||||||
|
misaki/glasses-side
|
||||||
|
bounds: 354, 111, 8, 23
|
||||||
|
rotate: 90
|
||||||
|
misaki/hair-front
|
||||||
|
bounds: 499, 187, 140, 59
|
||||||
|
misaki/hair-side
|
||||||
|
bounds: 2, 2, 47, 140
|
||||||
|
rotate: 90
|
||||||
|
misaki/head-base
|
||||||
|
bounds: 354, 121, 143, 125
|
||||||
|
misaki/leg
|
||||||
|
bounds: 741, 218, 28, 101
|
||||||
|
rotate: 90
|
||||||
|
misaki/skirt
|
||||||
|
bounds: 499, 95, 108, 90
|
||||||
|
|
||||||
|
chibi-stickers-pma_7.png
|
||||||
|
size: 512, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
scale: 0.5
|
||||||
|
nate/arm
|
||||||
|
bounds: 151, 65, 28, 90
|
||||||
|
rotate: 90
|
||||||
|
nate/back-hair
|
||||||
|
bounds: 2, 109, 158, 141
|
||||||
|
nate/beard
|
||||||
|
bounds: 2, 39, 147, 68
|
||||||
|
nate/blush
|
||||||
|
bounds: 407, 165, 29, 18
|
||||||
|
nate/body
|
||||||
|
bounds: 307, 113, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
nate/ear
|
||||||
|
bounds: 451, 208, 34, 42
|
||||||
|
nate/eyebrow
|
||||||
|
bounds: 265, 111, 27, 12
|
||||||
|
nate/glasses
|
||||||
|
bounds: 2, 2, 141, 35
|
||||||
|
nate/glasses-side
|
||||||
|
bounds: 151, 47, 8, 16
|
||||||
|
nate/hair-front
|
||||||
|
bounds: 307, 185, 142, 65
|
||||||
|
nate/head-base
|
||||||
|
bounds: 162, 125, 143, 125
|
||||||
|
nate/leg
|
||||||
|
bounds: 162, 95, 28, 101
|
||||||
|
rotate: 90
|
||||||
|
|
||||||
|
chibi-stickers-pma_8.png
|
||||||
|
size: 512, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
scale: 0.5
|
||||||
|
sinisa/arm
|
||||||
|
bounds: 147, 52, 28, 90
|
||||||
|
rotate: 90
|
||||||
|
sinisa/back-hair
|
||||||
|
bounds: 2, 96, 158, 141
|
||||||
|
sinisa/beard
|
||||||
|
bounds: 307, 192, 139, 45
|
||||||
|
sinisa/blush
|
||||||
|
bounds: 147, 32, 29, 18
|
||||||
|
sinisa/body
|
||||||
|
bounds: 307, 120, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
sinisa/body-decoration
|
||||||
|
bounds: 265, 83, 27, 27
|
||||||
|
sinisa/ear
|
||||||
|
bounds: 448, 195, 34, 42
|
||||||
|
sinisa/eyebrow
|
||||||
|
bounds: 407, 171, 38, 19
|
||||||
|
sinisa/hair-front
|
||||||
|
bounds: 2, 2, 143, 92
|
||||||
|
sinisa/head-base
|
||||||
|
bounds: 162, 112, 143, 125
|
||||||
|
sinisa/leg
|
||||||
|
bounds: 162, 82, 28, 101
|
||||||
|
rotate: 90
|
||||||
|
|
||||||
|
chibi-stickers-pma_9.png
|
||||||
|
size: 512, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
scale: 0.5
|
||||||
|
soeren/arm
|
||||||
|
bounds: 254, 47, 28, 90
|
||||||
|
soeren/back-hair
|
||||||
|
bounds: 2, 111, 150, 141
|
||||||
|
soeren/beard
|
||||||
|
bounds: 2, 41, 145, 68
|
||||||
|
soeren/blush
|
||||||
|
bounds: 284, 119, 29, 18
|
||||||
|
soeren/body
|
||||||
|
bounds: 154, 67, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
soeren/ear
|
||||||
|
bounds: 200, 23, 34, 42
|
||||||
|
soeren/eyebrow
|
||||||
|
bounds: 460, 137, 27, 12
|
||||||
|
soeren/glasses
|
||||||
|
bounds: 2, 2, 152, 37
|
||||||
|
soeren/glasses-side
|
||||||
|
bounds: 490, 245, 7, 20
|
||||||
|
rotate: 90
|
||||||
|
soeren/glove
|
||||||
|
bounds: 156, 12, 42, 53
|
||||||
|
soeren/hair-front
|
||||||
|
bounds: 154, 139, 159, 113
|
||||||
|
soeren/head-base
|
||||||
|
bounds: 315, 127, 143, 125
|
||||||
|
soeren/leg
|
||||||
|
bounds: 460, 151, 28, 101
|
||||||
|
|
||||||
|
chibi-stickers-pma_10.png
|
||||||
|
size: 512, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
pma: true
|
||||||
|
scale: 0.5
|
||||||
|
spineboy/arm
|
||||||
|
bounds: 407, 97, 28, 90
|
||||||
|
rotate: 90
|
||||||
|
spineboy/arm-decoration
|
||||||
|
bounds: 307, 127, 32, 29
|
||||||
|
spineboy/arm-shoulder-decoration
|
||||||
|
bounds: 451, 72, 23, 23
|
||||||
|
spineboy/back-hair
|
||||||
|
bounds: 2, 106, 158, 141
|
||||||
|
spineboy/blush
|
||||||
|
bounds: 2, 2, 29, 18
|
||||||
|
spineboy/body
|
||||||
|
bounds: 307, 55, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
spineboy/ear
|
||||||
|
bounds: 407, 61, 34, 42
|
||||||
|
rotate: 90
|
||||||
|
spineboy/eyebrow
|
||||||
|
bounds: 143, 77, 27, 12
|
||||||
|
rotate: 90
|
||||||
|
spineboy/glasses
|
||||||
|
bounds: 162, 158, 179, 89
|
||||||
|
spineboy/glasses-shadow
|
||||||
|
bounds: 2, 22, 139, 82
|
||||||
|
spineboy/hair-front
|
||||||
|
bounds: 343, 127, 145, 120
|
||||||
|
spineboy/head-base
|
||||||
|
bounds: 162, 31, 143, 125
|
||||||
|
spineboy/leg
|
||||||
|
bounds: 307, 24, 29, 101
|
||||||
|
rotate: 90
|
||||||
BIN
spine-ts/spine-webgl/example/assets/chibi-stickers-pma.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
spine-ts/spine-webgl/example/assets/chibi-stickers-pma_10.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
spine-ts/spine-webgl/example/assets/chibi-stickers-pma_2.png
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
spine-ts/spine-webgl/example/assets/chibi-stickers-pma_3.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
spine-ts/spine-webgl/example/assets/chibi-stickers-pma_4.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
spine-ts/spine-webgl/example/assets/chibi-stickers-pma_5.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
spine-ts/spine-webgl/example/assets/chibi-stickers-pma_6.png
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
spine-ts/spine-webgl/example/assets/chibi-stickers-pma_7.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
spine-ts/spine-webgl/example/assets/chibi-stickers-pma_8.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
spine-ts/spine-webgl/example/assets/chibi-stickers-pma_9.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
425
spine-ts/spine-webgl/example/assets/chibi-stickers.atlas
Normal file
@ -0,0 +1,425 @@
|
|||||||
|
chibi-stickers.png
|
||||||
|
size: 512, 128
|
||||||
|
filter: Linear, Linear
|
||||||
|
scale: 0.5
|
||||||
|
common/angry-mark
|
||||||
|
bounds: 278, 85, 42, 41
|
||||||
|
common/big-purple-fear
|
||||||
|
bounds: 2, 54, 134, 72
|
||||||
|
common/big-tear
|
||||||
|
bounds: 138, 93, 33, 82
|
||||||
|
rotate: 90
|
||||||
|
common/eye-3
|
||||||
|
bounds: 226, 25, 15, 26
|
||||||
|
common/eye-closed-happy
|
||||||
|
bounds: 267, 7, 25, 9
|
||||||
|
rotate: 90
|
||||||
|
common/eye-dafault
|
||||||
|
bounds: 203, 20, 22, 21
|
||||||
|
rotate: 90
|
||||||
|
common/eye-equal
|
||||||
|
bounds: 308, 43, 25, 15
|
||||||
|
common/eye-fire
|
||||||
|
bounds: 278, 57, 26, 28
|
||||||
|
rotate: 90
|
||||||
|
common/eye-half-open
|
||||||
|
bounds: 138, 2, 26, 16
|
||||||
|
common/eye-heart
|
||||||
|
bounds: 308, 60, 26, 23
|
||||||
|
common/eye-reverse-v
|
||||||
|
bounds: 166, 2, 26, 16
|
||||||
|
common/eye-sideway-v
|
||||||
|
bounds: 336, 60, 21, 23
|
||||||
|
common/eye-slant-close
|
||||||
|
bounds: 194, 2, 23, 16
|
||||||
|
common/eye-small-dot
|
||||||
|
bounds: 119, 2, 15, 15
|
||||||
|
common/eye-sparkle
|
||||||
|
bounds: 372, 97, 30, 29
|
||||||
|
common/eye-star
|
||||||
|
bounds: 404, 99, 29, 27
|
||||||
|
common/eye-twirl
|
||||||
|
bounds: 226, 2, 21, 23
|
||||||
|
rotate: 90
|
||||||
|
common/eye-u
|
||||||
|
bounds: 2, 2, 24, 17
|
||||||
|
common/eye-x
|
||||||
|
bounds: 176, 20, 25, 22
|
||||||
|
common/lamp
|
||||||
|
bounds: 138, 44, 47, 65
|
||||||
|
rotate: 90
|
||||||
|
common/mouth-3
|
||||||
|
bounds: 89, 2, 15, 28
|
||||||
|
rotate: 90
|
||||||
|
common/mouth-bracket
|
||||||
|
bounds: 322, 85, 34, 11
|
||||||
|
common/mouth-doubt
|
||||||
|
bounds: 243, 34, 26, 15
|
||||||
|
common/mouth-fangs
|
||||||
|
bounds: 205, 52, 39, 14
|
||||||
|
rotate: 90
|
||||||
|
common/mouth-line
|
||||||
|
bounds: 435, 96, 36, 7
|
||||||
|
common/mouth-neutral
|
||||||
|
bounds: 245, 51, 27, 12
|
||||||
|
common/mouth-o-tall
|
||||||
|
bounds: 221, 53, 22, 33
|
||||||
|
common/mouth-open-smile
|
||||||
|
bounds: 138, 20, 36, 22
|
||||||
|
common/mouth-rectangle
|
||||||
|
bounds: 435, 105, 35, 21
|
||||||
|
common/mouth-reverse-v
|
||||||
|
bounds: 473, 95, 27, 10
|
||||||
|
common/mouth-s
|
||||||
|
bounds: 28, 8, 41, 11
|
||||||
|
common/mouth-smile-little
|
||||||
|
bounds: 117, 19, 33, 19
|
||||||
|
rotate: 90
|
||||||
|
common/mouth-toungue-sticking-out
|
||||||
|
bounds: 245, 65, 31, 21
|
||||||
|
common/mouth-u
|
||||||
|
bounds: 472, 107, 36, 19
|
||||||
|
common/mouth-v
|
||||||
|
bounds: 251, 5, 27, 14
|
||||||
|
rotate: 90
|
||||||
|
common/mouth-x
|
||||||
|
bounds: 335, 38, 21, 20
|
||||||
|
common/purple-fear-lines
|
||||||
|
bounds: 322, 98, 48, 28
|
||||||
|
common/shadow
|
||||||
|
bounds: 2, 21, 113, 31
|
||||||
|
common/small-dash
|
||||||
|
bounds: 404, 88, 9, 20
|
||||||
|
rotate: 90
|
||||||
|
common/small-drop-line
|
||||||
|
bounds: 71, 2, 16, 17
|
||||||
|
common/small-purple-fear
|
||||||
|
bounds: 222, 88, 54, 38
|
||||||
|
common/tear
|
||||||
|
bounds: 274, 36, 20, 19
|
||||||
|
|
||||||
|
chibi-stickers_2.png
|
||||||
|
size: 1024, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
scale: 0.5
|
||||||
|
erikari/arm
|
||||||
|
bounds: 981, 164, 28, 90
|
||||||
|
erikari/arm-shoulder-decoration
|
||||||
|
bounds: 790, 149, 32, 43
|
||||||
|
erikari/back-hair
|
||||||
|
bounds: 258, 113, 158, 141
|
||||||
|
erikari/back-hair-long
|
||||||
|
bounds: 2, 34, 220, 254
|
||||||
|
rotate: 90
|
||||||
|
erikari/blush
|
||||||
|
bounds: 981, 133, 29, 18
|
||||||
|
rotate: 90
|
||||||
|
erikari/body
|
||||||
|
bounds: 584, 115, 70, 98
|
||||||
|
erikari/bracelet
|
||||||
|
bounds: 1011, 221, 33, 11
|
||||||
|
rotate: 90
|
||||||
|
erikari/collar
|
||||||
|
bounds: 390, 48, 61, 62
|
||||||
|
erikari/ear
|
||||||
|
bounds: 258, 2, 34, 42
|
||||||
|
erikari/eyebrow
|
||||||
|
bounds: 453, 98, 20, 12
|
||||||
|
erikari/hair-front
|
||||||
|
bounds: 258, 46, 130, 65
|
||||||
|
erikari/hair-side
|
||||||
|
bounds: 656, 149, 43, 132
|
||||||
|
rotate: 90
|
||||||
|
erikari/hat-border
|
||||||
|
bounds: 418, 215, 254, 39
|
||||||
|
erikari/hat-top
|
||||||
|
bounds: 674, 194, 160, 60
|
||||||
|
erikari/head-base
|
||||||
|
bounds: 836, 129, 143, 125
|
||||||
|
erikari/leg
|
||||||
|
bounds: 2, 4, 28, 101
|
||||||
|
rotate: 90
|
||||||
|
erikari/leg-decoration
|
||||||
|
bounds: 770, 134, 36, 13
|
||||||
|
erikari/skirt
|
||||||
|
bounds: 418, 112, 164, 101
|
||||||
|
erikari/strawberries-decoration
|
||||||
|
bounds: 656, 91, 112, 56
|
||||||
|
|
||||||
|
chibi-stickers_3.png
|
||||||
|
size: 512, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
scale: 0.5
|
||||||
|
harri/arm
|
||||||
|
bounds: 147, 21, 28, 90
|
||||||
|
rotate: 90
|
||||||
|
harri/back-hair
|
||||||
|
bounds: 2, 107, 158, 141
|
||||||
|
harri/back-hair-long
|
||||||
|
bounds: 147, 51, 40, 80
|
||||||
|
rotate: 90
|
||||||
|
harri/beard
|
||||||
|
bounds: 2, 2, 10, 11
|
||||||
|
harri/blush
|
||||||
|
bounds: 265, 103, 29, 18
|
||||||
|
harri/body
|
||||||
|
bounds: 307, 94, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
harri/body-decoration
|
||||||
|
bounds: 407, 97, 70, 67
|
||||||
|
harri/ear
|
||||||
|
bounds: 229, 57, 34, 42
|
||||||
|
rotate: 90
|
||||||
|
harri/eyebrow
|
||||||
|
bounds: 494, 226, 22, 12
|
||||||
|
rotate: 90
|
||||||
|
harri/hair-front
|
||||||
|
bounds: 2, 15, 143, 90
|
||||||
|
harri/head-base
|
||||||
|
bounds: 162, 123, 143, 125
|
||||||
|
harri/leg
|
||||||
|
bounds: 162, 93, 28, 101
|
||||||
|
rotate: 90
|
||||||
|
harri/sword
|
||||||
|
bounds: 307, 166, 185, 82
|
||||||
|
|
||||||
|
chibi-stickers_4.png
|
||||||
|
size: 1024, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
scale: 0.5
|
||||||
|
luke/arm
|
||||||
|
bounds: 930, 224, 28, 90
|
||||||
|
rotate: 90
|
||||||
|
luke/arm-shoulder-decoration
|
||||||
|
bounds: 581, 112, 31, 27
|
||||||
|
rotate: 90
|
||||||
|
luke/back-hair
|
||||||
|
bounds: 173, 111, 158, 141
|
||||||
|
luke/blush
|
||||||
|
bounds: 151, 68, 29, 18
|
||||||
|
rotate: 90
|
||||||
|
luke/body
|
||||||
|
bounds: 700, 123, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
luke/eyebrow
|
||||||
|
bounds: 2, 2, 27, 12
|
||||||
|
luke/face-cover
|
||||||
|
bounds: 2, 99, 169, 153
|
||||||
|
luke/glasses-shadow
|
||||||
|
bounds: 2, 16, 147, 81
|
||||||
|
luke/hair-decoration
|
||||||
|
bounds: 478, 145, 130, 107
|
||||||
|
luke/hair-front
|
||||||
|
bounds: 700, 195, 122, 57
|
||||||
|
luke/head-base
|
||||||
|
bounds: 333, 127, 143, 125
|
||||||
|
luke/leg
|
||||||
|
bounds: 478, 115, 28, 101
|
||||||
|
rotate: 90
|
||||||
|
luke/shield
|
||||||
|
bounds: 610, 148, 88, 104
|
||||||
|
luke/skirt
|
||||||
|
bounds: 930, 191, 81, 31
|
||||||
|
luke/sword
|
||||||
|
bounds: 824, 181, 104, 71
|
||||||
|
|
||||||
|
chibi-stickers_5.png
|
||||||
|
size: 512, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
scale: 0.5
|
||||||
|
mario/arm
|
||||||
|
bounds: 244, 2, 28, 90
|
||||||
|
mario/back-hair
|
||||||
|
bounds: 2, 101, 168, 148
|
||||||
|
mario/back-hair-long
|
||||||
|
bounds: 151, 6, 86, 91
|
||||||
|
rotate: 90
|
||||||
|
mario/beard
|
||||||
|
bounds: 2, 6, 147, 93
|
||||||
|
mario/blush
|
||||||
|
bounds: 492, 220, 29, 18
|
||||||
|
rotate: 90
|
||||||
|
mario/body
|
||||||
|
bounds: 317, 111, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
mario/ear
|
||||||
|
bounds: 456, 207, 34, 42
|
||||||
|
mario/eyebrow
|
||||||
|
bounds: 417, 164, 32, 17
|
||||||
|
mario/hair-front
|
||||||
|
bounds: 317, 183, 137, 66
|
||||||
|
mario/head-base
|
||||||
|
bounds: 172, 124, 143, 125
|
||||||
|
mario/leg
|
||||||
|
bounds: 172, 94, 28, 101
|
||||||
|
rotate: 90
|
||||||
|
|
||||||
|
chibi-stickers_6.png
|
||||||
|
size: 1024, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
scale: 0.5
|
||||||
|
misaki/arm
|
||||||
|
bounds: 609, 95, 28, 90
|
||||||
|
misaki/back-hair
|
||||||
|
bounds: 194, 105, 158, 141
|
||||||
|
misaki/back-hair-long
|
||||||
|
bounds: 2, 51, 190, 195
|
||||||
|
misaki/belt
|
||||||
|
bounds: 741, 190, 76, 26
|
||||||
|
misaki/blush
|
||||||
|
bounds: 844, 228, 29, 18
|
||||||
|
misaki/body
|
||||||
|
bounds: 641, 176, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
misaki/ear
|
||||||
|
bounds: 144, 7, 34, 42
|
||||||
|
misaki/eyebrow
|
||||||
|
bounds: 194, 54, 30, 12
|
||||||
|
misaki/glasses
|
||||||
|
bounds: 194, 68, 141, 35
|
||||||
|
misaki/glasses-side
|
||||||
|
bounds: 354, 111, 8, 23
|
||||||
|
rotate: 90
|
||||||
|
misaki/hair-front
|
||||||
|
bounds: 499, 187, 140, 59
|
||||||
|
misaki/hair-side
|
||||||
|
bounds: 2, 2, 47, 140
|
||||||
|
rotate: 90
|
||||||
|
misaki/head-base
|
||||||
|
bounds: 354, 121, 143, 125
|
||||||
|
misaki/leg
|
||||||
|
bounds: 741, 218, 28, 101
|
||||||
|
rotate: 90
|
||||||
|
misaki/skirt
|
||||||
|
bounds: 499, 95, 108, 90
|
||||||
|
|
||||||
|
chibi-stickers_7.png
|
||||||
|
size: 512, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
scale: 0.5
|
||||||
|
nate/arm
|
||||||
|
bounds: 151, 65, 28, 90
|
||||||
|
rotate: 90
|
||||||
|
nate/back-hair
|
||||||
|
bounds: 2, 109, 158, 141
|
||||||
|
nate/beard
|
||||||
|
bounds: 2, 39, 147, 68
|
||||||
|
nate/blush
|
||||||
|
bounds: 407, 165, 29, 18
|
||||||
|
nate/body
|
||||||
|
bounds: 307, 113, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
nate/ear
|
||||||
|
bounds: 451, 208, 34, 42
|
||||||
|
nate/eyebrow
|
||||||
|
bounds: 265, 111, 27, 12
|
||||||
|
nate/glasses
|
||||||
|
bounds: 2, 2, 141, 35
|
||||||
|
nate/glasses-side
|
||||||
|
bounds: 151, 47, 8, 16
|
||||||
|
nate/hair-front
|
||||||
|
bounds: 307, 185, 142, 65
|
||||||
|
nate/head-base
|
||||||
|
bounds: 162, 125, 143, 125
|
||||||
|
nate/leg
|
||||||
|
bounds: 162, 95, 28, 101
|
||||||
|
rotate: 90
|
||||||
|
|
||||||
|
chibi-stickers_8.png
|
||||||
|
size: 512, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
scale: 0.5
|
||||||
|
sinisa/arm
|
||||||
|
bounds: 147, 52, 28, 90
|
||||||
|
rotate: 90
|
||||||
|
sinisa/back-hair
|
||||||
|
bounds: 2, 96, 158, 141
|
||||||
|
sinisa/beard
|
||||||
|
bounds: 307, 192, 139, 45
|
||||||
|
sinisa/blush
|
||||||
|
bounds: 147, 32, 29, 18
|
||||||
|
sinisa/body
|
||||||
|
bounds: 307, 120, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
sinisa/body-decoration
|
||||||
|
bounds: 265, 83, 27, 27
|
||||||
|
sinisa/ear
|
||||||
|
bounds: 448, 195, 34, 42
|
||||||
|
sinisa/eyebrow
|
||||||
|
bounds: 407, 171, 38, 19
|
||||||
|
sinisa/hair-front
|
||||||
|
bounds: 2, 2, 143, 92
|
||||||
|
sinisa/head-base
|
||||||
|
bounds: 162, 112, 143, 125
|
||||||
|
sinisa/leg
|
||||||
|
bounds: 162, 82, 28, 101
|
||||||
|
rotate: 90
|
||||||
|
|
||||||
|
chibi-stickers_9.png
|
||||||
|
size: 512, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
scale: 0.5
|
||||||
|
soeren/arm
|
||||||
|
bounds: 254, 47, 28, 90
|
||||||
|
soeren/back-hair
|
||||||
|
bounds: 2, 111, 150, 141
|
||||||
|
soeren/beard
|
||||||
|
bounds: 2, 41, 145, 68
|
||||||
|
soeren/blush
|
||||||
|
bounds: 284, 119, 29, 18
|
||||||
|
soeren/body
|
||||||
|
bounds: 154, 67, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
soeren/ear
|
||||||
|
bounds: 200, 23, 34, 42
|
||||||
|
soeren/eyebrow
|
||||||
|
bounds: 460, 137, 27, 12
|
||||||
|
soeren/glasses
|
||||||
|
bounds: 2, 2, 152, 37
|
||||||
|
soeren/glasses-side
|
||||||
|
bounds: 490, 245, 7, 20
|
||||||
|
rotate: 90
|
||||||
|
soeren/glove
|
||||||
|
bounds: 156, 12, 42, 53
|
||||||
|
soeren/hair-front
|
||||||
|
bounds: 154, 139, 159, 113
|
||||||
|
soeren/head-base
|
||||||
|
bounds: 315, 127, 143, 125
|
||||||
|
soeren/leg
|
||||||
|
bounds: 460, 151, 28, 101
|
||||||
|
|
||||||
|
chibi-stickers_10.png
|
||||||
|
size: 512, 256
|
||||||
|
filter: Linear, Linear
|
||||||
|
scale: 0.5
|
||||||
|
spineboy/arm
|
||||||
|
bounds: 407, 97, 28, 90
|
||||||
|
rotate: 90
|
||||||
|
spineboy/arm-decoration
|
||||||
|
bounds: 307, 127, 32, 29
|
||||||
|
spineboy/arm-shoulder-decoration
|
||||||
|
bounds: 451, 72, 23, 23
|
||||||
|
spineboy/back-hair
|
||||||
|
bounds: 2, 106, 158, 141
|
||||||
|
spineboy/blush
|
||||||
|
bounds: 2, 2, 29, 18
|
||||||
|
spineboy/body
|
||||||
|
bounds: 307, 55, 70, 98
|
||||||
|
rotate: 90
|
||||||
|
spineboy/ear
|
||||||
|
bounds: 407, 61, 34, 42
|
||||||
|
rotate: 90
|
||||||
|
spineboy/eyebrow
|
||||||
|
bounds: 143, 77, 27, 12
|
||||||
|
rotate: 90
|
||||||
|
spineboy/glasses
|
||||||
|
bounds: 162, 158, 179, 89
|
||||||
|
spineboy/glasses-shadow
|
||||||
|
bounds: 2, 22, 139, 82
|
||||||
|
spineboy/hair-front
|
||||||
|
bounds: 343, 127, 145, 120
|
||||||
|
spineboy/head-base
|
||||||
|
bounds: 162, 31, 143, 125
|
||||||
|
spineboy/leg
|
||||||
|
bounds: 307, 24, 29, 101
|
||||||
|
rotate: 90
|
||||||
7597
spine-ts/spine-webgl/example/assets/chibi-stickers.json
Normal file
BIN
spine-ts/spine-webgl/example/assets/chibi-stickers.skel
Normal file
@ -132,196 +132,78 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<!-- <div style="height: 1200px; flex-direction: column;">
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
/////////////////////
|
||||||
|
// start section 1 //
|
||||||
|
/////////////////////
|
||||||
|
-->
|
||||||
|
|
||||||
|
<div id="section1" class="section vertical-split">
|
||||||
|
|
||||||
|
<div class="split-top split">
|
||||||
|
<div class="split-left">
|
||||||
|
<spine-widget
|
||||||
|
atlas="assets/raptor-pma.atlas"
|
||||||
|
skeleton="assets/raptor-pro.skel"
|
||||||
|
animation="walk"
|
||||||
|
scale="3"
|
||||||
|
clip="true"
|
||||||
|
fit="fitHeight"
|
||||||
|
></spine-widget>
|
||||||
|
</div>
|
||||||
|
<div class="split-right">
|
||||||
|
<spine-widget
|
||||||
|
atlas="assets/spineboy-pma.atlas"
|
||||||
|
skeleton="assets/spineboy-pro.skel"
|
||||||
|
animation="walk"
|
||||||
|
scale="1.5"
|
||||||
|
fit="none"
|
||||||
|
clip="true"
|
||||||
|
></spine-widget>
|
||||||
|
</div>
|
||||||
|
<div class="split-right">
|
||||||
|
<spine-widget
|
||||||
|
atlas="assets/spineboy-pma.atlas"
|
||||||
|
skeleton="assets/spineboy-pro.skel"
|
||||||
|
animation="walk"
|
||||||
|
scale="1"
|
||||||
|
fit="none"
|
||||||
|
clip="true"
|
||||||
|
></spine-widget>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="split-right">
|
||||||
|
<spine-widget
|
||||||
|
atlas="assets/cloud-pot-pma.atlas"
|
||||||
|
skeleton="assets/cloud-pot.skel"
|
||||||
|
animation="playing-in-the-rain"
|
||||||
|
draggable="true"
|
||||||
|
></spine-widget>
|
||||||
|
</div>
|
||||||
|
<div class="split-right">
|
||||||
|
<spine-widget
|
||||||
|
atlas="assets/celestial-circus-pma.atlas"
|
||||||
|
skeleton="assets/celestial-circus-pro.skel"
|
||||||
|
animation="wings-and-feet"
|
||||||
|
draggable="true"
|
||||||
|
></spine-widget>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<div style="height: 1200px; flex-direction: column;">
|
<div style="height: 1200px; flex-direction: column;">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
/////////////////////
|
/////////////////////
|
||||||
// start section 7 //
|
// end section 1 //
|
||||||
/////////////////////
|
/////////////////////
|
||||||
-->
|
-->
|
||||||
<div id="section1" class="section vertical-split">
|
|
||||||
|
|
||||||
<div class="split" style="width: 100%; flex-direction: column;">
|
|
||||||
|
|
||||||
<div class="split-left" style="width: 80%; box-sizing: border-box;">
|
|
||||||
If you have many atlas pages, for example one for each skin, and you want to show only some of the skins,
|
|
||||||
pass to the <code>pages</code> the atlas pages you want to load as a comma concatenated list of indices.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="skin-grid">
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="emotes/wave"
|
|
||||||
skin="nate"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="skin-grid">
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="emotes/wave"
|
|
||||||
skin="erikari"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
offscreen="update"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="skin-grid">
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="emotes/wave"
|
|
||||||
skin="mario"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
offscreen="pose"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="split-bottom">
|
|
||||||
<pre><code id="code-display">
|
|
||||||
<script>
|
|
||||||
escapeHTMLandInject(`
|
|
||||||
<div class="skin-grid">
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="emotes/wave"
|
|
||||||
skin="nate"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="movement/trot-left"
|
|
||||||
skin="nate"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="emotes/idea"
|
|
||||||
skin="nate"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="emotes/hooray"
|
|
||||||
skin="nate"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="skin-grid">
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="emotes/wave"
|
|
||||||
skin="erikari"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="movement/trot-left"
|
|
||||||
skin="erikari"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="emotes/idea"
|
|
||||||
skin="erikari"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="emotes/hooray"
|
|
||||||
skin="erikari"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="skin-grid">
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="emotes/wave"
|
|
||||||
skin="mario"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="movement/trot-left"
|
|
||||||
skin="mario"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="emotes/idea"
|
|
||||||
skin="mario"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
<div class="skin-grid-element">
|
|
||||||
<spine-widget
|
|
||||||
atlas="assets/chibi-stickers-pma.atlas"
|
|
||||||
skeleton="assets/chibi-stickers.skel"
|
|
||||||
animation="emotes/hooray"
|
|
||||||
skin="mario"
|
|
||||||
pages="0,1,4,6"
|
|
||||||
></spine-widget>
|
|
||||||
</div>
|
|
||||||
</div>`)
|
|
||||||
</script>
|
|
||||||
</code></pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--
|
|
||||||
/////////////////////
|
|
||||||
// end section 7 //
|
|
||||||
/////////////////////
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -3,8 +3,8 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<script src="../dist/iife/spine-webgl.js"></script>
|
<!-- <script src="../dist/iife/spine-webgl.js"></script> -->
|
||||||
<!-- <script src="./spine-webgl.min.js"></script> -->
|
<script src="./spine-webgl.min.js"></script>
|
||||||
<title>JS Library Showcase</title>
|
<title>JS Library Showcase</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
@ -1558,6 +1558,200 @@ stretchyman.update = (canvas, delta, skeleton, state) => {
|
|||||||
/////////////////////
|
/////////////////////
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
/////////////////////
|
||||||
|
// start section 8 //
|
||||||
|
/////////////////////
|
||||||
|
-->
|
||||||
|
<div id="section1" class="section vertical-split">
|
||||||
|
|
||||||
|
<div class="split" style="width: 100%; flex-direction: column;">
|
||||||
|
|
||||||
|
<div class="split-left" style="width: 80%; box-sizing: border-box;">
|
||||||
|
If for some reason your skeleton bounds go outside the div,
|
||||||
|
you can use the <code>clip</code> property to clip everything is outside the html container.
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
Be aware that this will break batching!
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="split-left" style="width: 80%; box-sizing: border-box; height: 150px;">
|
||||||
|
<spine-widget
|
||||||
|
identifier="tank2"
|
||||||
|
atlas="assets/tank-pma.atlas"
|
||||||
|
skeleton="assets/tank-pro.skel"
|
||||||
|
animation="drive"
|
||||||
|
></spine-widget>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="split-left" style="width: 30%; box-sizing: border-box; height: 150px;">
|
||||||
|
<spine-widget
|
||||||
|
identifier="tank"
|
||||||
|
atlas="assets/tank-pma.atlas"
|
||||||
|
skeleton="assets/tank-pro.skel"
|
||||||
|
animation="drive"
|
||||||
|
fit="none"
|
||||||
|
clip="true"
|
||||||
|
></spine-widget>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(async () => {
|
||||||
|
const tank = spine.getSpineWidget("tank");
|
||||||
|
const tank2 = spine.getSpineWidget("tank2");
|
||||||
|
await tank.loadingPromise;
|
||||||
|
await tank2.loadingPromise;
|
||||||
|
|
||||||
|
tank.beforeUpdateWorldTransforms = (canvas, delta, skeleton, state) => {
|
||||||
|
if (!tank.onScreen) return;
|
||||||
|
tank.skeleton.scaleX = tank2.skeleton.scaleX;
|
||||||
|
tank.skeleton.scaleY = tank2.skeleton.scaleY;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="split-bottom">
|
||||||
|
<pre><code id="code-display">
|
||||||
|
<script>
|
||||||
|
escapeHTMLandInject(`
|
||||||
|
<div class="split-left" style="width: 80%; box-sizing: border-box; height: 150px;">
|
||||||
|
<spine-widget
|
||||||
|
identifier="tank2"
|
||||||
|
atlas="assets/tank-pma.atlas"
|
||||||
|
skeleton="assets/tank-pro.skel"
|
||||||
|
animation="drive"
|
||||||
|
></spine-widget>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="split-left" style="width: 30%; box-sizing: border-box; height: 150px;">
|
||||||
|
<spine-widget
|
||||||
|
identifier="tank"
|
||||||
|
atlas="assets/tank-pma.atlas"
|
||||||
|
skeleton="assets/tank-pro.skel"
|
||||||
|
animation="drive"
|
||||||
|
fit="none"
|
||||||
|
clip="true"
|
||||||
|
></spine-widget>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const tank = spine.getSpineWidget("tank");
|
||||||
|
const tank2 = spine.getSpineWidget("tank2");
|
||||||
|
await tank.loadingPromise;
|
||||||
|
await tank2.loadingPromise;
|
||||||
|
|
||||||
|
// since we want the tank to overflow the div, we set fit to none
|
||||||
|
// then we "sync" the tank scale to the one of the tank above
|
||||||
|
tank.beforeUpdateWorldTransforms = (canvas, delta, skeleton, state) => {
|
||||||
|
if (!tank.onScreen) return;
|
||||||
|
tank.skeleton.scaleX = tank2.skeleton.scaleX;
|
||||||
|
tank.skeleton.scaleY = tank2.skeleton.scaleY;
|
||||||
|
}
|
||||||
|
})();`);
|
||||||
|
</script>
|
||||||
|
</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
/////////////////////
|
||||||
|
// end section 8 //
|
||||||
|
/////////////////////
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
/////////////////////
|
||||||
|
// start section 8 //
|
||||||
|
/////////////////////
|
||||||
|
-->
|
||||||
|
<div id="section1" class="section vertical-split">
|
||||||
|
|
||||||
|
<div class="split" style="width: 100%; flex-direction: column;">
|
||||||
|
|
||||||
|
<div class="split-top split">
|
||||||
|
<div class="split-left">
|
||||||
|
<spine-widget
|
||||||
|
atlas="assets/spineboy-pma.atlas"
|
||||||
|
skeleton="assets/spineboy-pro.skel"
|
||||||
|
animation="walk"
|
||||||
|
scale="3"
|
||||||
|
fit="none"
|
||||||
|
clip="true"
|
||||||
|
></spine-widget>
|
||||||
|
</div>
|
||||||
|
<div class="split-right">
|
||||||
|
<spine-widget
|
||||||
|
atlas="assets/spineboy-pma.atlas"
|
||||||
|
skeleton="assets/spineboy-pro.skel"
|
||||||
|
animation="walk"
|
||||||
|
scale="1.5"
|
||||||
|
fit="none"
|
||||||
|
clip="true"
|
||||||
|
></spine-widget>
|
||||||
|
</div>
|
||||||
|
<div class="split-right">
|
||||||
|
<spine-widget
|
||||||
|
atlas="assets/spineboy-pma.atlas"
|
||||||
|
skeleton="assets/spineboy-pro.skel"
|
||||||
|
animation="walk"
|
||||||
|
scale="1"
|
||||||
|
fit="none"
|
||||||
|
clip="true"
|
||||||
|
></spine-widget>
|
||||||
|
</div>
|
||||||
|
<div class="split-right">
|
||||||
|
<spine-widget
|
||||||
|
atlas="assets/cloud-pot-pma.atlas"
|
||||||
|
skeleton="assets/cloud-pot.skel"
|
||||||
|
animation="playing-in-the-rain"
|
||||||
|
scale="0.5"
|
||||||
|
fit="none"
|
||||||
|
clip="true"
|
||||||
|
></spine-widget>
|
||||||
|
</div>
|
||||||
|
<div class="split-right">
|
||||||
|
<spine-widget
|
||||||
|
identifier="celeste"
|
||||||
|
atlas="assets/celestial-circus-pma.atlas"
|
||||||
|
skeleton="assets/celestial-circus-pro.skel"
|
||||||
|
animation="wings-and-feet"
|
||||||
|
clip="true"
|
||||||
|
></spine-widget>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(async () => {
|
||||||
|
const celeste = spine.getSpineWidget("celeste");
|
||||||
|
await celeste.loadingPromise;
|
||||||
|
celeste.state.setAnimation(0, "swing", true);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="split-bottom">
|
||||||
|
<pre><code id="code-display">
|
||||||
|
<script>
|
||||||
|
escapeHTMLandInject(`
|
||||||
|
...`);
|
||||||
|
</script>
|
||||||
|
</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
/////////////////////
|
||||||
|
// end section 8 //
|
||||||
|
/////////////////////
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|||||||
1941
spine-ts/spine-webgl/example/canvas9.html
Normal file
@ -470,6 +470,17 @@ export class SceneRenderer implements Disposable {
|
|||||||
this.camera.update();
|
this.camera.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resize3 (width: number, height: number) {
|
||||||
|
console.log("resize gl")
|
||||||
|
let canvas = this.canvas;
|
||||||
|
const dpr = window.devicePixelRatio;
|
||||||
|
this.canvas.width = Math.round(width * dpr);
|
||||||
|
this.canvas.height = Math.round(height * dpr);
|
||||||
|
this.context.gl.viewport(0, 0, canvas.width, canvas.height);
|
||||||
|
this.camera.setViewport(canvas.width, canvas.height);
|
||||||
|
this.camera.update();
|
||||||
|
}
|
||||||
|
|
||||||
resize (resizeMode: ResizeMode) {
|
resize (resizeMode: ResizeMode) {
|
||||||
let canvas = this.canvas;
|
let canvas = this.canvas;
|
||||||
var dpr = window.devicePixelRatio || 1;
|
var dpr = window.devicePixelRatio || 1;
|
||||||
|
|||||||
@ -36,7 +36,7 @@ interface Rectangle {
|
|||||||
height: number,
|
height: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateSpineFunction = (canvas: SpineCanvas, delta: number, skeleton: Skeleton, state: AnimationState) => void;
|
type UpdateSpineWidgetFunction = (canvas: SpineCanvas, delta: number, skeleton: Skeleton, state: AnimationState) => void;
|
||||||
|
|
||||||
type OffScreenUpdateBehaviourType = "pause" | "update" | "pose";
|
type OffScreenUpdateBehaviourType = "pause" | "update" | "pose";
|
||||||
function isOffScreenUpdateBehaviourType(value: string): value is OffScreenUpdateBehaviourType {
|
function isOffScreenUpdateBehaviourType(value: string): value is OffScreenUpdateBehaviourType {
|
||||||
@ -97,6 +97,7 @@ interface WidgetInternalState {
|
|||||||
dragY: number
|
dragY: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: add missing assets to main assets folder (chibi)
|
||||||
|
|
||||||
class SpineWebComponentWidget extends HTMLElement implements WidgetLayoutOptions, WidgetInternalState, Partial<WidgetPublicState> {
|
class SpineWebComponentWidget extends HTMLElement implements WidgetLayoutOptions, WidgetInternalState, Partial<WidgetPublicState> {
|
||||||
|
|
||||||
@ -107,7 +108,9 @@ class SpineWebComponentWidget extends HTMLElement implements WidgetLayoutOptions
|
|||||||
public animation?: string;
|
public animation?: string;
|
||||||
public skin?: string;
|
public skin?: string;
|
||||||
skeletonData?: SkeletonData; // TODO
|
skeletonData?: SkeletonData; // TODO
|
||||||
update?: UpdateSpineFunction; // TODO
|
update?: UpdateSpineWidgetFunction;
|
||||||
|
beforeUpdateWorldTransforms: UpdateSpineWidgetFunction = () => {};
|
||||||
|
afterUpdateWorldTransforms: UpdateSpineWidgetFunction= () => {};
|
||||||
|
|
||||||
// layout options
|
// layout options
|
||||||
public fit: FitType = "contain";
|
public fit: FitType = "contain";
|
||||||
@ -125,6 +128,7 @@ class SpineWebComponentWidget extends HTMLElement implements WidgetLayoutOptions
|
|||||||
public manualStart = false;
|
public manualStart = false;
|
||||||
public pages?: Array<number>;
|
public pages?: Array<number>;
|
||||||
public offScreenUpdateBehaviour: OffScreenUpdateBehaviourType = "pause";
|
public offScreenUpdateBehaviour: OffScreenUpdateBehaviourType = "pause";
|
||||||
|
public clip = false;
|
||||||
|
|
||||||
// state
|
// state
|
||||||
public skeleton?: Skeleton;
|
public skeleton?: Skeleton;
|
||||||
@ -135,14 +139,6 @@ class SpineWebComponentWidget extends HTMLElement implements WidgetLayoutOptions
|
|||||||
public started = false;
|
public started = false;
|
||||||
public onScreenAtLeastOnce = false;
|
public onScreenAtLeastOnce = false;
|
||||||
|
|
||||||
// TODO tomorrow: la onScreenFunction di default carica le textures quando il widget viene rivelato sullo schermo.
|
|
||||||
// capire se va bene come comportamento di default
|
|
||||||
// poi spiegare i tre case
|
|
||||||
// no manual loading, no pages: tutte le pagine vengono caricate subito
|
|
||||||
// no manual loading, si pages: solo le pagine specificate vengono caricate subito (le altre se ne deve occupare manualmente il tizio)
|
|
||||||
// manual loading, no pages: tutte le pagine vengono caricate solo quando il widget è nella viewport
|
|
||||||
// manual loading, si pages: le pagine specificate vengono caricate solo quando il widget è nella viewport
|
|
||||||
// magari capire se mettere un altro parametro, tipo: loadsOnViewport
|
|
||||||
public onScreenFunction: (widget: SpineWebComponentWidget) => void = async (widget) => {
|
public onScreenFunction: (widget: SpineWebComponentWidget) => void = async (widget) => {
|
||||||
if (widget.loading && !widget.onScreenAtLeastOnce) {
|
if (widget.loading && !widget.onScreenAtLeastOnce) {
|
||||||
widget.onScreenAtLeastOnce = true;
|
widget.onScreenAtLeastOnce = true;
|
||||||
@ -193,7 +189,8 @@ class SpineWebComponentWidget extends HTMLElement implements WidgetLayoutOptions
|
|||||||
"manual-start",
|
"manual-start",
|
||||||
"spinner",
|
"spinner",
|
||||||
"pages",
|
"pages",
|
||||||
"offscreen"
|
"offscreen",
|
||||||
|
"clip",
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,6 +324,10 @@ class SpineWebComponentWidget extends HTMLElement implements WidgetLayoutOptions
|
|||||||
this.manualStart = Boolean(newValue);
|
this.manualStart = Boolean(newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name === "clip") {
|
||||||
|
this.clip = Boolean(newValue);
|
||||||
|
}
|
||||||
|
|
||||||
if (name === "pages") {
|
if (name === "pages") {
|
||||||
this.pages = newValue.split(",").reduce((acc, pageIndex) => {
|
this.pages = newValue.split(",").reduce((acc, pageIndex) => {
|
||||||
const index = parseInt(pageIndex);
|
const index = parseInt(pageIndex);
|
||||||
@ -591,6 +592,7 @@ class SpineWebComponentOverlay extends HTMLElement {
|
|||||||
private resizeObserver:ResizeObserver;
|
private resizeObserver:ResizeObserver;
|
||||||
private input: Input;
|
private input: Input;
|
||||||
|
|
||||||
|
// TODO: the canvas is now beg as the screen - maybe we can reduce the enhancement of the canvas and just translate
|
||||||
// how many pixels to add to the edges to prevent "edge cuttin" on fast scrolling
|
// how many pixels to add to the edges to prevent "edge cuttin" on fast scrolling
|
||||||
// be aware that the canvas is already big as the display size
|
// be aware that the canvas is already big as the display size
|
||||||
// making it bigger might reduce performance significantly
|
// making it bigger might reduce performance significantly
|
||||||
@ -623,6 +625,17 @@ class SpineWebComponentOverlay extends HTMLElement {
|
|||||||
this.canvas.style.position = "absolute";
|
this.canvas.style.position = "absolute";
|
||||||
this.canvas.style.top = "0";
|
this.canvas.style.top = "0";
|
||||||
this.canvas.style.left = "0";
|
this.canvas.style.left = "0";
|
||||||
|
|
||||||
|
// sono per l'ennesima volta fermo alla dimensione del canvas.
|
||||||
|
// purtroppo la dimensione dello schermo non permette di determinare la posizione dei div container relativamente allo schermo
|
||||||
|
// se trovassimo un modo per farlo, sarebbe fatta. provare prima a investigare un pochino lì.
|
||||||
|
//
|
||||||
|
// alternativamente giocare ancora con i lvh o qualcosa del genere
|
||||||
|
// purtroppo ho già provato un po' e si hanno oggettivamente dei brevi flash allo scroll quando la dimensione del canvas
|
||||||
|
// ovvero quando compare o scompare la barra durante lo scroll da mobile
|
||||||
|
|
||||||
|
// this.canvas.style.width = "100lvw";
|
||||||
|
// this.canvas.style.height = "120lvh";
|
||||||
this.canvas.style.setProperty("pointer-events", "none");
|
this.canvas.style.setProperty("pointer-events", "none");
|
||||||
this.canvas.style.transform =`translate(0px,0px)`;
|
this.canvas.style.transform =`translate(0px,0px)`;
|
||||||
// this.canvas.style.setProperty("will-change", "transform"); // performance seems to be even worse with this uncommented
|
// this.canvas.style.setProperty("will-change", "transform"); // performance seems to be even worse with this uncommented
|
||||||
@ -675,9 +688,10 @@ class SpineWebComponentOverlay extends HTMLElement {
|
|||||||
const red = new Color(1, 0, 0, 1);
|
const red = new Color(1, 0, 0, 1);
|
||||||
const green = new Color(0, 1, 0, 1);
|
const green = new Color(0, 1, 0, 1);
|
||||||
const blue = new Color(0, 0, 1, 1);
|
const blue = new Color(0, 0, 1, 1);
|
||||||
|
const transparentWhite = new Color(1, 1, 1, .3);
|
||||||
return {
|
return {
|
||||||
update: (canvas: SpineCanvas, delta: number) => {
|
update: (canvas: SpineCanvas, delta: number) => {
|
||||||
this.skeletonList.forEach(({ skeleton, state, update, onScreen, offScreenUpdateBehaviour, skeletonPath }) => {
|
this.skeletonList.forEach(({ skeleton, state, update, onScreen, offScreenUpdateBehaviour, skeletonPath, beforeUpdateWorldTransforms, afterUpdateWorldTransforms }) => {
|
||||||
if (!skeleton || !state) return;
|
if (!skeleton || !state) return;
|
||||||
if (!onScreen && offScreenUpdateBehaviour === "pause") return;
|
if (!onScreen && offScreenUpdateBehaviour === "pause") return;
|
||||||
if (update) update(canvas, delta, skeleton, state)
|
if (update) update(canvas, delta, skeleton, state)
|
||||||
@ -688,7 +702,9 @@ class SpineWebComponentOverlay extends HTMLElement {
|
|||||||
|
|
||||||
if (onScreen || (!onScreen && offScreenUpdateBehaviour === "pose") ) {
|
if (onScreen || (!onScreen && offScreenUpdateBehaviour === "pose") ) {
|
||||||
state.apply(skeleton);
|
state.apply(skeleton);
|
||||||
|
beforeUpdateWorldTransforms(canvas, delta, skeleton, state);
|
||||||
skeleton.updateWorldTransform(Physics.update);
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
|
afterUpdateWorldTransforms(canvas, delta, skeleton, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -703,67 +719,106 @@ class SpineWebComponentOverlay extends HTMLElement {
|
|||||||
const devicePixelRatio = window.devicePixelRatio;
|
const devicePixelRatio = window.devicePixelRatio;
|
||||||
const tempVector = new Vector3();
|
const tempVector = new Vector3();
|
||||||
this.skeletonList.forEach((widget) => {
|
this.skeletonList.forEach((widget) => {
|
||||||
const { skeleton, bounds, mode, debug, offsetX, offsetY, xAxis, yAxis, dragX, dragY, fit, loadingSpinner, onScreen, loading } = widget;
|
const { skeleton, bounds, mode, debug, offsetX, offsetY, xAxis, yAxis, dragX, dragY, fit, loadingSpinner, onScreen, loading, clip } = widget;
|
||||||
|
|
||||||
if ((!onScreen && dragX === 0 && dragY === 0)) return;
|
if ((!onScreen && dragX === 0 && dragY === 0)) return;
|
||||||
|
|
||||||
const divBounds = widget.getHTMLElementReference().getBoundingClientRect();
|
const divBounds = widget.getHTMLElementReference().getBoundingClientRect();
|
||||||
divBounds.x += this.overflowLeftSize;
|
divBounds.x += this.overflowLeftSize;
|
||||||
divBounds.y += this.overflowTopSize;
|
divBounds.y += this.overflowTopSize;
|
||||||
// get the desired point into the the div (center by default) in world coordinate
|
|
||||||
const divX = divBounds.x + divBounds.width * (xAxis + .5);
|
|
||||||
const divY = divBounds.y + divBounds.height * (-yAxis + .5);
|
|
||||||
this.screenToWorld(tempVector, divX, divY);
|
|
||||||
|
|
||||||
if (loading) {
|
// TODO: drag does not work while clip is on
|
||||||
if (loadingSpinner) {
|
|
||||||
if (!widget.loadingScreen) widget.loadingScreen = new LoadingScreenWidget(renderer);
|
// TODO: now that the clip logic works, remove the code duplication
|
||||||
widget.loadingScreen!.draw(true, tempVector.x, tempVector.y, divBounds.width * devicePixelRatio, divBounds.height * devicePixelRatio);
|
if (clip) {
|
||||||
|
const clipToBoundStart = (canvas: SpineCanvas, divBounds: Rectangle) => {
|
||||||
|
const renderer = canvas.renderer;
|
||||||
|
|
||||||
|
// break current batch and start a new one
|
||||||
|
renderer.end();
|
||||||
|
|
||||||
|
// set the new viewport to the div bound
|
||||||
|
const viewportWidth = divBounds.width * window.devicePixelRatio;
|
||||||
|
const viewporthHeight = divBounds.height * window.devicePixelRatio;
|
||||||
|
canvas.gl.viewport(
|
||||||
|
divBounds.x * window.devicePixelRatio,
|
||||||
|
this.canvas.height - (divBounds.y + divBounds.height) * window.devicePixelRatio,
|
||||||
|
viewportWidth,
|
||||||
|
viewporthHeight
|
||||||
|
);
|
||||||
|
renderer.camera.setViewport(viewportWidth, viewporthHeight);
|
||||||
|
renderer.camera.update();
|
||||||
|
|
||||||
|
// start the new batch that will be filled with only this skeleton
|
||||||
|
renderer.begin();
|
||||||
|
|
||||||
|
// TODO: debug - to remove
|
||||||
|
if (false) {
|
||||||
|
renderer.circle(true, -viewportWidth / 2, -viewporthHeight / 2, 20, red);
|
||||||
|
renderer.circle(true, viewportWidth / 2, -viewporthHeight / 2, 20, red);
|
||||||
|
renderer.circle(true, -viewportWidth / 2, viewporthHeight / 2, 20, red);
|
||||||
|
renderer.circle(true, viewportWidth / 2, viewporthHeight / 2, 20, red);
|
||||||
|
renderer.circle(true, 0, 0, 10, red);
|
||||||
|
|
||||||
|
renderer.rect(true, 0, 0, -viewportWidth, -viewporthHeight, transparentWhite);
|
||||||
|
renderer.rect(true, 0, 0, viewportWidth, viewporthHeight, transparentWhite);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skeleton) {
|
const clipToBoundEnd = () => {
|
||||||
let x = tempVector.x;
|
// end clip batch
|
||||||
let y = tempVector.y;
|
renderer.end();
|
||||||
if (mode === 'inside') {
|
|
||||||
let { x: ax, y: ay, width: aw, height: ah } = bounds!;
|
|
||||||
|
|
||||||
// scale ratio
|
canvas.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
|
||||||
const scaleWidth = divBounds.width * devicePixelRatio / aw;
|
canvas.renderer.camera.setViewport(this.canvas.width, this.canvas.height);
|
||||||
const scaleHeight = divBounds.height * devicePixelRatio / ah;
|
canvas.renderer.camera.update();
|
||||||
|
|
||||||
let ratioW = skeleton.scaleX;
|
// start new normal batch
|
||||||
let ratioH = skeleton.scaleY;
|
renderer.begin();
|
||||||
|
}
|
||||||
|
|
||||||
if (fit === "fill") { // Fill the target box by distorting the source's aspect ratio.
|
|
||||||
ratioW = scaleWidth;
|
|
||||||
ratioH = scaleHeight;
|
clipToBoundStart(canvas, divBounds)
|
||||||
} else if (fit === "fitWidth") {
|
|
||||||
ratioW = scaleWidth;
|
|
||||||
ratioH = scaleWidth;
|
|
||||||
} else if (fit === "fitHeight") {
|
// get the desired point into the the div (center by default) in world coordinate
|
||||||
ratioW = scaleHeight;
|
const divX = divBounds.x + divBounds.width * (xAxis + .5);
|
||||||
ratioH = scaleHeight;
|
const divY = divBounds.y + divBounds.height * (-yAxis + .5);
|
||||||
} else if (fit === "contain") {
|
this.screenToWorld(tempVector, divX, divY);
|
||||||
// if scaled height is bigger than div height, use height ratio instead
|
|
||||||
if (ah * scaleWidth > divBounds.height * devicePixelRatio){
|
if (loading) {
|
||||||
ratioW = scaleHeight;
|
if (loadingSpinner) {
|
||||||
|
if (!widget.loadingScreen) widget.loadingScreen = new LoadingScreenWidget(renderer);
|
||||||
|
widget.loadingScreen!.draw(true, tempVector.x, tempVector.y, divBounds.width * devicePixelRatio, divBounds.height * devicePixelRatio);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skeleton) {
|
||||||
|
let x = tempVector.x;
|
||||||
|
let y = tempVector.y;
|
||||||
|
if (mode === 'inside') {
|
||||||
|
let { x: ax, y: ay, width: aw, height: ah } = bounds!;
|
||||||
|
|
||||||
|
// scale ratio
|
||||||
|
const scaleWidth = divBounds.width * devicePixelRatio / aw;
|
||||||
|
const scaleHeight = divBounds.height * devicePixelRatio / ah;
|
||||||
|
|
||||||
|
let ratioW = skeleton.scaleX;
|
||||||
|
let ratioH = skeleton.scaleY;
|
||||||
|
|
||||||
|
if (fit === "fill") { // Fill the target box by distorting the source's aspect ratio.
|
||||||
|
ratioW = scaleWidth;
|
||||||
ratioH = scaleHeight;
|
ratioH = scaleHeight;
|
||||||
} else {
|
} else if (fit === "fitWidth") {
|
||||||
ratioW = scaleWidth;
|
ratioW = scaleWidth;
|
||||||
ratioH = scaleWidth;
|
ratioH = scaleWidth;
|
||||||
}
|
} else if (fit === "fitHeight") {
|
||||||
} else if (fit === "cover") {
|
|
||||||
if (ah * scaleWidth < divBounds.height * devicePixelRatio){
|
|
||||||
ratioW = scaleHeight;
|
ratioW = scaleHeight;
|
||||||
ratioH = scaleHeight;
|
ratioH = scaleHeight;
|
||||||
} else {
|
} else if (fit === "contain") {
|
||||||
ratioW = scaleWidth;
|
// if scaled height is bigger than div height, use height ratio instead
|
||||||
ratioH = scaleWidth;
|
|
||||||
}
|
|
||||||
} else if (fit === "scaleDown") {
|
|
||||||
if (aw > divBounds.width * devicePixelRatio || ah > divBounds.height * devicePixelRatio) {
|
|
||||||
if (ah * scaleWidth > divBounds.height * devicePixelRatio){
|
if (ah * scaleWidth > divBounds.height * devicePixelRatio){
|
||||||
ratioW = scaleHeight;
|
ratioW = scaleHeight;
|
||||||
ratioH = scaleHeight;
|
ratioH = scaleHeight;
|
||||||
@ -771,66 +826,225 @@ class SpineWebComponentOverlay extends HTMLElement {
|
|||||||
ratioW = scaleWidth;
|
ratioW = scaleWidth;
|
||||||
ratioH = scaleWidth;
|
ratioH = scaleWidth;
|
||||||
}
|
}
|
||||||
|
} else if (fit === "cover") {
|
||||||
|
if (ah * scaleWidth < divBounds.height * devicePixelRatio){
|
||||||
|
ratioW = scaleHeight;
|
||||||
|
ratioH = scaleHeight;
|
||||||
|
} else {
|
||||||
|
ratioW = scaleWidth;
|
||||||
|
ratioH = scaleWidth;
|
||||||
|
}
|
||||||
|
} else if (fit === "scaleDown") {
|
||||||
|
if (aw > divBounds.width * devicePixelRatio || ah > divBounds.height * devicePixelRatio) {
|
||||||
|
if (ah * scaleWidth > divBounds.height * devicePixelRatio){
|
||||||
|
ratioW = scaleHeight;
|
||||||
|
ratioH = scaleHeight;
|
||||||
|
} else {
|
||||||
|
ratioW = scaleWidth;
|
||||||
|
ratioH = scaleWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the center of the bounds
|
||||||
|
const boundsX = (ax + aw / 2) * ratioW;
|
||||||
|
const boundsY = (ay + ah / 2) * ratioH;
|
||||||
|
|
||||||
|
// get vertices offset: calculate the distance between div center and bounds center
|
||||||
|
x = - boundsX;
|
||||||
|
y = - boundsY;
|
||||||
|
|
||||||
|
if (fit !== "none") {
|
||||||
|
// scale the skeleton
|
||||||
|
skeleton.scaleX = ratioW;
|
||||||
|
skeleton.scaleY = ratioH;
|
||||||
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the center of the bounds
|
widget.worldOffsetX = x + offsetX + dragX;
|
||||||
const boundsX = (ax + aw / 2) * ratioW;
|
widget.worldOffsetY = y + offsetY + dragY;
|
||||||
const boundsY = (ay + ah / 2) * ratioH;
|
|
||||||
|
|
||||||
// get vertices offset: calculate the distance between div center and bounds center
|
renderer.drawSkeleton(skeleton, true, -1, -1, (vertices, size, vertexSize) => {
|
||||||
x = tempVector.x - boundsX;
|
for (let i = 0; i < size; i+=vertexSize) {
|
||||||
y = tempVector.y - boundsY;
|
vertices[i] = vertices[i] + widget.worldOffsetX;
|
||||||
|
vertices[i+1] = vertices[i+1] + widget.worldOffsetY;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (fit !== "none") {
|
// drawing debug stuff
|
||||||
// scale the skeleton
|
if (debug) {
|
||||||
skeleton.scaleX = ratioW;
|
// if (true) {
|
||||||
skeleton.scaleY = ratioH;
|
let { x: ax, y: ay, width: aw, height: ah } = bounds!;
|
||||||
skeleton.updateWorldTransform(Physics.update);
|
|
||||||
|
// show bounds and its center
|
||||||
|
renderer.rect(false,
|
||||||
|
ax * skeleton.scaleX + widget.worldOffsetX,
|
||||||
|
ay * skeleton.scaleY + widget.worldOffsetY,
|
||||||
|
aw * skeleton.scaleX,
|
||||||
|
ah * skeleton.scaleY,
|
||||||
|
blue);
|
||||||
|
const bbCenterX = (ax + aw / 2) * skeleton.scaleX + widget.worldOffsetX;
|
||||||
|
const bbCenterY = (ay + ah / 2) * skeleton.scaleY + widget.worldOffsetY;
|
||||||
|
renderer.circle(true, bbCenterX, bbCenterY, 10, blue);
|
||||||
|
|
||||||
|
// show skeleton root
|
||||||
|
const root = skeleton.getRootBone()!;
|
||||||
|
renderer.circle(true, root.x + widget.worldOffsetX, root.y + widget.worldOffsetY, 10, red);
|
||||||
|
|
||||||
|
// show shifted origin
|
||||||
|
const originX = widget.worldOffsetX - dragX - offsetX;
|
||||||
|
const originY = widget.worldOffsetY - dragY - offsetY;
|
||||||
|
renderer.circle(true, originX, originY, 10, green);
|
||||||
|
|
||||||
|
// show line from origin to bounds center
|
||||||
|
renderer.line(originX, originY, bbCenterX, bbCenterY, green);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
widget.worldOffsetX = x + offsetX + dragX;
|
|
||||||
widget.worldOffsetY = y + offsetY + dragY;
|
|
||||||
|
|
||||||
renderer.drawSkeleton(skeleton, true, -1, -1, (vertices, size, vertexSize) => {
|
|
||||||
// console.log(vertices[0])
|
|
||||||
for (let i = 0; i < size; i+=vertexSize) {
|
|
||||||
vertices[i] = vertices[i] + widget.worldOffsetX;
|
|
||||||
vertices[i+1] = vertices[i+1] + widget.worldOffsetY;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// drawing debug stuff
|
clipToBoundEnd();
|
||||||
if (debug) {
|
|
||||||
// if (true) {
|
|
||||||
let { x: ax, y: ay, width: aw, height: ah } = bounds!;
|
|
||||||
|
|
||||||
// show bounds and its center
|
|
||||||
renderer.rect(false,
|
|
||||||
ax * skeleton.scaleX + widget.worldOffsetX,
|
|
||||||
ay * skeleton.scaleY + widget.worldOffsetY,
|
|
||||||
aw * skeleton.scaleX,
|
|
||||||
ah * skeleton.scaleY,
|
|
||||||
blue);
|
|
||||||
const bbCenterX = (ax + aw / 2) * skeleton.scaleX + widget.worldOffsetX;
|
|
||||||
const bbCenterY = (ay + ah / 2) * skeleton.scaleY + widget.worldOffsetY;
|
|
||||||
renderer.circle(true, bbCenterX, bbCenterY, 10, blue);
|
|
||||||
|
|
||||||
// show skeleton root
|
|
||||||
const root = skeleton.getRootBone()!;
|
|
||||||
renderer.circle(true, root.x + widget.worldOffsetX, root.y + widget.worldOffsetY, 10, red);
|
|
||||||
|
|
||||||
// show shifted origin
|
|
||||||
const originX = widget.worldOffsetX - dragX - offsetX;
|
|
||||||
const originY = widget.worldOffsetY - dragY - offsetY;
|
|
||||||
renderer.circle(true, originX, originY, 10, green);
|
|
||||||
|
|
||||||
// show line from origin to bounds center
|
|
||||||
renderer.line(originX, originY, bbCenterX, bbCenterY, green);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
|
||||||
|
// get the desired point into the the div (center by default) in world coordinate
|
||||||
|
const divX = divBounds.x + divBounds.width * (xAxis + .5);
|
||||||
|
const divY = divBounds.y + divBounds.height * (-yAxis + .5);
|
||||||
|
this.screenToWorld(tempVector, divX, divY);
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
if (loadingSpinner) {
|
||||||
|
if (!widget.loadingScreen) widget.loadingScreen = new LoadingScreenWidget(renderer);
|
||||||
|
widget.loadingScreen!.draw(true, tempVector.x, tempVector.y, divBounds.width * devicePixelRatio, divBounds.height * devicePixelRatio);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skeleton) {
|
||||||
|
let x = tempVector.x;
|
||||||
|
let y = tempVector.y;
|
||||||
|
if (mode === 'inside') {
|
||||||
|
let { x: ax, y: ay, width: aw, height: ah } = bounds!;
|
||||||
|
|
||||||
|
// scale ratio
|
||||||
|
const scaleWidth = divBounds.width * devicePixelRatio / aw;
|
||||||
|
const scaleHeight = divBounds.height * devicePixelRatio / ah;
|
||||||
|
|
||||||
|
let ratioW = skeleton.scaleX;
|
||||||
|
let ratioH = skeleton.scaleY;
|
||||||
|
|
||||||
|
if (fit === "fill") { // Fill the target box by distorting the source's aspect ratio.
|
||||||
|
ratioW = scaleWidth;
|
||||||
|
ratioH = scaleHeight;
|
||||||
|
} else if (fit === "fitWidth") {
|
||||||
|
ratioW = scaleWidth;
|
||||||
|
ratioH = scaleWidth;
|
||||||
|
} else if (fit === "fitHeight") {
|
||||||
|
ratioW = scaleHeight;
|
||||||
|
ratioH = scaleHeight;
|
||||||
|
} else if (fit === "contain") {
|
||||||
|
// if scaled height is bigger than div height, use height ratio instead
|
||||||
|
if (ah * scaleWidth > divBounds.height * devicePixelRatio){
|
||||||
|
ratioW = scaleHeight;
|
||||||
|
ratioH = scaleHeight;
|
||||||
|
} else {
|
||||||
|
ratioW = scaleWidth;
|
||||||
|
ratioH = scaleWidth;
|
||||||
|
}
|
||||||
|
} else if (fit === "cover") {
|
||||||
|
if (ah * scaleWidth < divBounds.height * devicePixelRatio){
|
||||||
|
ratioW = scaleHeight;
|
||||||
|
ratioH = scaleHeight;
|
||||||
|
} else {
|
||||||
|
ratioW = scaleWidth;
|
||||||
|
ratioH = scaleWidth;
|
||||||
|
}
|
||||||
|
} else if (fit === "scaleDown") {
|
||||||
|
if (aw > divBounds.width * devicePixelRatio || ah > divBounds.height * devicePixelRatio) {
|
||||||
|
if (ah * scaleWidth > divBounds.height * devicePixelRatio){
|
||||||
|
ratioW = scaleHeight;
|
||||||
|
ratioH = scaleHeight;
|
||||||
|
} else {
|
||||||
|
ratioW = scaleWidth;
|
||||||
|
ratioH = scaleWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the center of the bounds
|
||||||
|
const boundsX = (ax + aw / 2) * ratioW;
|
||||||
|
const boundsY = (ay + ah / 2) * ratioH;
|
||||||
|
|
||||||
|
// get vertices offset: calculate the distance between div center and bounds center
|
||||||
|
x = tempVector.x - boundsX;
|
||||||
|
y = tempVector.y - boundsY;
|
||||||
|
|
||||||
|
if (fit !== "none") {
|
||||||
|
// scale the skeleton
|
||||||
|
skeleton.scaleX = ratioW;
|
||||||
|
skeleton.scaleY = ratioH;
|
||||||
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
widget.worldOffsetX = x + offsetX + dragX;
|
||||||
|
widget.worldOffsetY = y + offsetY + dragY;
|
||||||
|
|
||||||
|
renderer.drawSkeleton(skeleton, true, -1, -1, (vertices, size, vertexSize) => {
|
||||||
|
for (let i = 0; i < size; i+=vertexSize) {
|
||||||
|
vertices[i] = vertices[i] + widget.worldOffsetX;
|
||||||
|
vertices[i+1] = vertices[i+1] + widget.worldOffsetY;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// drawing debug stuff
|
||||||
|
if (debug) {
|
||||||
|
// if (true) {
|
||||||
|
let { x: ax, y: ay, width: aw, height: ah } = bounds!;
|
||||||
|
|
||||||
|
// show bounds and its center
|
||||||
|
renderer.rect(false,
|
||||||
|
ax * skeleton.scaleX + widget.worldOffsetX,
|
||||||
|
ay * skeleton.scaleY + widget.worldOffsetY,
|
||||||
|
aw * skeleton.scaleX,
|
||||||
|
ah * skeleton.scaleY,
|
||||||
|
blue);
|
||||||
|
const bbCenterX = (ax + aw / 2) * skeleton.scaleX + widget.worldOffsetX;
|
||||||
|
const bbCenterY = (ay + ah / 2) * skeleton.scaleY + widget.worldOffsetY;
|
||||||
|
renderer.circle(true, bbCenterX, bbCenterY, 10, blue);
|
||||||
|
|
||||||
|
// show skeleton root
|
||||||
|
const root = skeleton.getRootBone()!;
|
||||||
|
renderer.circle(true, root.x + widget.worldOffsetX, root.y + widget.worldOffsetY, 10, red);
|
||||||
|
|
||||||
|
// show shifted origin
|
||||||
|
const originX = widget.worldOffsetX - dragX - offsetX;
|
||||||
|
const originY = widget.worldOffsetY - dragY - offsetY;
|
||||||
|
renderer.circle(true, originX, originY, 10, green);
|
||||||
|
|
||||||
|
// show line from origin to bounds center
|
||||||
|
renderer.line(originX, originY, bbCenterX, bbCenterY, green);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
renderer.end();
|
renderer.end();
|
||||||
@ -946,14 +1160,10 @@ class SpineWebComponentOverlay extends HTMLElement {
|
|||||||
|
|
||||||
const totalWidth = width * (1 + (this.overflowLeft + this.overflowRight));
|
const totalWidth = width * (1 + (this.overflowLeft + this.overflowRight));
|
||||||
const totalHeight = height * (1 + (this.overflowTop + this.overflowBottom));
|
const totalHeight = height * (1 + (this.overflowTop + this.overflowBottom));
|
||||||
|
|
||||||
this.canvas.style.width = totalWidth + "px";
|
this.canvas.style.width = totalWidth + "px";
|
||||||
this.canvas.style.height = totalHeight + "px";
|
this.canvas.style.height = totalHeight + "px";
|
||||||
|
this.spineCanvas.renderer.resize3(totalWidth, totalHeight);
|
||||||
const dpr = window.devicePixelRatio;
|
|
||||||
this.canvas.width = Math.round(totalWidth * dpr);
|
|
||||||
this.canvas.height = Math.round(totalHeight * dpr);
|
|
||||||
|
|
||||||
this.spineCanvas.renderer.resize2();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -981,6 +1191,12 @@ class SpineWebComponentOverlay extends HTMLElement {
|
|||||||
skeleton.scaleX = skeleton.scaleX / widget.currentScaleDpi * scale;
|
skeleton.scaleX = skeleton.scaleX / widget.currentScaleDpi * scale;
|
||||||
skeleton.scaleY = skeleton.scaleY / widget.currentScaleDpi * scale;
|
skeleton.scaleY = skeleton.scaleY / widget.currentScaleDpi * scale;
|
||||||
widget.currentScaleDpi = scale;
|
widget.currentScaleDpi = scale;
|
||||||
|
|
||||||
|
// TODO: improve this horrible thing
|
||||||
|
this.spineCanvas.renderer.resize3(
|
||||||
|
+this.canvas.style.width.substring(0, this.canvas.style.width.length - 2),
|
||||||
|
+this.canvas.style.height.substring(0, this.canvas.style.height.length - 2),
|
||||||
|
);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||