PageSourceSearch

https://nokaoiseikei.com/js/flipsnap.js

js nokaoiseikei.com collected 2026-10-06 08:10:10 UTC 12,844 bytes, 577 lines download raw bytes

1/**
2 * flipsnap.js
3 *
4 * @version  0.5.6
5 * @url http://pxgrid.github.com/js-flipsnap/
6 *
7 * Copyright 2011 PixelGrid, Inc.
8 * Licensed under the MIT License:
9 * http://www.opensource.org/licenses/mit-license.php
10 */
11
12(function(window, document, undefined) {
13
14var div = document.createElement('div');
15var prefix = ['webkit', 'moz', 'o', 'ms'];
16var saveProp = {};
17var support = Flipsnap.support = {};
18var gestureStart = false;
19
20support.transform3d = hasProp([
21  'perspectiveProperty',
22  'WebkitPerspective',
23  'MozPerspective',
24  'OPerspective',
25  'msPerspective'
26]);
27
28support.transform = hasProp([
29  'transformProperty',
30  'WebkitTransform',
31  'MozTransform',
32  'OTransform',
33  'msTransform'
34]);
35
36support.transition = hasProp([
37  'transitionProperty',
38  'WebkitTransitionProperty',
39  'MozTransitionProperty',
40  'OTransitionProperty',
41  'msTransitionProperty'
42]);
43
44support.addEventListener = 'addEventListener' in window;
45support.mspointer = window.navigator.msPointerEnabled;
46
47support.cssAnimation = (support.transform3d || support.transform) && support.transition;
48
49var eventTypes = ['touch', 'mouse'];
50var events = {
51  start: {
52    touch: 'touchstart',
53    mouse: 'mousedown'
54  },
55  move: {
56    touch: 'touchmove',
57    mouse: 'mousemove'
58  },
59  end: {
60    touch: 'touchend',
61    mouse: 'mouseup'
62  }
63};
64
65if (support.addEventListener) {
66  document.addEventListener('gesturestart', function() {
67    gestureStart = true;
68  });
69
70  document.addEventListener('gestureend', function() {
71    gestureStart = false;
72  });
73}
74
75function Flipsnap(element, opts) {
76  return (this instanceof Flipsnap)
77    ? this.init(element, opts)
78    : new Flipsnap(element, opts);
79}
80
81Flipsnap.prototype.init = function(element, opts) {
82  var self = this;
83
84  // set element
85  self.element = element;
86  if (typeof element === 'string') {
87    self.element = document.querySelector(element);
88  }
89
90  if (!self.element) {
91    throw new Error('element not found');
92  }
93
94  if (support.mspointer) {
95    self.element.style.msTouchAction = 'none';
96  }
97
98  // set opts
99  opts = opts || {};
100  self.distance = opts.distance;
101  self.maxPoint = opts.maxPoint;
102  self.disableTouch = (opts.disableTouch === undefined) ? false : opts.disableTouch;
103  self.disable3d = (opts.disable3d === undefined) ? false : opts.disable3d;
104  self.transitionDuration = (opts.transitionDuration === undefined) ? '350ms' : opts.transitionDuration + 'ms';
105
106  // set property
107  self.currentPoint = 0;
108  self.currentX = 0;
109  self.animation = false;
110  self.use3d = support.transform3d;
111  if (self.disable3d === true) {
112    self.use3d = false;
113  }
114
115  // set default style
116  if (support.cssAnimation) {
117    self._setStyle({
118      transitionProperty: getCSSVal('transform'),
119      transitionTimingFunction: 'cubic-bezier(0,0,0.25,1)',
120      transitionDuration: '0ms',
121      transform: self._getTranslate(0)
122    });
123  }
124  else {
125    self._setStyle({
126      position: 'relative',
127      left: '0px'
128    });
129  }
130
131  // initilize
132  self.refresh();
133
134  eventTypes.forEach(function(type) {
135    self.element.addEventListener(events.start[type], self, false);
136  });
137
138  return self;
139};
140
141Flipsnap.prototype.handleEvent = function(event) {
142  var self = this;
143
144  switch (event.type) {
145    case events.start.touch:
146    case events.start.mouse:
147      self._touchStart(event);
148      break;
149    case events.move.touch:
150    case events.move.mouse:
151      self._touchMove(event);
152      break;
153    case events.end.touch:
154    case events.end.mouse:
155      self._touchEnd(event);
156      break;
157    case 'click':
158      self._click(event);
159      break;
160  }
161};
162
163Flipsnap.prototype.refresh = function() {
164  var self = this;
165
166  // setting max point
167  self._maxPoint = (self.maxPoint === undefined) ? (function() {
168    var childNodes = self.element.childNodes,
169      itemLength = -1,
170      i = 0,
171      len = childNodes.length,
172      node;
173    for(; i < len; i++) {
174      node = childNodes[i];
175      if (node.nodeType === 1) {
176        itemLength++;
177      }
178    }
179
180    return itemLength;
181  })() : self.maxPoint;
182
183  // setting distance
184  if (self.distance === undefined) {
185    if (self._maxPoint < 0) {
186      self._distance = 0;
187    }
188    else {
189      self._distance = self.element.scrollWidth / (self._maxPoint + 1);
190    }
191  }
192  else {
193    self._distance = self.distance;
194  }
195
196  // setting maxX
197  self._maxX = -self._distance * self._maxPoint;
198
199  self.moveToPoint();
200};
201
202Flipsnap.prototype.hasNext = function() {
203  var self = this;
204
205  return self.currentPoint < self._maxPoint;
206};
207
208Flipsnap.prototype.hasPrev = function() {
209  var self = this;
210
211  return self.currentPoint > 0;
212};
213
214Flipsnap.prototype.toNext = function(transitionDuration) {
215  var self = this;
216
217  if (!self.hasNext()) {
218    return;
219  }
220
221  self.moveToPoint(self.currentPoint + 1, transitionDuration);
222};
223
224Flipsnap.prototype.toPrev = function(transitionDuration) {
225  var self = this;
226
227  if (!self.hasPrev()) {
228    return;
229  }
230
231  self.moveToPoint(self.currentPoint - 1, transitionDuration);
232};
233
234Flipsnap.prototype.moveToPoint = function(point, transitionDuration) {
235  var self = this;
236  
237  transitionDuration = transitionDuration === undefined
238    ? self.transitionDuration : transitionDuration + 'ms';
239
240  var beforePoint = self.currentPoint;
241
242  // not called from `refresh()`
243  if (point === undefined) {
244    point = self.currentPoint;
245  }
246
247  if (point < 0) {
248    self.currentPoint = 0;
249  }
250  else if (point > self._maxPoint) {
251    self.currentPoint = self._maxPoint;
252  }
253  else {
254    self.currentPoint = parseInt(point, 10);
255  }
256
257  if (support.cssAnimation) {
258    self._setStyle({ transitionDuration: transitionDuration });
259  }
260  else {
261    self.animation = true;
262  }
263  self._setX(- self.currentPoint * self._distance, transitionDuration);
264
265  if (beforePoint !== self.currentPoint) { // is move?
266    // `fsmoveend` is deprecated
267    // `fspointmove` is recommend.
268    self._triggerEvent('fsmoveend', true, false);
269    self._triggerEvent('fspointmove', true, false);
270  }
271};
272
273Flipsnap.prototype._setX = function(x, transitionDuration) {
274  var self = this;
275
276  self.currentX = x;
277  if (support.cssAnimation) {
278    self.element.style[ saveProp.transform ] = self._getTranslate(x);
279  }
280  else {
281    if (self.animation) {
282      self._animate(x, transitionDuration || self.transitionDuration);
283    }
284    else {
285      self.element.style.left = x + 'px';
286    }
287  }
288};
289
290Flipsnap.prototype._touchStart = function(event) {
291  var self = this;
292
293  if (self.disableTouch || self._eventType || gestureStart) {
294    return;
295  }
296
297  some(eventTypes, function(type) {
298    if (event.type === events.start[type]) {
299      self._eventType = type;
300      return true;
301    }
302  });
303
304  self.element.addEventListener(events.move[self._eventType], self, false);
305  document.addEventListener(events.end[self._eventType], self, false);
306
307  if (self._eventType === 'mouse') {
308    event.preventDefault();
309  }
310
311  if (support.cssAnimation) {
312    self._setStyle({ transitionDuration: '0ms' });
313  }
314  else {
315    self.animation = false;
316  }
317  self.scrolling = true;
318  self.moveReady = false;
319  self.startPageX = getPage(event, 'pageX');
320  self.startPageY = getPage(event, 'pageY');
321  self.basePageX = self.startPageX;
322  self.directionX = 0;
323  self.startTime = event.timeStamp;
324  self._triggerEvent('fstouchstart', true, false);
325};
326
327Flipsnap.prototype._touchMove = function(event) {
328  var self = this;
329
330  if (!self.scrolling || gestureStart) {
331    return;
332  }
333
334  var pageX = getPage(event, 'pageX'),
335    pageY = getPage(event, 'pageY'),
336    distX,
337    newX,
338    deltaX,
339    deltaY;
340
341  if (self.moveReady) {
342    event.preventDefault();
343    event.stopPropagation();
344
345    distX = pageX - self.basePageX;
346    newX = self.currentX + distX;
347    if (newX >= 0 || newX < self._maxX) {
348      newX = Math.round(self.currentX + distX / 3);
349    }
350
351    // When distX is 0, use one previous value.
352    // For android firefox. When touchend fired, touchmove also
353    // fired and distX is certainly set to 0. 
354    self.directionX =
355      distX === 0 ? self.directionX :
356      distX > 0 ? -1 : 1;
357
358    // if they prevent us then stop it
359    var isPrevent = !self._triggerEvent('fstouchmove', true, true, {
360      delta: distX,
361      direction: self.directionX
362    });
363
364    if (isPrevent) {
365      self._touchAfter({
366        moved: false,
367        originalPoint: self.currentPoint,
368        newPoint: self.currentPoint,
369        cancelled: true
370      });
371    } else {
372      self._setX(newX);
373    }
374  }
375  else {
376    deltaX = Math.abs(pageX - self.startPageX);
377    deltaY = Math.abs(pageY - self.startPageY);
378    if (deltaX > 5) {
379      event.preventDefault();
380      event.stopPropagation();
381      self.moveReady = true;
382      self.element.addEventListener('click', self, true);
383    }
384    else if (deltaY > 5) {
385      self.scrolling = false;
386    }
387  }
388
389  self.basePageX = pageX;
390};
391
392Flipsnap.prototype._touchEnd = function(event) {
393  var self = this;
394
395  self.element.removeEventListener(events.move[self._eventType], self, false);
396  document.removeEventListener(events.end[self._eventType], self, false);
397  self._eventType = null;
398
399  if (!self.scrolling) {
400    return;
401  }
402
403  var newPoint = -self.currentX / self._distance;
404  newPoint =
405    (self.directionX > 0) ? Math.ceil(newPoint) :
406    (self.directionX < 0) ? Math.floor(newPoint) :
407    Math.round(newPoint);
408
409  if (newPoint < 0) {
410    newPoint = 0;
411  }
412  else if (newPoint > self._maxPoint) {
413    newPoint = self._maxPoint;
414  }
415
416  self._touchAfter({
417    moved: newPoint !== self.currentPoint,
418    originalPoint: self.currentPoint,
419    newPoint: newPoint,
420    cancelled: false
421  });
422
423  self.moveToPoint(newPoint);
424};
425
426Flipsnap.prototype._click = function(event) {
427  var self = this;
428
429  event.stopPropagation();
430  event.preventDefault();
431};
432
433Flipsnap.prototype._touchAfter = function(params) {
434  var self = this;
435
436  self.scrolling = false;
437  self.moveReady = false;
438
439  setTimeout(function() {
440    self.element.removeEventListener('click', self, true);
441  }, 200);
442
443  self._triggerEvent('fstouchend', true, false, params);
444};
445
446Flipsnap.prototype._setStyle = function(styles) {
447  var self = this;
448  var style = self.element.style;
449
450  for (var prop in styles) {
451    setStyle(style, prop, styles[prop]);
452  }
453};
454
455Flipsnap.prototype._animate = function(x, transitionDuration) {
456  var self = this;
457
458  var elem = self.element;
459  var begin = +new Date();
460  var from = parseInt(elem.style.left, 10);
461  var to = x;
462  var duration = parseInt(transitionDuration, 10);
463  var easing = function(time, duration) {
464    return -(time /= duration) * (time - 2);
465  };
466  var timer = setInterval(function() {
467    var time = new Date() - begin;
468    var pos, now;
469    if (time > duration) {
470      clearInterval(timer);
471      now = to;
472    }
473    else {
474      pos = easing(time, duration);
475      now = pos * (to - from) + from;
476    }
477    elem.style.left = now + "px";
478  }, 10);
479};
480
481Flipsnap.prototype.destroy = function() {
482  var self = this;
483
484  eventTypes.forEach(function(type) {
485    self.element.removeEventListener(events.start[type], self, false);
486  });
487};
488
489Flipsnap.prototype._getTranslate = function(x) {
490  var self = this;
491
492  return self.use3d
493    ? 'translate3d(' + x + 'px, 0, 0)'
494    : 'translate(' + x + 'px, 0)';
495};
496
497Flipsnap.prototype._triggerEvent = function(type, bubbles, cancelable, data) {
498  var self = this;
499
500  var ev = document.createEvent('Event');
501  ev.initEvent(type, bubbles, cancelable);
502
503  if (data) {
504    for (var d in data) {
505      if (data.hasOwnProperty(d)) {
506        ev[d] = data[d];
507      }
508    }
509  }
510
511  return self.element.dispatchEvent(ev);
512};
513
514function getPage(event, page) {
515  return event.changedTouches ? event.changedTouches[0][page] : event[page];
516}
517
518function hasProp(props) {
519  return some(props, function(prop) {
520    return div.style[ prop ] !== undefined;
521  });
522}
523
524function setStyle(style, prop, val) {
525  var _saveProp = saveProp[ prop ];
526  if (_saveProp) {
527    style[ _saveProp ] = val;
528  }
529  else if (style[ prop ] !== undefined) {
530    saveProp[ prop ] = prop;
531    style[ prop ] = val;
532  }
533  else {
534    some(prefix, function(_prefix) {
535      var _prop = ucFirst(_prefix) + ucFirst(prop);
536      if (style[ _prop ] !== undefined) {
537        saveProp[ prop ] = _prop;
538        style[ _prop ] = val;
539        return true;
540      }
541    });
542  }
543}
544
545function getCSSVal(prop) {
546  if (div.style[ prop ] !== undefined) {
547    return prop;
548  }
549  else {
550    var ret;
551    some(prefix, function(_prefix) {
552      var _prop = ucFirst(_prefix) + ucFirst(prop);
553      if (div.style[ _prop ] !== undefined) {
554        ret = '-' + _prefix + '-' + prop;
555        return true;
556      }
557    });
558    return ret;
559  }
560}
561
562function ucFirst(str) {
563  return str.charAt(0).toUpperCase() + str.substr(1);
564}
565
566function some(ary, callback) {
567  for (var i = 0, len = ary.length; i < len; i++) {
568    if (callback(ary[i], i)) {
569      return true;
570    }
571  }
572  return false;
573}
574
575window.Flipsnap = Flipsnap;
576
577})(window, window.document);

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.