| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 (function(scope) { |
| 5 "use strict"; |
| 6 |
| 7 var width = 55; |
| 8 var scaleFactor = 200.0; |
| 9 var jumpHeight = 50; |
| 10 |
| 11 function createUIWorker() { |
| 12 scope.worker = new UIWorker('resources/scroll-linked-effects.js'); |
| 13 |
| 14 var scroller = document.getElementById('scroller'); |
| 15 var dancer = document.getElementById('dancer'); |
| 16 var shadow = document.getElementById('shadow'); |
| 17 |
| 18 scope.worker.postMessage([ |
| 19 scroller.bindAnimatedProperty('scrollTop'), |
| 20 dancer.bindAnimatedProperty('transform'), |
| 21 shadow.bindAnimatedProperty('transform') |
| 22 ]); |
| 23 } |
| 24 |
| 25 function translate(x, y) { |
| 26 return 'translate(' + x + 'px, ' + y + 'px) '; |
| 27 } |
| 28 |
| 29 function translate3d(x, y, z) { |
| 30 return 'translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px) '; |
| 31 } |
| 32 |
| 33 function rotateX(deg) { |
| 34 return 'rotateX(' + deg + 'deg) '; |
| 35 } |
| 36 |
| 37 function rotateY(deg) { |
| 38 return 'rotateY(' + deg + 'deg) '; |
| 39 } |
| 40 |
| 41 function aboutPoint(x, y, transform) { |
| 42 return translate(x, y) + transform + translate(-x, -y); |
| 43 } |
| 44 |
| 45 function perspective(depth, x, y) { |
| 46 return aboutPoint(x, y, 'perspective(' + depth + 'px) '); |
| 47 } |
| 48 |
| 49 function matrixFromScrollTop(scrollTop, perspX, perspY) { |
| 50 var str = perspective(depth, x, y) + |
| 51 aboutPoint(0, width, rotateX(-scrollTop)); |
| 52 console.log(str); |
| 53 return new WebKitCSSMatrix(str); |
| 54 } |
| 55 |
| 56 function getTranslationForMove(index) { |
| 57 var x = 0; |
| 58 var y = 0; |
| 59 for (var i = 0; i < index; i++) { |
| 60 switch (moves[i]) { |
| 61 case 'up': y -= 2*width; break; |
| 62 case 'down': y += 2*width; break; |
| 63 case 'left': x -= 2*width; break; |
| 64 case 'right': x += 2*width; break; |
| 65 case 'jump-up': y -= 4*width; break; |
| 66 case 'jump-down': y += 4*width; break; |
| 67 case 'jump-left': x -= 4*width; break; |
| 68 case 'jump-right': x += 4*width; break; |
| 69 } |
| 70 } |
| 71 return translate(x, y); |
| 72 } |
| 73 |
| 74 function getRotationForMove(index, fraction) { |
| 75 var degrees = fraction * 180.0 + 0.0001; |
| 76 var radians = fraction * Math.PI; |
| 77 switch (moves[index]) { |
| 78 case 'up': return aboutPoint(0, -width, rotateX(degrees)); |
| 79 case 'down': return aboutPoint(0, width, rotateX(-degrees)); |
| 80 case 'left': return aboutPoint(-width, 0, rotateY(-degrees)); |
| 81 case 'right': return aboutPoint(width, 0, rotateY(degrees)); |
| 82 case 'jump-up': |
| 83 return translate3d(0, -4 * width * fraction, |
| 84 (-1.0 + Math.cos(radians * 2)) * -jumpHeight); |
| 85 case 'jump-down': |
| 86 return translate3d(0, 6 * width * fraction, |
| 87 (-1.0 + Math.cos(radians * 2)) * -0.2 * jumpHeigh
t) |
| 88 + aboutPoint(0, -width, rotateX(degrees)); |
| 89 case 'jump-left': |
| 90 return translate3d(-4 * width * fraction, 0, |
| 91 (-1.0 + Math.cos(radians * 2)) * -jumpHeight) |
| 92 + 'rotateZ(' + degrees + 'deg)'; |
| 93 case 'jump-right': |
| 94 return translate3d(4 * width * fraction, 0, |
| 95 (-1.0 + Math.cos(radians * 2)) * -jumpHeight); |
| 96 } |
| 97 } |
| 98 |
| 99 function tick(context) { |
| 100 var scrollTop = context.getScalar(scope.scroll); |
| 101 |
| 102 var scaled = Math.floor(scrollTop / scaleFactor); |
| 103 var index = scaled % moves.length; |
| 104 var fraction = (scrollTop - scaled * scaleFactor) / scaleFactor; |
| 105 var translation = getTranslationForMove(index); |
| 106 var rotation = getRotationForMove(index, fraction); |
| 107 |
| 108 context.setMatrix(scope.dancer, |
| 109 new WebKitCSSMatrix(translation + dancerPerspective + rotation)); |
| 110 |
| 111 context.setMatrix(scope.shadow, |
| 112 new WebKitCSSMatrix(translation + shadowPerspective + rotation)); |
| 113 |
| 114 scope.teleportMessage(context, tick); |
| 115 } |
| 116 |
| 117 function onMessage(e) { |
| 118 var tokens = e.data |
| 119 scope.scroll = tokens[0]; |
| 120 scope.dancer = tokens[1]; |
| 121 scope.shadow = tokens[2]; |
| 122 |
| 123 // A cute trick: if you use different perspective origins, you get |
| 124 // directional shadows. |
| 125 scope.dancerPerspective = perspective(300, 50, 0); |
| 126 scope.shadowPerspective = perspective(300, 100, 40); |
| 127 |
| 128 // The following moves define the path taken by the dancer. |
| 129 scope.moves = [ |
| 130 "down", "right", "up", "right", "up", "left", "down", "left", |
| 131 "jump-right", "left", "down", "jump-up", "right", "down", "left", |
| 132 "jump-down", "up", "right", "up", "jump-left" |
| 133 ]; |
| 134 |
| 135 // TODO: we should have to request the current time. Otherwise, we should |
| 136 // wait until a change in the given values before spamming tick for max |
| 137 // battery efficiency. |
| 138 scope.teleportMessage(new TeleportContext(tokens), tick); |
| 139 } |
| 140 |
| 141 if (scope.window) { |
| 142 scope.window.onload = createUIWorker; |
| 143 } else { |
| 144 scope.onmessage = onMessage; |
| 145 } |
| 146 |
| 147 })(self); |
| OLD | NEW |