Created
May 9, 2011 19:13
-
-
Save tim-evans/963174 to your computer and use it in GitHub Desktop.
SC scroll events Cappuccino style
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
diff --git a/frameworks/core_foundation/resources/core.css b/frameworks/core_foundation/resources/core.css | |
index 821d88c..3aca696 100644 | |
--- a/frameworks/core_foundation/resources/core.css | |
+++ b/frameworks/core_foundation/resources/core.css | |
@@ -6,6 +6,17 @@ | |
-webkit-tap-highlight-color: rgba(0,0,0,0); | |
} | |
+#sc-scroller { | |
+ position: absolute; | |
+ visibility: hidden; | |
+ z-index: 999; | |
+ height: 60px; | |
+ width: 60px; | |
+ overflow: scroll; | |
+ opacity: 0; | |
+ filter: alpha(opacity=0); | |
+} | |
+ | |
/* Set here so when we set a border-width it will actually take up space | |
* Color should be changed with CSS for that view | |
* Only set on div, since occasionally we rely on native styling for other tags */ | |
diff --git a/frameworks/core_foundation/system/event.js b/frameworks/core_foundation/system/event.js | |
index 6b9383d..717ab85 100644 | |
--- a/frameworks/core_foundation/system/event.js | |
+++ b/frameworks/core_foundation/system/event.js | |
@@ -77,109 +77,11 @@ SC.Event = function(originalEvent) { | |
this.which = ((this.button & 1) ? 1 : ((this.button & 2) ? 3 : ( (this.button & 4) ? 2 : 0 ) )); | |
} | |
- // Normalize wheel delta values for mousewheel events | |
- if (this.type === 'mousewheel' || this.type === 'DOMMouseScroll' || this.type === 'MozMousePixelScroll') { | |
- var deltaMultiplier = SC.Event.MOUSE_WHEEL_MULTIPLIER, | |
- version = parseFloat(SC.browser.version); | |
- | |
- // normalize wheelDelta, wheelDeltaX, & wheelDeltaY for Safari | |
- if (SC.browser.webkit && originalEvent.wheelDelta!==undefined) { | |
- this.wheelDelta = 0-(originalEvent.wheelDeltaY || originalEvent.wheelDeltaX); | |
- this.wheelDeltaY = 0-(originalEvent.wheelDeltaY||0); | |
- this.wheelDeltaX = 0-(originalEvent.wheelDeltaX||0); | |
- | |
- // normalize wheelDelta for Firefox | |
- // note that we multiple the delta on FF to make it's acceleration more | |
- // natural. | |
- } else if (!SC.none(originalEvent.detail) && SC.browser.mozilla) { | |
- if (originalEvent.axis && (originalEvent.axis === originalEvent.HORIZONTAL_AXIS)) { | |
- this.wheelDeltaX = originalEvent.detail; | |
- this.wheelDeltaY = this.wheelDelta = 0; | |
- } else { | |
- this.wheelDeltaY = this.wheelDelta = originalEvent.detail ; | |
- this.wheelDeltaX = 0 ; | |
- } | |
- | |
- // handle all other legacy browser | |
- } else { | |
- this.wheelDelta = this.wheelDeltaY = SC.browser.msie ? 0-originalEvent.wheelDelta : originalEvent.wheelDelta ; | |
- this.wheelDeltaX = 0 ; | |
- } | |
- | |
- // we have a value over the limit and it wasn't caught when we generated MOUSE_WHEEL_MULTIPLIER | |
- // this will happen as new Webkit-based browsers are released and we haven't covered them off | |
- // in our browser detection. It'll scroll too quickly the first time, but we might as well learn | |
- // and change our handling for the next scroll | |
- if (this.wheelDelta > SC.Event.MOUSE_WHEEL_DELTA_LIMIT && !SC.Event._MOUSE_WHEEL_LIMIT_INVALIDATED) { | |
- deltaMultiplier = SC.Event.MOUSE_WHEEL_MULTIPLIER = 0.004; | |
- SC.Event._MOUSE_WHEEL_LIMIT_INVALIDATED = YES; | |
- } | |
- | |
- this.wheelDelta *= deltaMultiplier; | |
- this.wheelDeltaX *= deltaMultiplier; | |
- this.wheelDeltaY *= deltaMultiplier; | |
- } | |
- | |
return this; | |
} ; | |
SC.mixin(SC.Event, /** @scope SC.Event */ { | |
- /** | |
- We need this because some browsers deliver different values | |
- for mouse wheel deltas. Once the first mouse wheel event has | |
- been run, this value will get set. Because we don't know the | |
- maximum or minimum value ahead of time, if the event's delta | |
- exceeds `SC.Event.MOUSE_WHEEL_DELTA_LIMIT`, this value can be | |
- invalidated and changed during a later event. | |
- | |
- @field | |
- @type Number | |
- @default 1 | |
- */ | |
- MOUSE_WHEEL_MULTIPLIER: (function() { | |
- var deltaMultiplier = 1, | |
- version = parseFloat(SC.browser.version), | |
- didChange = NO; | |
- | |
- if (SC.browser.safari) { | |
- // Safari 5.0.1 and up | |
- if (version >= 533.17) { | |
- deltaMultiplier = 0.004; | |
- didChange = YES; | |
- } else if (version < 533) { | |
- // Scrolling in Safari 5.0 | |
- deltaMultiplier = 40; | |
- didChange = YES; | |
- } | |
- } else if (SC.browser.mozilla) { | |
- deltaMultiplier = 10; | |
- didChange = YES; | |
- } | |
- | |
- if (didChange) { SC.Event._MOUSE_WHEEL_LIMIT_INVALIDATED = YES; } | |
- | |
- return deltaMultiplier; | |
- })(), | |
- | |
- /** | |
- This represents the limit in the delta before a different multiplier | |
- will be applied. Because we can't generated an accurate mouse | |
- wheel event ahead of time, and browsers deliver differing values | |
- for mouse wheel deltas, this is necessary to ensure that | |
- browsers that scale their values largely are dealt with correctly | |
- in the future. | |
- | |
- @type Number | |
- @default 1000 | |
- */ | |
- MOUSE_WHEEL_DELTA_LIMIT: 1000, | |
- | |
- /** @private | |
- We only want to invalidate once | |
- */ | |
- _MOUSE_WHEEL_LIMIT_INVALIDATED: NO, | |
- | |
/** | |
Standard method to create a new event. Pass the native browser event you | |
wish to wrap if needed. | |
diff --git a/frameworks/core_foundation/system/root_responder.js b/frameworks/core_foundation/system/root_responder.js | |
index 1759dfd..ba9422f 100644 | |
--- a/frameworks/core_foundation/system/root_responder.js | |
+++ b/frameworks/core_foundation/system/root_responder.js | |
@@ -665,8 +665,22 @@ SC.RootResponder = SC.Object.extend({ | |
} | |
}, this); | |
- var mousewheel = 'mousewheel'; | |
+ // Create scroller | |
+ var scrollingElement = document.createElement("div"); | |
+ jQuery(scrollingElement).attr('id', 'sc-scroller'); | |
+ document.body.appendChild(scrollingElement); | |
+ this._scrr_scrollingElement = scrollingElement; | |
+ | |
+ var innerElement = document.createElement("div"); | |
+ innerElement.style.width = "400px"; | |
+ innerElement.style.height = "400px"; | |
+ scrollingElement.appendChild(innerElement); | |
+ // Set an initial scroll offset | |
+ scrollingElement.scrollTop = 150; | |
+ scrollingElement.scrollLeft = 150; | |
+ | |
+ var mousewheel = 'mousewheel'; | |
// Firefox emits different mousewheel events than other browsers | |
if (SC.browser.mozilla) { | |
// For Firefox <3.5, subscribe to DOMMouseScroll events | |
@@ -1853,10 +1867,51 @@ SC.RootResponder = SC.Object.extend({ | |
}, | |
mousewheel: function(evt) { | |
- var view = this.targetViewForEvent(evt) , | |
- handler = this.sendEvent('mouseWheel', evt, view) ; | |
+ var scrollingElement = this._scrr_scrollingElement, | |
+ view = this.targetViewForEvent(evt) || | |
+ SC.$(document.elementFromPoint(evt.clientY, evt.clientX)).view()[0]; | |
+ | |
+ if (this._scrr_hideScrollingElement) { | |
+ clearTimeout(this._scrr_hideScrollingElement); | |
+ this._scrr_hideScrollingElement = null; | |
+ } | |
+ | |
+ // Move the scrolling element to the current position | |
+ // where we got the scroll event. | |
+ jQuery(scrollingElement).css({ | |
+ visibility: 'visible', | |
+ top: (evt.clientY - 15) + "px", | |
+ left: (evt.clientX - 15) + "px" | |
+ }); | |
+ | |
+ setTimeout(function (e, scrollingElement, that, target) { | |
+ return function () { | |
+ var wheelDeltaY = scrollingElement.scrollTop - 150, | |
+ wheelDeltaX = scrollingElement.scrollLeft - 150; | |
+ | |
+ // Pixel precise mouse events might not have a delta. | |
+ // Ignore these events, since it'll just gum up the works | |
+ // with unnecessary events. | |
+ if (wheelDeltaX || wheelDeltaY) { | |
+ e.wheelDelta = wheelDeltaY || wheelDeltaX; | |
+ e.wheelDeltaY = wheelDeltaY; | |
+ e.wheelDeltaX = wheelDeltaX; | |
+ | |
+ that.sendEvent('mouseWheel', evt, target); | |
+ } | |
+ | |
+ scrollingElement.scrollTop = 150; | |
+ scrollingElement.scrollLeft = 150; | |
+ }; | |
+ }(evt, scrollingElement, this, view), 0); | |
+ | |
+ // Hide the scrolling element when we're done scrolling, | |
+ // allowing events to propagate down | |
+ this._scrr_hideScrollingElement = setTimeout(function () { | |
+ scrollingElement.style.visibility = 'hidden'; | |
+ }, 300); | |
- return (handler) ? evt.hasCustomEventHandling : YES ; | |
+ return YES; // let the browser handle events. | |
}, | |
_lastHovered: null, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment