Created
October 4, 2008 06:22
-
-
Save ombran/14728 to your computer and use it in GitHub Desktop.
drag and page scroll
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name DragScroll | |
| // @namespace http://github.com/ombran | |
| // @include * | |
| // ==/UserScript== | |
| (function(){ | |
| function DragScroll(){ | |
| this.initialize.apply(this, arguments); | |
| } | |
| DragScroll.prototype = { | |
| draw: false, | |
| speed: 50, | |
| maxStep: 150, | |
| brakeK: 3, | |
| hash: null, | |
| currentBlock: null, | |
| requestedX: 0, | |
| requestedY: 0, | |
| initialize: function(){ | |
| var ds = document.createElement("canvas"); | |
| ds.id = "drag-scroll"; | |
| document.body.appendChild(ds); | |
| var canvas = document.getElementById("drag-scroll"); | |
| var ctx = canvas.getContext("2d"); | |
| canvas.width = 128; | |
| canvas.height = 128; | |
| this.canvas = canvas; | |
| this.ctx = ctx; | |
| this.canvasStyle(); | |
| var self = this; | |
| addEventToListener(canvas, 'mouseup', function(event) { self.catchMouseEvent(event); }, false); | |
| addEventToListener(canvas, 'mousedown', function(event) { self.catchMouseEvent(event); }, false); | |
| addEventToListener(canvas, 'mouseover', function(event) { self.catchMouseEvent(event); }, false); | |
| addEventToListener(canvas, 'mouseout', function(event) { self.catchMouseEvent(event); }, false); | |
| addEventToListener(canvas, 'mousemove', function(event) { self.catchMouseEvent(event); }, false); | |
| addEventToListener(window, 'scroll', function(event) { self.catchMouseEvent(event); }, false); | |
| addEventToListener(window, 'resize', function(event) { self.catchMouseEvent(event); }, false); | |
| this.offDrawRader(); | |
| }, | |
| canvasStyle: function(){ | |
| this.dragWidth = this.canvas.width * ( getScroll().winW / getScroll().docW ); | |
| this.dragHeight = this.canvas.height * ( getScroll().winH / getScroll().docH ); | |
| this.canvas.style.position = "fixed"; | |
| this.canvas.style.top = getScroll().winH - this.canvas.height - 10 + "px"; | |
| this.canvas.style.left = getScroll().winW - this.canvas.width - 10 + "px"; | |
| this.canvas.style.zIndex = "100"; | |
| }, | |
| offDrawRader: function(){ | |
| this.clearCanvas(); | |
| var hx, hy, pw, ph, px, py; | |
| if (this.canvas.getContext){ | |
| px = this.canvas.width * ( getScroll().scrollX / getScroll().docW ); | |
| py = this.canvas.height * ( getScroll().scrollY / getScroll().docH ); | |
| pw = this.dragWidth; | |
| ph = this.dragHeight; | |
| this.ctx.fillStyle = "rgba(200,220,255,0.5)"; | |
| this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); | |
| this.ctx.fillStyle = "rgba(220,180,200,0.5)"; | |
| this.ctx.fillRect(px, py, pw, ph); | |
| } | |
| }, | |
| onDrawRader: function(){ | |
| this.clearCanvas(); | |
| var hx, hy, pw, ph, px, py; | |
| if (this.canvas.getContext){ | |
| px = this.canvas.width * ( getScroll().scrollX / getScroll().docW ); | |
| py = this.canvas.height * ( getScroll().scrollY / getScroll().docH ); | |
| pw = this.dragWidth; | |
| ph = this.dragHeight; | |
| this.ctx.fillStyle = "rgba(200,220,255,0.8)"; | |
| this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); | |
| this.ctx.fillStyle = "rgba(220,180,200,0.8)"; | |
| this.ctx.fillRect(px, py, pw, ph); | |
| } | |
| }, | |
| clearCanvas: function(){ | |
| if (this.canvas.getContext){ | |
| this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); | |
| } | |
| }, | |
| catchMouseEvent: function(event){ | |
| var x, y, ww, hh; | |
| x = event.clientX - this.canvas.offsetLeft - this.dragWidth/2; | |
| y = event.clientY - this.canvas.offsetTop - this.dragHeight/2; | |
| ww = getScroll().docW / this.canvas.width; | |
| hh = getScroll().docH / this.canvas.height; | |
| x = x * ww; | |
| y = y * hh; | |
| switch(event.type) { | |
| case 'mouseover': | |
| this.onDrawRader(); | |
| break; | |
| case 'mouseup': | |
| this.draw = false; | |
| this.initSmoothScroll(x, y); | |
| this.onDrawRader(); | |
| break; | |
| case 'mousedown': | |
| this.draw = true; | |
| this.onDrawRader(); | |
| break; | |
| case 'mouseout': | |
| this.draw = false; | |
| this.offDrawRader(); | |
| break; | |
| case 'mousemove': | |
| if (this.draw == true) { | |
| window.scroll(x, y); | |
| this.onDrawRader(); | |
| } | |
| break; | |
| case 'scroll': | |
| if (this.draw == false) { | |
| this.offDrawRader(); | |
| } | |
| break; | |
| case 'resize': | |
| this.canvasStyle(); | |
| break; | |
| } | |
| }, | |
| /* smooth scroll 機構 */ | |
| initSmoothScroll: function(x, y){ | |
| this.requestedX = x; | |
| this.requestedY = y; | |
| this.smoothScroll(); | |
| return false; | |
| }, | |
| smoothScroll: function(){ | |
| var top = getScroll().scrollY; | |
| var left = getScroll().scrollX; | |
| var winW = getScroll().winW; | |
| var winH = getScroll().winH; | |
| var docW = getScroll().docW; | |
| var docH = getScroll().docH; | |
| var endDistance, offsetX, offsetY; | |
| if(this.requestedY > top) { | |
| endDistance = Math.round((docH - (top + winH)) / this.brakeK); | |
| endDistance = Math.min(Math.round((this.requestedY-top)/ this.brakeK), endDistance); | |
| offsetY = Math.max(2, Math.min(endDistance, this.maxStep)); | |
| } else { | |
| offsetY = - Math.min(Math.abs(Math.round((this.requestedY-top)/ this.brakeK)), this.maxStep); | |
| } | |
| if(this.requestedX > left) { | |
| endDistance = Math.round((docW - (left + winW)) / this.brakeK); | |
| endDistance = Math.min(Math.round((this.requestedX-left)/ this.brakeK), endDistance); | |
| offsetX = Math.max(2, Math.min(endDistance, this.maxStep)); | |
| } else { | |
| offsetX = - Math.min(Math.abs(Math.round((this.requestedX-left)/ this.brakeK)), this.maxStep); | |
| } | |
| window.scrollTo(left + offsetX, top + offsetY); | |
| if((Math.abs(top-this.requestedY) <= 1 || getScroll().scrollY == top) && | |
| (Math.abs(left-this.requestedX) <= 1 || getScroll().scrollX == left)) { | |
| // window.scrollTo(this.requestX, this.requestedY); | |
| } else { | |
| var self = this; | |
| setTimeout(function(){ self.smoothScroll(); }, this.speed); | |
| } | |
| } | |
| } | |
| function addEventToListener(element, event, func, capture){ | |
| if (element.addEventListener) { | |
| element.addEventListener(event, func, capture); | |
| } | |
| else if (element.attachEvent) { | |
| element.attachEvent("on"+event, func); | |
| } | |
| else { | |
| alert("no support browser."); | |
| return(false); | |
| } | |
| } | |
| function getScroll(){ | |
| var Obj = new Object(); | |
| var scrollX1 = scrollX2 = scrollX3 = scrollY1 = scrollY2 = scrollY3 = 0; | |
| var docW1 = docW2 = docH1 = docH2 = 0; | |
| var winW1 = winW2 = winW3 = winH1 = winH2 = winH3 = 0; | |
| if (document.documentElement) { | |
| scrollX1 = document.documentElement.scrollLeft || 0; | |
| scrollY1 = document.documentElement.scrollTop || 0; | |
| docW1 = document.documentElement.scrollWidth || 0; | |
| docH1 = document.documentElement.scrollHeight || 0; | |
| winW1 = document.documentElement.clientWidth; | |
| winH1 = document.documentElement.clientHeight; | |
| } | |
| if (document.body) { | |
| scrollX2 = document.body.scrollLeft || 0; | |
| scrollY2 = document.body.scrollTop || 0; | |
| docW2 = document.body.scrollWidth || 0; | |
| docH2 = document.body.scrollHeight || 0; | |
| winW2 = document.body.clientWidth; | |
| winH2 = document.body.clientHeight; | |
| } | |
| scrollX3 = window.scrollX || 0; | |
| scrollY3 = window.scrollY || 0; | |
| winW3 = window.innerWidth; | |
| winH3 = window.innerHeight; | |
| Obj.scrollX = Math.max(scrollX1, Math.max(scrollX2, scrollX3)); | |
| Obj.scrollY = Math.max(scrollY1, Math.max(scrollY2, scrollY3)); | |
| Obj.docW = Math.max(docW1, docW2); | |
| Obj.docH = Math.max(docH1, docH2); | |
| Obj.winW = Math.min(winW1, Math.min(winW2, winW3)); | |
| Obj.winH = Math.min(winH1, Math.min(winH2, winH3)); | |
| return Obj; | |
| } | |
| addEventToListener(window, 'load', function(){ new DragScroll(); }, false); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment