PageSourceSearch

https://thunderjie.github.io/js/src/motion.js?v=6.4.2

js thunderjie.github.io collected 2026-10-03 10:04:56 UTC 10,559 bytes, 354 lines download raw bytes

1/* global NexT, CONFIG */
2
3$(document).ready(function() {
4  NexT.motion = {};
5
6  var sidebarToggleLines = {
7    lines: [],
8    push : function(line) {
9      this.lines.push(line);
10    },
11    init: function() {
12      this.lines.forEach(function(line) {
13        line.init();
14      });
15    },
16    arrow: function() {
17      this.lines.forEach(function(line) {
18        line.arrow();
19      });
20    },
21    close: function() {
22      this.lines.forEach(function(line) {
23        line.close();
24      });
25    }
26  };
27
28  function SidebarToggleLine(settings) {
29    this.el = $(settings.el);
30    this.status = $.extend({}, {
31      init: {
32        width  : '100%',
33        opacity: 1,
34        left   : 0,
35        rotateZ: 0,
36        top    : 0
37      }
38    }, settings.status);
39  }
40
41  SidebarToggleLine.prototype.init = function() {
42    this.transform('init');
43  };
44  SidebarToggleLine.prototype.arrow = function() {
45    this.transform('arrow');
46  };
47  SidebarToggleLine.prototype.close = function() {
48    this.transform('close');
49  };
50  SidebarToggleLine.prototype.transform = function(status) {
51    this.el.velocity('stop').velocity(this.status[status]);
52  };
53
54  var sidebarToggleLine1st = new SidebarToggleLine({
55    el    : '.sidebar-toggle-line-first',
56    status: {
57      arrow: {width: '50%', rotateZ: '-45deg', top: '2px'},
58      close: {width: '100%', rotateZ: '-45deg', top: '5px'}
59    }
60  });
61  var sidebarToggleLine2nd = new SidebarToggleLine({
62    el    : '.sidebar-toggle-line-middle',
63    status: {
64      arrow: {width: '90%'},
65      close: {opacity: 0}
66    }
67  });
68  var sidebarToggleLine3rd = new SidebarToggleLine({
69    el    : '.sidebar-toggle-line-last',
70    status: {
71      arrow: {width: '50%', rotateZ: '45deg', top: '-2px'},
72      close: {width: '100%', rotateZ: '45deg', top: '-5px'}
73    }
74  });
75
76  sidebarToggleLines.push(sidebarToggleLine1st);
77  sidebarToggleLines.push(sidebarToggleLine2nd);
78  sidebarToggleLines.push(sidebarToggleLine3rd);
79
80  var SIDEBAR_WIDTH = CONFIG.sidebar.width ? CONFIG.sidebar.width : '320px';
81  var SIDEBAR_DISPLAY_DURATION = 200;
82  var xPos, yPos;
83
84  var sidebarToggleMotion = {
85    toggleEl        : $('.sidebar-toggle'),
86    dimmerEl        : $('#sidebar-dimmer'),
87    sidebarEl       : $('.sidebar'),
88    isSidebarVisible: false,
89    init            : function() {
90      this.toggleEl.on('click', this.clickHandler.bind(this));
91      this.dimmerEl.on('click', this.clickHandler.bind(this));
92      this.toggleEl.on('mouseenter', this.mouseEnterHandler.bind(this));
93      this.toggleEl.on('mouseleave', this.mouseLeaveHandler.bind(this));
94      this.sidebarEl.on('touchstart', this.touchstartHandler.bind(this));
95      this.sidebarEl.on('touchend', this.touchendHandler.bind(this));
96      this.sidebarEl.on('touchmove', function(e) { e.preventDefault(); });
97
98      $(document)
99        .on('sidebar.isShowing', function() {
100          NexT.utils.isDesktop() && $('body').velocity('stop').velocity(
101            {paddingRight: SIDEBAR_WIDTH},
102            SIDEBAR_DISPLAY_DURATION
103          );
104        })
105        .on('sidebar.isHiding', function() {
106        });
107    },
108    clickHandler: function() {
109      this.isSidebarVisible ? this.hideSidebar() : this.showSidebar();
110      this.isSidebarVisible = !this.isSidebarVisible;
111    },
112    mouseEnterHandler: function() {
113      if (this.isSidebarVisible) {
114        return;
115      }
116      sidebarToggleLines.arrow();
117    },
118    mouseLeaveHandler: function() {
119      if (this.isSidebarVisible) {
120        return;
121      }
122      sidebarToggleLines.init();
123    },
124    touchstartHandler: function(e) {
125      xPos = e.originalEvent.touches[0].clientX;
126      yPos = e.originalEvent.touches[0].clientY;
127    },
128    touchendHandler: function(e) {
129      var _xPos = e.originalEvent.changedTouches[0].clientX;
130      var _yPos = e.originalEvent.changedTouches[0].clientY;
131      if (_xPos - xPos > 30 && Math.abs(_yPos - yPos) < 20) {
132        this.clickHandler();
133      }
134    },
135    showSidebar: function() {
136      var self = this;
137
138      sidebarToggleLines.close();
139
140      this.sidebarEl.velocity('stop').velocity({
141        width: SIDEBAR_WIDTH
142      }, {
143        display : 'block',
144        duration: SIDEBAR_DISPLAY_DURATION,
145        begin   : function() {
146          $('.sidebar .motion-element').velocity(
147            'transition.slideRightIn',
148            {
149              stagger : 50,
150              drag    : true,
151              complete: function() {
152                self.sidebarEl.trigger('sidebar.motion.complete');
153              }
154            }
155          );
156        },
157        complete: function() {
158          self.sidebarEl.addClass('sidebar-active');
159          self.sidebarEl.trigger('sidebar.didShow');
160        }
161      }
162      );
163
164      this.sidebarEl.trigger('sidebar.isShowing');
165    },
166    hideSidebar: function() {
167      NexT.utils.isDesktop() && $('body').velocity('stop').velocity({paddingRight: 0});
168      this.sidebarEl.find('.motion-element').velocity('stop').css('display', 'none');
169      this.sidebarEl.velocity('stop').velocity({width: 0}, {display: 'none'});
170
171      sidebarToggleLines.init();
172
173      this.sidebarEl.removeClass('sidebar-active');
174      this.sidebarEl.trigger('sidebar.isHiding');
175
176      // Prevent adding TOC to Overview if Overview was selected when close & open sidebar.
177      if ($('.post-toc-wrap')) {
178        if ($('.site-overview-wrap').css('display') === 'block') {
179          $('.post-toc-wrap').removeClass('motion-element');
180        } else {
181          $('.post-toc-wrap').addClass('motion-element');
182        }
183      }
184    }
185  };
186  sidebarToggleMotion.init();
187
188  NexT.motion.integrator = {
189    queue : [],
190    cursor: -1,
191    add   : function(fn) {
192      this.queue.push(fn);
193      return this;
194    },
195    next: function() {
196      this.cursor++;
197      var fn = this.queue[this.cursor];
198      $.isFunction(fn) && fn(NexT.motion.integrator);
199    },
200    bootstrap: function() {
201      this.next();
202    }
203  };
204
205  NexT.motion.middleWares = {
206    logo: function(integrator) {
207      var sequence = [];
208      var $brand = $('.brand');
209      var $title = $('.site-title');
210      var $subtitle = $('.site-subtitle');
211      var $logoLineTop = $('.logo-line-before i');
212      var $logoLineBottom = $('.logo-line-after i');
213
214      $brand.length > 0 && sequence.push({
215        e: $brand,
216        p: {opacity: 1},
217        o: {duration: 200}
218      });
219
220      /**
221       * Check if $elements exist.
222       * @param {jQuery|Array} $elements
223       * @returns {boolean}
224       */
225      function hasElement($elements) {
226        $elements = Array.isArray($elements) ? $elements : [$elements];
227        return $elements.every(function($element) {
228          return $element.length > 0;
229        });
230      }
231
232      function getMistLineSettings(element, translateX) {
233        return {
234          e: $(element),
235          p: {translateX: translateX},
236          o: {
237            duration     : 500,
238            sequenceQueue: false
239          }
240        };
241      }
242
243      NexT.utils.isMist() && hasElement([$logoLineTop, $logoLineBottom])
244      && sequence.push(
245        getMistLineSettings($logoLineTop, '100%'),
246        getMistLineSettings($logoLineBottom, '-100%')
247      );
248
249      hasElement($title) && sequence.push({
250        e: $title,
251        p: {opacity: 1, top: 0},
252        o: { duration: 200 }
253      });
254
255      hasElement($subtitle) && sequence.push({
256        e: $subtitle,
257        p: {opacity: 1, top: 0},
258        o: {duration: 200}
259      });
260
261      if (CONFIG.motion.async) {
262        integrator.next();
263      }
264
265      if (sequence.length > 0) {
266        sequence[sequence.length - 1].o.complete = function() {
267          integrator.next();
268        };
269        /* eslint-disable */
270        $.Velocity.RunSequence(sequence);
271        /* eslint-enable */
272      } else {
273        integrator.next();
274      }
275    },
276
277    menu: function(integrator) {
278
279      if (CONFIG.motion.async) {
280        integrator.next();
281      }
282
283      $('.menu-item').velocity('transition.slideDownIn', {
284        display : null,
285        duration: 200,
286        complete: function() {
287          integrator.next();
288        }
289      });
290    },
291
292    postList: function(integrator) {
293
294      //var $post = $('.post');
295      var $postBlock = $('.post-block, .pagination, .comments');
296      var $postBlockTransition = CONFIG.motion.transition.post_block;
297      var $postHeader = $('.post-header');
298      var $postHeaderTransition = CONFIG.motion.transition.post_header;
299      var $postBody = $('.post-body');
300      var $postBodyTransition = CONFIG.motion.transition.post_body;
301      var $collHeader = $('.collection-title, .archive-year');
302      var $collHeaderTransition = CONFIG.motion.transition.coll_header;
303      var $sidebarAffix = $('.sidebar-inner');
304      var $sidebarAffixTransition = CONFIG.motion.transition.sidebar;
305      var hasPost = $postBlock.length > 0;
306
307      function postMotion() {
308        var postMotionOptions = window.postMotionOptions || {
309          stagger: 100,
310          drag   : true
311        };
312        postMotionOptions.complete = function() {
313          // After motion complete need to remove transform from sidebar to let affix work on Pisces | Gemini.
314          if (CONFIG.motion.transition.sidebar && (NexT.utils.isPisces() || NexT.utils.isGemini())) {
315            $sidebarAffix.css({ 'transform': 'initial' });
316          }
317          integrator.next();
318        };
319
320        //$post.velocity('transition.slideDownIn', postMotionOptions);
321        if (CONFIG.motion.transition.post_block) {
322          $postBlock.velocity('transition.' + $postBlockTransition, postMotionOptions);
323        }
324        if (CONFIG.motion.transition.post_header) {
325          $postHeader.velocity('transition.' + $postHeaderTransition, postMotionOptions);
326        }
327        if (CONFIG.motion.transition.post_body) {
328          $postBody.velocity('transition.' + $postBodyTransition, postMotionOptions);
329        }
330        if (CONFIG.motion.transition.coll_header) {
331          $collHeader.velocity('transition.' + $collHeaderTransition, postMotionOptions);
332        }
333        // Only for Pisces | Gemini.
334        if (CONFIG.motion.transition.sidebar && (NexT.utils.isPisces() || NexT.utils.isGemini())) {
335          $sidebarAffix.velocity('transition.' + $sidebarAffixTransition, postMotionOptions);
336        }
337      }
338
339      hasPost ? postMotion() : integrator.next();
340
341      if (CONFIG.motion.async) {
342        integrator.next();
343      }
344    },
345
346    sidebar: function(integrator) {
347      if (CONFIG.sidebar.display === 'always') {
348        NexT.utils.displaySidebar();
349      }
350      integrator.next();
351    }
352  };
353
354});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.