Skip to content

Instantly share code, notes, and snippets.

@tim-evans
Created May 9, 2011 19:13
Show Gist options
  • Save tim-evans/963174 to your computer and use it in GitHub Desktop.
Save tim-evans/963174 to your computer and use it in GitHub Desktop.
SC scroll events Cappuccino style
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