Skip to content

Instantly share code, notes, and snippets.

@w-log
Created March 25, 2018 12:20
Show Gist options
  • Save w-log/f2f4083ec6732f3ee146992b5ffa80a4 to your computer and use it in GitHub Desktop.
Save w-log/f2f4083ec6732f3ee146992b5ffa80a4 to your computer and use it in GitHub Desktop.
마우스로 드래그해서 스크롤링하기 예제
body {
margin: 0;
}
.scroll-container {
width:500px;
height:500px;
overflow:hidden;
}
.scroll-container:active {
cursor: grab;
cursor: -moz-grab;
cursor: -webkit-grab;
}
.content {
width: 1000px;
height: 1000px;
background-image:url('https://www.google.co.kr/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png');
user-select:none;
}
<div id="touch" class="scroll-container">
<div class="content"></div>
<div class="content"></div>
<div class="content"></div>
</div>
(function(w) {
"use strict";
// easing 함수 주소 : http://goo.gl/5HLl8
var easing = {
linear: function (t, b, c, d) {
t /= d;
return b + c * (t);
},
easeOut: function (t, b, c, d) {
var ts = (t /= d) * t;
var tc = ts * t;
return b + c * (0.9 * tc * ts + -4.35 * ts * ts + 8.6 * tc + -8.7 * ts + 4.55 * t);
}
};
var requestAniFrame = (function () {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
function ScrollAnimation(el, position) {
this.elPosition = this.setElement(el, position);
this.scrolled = false;
this.canceled = false;
}
ScrollAnimation.prototype.setElement = function (el, position) {
"use strict";
return {
setScroll: function (val) {
position === 'x' ? (el.scrollLeft = val) : (el.scrollTop = val);
},
getScroll: function () {
return position === 'x' ? (el.scrollLeft) : (el.scrollTop);
}
};
};
ScrollAnimation.prototype.getScrolled = function () {
return this.scrolled;
};
ScrollAnimation.prototype.stopAnimate = function () {
if (this.scrolled) {
this.canceled = true;
}
};
ScrollAnimation.prototype.scrollAnimation = function (to, duration, easingName, callback) {
var start = this.elPosition.getScroll(),
change = to - start,
currentTime = 0,
increment = 1000 / 60,
self = this;
duration = typeof duration === 'undefined' ? 500 : duration;
this.scrolled = true;
var animate = function () {
currentTime += increment;
var val = easing[easingName] ? easing[easingName](currentTime, start, change, duration) : easing["linear"](currentTime, start, change, duration);
self.elPosition.setScroll(val);
if (currentTime <= duration && !self.canceled) {
requestAniFrame(animate);
} else {
if (callback && typeof(callback) === 'function') {
callback();
}
self.scrolled = false;
self.canceled = false;
}
};
animate();
};
window.ScrollAnimation = ScrollAnimation;
})(window || (window = {}));
(function(w){
"use strict";
var ScrollAnimation = w.ScrollAnimation;
var isDown = false;
var x = 0,
y = 0,
offsetX = 0,
offsetY = 0;
var eventTarget = null;
var scrollWidth = 0,
scrollHeight = 0;
var scrollEl = document.getElementById('touch');
var scrollXAnimate = new ScrollAnimation(scrollEl, 'x');
var scrollYAnimate = new ScrollAnimation(scrollEl, 'y');
var time = 0, millisecond = 0, distanceX = 0, distanceY = 0;
function mouseMove(e) {
if (!isDown || !eventTarget) {
return false;
}
var self = this;
requestAnimationFrame(function() {
var currentX = e.clientX + x;
var currentY = e.clientY + y;
if(time > 0) {
millisecond += e.timeStamp - time;
time = e.timeStamp;
distanceX += (currentX - offsetX);
distanceY += (currentY - offsetY);
}
var scrollTop = y - (currentY - offsetY);
var scrollLeft = x - (currentX - offsetX);
if (scrollTop < 0 || scrollTop > scrollHeight) {
scrollTop = scrollTop < 0 ? 0 : scrollTop > scrollHeight ? scrollHeight : scrollTop;
offsetY = currentY;
}
if (scrollLeft < 0 || scrollLeft > scrollWidth) {
scrollLeft = scrollLeft < 0 ? 0 : scrollLeft > scrollWidth ? scrollWidth : scrollLeft;
offsetX = currentX;
}
self.scrollTop = scrollTop;
self.scrollLeft = scrollLeft;
y = scrollTop;
x = scrollLeft;
});
}
function mouseDown(e) {
scrollWidth = this.scrollWidth - this.offsetWidth;
scrollHeight = this.scrollHeight - this.offsetHeight;
y = this.scrollTop;
x = this.scrollLeft;
offsetX = e.clientX + x;
offsetY = e.clientY + y;
isDown = true;
eventTarget = e;
time = e.timeStamp;
(scrollXAnimate.getScrolled() ? scrollXAnimate.stopAnimate() : '');
(scrollYAnimate.getScrolled() ? scrollYAnimate.stopAnimate() : '');
}
function mouseUp(e) {
if (e.type === 'mouseout' && this.contains(e.target)) {
return false;
}
isDown = false;
if(time > 0) {
var targetX = x - (distanceX / (millisecond / 1000)) / 10;
var targetY = y - (distanceY / (millisecond / 1000)) / 10;
if(!isNaN(targetX) && !isNaN(targetY)) {
scrollXAnimate.scrollAnimation(targetX, 1000, 'easeOut', null);
scrollYAnimate.scrollAnimation(targetY, 1000, 'easeOut', null);
}
}
time = 0;
millisecond = 0;
distanceX = 0;
distanceY = 0;
}
scrollEl.addEventListener('mousedown', mouseDown, false);
scrollEl.addEventListener('mouseup', mouseUp);
scrollEl.addEventListener('mouseleave', mouseUp);
scrollEl.addEventListener('mousemove', mouseMove, false);
})(window || (window = {}));
@w-log
Copy link
Author

w-log commented Mar 28, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment