Skip to content
This repository was archived by the owner on Jun 5, 2019. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion docs/stack.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ Can't imagine doing web differently to be honest. I'm sure we will soon, but for

I like `preact` as well. I feel like the switching over will be pretty simple and I probably will.


## Component Styling ##

> **glamor**
Expand Down Expand Up @@ -73,6 +72,17 @@ Start your app only when your gut says, "You'll fuck this up long before your st
`glamor` gives me that vibe. 💃


## Animations

**react-transition-group**

Brings enter + leave lifecycle events for animations.

**popmotion**

Power animation & tweening library.


## State Management

> **mobx**, **mobx-react**
Expand Down
64 changes: 64 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@
"mobx": "3.2.2",
"mobx-react": "4.2.2",
"mousetrap": "1.6.1",
"popmotion-react": "^1.1.0",
"ramda": "0.24.1",
"react": "15.6.1",
"react-dom": "15.6.1"
"react-dom": "15.6.1",
"react-transition-group": "^2.2.0"
},
"description": "An electron starter project.",
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export class DogTab extends React.PureComponent<DogTabProps, {}> {
render() {
return (
<CenteredContent style={this.props.style}>
<Text style={TEXT_STYLE}>Do a barrel roll.</Text>
<FunDog />
<Text style={TEXT_STYLE}>Wake up and smell the electrons.</Text>
<Logo />
</CenteredContent>
)
Expand Down
8 changes: 6 additions & 2 deletions src/renderer/features/example-using-tabs/fun-dog/fun-dog.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react'
import dogImage from './fun-dog.jpg'
import { cssProps, colors } from '../../../platform'
import { cssProps, colors, SpinAnimation } from '../../../platform'
import { css } from 'glamor'

const ROOT = cssProps({
Expand All @@ -12,5 +12,9 @@ const ROOT = cssProps({
})

export function FunDog() {
return <img draggable={false} src={dogImage} {...css(ROOT)} />
return (
<SpinAnimation>
<img draggable={false} src={dogImage} {...css(ROOT)} />
</SpinAnimation>
)
}
1 change: 1 addition & 0 deletions src/renderer/platform/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './scrollable-content'
export * from './centered-content'
export * from './tab'
export * from './enter-animation'
export * from './spin-animation'
1 change: 1 addition & 0 deletions src/renderer/platform/components/spin-animation/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './spin-animation'
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { StateChangeEvent, MotionStates, MotionStateProps } from 'popmotion-react'
import { tween } from 'popmotion'

const DEFAULT_DURATION = 500
const DEFAULT_REVOLUTIONS = 1

export interface SpinAnimationStateProps {
/** How long does the animation take in milliseconds. (default: 1000) */
duration?: number
/** How many spins. (default: 1) */
revolutions?: number
}

/**
* Creates the animation states.
*/
export function createSpinStates(props: SpinAnimationStateProps): MotionStates {
const duration = props.duration || DEFAULT_DURATION
const forwardAngle = 360 * (props.revolutions || DEFAULT_REVOLUTIONS)

// a helper function to create the 2 states
const createState = (to: number) => (e: StateChangeEvent) =>
tween({
from: e.value.get(),
to,
duration,
onUpdate: e.value,
}).start()

return {
forward: createState(forwardAngle),
back: createState(0),
}
}

/**
* The function that goes to the next state.
*
* @param current The current state.
*/
export function next(current: MotionStateProps) {
return current.state === 'forward' ? current.setStateTo.back : current.setStateTo.forward
}
34 changes: 34 additions & 0 deletions src/renderer/platform/components/spin-animation/spin-animation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as React from 'react'
import { MotionValue, MotionStates, MotionStateProps } from 'popmotion-react'
import { SpinAnimationStateProps, createSpinStates, next } from './spin-animation-state'

/**
* Provides a container which will do a barrel roll when clicked.
*/
export class SpinAnimation extends React.PureComponent<SpinAnimationStateProps, {}> {
animationStates: MotionStates

componentWillMount() {
this.animationStates = createSpinStates(this.props)
}

componentWillReceiveProps(newProps: SpinAnimationStateProps) {
this.animationStates = createSpinStates(newProps)
}

render() {
// the view to spin
// NOTE: This is a function and not a component due to popmotion-react.
const spinWrapper = (motionState: MotionStateProps) => {
const props = {
style: { transform: `rotate(${motionState.v}deg)`, cursor: 'pointer' },
onClick: next(motionState),
children: this.props.children,
}

return <div {...props} />
}

return <MotionValue onStateChange={this.animationStates} children={spinWrapper} />
}
}
63 changes: 63 additions & 0 deletions types/popmotion-react.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
declare module 'popmotion-react' {
import { Component } from 'react'

export interface StateChangeValue {
[name: string]: any
}

export interface SetStateFunctions {
[name: string]: () => void
}

export interface MotionStateProps {
/** The current numerical value, or object of named values. */
v: number | StateChangeValue

/** Current velocity, or object of named velocities. */
velocity: number

/** Current state name. */
state: string

/** Object of setter functions, generated from the states defined in onStateChange (each optionally accepts an Event). */
setStateTo: SetStateFunctions

/** Provides onStateChange setters a ref attribute for an escape hatch to the DOM (for instance attaching/removing events). */
setRef(ref: React.ReactNode): void
}

export interface StateChangeEvent {
/** The popmotion value object. */
value: any
/** State before current state change. */
previousState: string
/** Object of state setters (each optionally accepts an Event). */
setStateTo: any
/** : A reference to the mounted React component, if a component was provided setRef. */
ref: React.ReactNode
/** The triggering event, if a state setter was called with one. */
e: Event
/** When hooking into TransitionGroup lifecycle events componentWillEnter, componentWillAppear and componentWillLeave, this callback is provided and required. */
onComplete?: () => void
}

export interface MotionStates {
[stateName: string]: (onStateChange: StateChangeEvent) => void
}

export interface MotionValueProps {
/**
* The initial state to start in.
*/
initialState?: string

/**
* A state machine mapping state names to action states.
*/
onStateChange?: MotionStates
}

export class MotionValue extends Component<MotionValueProps, {}> {
constructor()
}
}
34 changes: 34 additions & 0 deletions types/popmotion.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
declare module 'popmotion' {
export interface ActionProps {
/** Fires every frame the value is updated. */
onUpdate?(): void
/** Fires when an action starts. */
onStart?(): void
/** Fires when an action is stopped. */
onStop?(): void
/** Fires when an action is completed. */
onComplete?(): void
/** If defined, get and onUpdate will pass the current value through this function before returning. */
transform?(): void
}

export interface TweenProps {
/** The amount of time for the tween to take, in milliseconds. (default: 300) */
duration?: number
/** Easing function */
ease?: () => void
/** The number to tween from. (default 0) */
from?: number
/** The number to tween to. (default: 1) */
to?: number
/** Number of times to flip tween on tween complete. (default: 0) */
flip?: number
/** Number of times to restart tween from beginning on tween complete. (default: 0) */
loop?: number
/** yoyo <Number>: Number of times to reverse tween on tween complete. (default: 0) */
yoyo?: number
}

export function tween(options: TweenProps & ActionProps): any
export const transform: any
}