Skip to content

Commit

Permalink
Move fit-to-width to esper container
Browse files Browse the repository at this point in the history
  • Loading branch information
inukshuk committed Jul 31, 2017
1 parent 712cdcb commit b049d3e
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 38 deletions.
70 changes: 62 additions & 8 deletions src/components/esper/esper.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,65 +5,116 @@ const { PureComponent } = React
const { EsperStage } = require('./stage')
const { EsperToolbar } = require('./toolbar')
const { bool, node, object } = require('prop-types')
const { bounds, on, off } = require('../../dom')

class Esper extends PureComponent {
constructor(props) {
super(props)
this.state = this.getStateFromProps(props)
}

componentDidMount() {
on(window, 'resize', this.resize)
}

componentWillUnmount() {
off(window, 'resize', this.resize)
}


componentWillReceiveProps(props) {
if (props !== this.props) {
this.setState(this.getStateFromProps(props))
}
}

getStateFromProps(props) {
const { photo, isVisible, isDisabled } = props
const { photo, isVisible, isDisabled, isAutoZoomActive } = props

if (photo == null || photo.pending) {
return {
isAutoZoomActive,
isDisabled: true,
isVisible: false,
src: null,
width: 0,
height: 0,
angle: 0
angle: 0,
zoom: 1
}
}

return {
isAutoZoomActive,
isDisabled,
isVisible,
src: `${photo.protocol}://${photo.path}`,
width: photo.width,
height: photo.height,
angle: 0
angle: 0,
zoom: isAutoZoomActive ? this.fitToWidth(props) : 1
}
}

get bounds() {
return bounds(this.stage.container)
}

fitToWidth({ photo } = this.props, width = this.stage.screen.width) {
return (photo == null || photo.width === 0) ? 1 : width / photo.width
}

setStage = (stage) => {
this.stage = stage
}

resize = () => {
this.stage.resize()
}
let { width, height } = this.bounds
let zoom = this.state.zoom

if (this.state.isAutoZoomActive) {
zoom = this.fitToWidth(this.props, width)
this.setState({ zoom })
}

handleRotate = (by) => {
this.stage.resize({ width, height, zoom })
}

handleRotationChange = (by) => {
this.setState({
angle: (360 + (this.state.angle + by)) % 360
})
}

handleZoomChange = (zoom) => {
this.setState({ zoom, isAutoZoomActive: false })
this.stage.zoom(zoom)
}

handleZoomToggle = () => {
let { zoom, isAutoZoomActive } = this.state

isAutoZoomActive = !isAutoZoomActive

if (isAutoZoomActive) {
zoom = this.fitToWidth()
}

this.setState({ zoom, isAutoZoomActive })
this.stage.zoom(zoom)
}

render() {
return (
<section className="esper">
<EsperHeader>
<EsperToolbar
isAutoZoomActive={this.state.isAutoZoomActive}
isDisabled={this.state.isDisabled}
onRotate={this.handleRotate}/>
zoom={this.state.zoom}
onRotationChange={this.handleRotationChange}
onZoomChange={this.handleZoomChange}
onZoomToggle={this.handleZoomToggle}/>
</EsperHeader>
<EsperStage
ref={this.setStage}
Expand All @@ -72,18 +123,21 @@ class Esper extends PureComponent {
src={this.state.src}
angle={this.state.angle}
width={this.state.width}
height={this.state.height}/>
height={this.state.height}
zoom={this.state.zoom}/>
</section>
)
}

static propTypes = {
isAutoZoomActive: bool,
isDisabled: bool,
isVisible: bool,
photo: object
}

static defaultProps = {
isAutoZoomActive: true,
isVisible: false
}
}
Expand Down
46 changes: 22 additions & 24 deletions src/components/esper/stage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const React = require('react')
const { PureComponent } = React
const { bool, func, number, string } = require('prop-types')
const { append, bounds, on, off } = require('../../dom')
const { append, bounds } = require('../../dom')
const PIXI = require('pixi.js')
const { Sprite } = PIXI
const { TextureCache, skipHello } = PIXI.utils
Expand Down Expand Up @@ -34,12 +34,10 @@ class EsperStage extends PureComponent {

append(this.pixi.view, this.container)

on(window, 'resize', this.resize)
this.handlePropsChange(this.props)
}

componentWillUnmount() {
off(window, 'resize', this.resize)
this.pixi.destroy(true)
}

Expand All @@ -58,7 +56,6 @@ class EsperStage extends PureComponent {
this.reset(props)
}

this.zoom(props)
this.rotate(props)

if (props.isVisible) {
Expand All @@ -75,6 +72,9 @@ class EsperStage extends PureComponent {
if (props.src != null) {
this.image = new Sprite()
this.image.anchor.set(0.5)
this.image.x = this.screen.width / 2
this.image.y = this.screen.height / 2
this.image.scale.set(props.zoom)

this.load(props.src, this.image)
this.pixi.stage.addChildAt(this.image, 0)
Expand All @@ -101,22 +101,23 @@ class EsperStage extends PureComponent {
}
}

resize = () => {
const { width, height } = bounds(this.container)
resize({ width, height, zoom }) {
this.pixi.renderer.resize(width, height)
this.zoom()
}

zoom(props = this.props) {
if (props.scale != null) {
return this.scale = props.scale
if (this.image != null) {
this.image.x = width / 2
this.image.y = height / 2
this.image.scale.set(zoom)
}
}

if (props.width === 0) {
return this.scale = 1
}
zoom(zoom) {
if (this.image == null) return

return this.scale = this.pixi.screen.width / props.width
new Tween(this.image.scale)
.to({ x: zoom, y: zoom }, 250)
.easing(Cubic.InOut)
.start()
}

rotate(props = this.props.angle) {
Expand All @@ -127,13 +128,7 @@ class EsperStage extends PureComponent {
TWEEN.update(performance.now())

if (this.isDirty()) {
const { image, rotation, scale } = this

image.x = this.pixi.screen.width / 2
image.y = this.pixi.screen.height / 2

image.scale.set(scale)

const { image, rotation } = this

const diff = abs(image.rotation - rotation)

Expand All @@ -152,10 +147,9 @@ class EsperStage extends PureComponent {


isDirty() {
const { image, scale, rotation } = this
const { image, rotation } = this

if (image == null) return false
if (image.scale.x !== scale) return true
if (image.rotation !== rotation) return true

return false
Expand All @@ -165,6 +159,10 @@ class EsperStage extends PureComponent {
return this.pixi.loader.loading
}

get screen() {
return this.pixi.screen
}


setContainer = (container) => {
this.container = container
Expand Down
31 changes: 25 additions & 6 deletions src/components/esper/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const React = require('react')
const { PureComponent } = React
const { Toolbar, ToolbarLeft, ToolGroup } = require('../toolbar')
const { IconButton } = require('../button')
const { bool, func } = require('prop-types')
const { bool, func, number } = require('prop-types')

const {
IconArrow,
Expand All @@ -19,7 +19,15 @@ const {

class EsperToolbar extends PureComponent {
handleRotate = () => {
this.props.onRotate(-90)
this.props.onRotationChange(-90)
}

handleZoomIn = () => {
this.props.onZoomChange(this.props.zoom + 0.1)
}

handleZoomOut = () => {
this.props.onZoomChange(this.props.zoom - 0.1)
}

render() {
Expand Down Expand Up @@ -47,11 +55,18 @@ class EsperToolbar extends PureComponent {
<IconButton
icon={<IconHand/>}/>
<IconButton
icon={<IconMinusCircle/>}/>
icon={<IconMinusCircle/>}
isDisabled={this.props.isDisabled}
onClick={this.handleZoomOut}/>
<IconButton
icon={<IconPlusCircle/>}/>
icon={<IconPlusCircle/>}
isDisabled={this.props.isDisabled}
onClick={this.handleZoomIn}/>
<IconButton
icon={<IconFit/>}/>
icon={<IconFit/>}
isDisabled={this.props.isDisabled}
isActive={this.props.isAutoZoomActive}
onClick={this.props.onZoomToggle}/>
</ToolGroup>
</ToolbarLeft>
</Toolbar>
Expand All @@ -60,7 +75,11 @@ class EsperToolbar extends PureComponent {

static propTypes = {
isDisabled: bool.isRequired,
onRotate: func.isRequired
isAutoZoomActive: bool.isRequired,
zoom: number.isRequired,
onRotationChange: func.isRequired,
onZoomChange: func.isRequired,
onZoomToggle: func.isRequired
}
}

Expand Down

0 comments on commit b049d3e

Please sign in to comment.