animate_folding.html 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <!--
  5. Animate Code Folding Experiment
  6. Animates closing of folds in Chrome and WebKit. Requires 3D CSS and CSS
  7. transitions.
  8. TODO
  9. * animate opening
  10. * fix closing at the bottom of the file
  11. * support folding with closed folds on the screen (rows are off)
  12. * support more browsers
  13. * speed
  14. -->
  15. <meta charset="UTF-8">
  16. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  17. <title>Editor</title>
  18. <style type="text/css" media="screen">
  19. body {
  20. overflow: hidden;
  21. }
  22. pre {
  23. margin: 0;
  24. }
  25. #editor {
  26. position: absolute;
  27. height: 100%;
  28. width: 100%;
  29. }
  30. #container {
  31. -webkit-transform: scaleZ(0.0000001);
  32. margin: 0;
  33. position: absolute;
  34. top: 0;
  35. left: 0;
  36. width: 100%;
  37. height: 100%;
  38. overflow: hidden;
  39. }
  40. .ace_slide {
  41. position: absolute;
  42. width: 100%;
  43. overflow: hidden;
  44. background-image: url(zenbg.png);
  45. /* ease in sine */
  46. -webkit-transition: height 500ms cubic-bezier(0.470, 0.000, 0.745, 0.715);
  47. -webkit-perspective: 2000;
  48. -webkit-perspective-origin: 50% 50%;
  49. }
  50. .ace_anim_slide_top {
  51. z-index: -1;
  52. background-color: white;
  53. background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0) 0%,rgba(0, 0, 0, 0.05) 50%);
  54. top: 0;
  55. -webkit-transition: -webkit-transform 500ms linear;
  56. -webkit-transform-style: preserve-3d;
  57. -webkit-transform-origin: top;
  58. -webkit-transform: rotateX(0deg);
  59. }
  60. .ace_anim_slide_bottom {
  61. background-color: white;
  62. background-image: -webkit-linear-gradient(bottom, rgba(255, 255, 255, 0) 0%,rgba(0, 0, 0, 0.05) 100%);
  63. bottom: 0;
  64. -webkit-transition: -webkit-transform 500ms linear;
  65. -webkit-transform-style: preserve-3d;
  66. -webkit-transform-origin: bottom;
  67. -webkit-transform: rotateX(0deg);
  68. }
  69. .ace_anim_hidden .ace_anim_slide_top {
  70. -webkit-transform: rotateX(-90deg);
  71. }
  72. .ace_anim_hidden .ace_anim_slide_bottom {
  73. -webkit-transform: rotateX(90deg);
  74. }
  75. .ace_anim_bottom {
  76. /* ease in sine */
  77. -webkit-transition: top 500ms cubic-bezier(0.470, 0.000, 0.745, 0.715);
  78. -webkit-transform: scaleZ(0.0000001);
  79. }
  80. </style>
  81. </head>
  82. <body>
  83. <div id="container">
  84. <div id="editor"></div>
  85. </div>
  86. <script src="../build/src/ace-uncompressed.js" type="text/javascript" charset="utf-8"></script>
  87. <script src="../build/src/mode-javascript.js" type="text/javascript" charset="utf-8"></script>
  88. <script id="main">
  89. window.onload = function() {
  90. var editor = ace.edit("editor");
  91. var JavaScriptMode = require("ace/mode/javascript").Mode;
  92. var EditSession = require("ace/edit_session").EditSession;
  93. var lang = require("ace/lib/lang");
  94. var Range = require("ace/range").Range;
  95. editor.getSession().setMode(new JavaScriptMode());
  96. editor.getSession().setValue(document.getElementById("main").innerHTML);
  97. function cloneSession(session) {
  98. var s = new EditSession(session.getDocument(), session.getMode());
  99. // Copy over 'settings' from the session.
  100. s.setTabSize(session.getTabSize());
  101. s.setUseSoftTabs(session.getUseSoftTabs());
  102. s.setOverwrite(session.getOverwrite());
  103. s.setBreakpoints(session.getBreakpoints());
  104. s.setUseWrapMode(session.getUseWrapMode());
  105. s.setUseWorker(false);
  106. s.setWrapLimitRange(session.$wrapLimitRange.min, session.$wrapLimitRange.max);
  107. s.$foldData = session.$cloneFoldData();
  108. return s;
  109. }
  110. function animateFold(editor, placeholder, range) {
  111. var session = editor.getSession();
  112. var ed = document.getElementById("editor");
  113. var parent = ed.parentNode;
  114. var clone = ed.cloneNode();
  115. var cloneEd = ace.edit(clone);
  116. var renderer = cloneEd.renderer;
  117. cloneEd.setSession(cloneSession(session));
  118. cloneEd.setTheme(editor.getTheme());
  119. renderer.scrollToY(editor.renderer.getScrollTop());
  120. parent.appendChild(clone);
  121. cloneEd.resize();
  122. renderer.$size = lang.copyObject(cloneEd.renderer.$size);
  123. renderer.layerConfig = lang.copyObject(cloneEd.renderer.layerConfig);
  124. renderer.$textLayer.$characterSize = lang.copyObject(editor.renderer.$textLayer.$characterSize);
  125. renderer.$textLayer._emit("changeCharaterSize", {data: renderer.$textLayer.$characterSize});
  126. renderer.$loop.onRender(renderer.$loop.changes);
  127. // top area
  128. var clone2 = clone.cloneNode(true);
  129. var topHeight = range.start.row * renderer.lineHeight - renderer.scrollTop
  130. clone2.style.height = topHeight + "px";
  131. parent.appendChild(clone2);
  132. // middle
  133. cloneEd.scrollToRow(range.start.row);
  134. renderer.$loop.onRender(renderer.$loop.changes);
  135. var middleHeight = (range.end.row - range.start.row) * renderer.lineHeight;
  136. var slide = document.createElement("div");
  137. slide.className = "ace_slide";
  138. slide.style.top = topHeight + "px";
  139. slide.style.height = middleHeight + "px";
  140. var clone3 = clone.cloneNode(true);
  141. clone3.className += " ace_anim_slide_top";
  142. clone3.style.height = middleHeight + "px";
  143. slide.appendChild(clone3);
  144. renderer.scrollToY(renderer.scrollTop + Math.floor(middleHeight / 2));
  145. renderer.$loop.onRender(renderer.$loop.changes);
  146. var clone3 = clone.cloneNode(true);
  147. clone3.className += " ace_anim_slide_bottom";
  148. clone3.style.top = null;
  149. clone3.style.height = (middleHeight / 2) + "px";
  150. slide.appendChild(clone3);
  151. parent.appendChild(slide);
  152. // bottom
  153. cloneEd.scrollToRow(range.start.row)
  154. cloneEd.getSession().addFold(placeholder, range);
  155. renderer.$loop.onRender(renderer.$loop.changes);
  156. var clone4 = clone.cloneNode(true);
  157. clone4.className += " ace_anim_bottom";
  158. clone4.style.top = (topHeight + middleHeight) + "px";
  159. parent.appendChild(clone4);
  160. cloneEd.destroy();
  161. parent.removeChild(clone);
  162. ed.style.left = "-10000px";
  163. setTimeout(function() {
  164. clone4.style.top = topHeight + "px";
  165. slide.style.height = 0;
  166. slide.className += " ace_anim_hidden";
  167. setTimeout(function() {
  168. ed.style.left = 0;
  169. setTimeout(function() {
  170. parent.removeChild(clone2);
  171. parent.removeChild(slide);
  172. parent.removeChild(clone4);
  173. }, 0);
  174. }, 500);
  175. }, 0);
  176. }
  177. var origOnFoldWidgetClick = EditSession.prototype.onFoldWidgetClick;
  178. EditSession.prototype.onFoldWidgetClick = function() {
  179. var orig = EditSession.prototype.addFold;
  180. EditSession.prototype.addFold = function(placeholder, range) {
  181. EditSession.prototype.addFold = orig;
  182. animateFold(editor, placeholder, range);
  183. this.addFold(placeholder, range);
  184. }
  185. var ret = origOnFoldWidgetClick.apply(this, arguments);
  186. return ret;
  187. }
  188. };
  189. </script>
  190. </body>
  191. </html>