physics2.html 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. </head>
  7. <script src="../dist/iife/spine-webgl.js"></script>
  8. <link rel="stylesheet" href="../../index.css">
  9. <body>
  10. <div class="overlay" style="user-select: none;">
  11. <span>Drag anywhere</span>
  12. <span id="fps"></span>
  13. <button id="fullscreen" class="btn">Fullscreen</div>
  14. </div>
  15. <canvas id="canvas" style="position: absolute; width: 100%; height: 100vh;"></canvas>
  16. <script>
  17. class App {
  18. constructor() {
  19. this.skeleton = null;
  20. this.animationState = null;
  21. this.fps = document.body.querySelector("#fps");
  22. const fsButton = document.body.querySelector("#fullscreen");
  23. let fsEnabled = false;
  24. fsButton.addEventListener("click", () => {
  25. if (fsEnabled) {
  26. document.exitFullscreen();
  27. fsButton.innerText = "Fullscreen"
  28. } else {
  29. document.body.requestFullscreen()
  30. fsButton.innerText = "Windowed";
  31. }
  32. fsEnabled = !fsEnabled;
  33. })
  34. }
  35. loadAssets(canvas) {
  36. // Load the skeleton file.
  37. canvas.assetManager.loadBinary("assets/celestial-circus-pro.skel");
  38. // Load the atlas and its pages.
  39. canvas.assetManager.loadTextureAtlas("assets/celestial-circus-pma.atlas");
  40. }
  41. initialize(canvas) {
  42. let assetManager = canvas.assetManager;
  43. // Create the texture atlas.
  44. var atlas = assetManager.require("assets/celestial-circus-pma.atlas");
  45. // Create a AtlasAttachmentLoader that resolves region, mesh, boundingbox and path attachments
  46. var atlasLoader = new spine.AtlasAttachmentLoader(atlas);
  47. // Create a SkeletonBinary instance for parsing the .skel file.
  48. var skeletonBinary = new spine.SkeletonBinary(atlasLoader);
  49. // Set the scale to apply during parsing, parse the file, and create a new skeleton.
  50. skeletonBinary.scale = 0.5;
  51. var skeletonData = skeletonBinary.readSkeletonData(assetManager.require("assets/celestial-circus-pro.skel"));
  52. this.skeleton = new spine.Skeleton(skeletonData);
  53. // Create an AnimationState, and set the "run" animation in looping mode.
  54. var animationStateData = new spine.AnimationStateData(skeletonData);
  55. this.animationState = new spine.AnimationState(animationStateData);
  56. this.animationState.setAnimation(0, "eyeblink-long", true);
  57. // Center the camera on the skeleton
  58. const offset = new spine.Vector2();
  59. const size = new spine.Vector2();
  60. this.skeleton.setToSetupPose();
  61. this.skeleton.update(0);
  62. this.skeleton.updateWorldTransform(spine.Physics.update);
  63. this.skeleton.getBounds(offset, size);
  64. canvas.renderer.camera.position.x = offset.x + size.x / 2;
  65. canvas.renderer.camera.position.y = offset.y + size.y / 2;
  66. // Setup an input listener on the canvas to process touch/mouse events. Allow drawing the skeleton around
  67. // by clicking and dragging anywhere on the canvas.
  68. let lastX = -1, lastY = -1;
  69. canvas.input.addListener({
  70. down: (x, y) => {
  71. // Calculate the mouse position in the coordinate space of the camera, aka world space.
  72. // The skeleton and its bones live in the same coordinate space.
  73. let mousePosition = new spine.Vector3(x, y);
  74. canvas.renderer.camera.screenToWorld(mousePosition, canvas.htmlCanvas.clientWidth, canvas.htmlCanvas.clientHeight);
  75. lastX = mousePosition.x;
  76. lastY = mousePosition.y;
  77. },
  78. dragged: (x, y) => {
  79. // Calculate the mouse position in the coordinate space of the camera, aka world space.
  80. // The skeleton and its bones live in this coordinate space.
  81. let mousePosition = new spine.Vector3(x, y);
  82. canvas.renderer.camera.screenToWorld(mousePosition, canvas.htmlCanvas.clientWidth, canvas.htmlCanvas.clientHeight);
  83. this.skeleton.x += mousePosition.x - lastX;
  84. this.skeleton.y += mousePosition.y - lastY;
  85. lastX = mousePosition.x;
  86. lastY = mousePosition.y;
  87. }
  88. })
  89. }
  90. update(canvas, delta) {
  91. // Update the animation state using the delta time.
  92. this.animationState.update(delta);
  93. // Apply the animation state to the skeleton.
  94. this.animationState.apply(this.skeleton);
  95. // Let the skeleton update the transforms of its bones and apply physics
  96. this.skeleton.update(delta);
  97. this.skeleton.updateWorldTransform(spine.Physics.update);
  98. this.fps.innerText = canvas.time.framesPerSecond.toFixed(2) + " fps";
  99. }
  100. render(canvas) {
  101. let renderer = canvas.renderer;
  102. // Resize the viewport to the full canvas.
  103. renderer.resize(spine.ResizeMode.Expand);
  104. // Clear the canvas with a light gray color.
  105. canvas.clear(0.2, 0.2, 0.2, 1);
  106. // Begin rendering.
  107. renderer.begin();
  108. // Draw the skeleton
  109. renderer.drawSkeleton(this.skeleton, true);
  110. // Complete rendering.
  111. renderer.end();
  112. }
  113. }
  114. new spine.SpineCanvas(document.getElementById("canvas"), {
  115. app: new App()
  116. })
  117. </script>
  118. </body>
  119. </html>