PageRenderTime 57ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/js/sprite.js

https://github.com/Breton/HTML5-Storybook
JavaScript | 280 lines | 195 code | 57 blank | 28 comment | 63 complexity | 72ad01ca0e2a899c6492dd79a7b79e5f MD5 | raw file
  1. // ------------------------------------------------------------------
  2. // sprite.js
  3. //
  4. // Copyright 2012 PBS KIDS Interactive. All Rights Reserved.
  5. PBS.KIDS.storybook.sprite = function (GLOBAL, PBS, options) {
  6. "use strict";
  7. var that,
  8. element,
  9. resource = (options && options.resource !== undefined) ? options.resource : undefined,
  10. ctx,
  11. initialized = false,
  12. spec = {},
  13. curFrame = 0,
  14. frameWidth,
  15. frameHeight,
  16. frameDelay = options.frameDelay || 1,
  17. loop = options.loop,
  18. parentElement = options && options.parentElement,
  19. paused = false,
  20. parentWidthRatio = 1,
  21. parentHeightRatio = 1,
  22. backgroundColor = options.color,
  23. horizontalAlign = (options && options.horizontalAlign !== undefined) ? options.horizontalAlign.toUpperCase() : "LEFT",
  24. verticalAlign = (options && options.verticalAlign !== undefined) ? options.verticalAlign.toUpperCase() : "TOP",
  25. resourcesReady = function () {
  26. var width;
  27. if (!initialized) {
  28. initialized = true;
  29. // Set the position of the sprite relative to the left or right
  30. if (horizontalAlign === "RIGHT") {
  31. element.style.right = that.x + "%";
  32. } else {
  33. element.style.left = that.x + "%";
  34. }
  35. // Set the position of the sprite relative to the top or bottom
  36. if (verticalAlign === "BOTTOM") {
  37. element.style.bottom = that.y + "%";
  38. } else {
  39. element.style.top = that.y + "%";
  40. }
  41. // If the sprite has an image
  42. if (resource && resource.image) {
  43. that.width = resource.image.width;
  44. that.height = resource.image.height;
  45. } else {
  46. that.width = 100;
  47. that.height = 100;
  48. }
  49. // Determine the dimensions of the frame. It may be different from the image dimensions if more than one frame
  50. frameWidth = options.numFrames ? (that.width / options.numFrames) : that.width;
  51. frameHeight = that.height;
  52. // Set the dimensions of the element
  53. element.width = frameWidth;
  54. element.height = frameHeight;
  55. // If the width was specified
  56. if (options.width) {
  57. // If px is in the width (e.g. 100px)
  58. if (options.width.toString().indexOf("px") !== -1) {
  59. element.style.width = options.width;
  60. } else {
  61. element.style.width = options.width + "%";
  62. }
  63. // Scale sprite if the parent is scaled
  64. } else if (options.parentWidth) {
  65. parentWidthRatio = (element.width / options.parentWidth);
  66. element.style.width = (parentWidthRatio * 100) + "%";
  67. }
  68. // If the width was specified
  69. if (options.height) {
  70. // If px is in the width (e.g. 100px)
  71. if (options.height.toString().indexOf("px") !== -1) {
  72. element.style.height = options.height;
  73. } else {
  74. element.style.height = options.height + "%";
  75. }
  76. // Scale sprite if the parent is scaled
  77. } else if (options.parentHeight) {
  78. parentHeightRatio = (element.height / options.parentHeight);
  79. element.style.height = (parentHeightRatio * 100) + "%";
  80. }
  81. that.dirty = true;
  82. }
  83. };
  84. spec.width = 100 + "px";
  85. spec.height = 100 + "px";
  86. spec.className = "pbsCanvas pbsSprite";
  87. if (options && options.className) {
  88. spec.className += " " + options.className
  89. }
  90. ctx = PBS.KIDS.storybook.createCanvas(parentElement, spec);
  91. // Inherit the view
  92. that = PBS.KIDS.storybook.view(PBS, ctx.canvas);
  93. element = that.getElement();
  94. that.dirty = false;
  95. that.x = options && (options.x !== undefined) ? options.x : 0;
  96. that.y = options && (options.y !== undefined) ? options.y : 0;
  97. that.width = options && (options.width !== undefined) ? options.width : 0;
  98. that.height = options && (options.height !== undefined) ? options.height : 0;
  99. that.visible = true;
  100. that.alpha;
  101. that.destroyed = false;
  102. that.url = options && options.url;
  103. that.autoStart = options && (options.autoStart !== undefined) ? options.autoStart : true;
  104. that.autoReset = options && (options.autoReset !== undefined) ? options.autoReset : false;
  105. that.update = function () {
  106. var previousCurFrame;
  107. // TODO: Move the height assignment so it updates only when the parent height changes
  108. //element.style.height = element.offsetWidth / element.width + "%";
  109. if (options.numFrames && !paused) {
  110. previousCurFrame = Math.floor(curFrame / frameDelay) ;
  111. // If the next frame is greater than the number of frame times the delay
  112. if (curFrame + 1 >= options.numFrames * frameDelay) {
  113. if (loop) {
  114. curFrame = 0;
  115. } else if (that.autoReset) {
  116. if (curFrame + 1 >= (options.numFrames + 1) * frameDelay) {
  117. curFrame += 1;
  118. } else {
  119. curFrame = 0;
  120. that.stop();
  121. }
  122. }
  123. } else {
  124. curFrame += 1;
  125. }
  126. if (previousCurFrame !== Math.floor(curFrame / frameDelay)) {
  127. that.dirty = true;
  128. }
  129. }
  130. };
  131. that.render = function () {
  132. var curAlpha;
  133. if (initialized) {
  134. if (that.dirty) {
  135. // If the sprite is visible
  136. if (that.visible) {
  137. curAlpha = ctx.globalAlpha;
  138. ctx.globalAlpha = that.alpha;
  139. // If page background color
  140. if (backgroundColor) {
  141. // Draw the background color
  142. ctx.fillStyle = backgroundColor;
  143. ctx.fillRect(0, 0, frameWidth, frameHeight);
  144. }
  145. // If the sprite has an image
  146. if (resource && resource.image) {
  147. // If the sprite is an animation
  148. if (options.numFrames) {
  149. ctx.clearRect(0, 0, frameWidth, frameHeight);
  150. ctx.drawImage(
  151. resource.image,
  152. Math.floor(curFrame / frameDelay) * frameWidth,
  153. 0,
  154. frameWidth,
  155. frameHeight,
  156. 0,
  157. 0,
  158. frameWidth,
  159. frameHeight
  160. );
  161. } else {
  162. ctx.drawImage(resource.image, 0, 0, frameWidth, frameHeight);
  163. }
  164. ctx.globalAlpha = curAlpha;
  165. }
  166. } else {
  167. ctx.clearRect(0, 0, frameWidth, frameHeight);
  168. }
  169. // Don't render again until set to dirty
  170. that.dirty = false;
  171. }
  172. }
  173. };
  174. that.destroy = function () {
  175. that.destroyed = true;
  176. element = null;
  177. that = null;
  178. };
  179. that.play = function () {
  180. that.reset();
  181. paused = false;
  182. };
  183. that.resume = function () {
  184. paused = false;
  185. that.dirty = true;
  186. };
  187. that.stop = function () {
  188. paused = true;
  189. };
  190. that.reset = function () {
  191. if (curFrame !== 0) {
  192. curFrame = 0;
  193. that.dirty = true;
  194. that.stop();
  195. }
  196. };
  197. that.press = function () {
  198. if (options.playOnPress) {
  199. that.play();
  200. } else if (options.stopOnPress) {
  201. that.stop();
  202. } else if (options.toggleOnPress) {
  203. if (paused) {
  204. that.resume();
  205. } else {
  206. that.stop();
  207. }
  208. }
  209. };
  210. // If the sprite has an image
  211. if (resource && resource.image) {
  212. // Listen to when the image is loaded
  213. resource.image.addEventListener("load", resourcesReady);
  214. } else {
  215. resourcesReady();
  216. }
  217. // Listen to when the sprite is touched or clicked
  218. that.addEventListener("PRESS", that.press);
  219. if (that.autoStart === false) {
  220. paused = true;
  221. }
  222. return that;
  223. };