Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Unified Diff: LayoutTests/fast/workers/resources/snap-points.js

Issue 474683003: Not for review - Rebase of crrev.com/62833003 Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: . Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « LayoutTests/fast/workers/resources/snap.js ('k') | LayoutTests/fast/workers/resources/teleport.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: LayoutTests/fast/workers/resources/snap-points.js
diff --git a/LayoutTests/fast/workers/resources/snap-points.js b/LayoutTests/fast/workers/resources/snap-points.js
new file mode 100644
index 0000000000000000000000000000000000000000..7854c92651e5b96fcda25927f175d47bcf1d1d81
--- /dev/null
+++ b/LayoutTests/fast/workers/resources/snap-points.js
@@ -0,0 +1,212 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+(function(scope) {
+ "use strict";
+
+ var width = 55;
+ var scaleFactor = 200.0;
+ var jumpHeight = 50;
+ var scrollTops = [];
+ var kernel = [0.1, 0.1, 0.1, 0.1, 0.2, 0.2, 0.2];
+ var epsilon = 0.0001;
+
+ function createUIWorker() {
+ scope.worker = new UIWorker('resources/snap-points.js');
+
+ var scroller = document.getElementById('scroller');
+ var dancer = document.getElementById('dancer');
+ var shadow = document.getElementById('shadow');
+
+ scope.worker.postMessage({
+ 'cmd': 'setup-scene',
+ 'tokens': [
+ scroller.bindAnimatedProperty('scrollTop'),
+ dancer.bindAnimatedProperty('transform'),
+ shadow.bindAnimatedProperty('transform')
+ ]
+ });
+
+ document.body.addEventListener('touchstart', function(e) {
+ scope.worker.postMessage({'cmd': 'touchstart'});
+ });
+
+ document.body.addEventListener('touchend', function(e) {
+ scope.worker.postMessage({'cmd': 'touchend'});
+ });
+ }
+
+ function translate(x, y) {
+ return 'translate(' + x + 'px, ' + y + 'px) ';
+ }
+
+ function translate3d(x, y, z) {
+ return 'translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px) ';
+ }
+
+ function rotateX(deg) {
+ return 'rotateX(' + deg + 'deg) ';
+ }
+
+ function rotateY(deg) {
+ return 'rotateY(' + deg + 'deg) ';
+ }
+
+ function aboutPoint(x, y, transform) {
+ return translate(x, y) + transform + translate(-x, -y);
+ }
+
+ function perspective(depth, x, y) {
+ return aboutPoint(x, y, 'perspective(' + depth + 'px) ');
+ }
+
+ function matrixFromScrollTop(scrollTop, perspX, perspY) {
+ var str = perspective(depth, x, y) +
+ aboutPoint(0, width, rotateX(-scrollTop));
+ console.log(str);
+ return new WebKitCSSMatrix(str);
+ }
+
+ function getTranslationForMove(index) {
+ var x = 0;
+ var y = 0;
+ for (var i = 0; i < index; i++) {
+ switch (moves[i]) {
+ case 'up': y -= 2*width; break;
+ case 'down': y += 2*width; break;
+ case 'left': x -= 2*width; break;
+ case 'right': x += 2*width; break;
+ case 'jump-up': y -= 4*width; break;
+ case 'jump-down': y += 4*width; break;
+ case 'jump-left': x -= 4*width; break;
+ case 'jump-right': x += 4*width; break;
+ }
+ }
+ return translate(x, y);
+ }
+
+ function getRotationForMove(index, fraction) {
+ var degrees = fraction * 180.0 + 0.0001;
+ var radians = fraction * Math.PI;
+ switch (moves[index]) {
+ case 'up': return aboutPoint(0, -width, rotateX(degrees));
+ case 'down': return aboutPoint(0, width, rotateX(-degrees));
+ case 'left': return aboutPoint(-width, 0, rotateY(-degrees));
+ case 'right': return aboutPoint(width, 0, rotateY(degrees));
+ case 'jump-up':
+ return translate3d(0, -4 * width * fraction,
+ (-1.0 + Math.cos(radians * 2)) * -jumpHeight);
+ case 'jump-down':
+ return translate3d(0, 6 * width * fraction,
+ (-1.0 + Math.cos(radians * 2)) * -0.2 * jumpHeight)
+ + aboutPoint(0, -width, rotateX(degrees));
+ case 'jump-left':
+ return translate3d(-4 * width * fraction, 0,
+ (-1.0 + Math.cos(radians * 2)) * -jumpHeight)
+ + 'rotateZ(' + degrees + 'deg)';
+ case 'jump-right':
+ return translate3d(4 * width * fraction, 0,
+ (-1.0 + Math.cos(radians * 2)) * -jumpHeight);
+ }
+ }
+
+ function tick(context) {
+ var scrollTop = context.getScalar(scope.scroll);
+ scrollTops.push(scrollTop);
+ if (scrollTops.length == kernel.length + 3) {
+ scrollTops.shift();
+ scrollTops.shift();
+ var sum = 0;
+ for (var i = 0; i < kernel.length; ++i) {
+ var ds = scrollTops[i + 1] - scrollTops[i];
+ sum += ds * kernel[i];
+ }
+ var estimatedVelocity = (sum * 60.0) / 1000.0;
+ if (!scope.lastVelocity)
+ scope.lastVelocity = estimatedVelocity;
+ scope.lastVelocity *= 0.2;
+ scope.lastVelocity += 0.8 * estimatedVelocity;
+ if (Math.abs(scope.lastVelocity) < epsilon)
+ scope.lastVelocity = 0.0;
+ }
+
+ if (scope.inFling &&
+ !scope.gravityOn &&
+ Math.abs(scope.lastVelocity) < 0.05) {
+ scope.gravityOn = true;
+ scope.target = Math.round(scope.lastScrollTop / 200.0) * 200.0;
+ }
+
+ if (scope.gravityOn) {
+ var correction = scope.target - scrollTop;
+ scrollTop -= scope.lastVelocity;
+ scope.lastVelocity = scope.lastVelocity * 0.97 + correction * 0.03;
+ scrollTop += scope.lastVelocity;
+ context.setScalar(scope.scroll, scrollTop);
+ if (Math.abs(scrollTop - scope.target) < epsilon) {
+ scope.inFling = false;
+ scope.gravityOn = false;
+ }
+ }
+
+ scope.lastScrollTop = scrollTop;
+
+ var scaled = Math.floor(scrollTop / scaleFactor);
+ var index = scaled % moves.length;
+ var fraction = (scrollTop - scaled * scaleFactor) / scaleFactor;
+ var translation = getTranslationForMove(index);
+ var rotation = getRotationForMove(index, fraction);
+
+ context.setMatrix(scope.dancer,
+ new WebKitCSSMatrix(translation + dancerPerspective + rotation));
+
+ context.setMatrix(scope.shadow,
+ new WebKitCSSMatrix(translation + shadowPerspective + rotation));
+
+ scope.teleportMessage(context, tick);
+ }
+
+ function setupScene(tokens) {
+ scope.scroll = tokens[0];
+ scope.dancer = tokens[1];
+ scope.shadow = tokens[2];
+
+ // A cute trick: if you use different perspective origins, you get
+ // directional shadows.
+ scope.dancerPerspective = perspective(300, 50, 0);
+ scope.shadowPerspective = perspective(300, 100, 40);
+
+ // The following moves define the path taken by the dancer.
+ scope.moves = [
+ "down", "right", "up", "right", "up", "left", "down", "left",
+ "jump-right", "left", "down", "jump-up", "right", "down", "left",
+ "jump-down", "up", "right", "up", "jump-left"
+ ];
+
+ // TODO: we should have to request the current time. Otherwise, we should
+ // wait until a change in the given values before spamming tick for max
+ // battery efficiency.
+ scope.teleportMessage(new TeleportContext(tokens), tick);
+ }
+
+ function onMessage(e) {
+ switch (e.data.cmd) {
+ case 'setup-scene': setupScene(e.data.tokens); break;
+ case 'touchstart':
+ scope.gravityOn = false;
+ scope.inFling = false;
+ break;
+ case 'touchend':
+ scope.inFling = true;
+ scrollTops.length = 0;
+ break;
+ }
+ }
+
+ if (scope.window) {
+ scope.window.onload = createUIWorker;
+ } else {
+ scope.onmessage = onMessage;
+ }
+
+})(self);
« no previous file with comments | « LayoutTests/fast/workers/resources/snap.js ('k') | LayoutTests/fast/workers/resources/teleport.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698