Instantly share code, notes, and snippets.
Last active
August 29, 2015 14:16
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save thomaswilburn/b4f0f3b9dcbe512ee45a to your computer and use it in GitHub Desktop.
Sample code report for WEB150
This file contains 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
/** | |
* Originally taken from: | |
* https://raw.githubusercontent.com/GoogleChrome/devsummit/7ba921827a7cd080e31291275c0eda394ec21c9d/src/static/scripts/components/button.js | |
* | |
* This code enables the "material ripple" animation on buttons for the Chrome Dev Summit | |
* site (https://developer.chrome.com/devsummit/). It finds all buttons on the page, and | |
* adds an animation to them that plays on click. Button elements tend to look like this: | |
* | |
* <button data-embed="..." class="paper-button session__fab"> | |
* <div class="session__fab-inner"> | |
* <div class="button__ripple"></div> | |
* </div> | |
* </button> | |
* | |
* Executive summary: | |
* | |
* Paper button elements contain an inner "ripple" effect that plays on click, where a | |
* circle expands out from the center of a mouse click. To create this, a circular, semi- | |
* transparent element is positioned at the click and scaled down. Animations are then | |
* enabled on the button, and the transform is updated, causing the element to expand | |
* out to its original size. | |
* | |
* Because this module maintains a single animation state at any time, and ignores any | |
* clicks while that animation is running, it's basically only good for a single button | |
* press, and doesn't really support multitouch in any way. A future improvement for | |
* the module would be to use a closure or a state object linked to individual elements, | |
* so that multiple ripple animations can run simultaneously. This is not a huge | |
* burden on the CPU, frankly, since these animations are run completely via CSS. | |
* | |
*/ | |
/** | |
* Copyright 2014 Google Inc. All rights reserved. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
CDS.Button = (function() { | |
"use strict"; | |
// First, find all buttons on the page, and set up some global state variables. | |
var buttons = document.querySelectorAll('.paper-button'); | |
var button, bound, x, y, ripple, size, transformString; | |
var frameCount = 0; | |
//For each paper button... | |
for (var b = 0; b < buttons.length; b++) { | |
//Find the size of the button from its outer bounding rectangle (set from CSS) and double it | |
button = buttons[b]; | |
bound = button.getBoundingClientRect(); | |
size = Math.max(bound.width, bound.height) * 2; | |
//if there's a ripple element, locate that for animation | |
ripple = button.querySelector('.button__ripple'); | |
if (!ripple) | |
continue; | |
//Set the ripple to be twice the size of the button (see above) | |
ripple.style.width = size + 'px'; | |
ripple.style.height = size + 'px'; | |
//add the onClick listener | |
button.addEventListener('click', onClick); | |
} | |
function onClick(evt) { | |
//If the animation is already running, do nothing. | |
if (frameCount > 0) | |
return; | |
//If the element has a Youtube video attribute (data-embed), embed and play it. | |
if (evt.currentTarget.dataset && evt.currentTarget.dataset.embed) | |
CDS.VideoEmbedder.embed(evt.currentTarget); | |
//If the element has a data-url attribute, navigate to that URL. | |
if (evt.currentTarget.dataset && evt.currentTarget.dataset.url) | |
window.location = evt.currentTarget.dataset.url; | |
//Start the animation by setting the frameCount flag | |
//I suspect that frameCount being numerical is a holdover from a more elaborate version of this animation. | |
frameCount = 1; | |
//We get the size of the element, and create a transform that centers it on the mouse click at a very small size. | |
//Effectively, this makes it very small, so that when we remove the transform, it'll expand outward. | |
bound = evt.currentTarget.getBoundingClientRect(); | |
x = Math.round(evt.clientX - bound.left); | |
y = Math.round(evt.clientY - bound.top); | |
transformString = 'translate(-50%, -50%) ' + | |
'translate(' + x + 'px, ' + y + 'px) ' + | |
'scale(0.0001, 0.0001)'; | |
//Next we find the ripple, and set its transform property, thus positioning it for the start of the animation | |
ripple = evt.currentTarget.querySelector('.button__ripple'); | |
ripple.style.webkitTransform = transformString; | |
ripple.style.transform = transformString; | |
ripple.style.opacity = '0.4'; | |
//Remove animations to instantly move the ripple into its scaled position | |
ripple.classList.remove('button__ripple--animate'); | |
//Now wait a frame, then call reset, which will actually play the animation | |
requestAnimFrame(reset); | |
} | |
function reset() { | |
//If the framecount is still high, wait before triggering animation (never happens) | |
if (frameCount-- > 0) { | |
requestAnimFrame(reset); | |
} else { | |
//create a new transform where the ripple is still centered, but at its normal size | |
transformString = 'translate(-50%, -50%) ' + | |
'translate(' + x + 'px, ' + y + 'px)' + | |
'scale(1, 1)'; | |
//set that transform, and re-enable animations | |
ripple.style.webkitTransform = transformString; | |
ripple.style.transform = transformString; | |
ripple.style.opacity = '0'; | |
ripple.classList.add('button__ripple--animate'); | |
//At this point the button has a faint, fading "ripple" expand across its surface. | |
//Ironically, this is incredibly hard to notice, because the button is also contracting at the same time. | |
//If the styles of the .hidden class are disabled, you can see it actually run more effectively. | |
} | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment