Create a gist now

Instantly share code, notes, and snippets.

@elrumordelaluz /App.js Secret
Created Oct 1, 2016

What would you like to do?
<Shake /> [4]
import React, { Component } from 'react';
import Shake from './Shake';
class App extends Component {
render() {
return (
<div className="App">
<Shake
className="my-custom-class"
style={{ color: 'deepskyblue' }}>
&lt;Shake /&gt;
</Shake>
<Shake fixed>
&lt;Shake fixed /&gt;
</Shake>
<Shake freez style={{
textDecoration: 'line-through',
fontWeight: '100',
margin: '1em'
}}>
&lt;Shake freez /&gt;
</Shake>
<Shake fixed freez>
&lt;Shake fixed freez /&gt;
</Shake>
<Shake fixed fixedStop style={{
letterSpacing: '2',
margin: '1em'
}}>
&lt;Shake fixed fixedStop /&gt;
</Shake>
</div>
);
}
}
export default App;
import React from 'react';
import { StyleSheet, css } from 'aphrodite/no-important';
import classNames from 'classnames';
const Shake = ({
h = 5,
v = 5,
r = 3,
dur = 300,
q = 'infinite',
tf = 'ease-in-out',
int = 10,
max = 100,
orig = 'center center',
fixed = false,
freez = false,
active = true,
trigger = ':hover',
fixedStop = false,
...props,
}) => {
const random = (max, min = 0) => {
return (Math.random() * (max - min) - max / 2);
};
const doKeyframes = () => {
// el objecto que iremos llenando
let kf = {};
const init = 'translate(0,0) rotate(0)';
// loop con intervalos basados en `int`
for (let st = int; st <= max; st += int) {
// Numeros aleatorios en cada keyframe
const x = random(h);
const y = random(v);
const rot = random(r);
kf[`${st}%`] = {
transform: `translate(${x}px, ${y}px) rotate(${rot}deg)`,
}
}
// Init de las transformaciones en 0% y 100%
kf[`0%`] = kf[`100%`] = {
transform: init,
}
// Init también en caso el `max` < 100
if (max < 100) {
kf[`${max}%`] = {
transform: init,
}
}
return kf;
};
// Creamos los `@keyframes`
const keyframes = doKeyframes();
const animAttrs = {
animationName: keyframes,
animationDuration: `${dur}ms`,
animationIterationCount: q,
};
const styles = StyleSheet.create({
base: {
display: 'inline-block',
transformOrigin: orig,
},
shake: {
...animAttrs,
},
triggered: {
[trigger]: {
...animAttrs,
},
},
freez: {
animationPlayState: !fixed ? 'paused' : 'running',
[trigger]: {
animationPlayState: !fixed ? 'running' : 'paused',
},
},
init: {
[trigger]: {
animation: 'initial',
},
},
});
const shouldShakeDefault = fixed || (!fixed && freez);
const shouldShakeWhenTriggered = !fixed && !freez;
const className = css(
shouldShakeWhenTriggered && styles.triggered,
shouldShakeDefault && styles.shake,
freez && styles.freez,
fixed && fixedStop && styles.init,
);
return (
<div
style={props.style}
className={classNames(props.className, css(styles.base), {
[className]: active
})}>
{ props.children }
</div>
);
};
export default Shake;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment