mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
fix #502: add smoothscroll polyfill
This commit is contained in:
parent
9538e03928
commit
71ec809aea
@ -35,7 +35,7 @@
|
|||||||
// Ensure the currently the selected layer is visible.
|
// Ensure the currently the selected layer is visible.
|
||||||
var currentLayerEl = this.layersListEl.querySelector('.current-layer-item');
|
var currentLayerEl = this.layersListEl.querySelector('.current-layer-item');
|
||||||
if (currentLayerEl) {
|
if (currentLayerEl) {
|
||||||
currentLayerEl.scrollIntoView();
|
currentLayerEl.scrollIntoView({behavior: 'smooth'});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
20
src/js/lib/smoothscroll/LICENSE.txt
Normal file
20
src/js/lib/smoothscroll/LICENSE.txt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013 Dustan Kasten
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
277
src/js/lib/smoothscroll/smoothscroll.js
Normal file
277
src/js/lib/smoothscroll/smoothscroll.js
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
/*
|
||||||
|
* smoothscroll polyfill - v0.3.3
|
||||||
|
* https://iamdustan.github.io/smoothscroll
|
||||||
|
* 2016 (c) Dustan Kasten, Jeremias Menichelli - MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(w, d, undefined) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* aliases
|
||||||
|
* w: window global object
|
||||||
|
* d: document
|
||||||
|
* undefined: undefined
|
||||||
|
*/
|
||||||
|
|
||||||
|
// polyfill
|
||||||
|
function polyfill() {
|
||||||
|
// return when scrollBehavior interface is supported
|
||||||
|
if ('scrollBehavior' in d.documentElement.style) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* globals
|
||||||
|
*/
|
||||||
|
var Element = w.HTMLElement || w.Element;
|
||||||
|
var SCROLL_TIME = 468;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* object gathering original scroll methods
|
||||||
|
*/
|
||||||
|
var original = {
|
||||||
|
scroll: w.scroll || w.scrollTo,
|
||||||
|
scrollBy: w.scrollBy,
|
||||||
|
scrollIntoView: Element.prototype.scrollIntoView
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* define timing method
|
||||||
|
*/
|
||||||
|
var now = w.performance && w.performance.now
|
||||||
|
? w.performance.now.bind(w.performance) : Date.now;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* changes scroll position inside an element
|
||||||
|
* @method scrollElement
|
||||||
|
* @param {Number} x
|
||||||
|
* @param {Number} y
|
||||||
|
*/
|
||||||
|
function scrollElement(x, y) {
|
||||||
|
this.scrollLeft = x;
|
||||||
|
this.scrollTop = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns result of applying ease math function to a number
|
||||||
|
* @method ease
|
||||||
|
* @param {Number} k
|
||||||
|
* @returns {Number}
|
||||||
|
*/
|
||||||
|
function ease(k) {
|
||||||
|
return 0.5 * (1 - Math.cos(Math.PI * k));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* indicates if a smooth behavior should be applied
|
||||||
|
* @method shouldBailOut
|
||||||
|
* @param {Number|Object} x
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
function shouldBailOut(x) {
|
||||||
|
if (typeof x !== 'object'
|
||||||
|
|| x.behavior === undefined
|
||||||
|
|| x.behavior === 'auto'
|
||||||
|
|| x.behavior === 'instant') {
|
||||||
|
// first arg not an object, or behavior is auto, instant or undefined
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof x === 'object'
|
||||||
|
&& x.behavior === 'smooth') {
|
||||||
|
// first argument is an object and behavior is smooth
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// throw error when behavior is not supported
|
||||||
|
throw new TypeError('behavior not valid');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* finds scrollable parent of an element
|
||||||
|
* @method findScrollableParent
|
||||||
|
* @param {Node} el
|
||||||
|
* @returns {Node} el
|
||||||
|
*/
|
||||||
|
function findScrollableParent(el) {
|
||||||
|
do {
|
||||||
|
el = el.parentNode;
|
||||||
|
} while (el !== d.body
|
||||||
|
&& !(el.clientHeight < el.scrollHeight
|
||||||
|
|| el.clientWidth < el.scrollWidth));
|
||||||
|
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* self invoked function that, given a context, steps through scrolling
|
||||||
|
* @method step
|
||||||
|
* @param {Object} context
|
||||||
|
*/
|
||||||
|
function step(context) {
|
||||||
|
// call method again on next available frame
|
||||||
|
context.frame = w.requestAnimationFrame(step.bind(w, context));
|
||||||
|
|
||||||
|
var time = now();
|
||||||
|
var value;
|
||||||
|
var currentX;
|
||||||
|
var currentY;
|
||||||
|
var elapsed = (time - context.startTime) / SCROLL_TIME;
|
||||||
|
|
||||||
|
// avoid elapsed times higher than one
|
||||||
|
elapsed = elapsed > 1 ? 1 : elapsed;
|
||||||
|
|
||||||
|
// apply easing to elapsed time
|
||||||
|
value = ease(elapsed);
|
||||||
|
|
||||||
|
currentX = context.startX + (context.x - context.startX) * value;
|
||||||
|
currentY = context.startY + (context.y - context.startY) * value;
|
||||||
|
|
||||||
|
context.method.call(context.scrollable, currentX, currentY);
|
||||||
|
|
||||||
|
// return when end points have been reached
|
||||||
|
if (currentX === context.x && currentY === context.y) {
|
||||||
|
w.cancelAnimationFrame(context.frame);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* scrolls window with a smooth behavior
|
||||||
|
* @method smoothScroll
|
||||||
|
* @param {Object|Node} el
|
||||||
|
* @param {Number} x
|
||||||
|
* @param {Number} y
|
||||||
|
*/
|
||||||
|
function smoothScroll(el, x, y) {
|
||||||
|
var scrollable;
|
||||||
|
var startX;
|
||||||
|
var startY;
|
||||||
|
var method;
|
||||||
|
var startTime = now();
|
||||||
|
var frame;
|
||||||
|
|
||||||
|
// define scroll context
|
||||||
|
if (el === d.body) {
|
||||||
|
scrollable = w;
|
||||||
|
startX = w.scrollX || w.pageXOffset;
|
||||||
|
startY = w.scrollY || w.pageYOffset;
|
||||||
|
method = original.scroll;
|
||||||
|
} else {
|
||||||
|
scrollable = el;
|
||||||
|
startX = el.scrollLeft;
|
||||||
|
startY = el.scrollTop;
|
||||||
|
method = scrollElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cancel frame when a scroll event's happening
|
||||||
|
if (frame) {
|
||||||
|
w.cancelAnimationFrame(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
// scroll looping over a frame
|
||||||
|
step({
|
||||||
|
scrollable: scrollable,
|
||||||
|
method: method,
|
||||||
|
startTime: startTime,
|
||||||
|
startX: startX,
|
||||||
|
startY: startY,
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
frame: frame
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ORIGINAL METHODS OVERRIDES
|
||||||
|
*/
|
||||||
|
|
||||||
|
// w.scroll and w.scrollTo
|
||||||
|
w.scroll = w.scrollTo = function() {
|
||||||
|
// avoid smooth behavior if not required
|
||||||
|
if (shouldBailOut(arguments[0])) {
|
||||||
|
original.scroll.call(
|
||||||
|
w,
|
||||||
|
arguments[0].left || arguments[0],
|
||||||
|
arguments[0].top || arguments[1]
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LET THE SMOOTHNESS BEGIN!
|
||||||
|
smoothScroll.call(
|
||||||
|
w,
|
||||||
|
d.body,
|
||||||
|
~~arguments[0].left,
|
||||||
|
~~arguments[0].top
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// w.scrollBy
|
||||||
|
w.scrollBy = function() {
|
||||||
|
// avoid smooth behavior if not required
|
||||||
|
if (shouldBailOut(arguments[0])) {
|
||||||
|
original.scrollBy.call(
|
||||||
|
w,
|
||||||
|
arguments[0].left || arguments[0],
|
||||||
|
arguments[0].top || arguments[1]
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LET THE SMOOTHNESS BEGIN!
|
||||||
|
smoothScroll.call(
|
||||||
|
w,
|
||||||
|
d.body,
|
||||||
|
~~arguments[0].left + (w.scrollX || w.pageXOffset),
|
||||||
|
~~arguments[0].top + (w.scrollY || w.pageYOffset)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Element.prototype.scrollIntoView
|
||||||
|
Element.prototype.scrollIntoView = function() {
|
||||||
|
// avoid smooth behavior if not required
|
||||||
|
if (shouldBailOut(arguments[0])) {
|
||||||
|
original.scrollIntoView.call(this, arguments[0] || true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LET THE SMOOTHNESS BEGIN!
|
||||||
|
var scrollableParent = findScrollableParent(this);
|
||||||
|
var parentRects = scrollableParent.getBoundingClientRect();
|
||||||
|
var clientRects = this.getBoundingClientRect();
|
||||||
|
|
||||||
|
if (scrollableParent !== d.body) {
|
||||||
|
// reveal element inside parent
|
||||||
|
smoothScroll.call(
|
||||||
|
this,
|
||||||
|
scrollableParent,
|
||||||
|
scrollableParent.scrollLeft + clientRects.left - parentRects.left,
|
||||||
|
scrollableParent.scrollTop + clientRects.top - parentRects.top
|
||||||
|
);
|
||||||
|
// reveal parent in viewport
|
||||||
|
w.scrollBy({
|
||||||
|
left: parentRects.left,
|
||||||
|
top: parentRects.top,
|
||||||
|
behavior: 'smooth'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// reveal element in viewport
|
||||||
|
w.scrollBy({
|
||||||
|
left: clientRects.left,
|
||||||
|
top: clientRects.top,
|
||||||
|
behavior: 'smooth'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof exports === 'object') {
|
||||||
|
// commonjs
|
||||||
|
module.exports = { polyfill: polyfill };
|
||||||
|
} else {
|
||||||
|
// global
|
||||||
|
polyfill();
|
||||||
|
}
|
||||||
|
})(window, document);
|
@ -53,6 +53,9 @@
|
|||||||
// JSZip https://github.com/Stuk/jszip
|
// JSZip https://github.com/Stuk/jszip
|
||||||
"js/lib/jszip/jszip.min.js",
|
"js/lib/jszip/jszip.min.js",
|
||||||
|
|
||||||
|
// Smoothscroll: https://github.com/iamdustan/smoothscroll
|
||||||
|
"js/lib/smoothscroll/smoothscroll.js",
|
||||||
|
|
||||||
// Spectrum color-picker library
|
// Spectrum color-picker library
|
||||||
"js/lib/spectrum/spectrum.js",
|
"js/lib/spectrum/spectrum.js",
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user