Guest User

Untitled

a guest
Jan 23rd, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.89 KB | None | 0 0
  1. function Spinner(div, src, frames) {
  2. this.div = div;
  3. this.src = src || div.dataset.src;
  4. this.frameCount = frames || div.dataset.frames || 36;
  5.  
  6. this.canvas = document.createElement("canvas");
  7. div.appendChild(this.canvas);
  8.  
  9. this.degrees = 0;
  10. this.rotation = 0;
  11.  
  12. var self = this;
  13.  
  14. this.image = new Image();
  15. this.image.onload = function () {
  16. self.frameHeight = Math.round(this.naturalHeight / self.frameCount);
  17.  
  18. self.canvas.width = this.naturalWidth;
  19. self.canvas.height = self.frameHeight;
  20. self.div.style.height = self.frameHeight + "px";
  21.  
  22. self.setFrame(0);
  23. }
  24. this.image.onerror = function () {
  25. var swfSrc = src.replace(/\.jpg$/, ".swf"); // looking for a .swf (the showSpin func replaces .swf with .jpg)
  26. self.div.classList.remove("spin-360-deg"); // the transaprent ::before blocks the flash from spinning
  27. self.div.innerHTML = '<embed type="application/x-shockwave-flash" ' +
  28. 'src="' + swfSrc + '" ' +
  29. 'width="400" height="450" quality="high" wmode="opaque">';
  30. self.image = null;
  31. }
  32. this.image.src = this.src;
  33. window.addEventListener("load", function () { self.animateSpin() });
  34.  
  35. this.dragging = false;
  36. this.lastPosition = [0, 0];
  37.  
  38. this.div.onmousedown = function (event) {
  39. self.lastPosition = {x: event.screenX, y: event.screenY};
  40. self.dragging = true;
  41. }
  42. this.div.ontouchstart = function (event) {
  43. self.lastPosition = {x: event.changedTouches[0].screenX, y: event.changedTouches[0].screenY};
  44. self.dragging = true;
  45. }
  46. this.div.onmousemove = function (event) { self.mouseMove(event); }
  47. this.div.ontouchmove = function (event) { self.mouseMove(event, true); }
  48. this.div.onmouseup = function (event) { self.stopDragging(); };
  49. this.div.onmouseleave = function (event) { self.stopDragging(); };
  50. this.div.ontouchend = function (event) { self.stopDragging(); };
  51. this.div.ontouchcancel = function (event) { self.stopDragging(); };
  52.  
  53. this.div.ondragstart = function () { return false; } // for reals, IE, no dragging!
  54.  
  55. this.div.ondblclick = function () { self.animateSpin(); }
  56. }
  57.  
  58. Spinner.prototype.mouseMove = function (event, tap) {
  59. if (!this.dragging) return;
  60.  
  61. this.stopSpinAnimation();
  62.  
  63. if (event.changedTouches) {
  64. if (event.changedTouches.length > 1) return; // multi-touch gesture, probably zoom
  65.  
  66. var diffX = this.lastPosition.x - event.changedTouches[0].screenX;
  67. var diffY = this.lastPosition.y - event.changedTouches[0].screenY;
  68. var angle = Math.abs(Math.atan2(diffX, diffY));
  69. if (angle > 0.3 && angle < 2.7) {
  70. // reduce scrolling when swiping sideways
  71.  
  72. event.preventDefault();
  73. event.stopPropagation();
  74. }
  75.  
  76. this.rotation = diffX;
  77. this.lastPosition = {x: event.changedTouches[0].screenX, y: event.changedTouches[0].screenY};
  78. } else {
  79. this.rotation = this.lastPosition.x - event.screenX;
  80. this.lastPosition = {x: event.screenX, y: event.screenY};
  81. }
  82.  
  83. this.rotateBy(this.rotation);
  84. }
  85.  
  86. Spinner.prototype.stopDragging = function () {
  87. this.dragging = false;
  88. var self = this;
  89.  
  90. function animateInertia() {
  91. // user rotating again, stop animating
  92. if (self.dragging) return;
  93.  
  94. self.rotation *= 0.95;
  95. self.rotateBy(self.rotation);
  96.  
  97. // animate until rotation gets low enough
  98. if (Math.abs(self.rotation) > 1) {
  99. requestAnimationFrame(animateInertia);
  100. }
  101. }
  102. animateInertia();
  103. }
  104.  
  105. Spinner.prototype.rotateBy = function (angle) {
  106. this.degrees = Math.round(360 + this.degrees + angle) % 360;
  107. var frame = Math.round((this.degrees / 360.0) * this.frameCount);
  108. this.setFrame(frame);
  109. }
  110. Spinner.prototype.setFrame = function (frame) {
  111. frame = Math.round(frame) % this.frameCount;
  112. this.oldFrame = this.frame;
  113. this.frame = frame;
  114. this.draw();
  115. }
  116. Spinner.prototype.draw = function () {
  117. if (!this.image) return; // image failed to load
  118.  
  119. var self = this;
  120.  
  121. function rafDraw() {
  122. var context = self.canvas.getContext("2d");
  123.  
  124. // draw image
  125. context.drawImage(
  126. self.image, // image
  127. 0, self.frameHeight * self.frame, // position in source image
  128. self.image.naturalWidth, self.frameHeight, // width, height in source image
  129. 0, 0, // position on canvas
  130. self.image.naturalWidth, self.frameHeight // width, height on canvas
  131. );
  132. }
  133. requestAnimationFrame(rafDraw);
  134. }
  135.  
  136. Spinner.prototype.animateSpin = function () {
  137. var self = this;
  138. var frameCount = this.frameCount;
  139. var animate = function () {
  140. if (frameCount-- == 0) return;
  141.  
  142. self.setFrame(self.frame + 1);
  143.  
  144. self.animateTimeout = setTimeout(animate, 33); // 30 fps
  145. }
  146.  
  147. animate();
  148. }
  149. Spinner.prototype.stopSpinAnimation = function () {
  150. // this.degrees = 360 * (this.frame / this.frameCount);
  151. clearTimeout(this.animateTimeout);
  152. }
  153.  
  154.  
  155. function showSpin(file, frames) {
  156. frames = frames || 36; // 36 frames by default
  157. file = file.replace(".swf", ".jpg");
  158.  
  159. document.write('<div class="spin-360-deg" draggable="false"></div>');
  160. new Spinner(document.querySelector(".spin-360-deg"), file, frames);
  161. }
Add Comment
Please, Sign In to add comment