From 70c01d9a6855b8d5438050527fc05c53b3f3b4be Mon Sep 17 00:00:00 2001 From: Boris Yankov Date: Mon, 21 Jan 2013 02:44:04 +0200 Subject: [PATCH] Add Zynga Scroller definitions and tests --- README.md | 1 + scroller/easyscroller.d.ts | 15 +++ scroller/scroller-tests.ts | 254 +++++++++++++++++++++++++++++++++++++ scroller/scroller.d.ts | 50 ++++++++ 4 files changed, 320 insertions(+) create mode 100644 scroller/easyscroller.d.ts create mode 100644 scroller/scroller-tests.ts create mode 100644 scroller/scroller.d.ts diff --git a/README.md b/README.md index 9d27edfb9..ea97bba14 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,7 @@ List of Definitions * [Vimeo](http://developer.vimeo.com/player/js-api) (by [Daz Wilkin](https://github.com/DazWilkin/)) * [WebRTC](http://dev.w3.org/2011/webrtc/editor/webrtc.html) (by [Ken Smith](https://github.com/smithkl42)) * [YouTube](https://developers.google.com/youtube/) (by [Daz Wilkin](https://github.com/DazWilkin/)) +* [Zynga Scroller](https://github.com/zynga/scroller) (by [Boris Yankov](https://github.com/borisyankov)) Requested Definitions --------------------- diff --git a/scroller/easyscroller.d.ts b/scroller/easyscroller.d.ts new file mode 100644 index 000000000..5b6477fe5 --- /dev/null +++ b/scroller/easyscroller.d.ts @@ -0,0 +1,15 @@ +// Type definitions for Zynga EasyScroller +// Project: https://github.com/zynga/scroller +// Definitions by: Boris Yankov https://github.com/borisyankov +// Definitions: https://github.com/borisyankov/DefinitelyTyped + + +/// + +class EasyScroller { + constructor (content: any, options: ScrollerOptions); + + render(): void; + reflow(): void; + bindEvents(): void; +} \ No newline at end of file diff --git a/scroller/scroller-tests.ts b/scroller/scroller-tests.ts new file mode 100644 index 000000000..9daaab498 --- /dev/null +++ b/scroller/scroller-tests.ts @@ -0,0 +1,254 @@ +/// + +function test_basic() { + var scrollerObj = new Scroller(function (left, top, zoom) { + }, { + scrollingY: false + }); + scrollerObj.setDimensions(1000, 1000, 3000, 3000); +} + +function test_canvas() { + var contentWidth = 2000; + var contentHeight = 2000; + var cellWidth = 100; + var cellHeight = 100; + var content = document.getElementById('content'); + var context = content.getContext('2d'); + var tiling = new Tiling(); + var render = function (left, top, zoom) { + content.width = clientWidth; + content.height = clientHeight; + context.clearRect(0, 0, clientWidth, clientHeight); + tiling.setup(clientWidth, clientHeight, contentWidth, contentHeight, cellWidth, cellHeight); + tiling.render(left, top, zoom, paint); + }; + var paint = function (row, col, left, top, width, height, zoom) { + context.fillStyle = row % 2 + col % 2 > 0 ? "#ddd" : "#fff"; + context.fillRect(left, top, width, height); + context.fillStyle = "black"; + context.font = (14 * zoom).toFixed(2) + 'px "Helvetica Neue", Helvetica, Arial, sans-serif'; + context.fillText(row + "," + col, left + (6 * zoom), top + (18 * zoom)); + }; +} + +function test_domlist() { + var container = document.getElementById("container"); + var content = document.getElementById("content"); + var refreshElem = content.getElementsByTagName("div")[0]; + var scroller = new Scroller(render, { + scrollingX: false + }); + scroller.activatePullToRefresh(50, function () { + refreshElem.className += " active"; + refreshElem.innerHTML = "Release to Refresh"; + }, function () { + refreshElem.className = refreshElem.className.replace(" active", ""); + refreshElem.innerHTML = "Pull to Refresh"; + }, function () { + refreshElem.className += " running"; + refreshElem.innerHTML = "Refreshing..."; + setTimeout(function () { + refreshElem.className = refreshElem.className.replace(" running", ""); + insertItems(); + scroller.finishPullToRefresh(); + }, 2000); + }); + var rect = container.getBoundingClientRect(); + scroller.setPosition(rect.left + container.clientLeft, rect.top + container.clientTop); + var insertItems = function () { + for (var i = 0; i < 15; i++) { + var row = document.createElement("div"); + row.className = "row"; + row.style.backgroundColor = i % 2 > 0 ? "#ddd" : ""; + row.innerHTML = Math.random(); + if (content.firstChild == content.lastChild) { + content.appendChild(row); + } else { + content.insertBefore(row, content.childNodes[1]) + } + } + scroller.setDimensions(container.clientWidth, container.clientHeight, content.offsetWidth, content.offsetHeight - 50); + }; + insertItems(); + if ('ontouchstart' in window) { + container.addEventListener("touchstart", function (e) { + // Don't react if initial down happens on a form element + if (e.target.tagName.match(/input|textarea|select/i)) { + return; + } + scroller.doTouchStart(e.touches, e.timeStamp); + e.preventDefault(); + }, false); + document.addEventListener("touchmove", function (e) { + scroller.doTouchMove(e.touches, e.timeStamp); + }, false); + document.addEventListener("touchend", function (e) { + scroller.doTouchEnd(e.timeStamp); + }, false); + } else { + var mousedown = false; + container.addEventListener("mousedown", function (e) { + if (e.target.tagName.match(/input|textarea|select/i)) { + return; + } + scroller.doTouchStart([{ + pageX: e.pageX, + pageY: e.pageY + }], e.timeStamp); + mousedown = true; + }, false); + document.addEventListener("mousemove", function (e) { + if (!mousedown) { + return; + } + scroller.doTouchMove([{ + pageX: e.pageX, + pageY: e.pageY + }], e.timeStamp); + mousedown = true; + }, false); + document.addEventListener("mouseup", function (e) { + if (!mousedown) { + return; + } + scroller.doTouchEnd(e.timeStamp); + mousedown = false; + }, false); + } +} + +function test_dompaging() { + var container = document.getElementById("container"); + var content = document.getElementById("content"); + var size = 400; + var frag = document.createDocumentFragment(); + for (var cell = 0, cl = content.clientWidth / size; cell < cl; cell++) { + elem = document.createElement("div"); + elem.className = "cell"; + elem.style.backgroundColor = cell % 2 > 0 ? "#ddd" : ""; + elem.innerHTML = cell; + frag.appendChild(elem); + } + content.appendChild(frag); + var scroller = new Scroller(render, { + scrollingY: false, + paging: true + }); + var rect = container.getBoundingClientRect(); + scroller.setPosition(rect.left + container.clientLeft, rect.top + container.clientTop); + scroller.setDimensions(container.clientWidth, container.clientHeight, content.offsetWidth, content.offsetHeight); + if ('ontouchstart' in window) { + container.addEventListener("touchstart", function (e) { + if (e.target.tagName.match(/input|textarea|select/i)) { + return; + } + scroller.doTouchStart(e.touches, e.timeStamp); + e.preventDefault(); + }, false); + document.addEventListener("touchmove", function (e) { + scroller.doTouchMove(e.touches, e.timeStamp); + }, false); + document.addEventListener("touchend", function (e) { + scroller.doTouchEnd(e.timeStamp); + }, false); + } else { + var mousedown = false; + container.addEventListener("mousedown", function (e) { + if (e.target.tagName.match(/input|textarea|select/i)) { + return; + } + scroller.doTouchStart([{ + pageX: e.pageX, + pageY: e.pageY + }], e.timeStamp); + mousedown = true; + }, false); + document.addEventListener("mousemove", function (e) { + if (!mousedown) { + return; + } + scroller.doTouchMove([{ + pageX: e.pageX, + pageY: e.pageY + }], e.timeStamp); + mousedown = true; + }, false); + + document.addEventListener("mouseup", function (e) { + if (!mousedown) { + return; + } + scroller.doTouchEnd(e.timeStamp); + mousedown = false; + }, false); + } +} + +function test_domsnapping() { + var container = document.getElementById("container"); + var content = document.getElementById("content"); + var size = 100; + var frag = document.createDocumentFragment(); + for (var row = 0, rl = content.clientHeight / size; row < rl; row++) { + for (var cell = 0, cl = content.clientWidth / size; cell < cl; cell++) { + elem = document.createElement("div"); + elem.className = "cell"; + elem.style.backgroundColor = row % 2 + cell % 2 > 0 ? "#ddd" : ""; + elem.innerHTML = row + "," + cell; + frag.appendChild(elem); + } + } + content.appendChild(frag); + var scroller = new Scroller(render, { + snapping: true + }); + var rect = container.getBoundingClientRect(); + scroller.setPosition(rect.left + container.clientLeft, rect.top + container.clientTop); + scroller.setDimensions(container.clientWidth, container.clientHeight, content.offsetWidth, content.offsetHeight); + scroller.setSnapSize(100, 100); + if ('ontouchstart' in window) { + container.addEventListener("touchstart", function (e) { + if (e.target.tagName.match(/input|textarea|select/i)) { + return; + } + scroller.doTouchStart(e.touches, e.timeStamp); + e.preventDefault(); + }, false); + document.addEventListener("touchmove", function (e) { + scroller.doTouchMove(e.touches, e.timeStamp); + }, false); + document.addEventListener("touchend", function (e) { + scroller.doTouchEnd(e.timeStamp); + }, false); + } else { + var mousedown = false; + container.addEventListener("mousedown", function (e) { + if (e.target.tagName.match(/input|textarea|select/i)) { + return; + } + scroller.doTouchStart([{ + pageX: e.pageX, + pageY: e.pageY + }], e.timeStamp); + mousedown = true; + }, false); + document.addEventListener("mousemove", function (e) { + if (!mousedown) { + return; + } + scroller.doTouchMove([{ + pageX: e.pageX, + pageY: e.pageY + }], e.timeStamp); + mousedown = true; + }, false); + document.addEventListener("mouseup", function (e) { + if (!mousedown) { + return; + } + scroller.doTouchEnd(e.timeStamp); + mousedown = false; + }, false); + } +} \ No newline at end of file diff --git a/scroller/scroller.d.ts b/scroller/scroller.d.ts new file mode 100644 index 000000000..72bf30d2f --- /dev/null +++ b/scroller/scroller.d.ts @@ -0,0 +1,50 @@ +// Type definitions for Zynga Scroller +// Project: https://github.com/zynga/scroller +// Definitions by: Boris Yankov https://github.com/borisyankov +// Definitions: https://github.com/borisyankov/DefinitelyTyped + + +interface ScrollerOptions { + scrollingX?: bool; + scrollingY?: bool; + animating?: bool; + animationDuration?: number; + bouncing?: bool; + locking?: bool; + paging?: bool; + snapping?: bool; + zooming?: bool; + minZoom?: number; + maxZoom?: number; + speedMultiplier?: number; +} + +interface ScrollValues { + left: number; + top: number; +} + +interface ScrollValuesWithZoom extends ScrollValues { + zoom: number; +} + +class Scroller { + constructor (callback: (left: number, top: number, zoom: number) => void , options: ScrollerOptions); + + setDimensions(clientWidth: number, clientHeight: number, contentWidth: number, contentHeight: number): void; + setPosition(left: number, top: number): void; + setSnapSize(width: number, height: number): void; + activatePullToRefresh(height: number, activateCallback: Function, deactivateCallback: Function, startCallback: Function): void; + finishPullToRefresh(): void; + getValues(): ScrollValuesWithZoom; + getScrollMax(): ScrollValues; + zoomTo(level: number, animate?: bool, originLeft?: bool, originTop?: bool): void; + zoomBy(factor: number, animate?: bool, originLeft?: bool, originTop?: bool): void; + scrollTo(left?: number, top?: number, animate?: number, zoom?: number): void; + scrollBy(left?: number, top?: number, animate?: number): void; + + doMouseZoom(wheelDelta: number, timeStamp: number, pageX: number, pageY: number): void; + doTouchStart(touches: any[], timeStamp: number): void; + doTouchMove(touches: any[], timeStamp: number, scale?: number): void; + doTouchEnd(timeStamp: number): void; +} \ No newline at end of file