diff --git a/src/components/direction-picker/dial.css b/src/components/direction-picker/dial.css
new file mode 100644
index 0000000000000000000000000000000000000000..ce9b7daea87f1f91f59437877c0504255b758666
--- /dev/null
+++ b/src/components/direction-picker/dial.css
@@ -0,0 +1,41 @@
+@import "../../css/colors.css";
+
+.container {
+    padding: 1rem;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    user-select: none;
+}
+
+.dial-container {
+    position: relative;
+}
+
+.dial-face, .dial-handle, .gauge {
+    position: absolute;
+    top: 0;
+    left: 0;
+    overflow: visible;
+}
+
+.dial-face {
+    width: 100%;
+}
+
+$dial-size: 40px;
+
+.dial-handle {
+    cursor: pointer;
+    width: $dial-size;
+    height: $dial-size;
+    /* Use margin to make positioning via top/left easier */
+    margin-left: calc($dial-size / -2);
+    margin-top: calc($dial-size / -2);
+}
+
+.gauge-path {
+    fill: $motion-transparent;
+    stroke: $motion-primary;
+    stroke-width: 1px;
+}
diff --git a/src/components/direction-picker/dial.jsx b/src/components/direction-picker/dial.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..df97fda7fa4cc03cdf61f2b4fc52f6dfcd05c814
--- /dev/null
+++ b/src/components/direction-picker/dial.jsx
@@ -0,0 +1,156 @@
+import PropTypes from 'prop-types';
+import bindAll from 'lodash.bindall';
+import React from 'react';
+import {getEventXY} from '../../lib/touch-utils';
+
+import styles from './dial.css';
+
+import dialFace from './icon--dial.svg';
+import dialHandle from './icon--handle.svg';
+
+class Dial extends React.Component {
+    constructor (props) {
+        super(props);
+        bindAll(this, [
+            'handleMouseDown',
+            'handleMouseMove',
+            'containerRef',
+            'handleRef',
+            'unbindMouseEvents'
+        ]);
+    }
+
+    componentDidMount () {
+        // Manually add touch/mouse handlers so that preventDefault can be used
+        // to prevent scrolling on touch.
+        // Tracked as a react issue https://github.com/facebook/react/issues/6436
+        this.handleElement.addEventListener('mousedown', this.handleMouseDown);
+        this.handleElement.addEventListener('touchstart', this.handleMouseDown);
+    }
+
+    componentWillUnmount () {
+        this.unbindMouseEvents();
+        this.handleElement.removeEventListener('mousedown', this.handleMouseDown);
+        this.handleElement.removeEventListener('touchstart', this.handleMouseDown);
+    }
+
+    /**
+     * Get direction from dial center to mouse move event.
+     * @param {Event} e - Mouse move event.
+     * @returns {number} Direction in degrees, clockwise, 90=horizontal.
+     */
+    directionToMouseEvent (e) {
+        const {x: mx, y: my} = getEventXY(e);
+        const bbox = this.containerElement.getBoundingClientRect();
+        const cy = bbox.top + (bbox.height / 2);
+        const cx = bbox.left + (bbox.width / 2);
+        const angle = Math.atan2(my - cy, mx - cx);
+        const degrees = angle * (180 / Math.PI);
+        return degrees + 90; // To correspond with scratch coordinate system
+    }
+
+    /**
+     * Create SVG path data string for the dial "gauge", the overlaid arc slice.
+     * @param {number} radius - The radius of the dial.
+     * @param {number} direction - Direction in degrees, clockwise, 90=horizontal.
+     * @returns {string} Path data string for the gauge.
+     */
+    gaugePath (radius, direction) {
+        const rads = (direction) * (Math.PI / 180);
+        const path = [];
+        path.push(`M ${radius} 0`);
+        path.push(`L ${radius} ${radius}`);
+        path.push(`L ${radius + (radius * Math.sin(rads))} ${radius - (radius * Math.cos(rads))}`);
+        path.push(`A ${radius} ${radius} 0 0 ${direction < 0 ? 1 : 0} ${radius} 0`);
+        path.push(`Z`);
+        return path.join(' ');
+    }
+
+    handleMouseMove (e) {
+        this.props.onChange(this.directionToMouseEvent(e) + this.directionOffset);
+        e.preventDefault();
+    }
+
+    unbindMouseEvents () {
+        window.removeEventListener('mousemove', this.handleMouseMove);
+        window.removeEventListener('mouseup', this.unbindMouseEvents);
+        window.removeEventListener('touchmove', this.handleMouseMove);
+        window.removeEventListener('touchend', this.unbindMouseEvents);
+    }
+
+    handleMouseDown (e) {
+        // Because the drag handle is not a single point, there is some initial
+        // difference between the current sprite direction and the direction to the mouse
+        // Store this offset to prevent jumping when the mouse is moved.
+        this.directionOffset = this.props.direction - this.directionToMouseEvent(e);
+        window.addEventListener('mousemove', this.handleMouseMove);
+        window.addEventListener('mouseup', this.unbindMouseEvents);
+        window.addEventListener('touchmove', this.handleMouseMove);
+        window.addEventListener('touchend', this.unbindMouseEvents);
+        e.preventDefault();
+    }
+
+    containerRef (el) {
+        this.containerElement = el;
+    }
+
+    handleRef (el) {
+        this.handleElement = el;
+    }
+
+    render () {
+        const {direction, radius} = this.props;
+        return (
+            <div className={styles.container}>
+                <div
+                    className={styles.dialContainer}
+                    ref={this.containerRef}
+                    style={{
+                        width: `${radius * 2}px`,
+                        height: `${radius * 2}px`
+                    }}
+                >
+                    <img
+                        className={styles.dialFace}
+                        draggable={false}
+                        src={dialFace}
+                    />
+                    <svg
+                        className={styles.gauge}
+                        height={radius * 2}
+                        width={radius * 2}
+                    >
+                        <path
+                            className={styles.gaugePath}
+                            d={this.gaugePath(radius, direction)}
+                        />
+                    </svg>
+                    <img
+                        className={styles.dialHandle}
+                        draggable={false}
+                        ref={this.handleRef}
+                        src={dialHandle}
+                        style={{
+                            top: `${radius - (radius * Math.cos(direction * (Math.PI / 180)))}px`,
+                            left: `${radius + (radius * Math.sin(direction * (Math.PI / 180)))}px`,
+                            transform: `rotate(${direction}deg)`
+                        }}
+                    />
+                </div>
+            </div>
+        );
+    }
+}
+
+Dial.propTypes = {
+    direction: PropTypes.number,
+    onChange: PropTypes.func.isRequired,
+    radius: PropTypes.number
+};
+
+Dial.defaultProps = {
+    direction: 90, // degrees
+    radius: 56 // px
+};
+
+export default Dial;
diff --git a/src/components/direction-picker/direction-picker.css b/src/components/direction-picker/direction-picker.css
new file mode 100644
index 0000000000000000000000000000000000000000..501ff02171425a3a229e56b789823a748b2d4554
--- /dev/null
+++ b/src/components/direction-picker/direction-picker.css
@@ -0,0 +1,32 @@
+@import "../../css/colors.css";
+
+.button-row {
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+
+}
+
+.icon-button {
+    margin: 0.25rem;
+    border: none;
+    background: none;
+    outline: none;
+    cursor: pointer;
+    user-select: none;
+}
+
+.icon-button:active > img {
+    width: 20px;
+    height: 20px;
+    transform: scale(1.15);
+}
+
+.icon-button > img {
+    transition: transform 0.1s;
+    filter: grayscale(100%);
+}
+
+.icon-button.active > img {
+    filter: none;
+}
diff --git a/src/components/direction-picker/direction-picker.jsx b/src/components/direction-picker/direction-picker.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..626957381abf5d42680e4580ce49d557cde06a49
--- /dev/null
+++ b/src/components/direction-picker/direction-picker.jsx
@@ -0,0 +1,142 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import Popover from 'react-popover';
+import {injectIntl, intlShape, defineMessages, FormattedMessage} from 'react-intl';
+
+import Label from '../forms/label.jsx';
+import Input from '../forms/input.jsx';
+import BufferedInputHOC from '../forms/buffered-input-hoc.jsx';
+import Dial from './dial.jsx';
+
+import styles from './direction-picker.css';
+
+import allAroundIcon from './icon--all-around.svg';
+import leftRightIcon from './icon--left-right.svg';
+import dontRotateIcon from './icon--dont-rotate.svg';
+
+const BufferedInput = BufferedInputHOC(Input);
+
+const directionLabel = (
+    <FormattedMessage
+        defaultMessage="Direction"
+        description="Sprite info direction label"
+        id="gui.SpriteInfo.direction"
+    />
+);
+
+const RotationStyles = {
+    ALL_AROUND: 'all around',
+    LEFT_RIGHT: 'left-right',
+    DONT_ROTATE: "don't rotate"
+};
+
+const messages = defineMessages({
+    allAround: {
+        id: 'gui.directionPicker.rotationStyles.allAround',
+        description: 'Button to change to the all around rotation style',
+        defaultMessage: 'All Around'
+    },
+    leftRight: {
+        id: 'gui.directionPicker.rotationStyles.leftRight',
+        description: 'Button to change to the left-right rotation style',
+        defaultMessage: 'Left/Right'
+    },
+    dontRotate: {
+        id: 'gui.directionPicker.rotationStyles.dontRotate',
+        description: 'Button to change to the dont rotate rotation style',
+        defaultMessage: 'Do not rotate'
+    }
+});
+
+const DirectionPicker = props => (
+    <Label
+        secondary
+        text={directionLabel}
+    >
+        <Popover
+            body={
+                <div>
+                    <Dial
+                        direction={props.direction}
+                        onChange={props.onChangeDirection}
+                    />
+                    <div className={styles.buttonRow}>
+                        <button
+                            className={classNames(styles.iconButton, {
+                                [styles.active]: props.rotationStyle === RotationStyles.ALL_AROUND
+                            })}
+                            title={props.intl.formatMessage(messages.allAround)}
+                            onClick={props.onClickAllAround}
+                        >
+                            <img
+                                draggable={false}
+                                src={allAroundIcon}
+                            />
+                        </button>
+                        <button
+                            className={classNames(styles.iconButton, {
+                                [styles.active]: props.rotationStyle === RotationStyles.LEFT_RIGHT
+                            })}
+                            title={props.intl.formatMessage(messages.leftRight)}
+                            onClick={props.onClickLeftRight}
+                        >
+                            <img
+                                draggable={false}
+                                src={leftRightIcon}
+                            />
+                        </button>
+                        <button
+                            className={classNames(styles.iconButton, {
+                                [styles.active]: props.rotationStyle === RotationStyles.DONT_ROTATE
+                            })}
+                            title={props.intl.formatMessage(messages.dontRotate)}
+                            onClick={props.onClickDontRotate}
+                        >
+                            <img
+                                draggable={false}
+                                src={dontRotateIcon}
+                            />
+                        </button>
+                    </div>
+                </div>
+            }
+            isOpen={props.popoverOpen}
+            preferPlace="above"
+            onOuterAction={props.onClosePopover}
+        >
+            <BufferedInput
+                small
+                disabled={props.disabled}
+                label={directionLabel}
+                tabIndex="0"
+                type="text"
+                value={props.disabled ? '' : props.direction}
+                onFocus={props.onOpenPopover}
+                onSubmit={props.onChangeDirection}
+            />
+        </Popover>
+    </Label>
+
+);
+
+DirectionPicker.propTypes = {
+    direction: PropTypes.number,
+    disabled: PropTypes.bool.isRequired,
+    intl: intlShape,
+    onChangeDirection: PropTypes.func.isRequired,
+    onClickAllAround: PropTypes.func.isRequired,
+    onClickDontRotate: PropTypes.func.isRequired,
+    onClickLeftRight: PropTypes.func.isRequired,
+    onClosePopover: PropTypes.func.isRequired,
+    onOpenPopover: PropTypes.func.isRequired,
+    popoverOpen: PropTypes.bool.isRequired,
+    rotationStyle: PropTypes.string
+};
+
+const WrappedDirectionPicker = injectIntl(DirectionPicker);
+
+export {
+    WrappedDirectionPicker as default,
+    RotationStyles
+};
diff --git a/src/components/direction-picker/icon--all-around.svg b/src/components/direction-picker/icon--all-around.svg
new file mode 100644
index 0000000000000000000000000000000000000000..2412c0b2327c3db488418d978ad382fa72335702
Binary files /dev/null and b/src/components/direction-picker/icon--all-around.svg differ
diff --git a/src/components/direction-picker/icon--dial.svg b/src/components/direction-picker/icon--dial.svg
new file mode 100644
index 0000000000000000000000000000000000000000..d4aa8ed8205a7d51ee4c78086e409c2ef3248ff5
Binary files /dev/null and b/src/components/direction-picker/icon--dial.svg differ
diff --git a/src/components/direction-picker/icon--dont-rotate.svg b/src/components/direction-picker/icon--dont-rotate.svg
new file mode 100644
index 0000000000000000000000000000000000000000..4796c03af2562424f84487a4d8522ea16f20537c
Binary files /dev/null and b/src/components/direction-picker/icon--dont-rotate.svg differ
diff --git a/src/components/direction-picker/icon--handle.svg b/src/components/direction-picker/icon--handle.svg
new file mode 100644
index 0000000000000000000000000000000000000000..8e5fee6e0ba3c7edd111b8a52e8fd58cb6239ddd
Binary files /dev/null and b/src/components/direction-picker/icon--handle.svg differ
diff --git a/src/components/direction-picker/icon--left-right.svg b/src/components/direction-picker/icon--left-right.svg
new file mode 100644
index 0000000000000000000000000000000000000000..4525bd6e917188b4f348b4215d4f00a15955f78d
Binary files /dev/null and b/src/components/direction-picker/icon--left-right.svg differ
diff --git a/src/components/sprite-info/sprite-info.jsx b/src/components/sprite-info/sprite-info.jsx
index 37e18735a8c6b2bddbba1443f356b820f50ca321..b46b889a4a87a500a05e43500825aa04d1ce0eda 100644
--- a/src/components/sprite-info/sprite-info.jsx
+++ b/src/components/sprite-info/sprite-info.jsx
@@ -6,6 +6,8 @@ import Box from '../box/box.jsx';
 import Label from '../forms/label.jsx';
 import Input from '../forms/input.jsx';
 import BufferedInputHOC from '../forms/buffered-input-hoc.jsx';
+import DirectionPicker from '../../containers/direction-picker.jsx';
+
 import {injectIntl, intlShape, defineMessages, FormattedMessage} from 'react-intl';
 
 import {STAGE_DISPLAY_SIZES} from '../../lib/layout-constants.js';
@@ -29,6 +31,7 @@ const messages = defineMessages({
 class SpriteInfo extends React.Component {
     shouldComponentUpdate (nextProps) {
         return (
+            this.props.rotationStyle !== nextProps.rotationStyle ||
             this.props.direction !== nextProps.direction ||
             this.props.disabled !== nextProps.disabled ||
             this.props.name !== nextProps.name ||
@@ -65,13 +68,6 @@ class SpriteInfo extends React.Component {
                 id="gui.SpriteInfo.size"
             />
         );
-        const directionLabel = (
-            <FormattedMessage
-                defaultMessage="Direction"
-                description="Sprite info direction label"
-                id="gui.SpriteInfo.direction"
-            />
-        );
 
         const spriteNameInput = (
             <BufferedInput
@@ -234,20 +230,13 @@ class SpriteInfo extends React.Component {
                         </Label>
                     </div>
                     <div className={classNames(styles.group, styles.largerInput)}>
-                        <Label
-                            secondary
-                            text={directionLabel}
-                        >
-                            <BufferedInput
-                                small
-                                disabled={this.props.disabled}
-                                label={directionLabel}
-                                tabIndex="0"
-                                type="text"
-                                value={this.props.disabled ? '' : this.props.direction}
-                                onSubmit={this.props.onChangeDirection}
-                            />
-                        </Label>
+                        <DirectionPicker
+                            direction={this.props.direction}
+                            disabled={this.props.disabled}
+                            rotationStyle={this.props.rotationStyle}
+                            onChangeDirection={this.props.onChangeDirection}
+                            onChangeRotationStyle={this.props.onChangeRotationStyle}
+                        />
                     </div>
                 </div>
             </Box>
@@ -265,6 +254,7 @@ SpriteInfo.propTypes = {
     name: PropTypes.string,
     onChangeDirection: PropTypes.func,
     onChangeName: PropTypes.func,
+    onChangeRotationStyle: PropTypes.func,
     onChangeSize: PropTypes.func,
     onChangeX: PropTypes.func,
     onChangeY: PropTypes.func,
@@ -272,6 +262,7 @@ SpriteInfo.propTypes = {
     onClickVisible: PropTypes.func,
     onPressNotVisible: PropTypes.func,
     onPressVisible: PropTypes.func,
+    rotationStyle: PropTypes.string,
     size: PropTypes.oneOfType([
         PropTypes.string,
         PropTypes.number
diff --git a/src/components/sprite-selector/sprite-selector.jsx b/src/components/sprite-selector/sprite-selector.jsx
index e6948c5b7d85c08720a24625425e560c345811aa..1ab064d38c3e6aecf7ead60cd394d58051fbf7d6 100644
--- a/src/components/sprite-selector/sprite-selector.jsx
+++ b/src/components/sprite-selector/sprite-selector.jsx
@@ -47,6 +47,7 @@ const SpriteSelectorComponent = function (props) {
         intl,
         onChangeSpriteDirection,
         onChangeSpriteName,
+        onChangeSpriteRotationStyle,
         onChangeSpriteSize,
         onChangeSpriteVisibility,
         onChangeSpriteX,
@@ -84,6 +85,7 @@ const SpriteSelectorComponent = function (props) {
                 direction={selectedSprite.direction}
                 disabled={spriteInfoDisabled}
                 name={selectedSprite.name}
+                rotationStyle={selectedSprite.rotationStyle}
                 size={selectedSprite.size}
                 stageSize={stageSize}
                 visible={selectedSprite.visible}
@@ -91,6 +93,7 @@ const SpriteSelectorComponent = function (props) {
                 y={selectedSprite.y}
                 onChangeDirection={onChangeSpriteDirection}
                 onChangeName={onChangeSpriteName}
+                onChangeRotationStyle={onChangeSpriteRotationStyle}
                 onChangeSize={onChangeSpriteSize}
                 onChangeVisibility={onChangeSpriteVisibility}
                 onChangeX={onChangeSpriteX}
@@ -152,6 +155,7 @@ SpriteSelectorComponent.propTypes = {
     intl: intlShape.isRequired,
     onChangeSpriteDirection: PropTypes.func,
     onChangeSpriteName: PropTypes.func,
+    onChangeSpriteRotationStyle: PropTypes.func,
     onChangeSpriteSize: PropTypes.func,
     onChangeSpriteVisibility: PropTypes.func,
     onChangeSpriteX: PropTypes.func,
diff --git a/src/components/target-pane/target-pane.jsx b/src/components/target-pane/target-pane.jsx
index c620c8504c13a1dbd2034a9a2d3a72f80e3d8b85..565c9881cf405e6cb3856eb38671e69995a2ac2f 100644
--- a/src/components/target-pane/target-pane.jsx
+++ b/src/components/target-pane/target-pane.jsx
@@ -23,6 +23,7 @@ const TargetPane = ({
     spriteLibraryVisible,
     onChangeSpriteDirection,
     onChangeSpriteName,
+    onChangeSpriteRotationStyle,
     onChangeSpriteSize,
     onChangeSpriteVisibility,
     onChangeSpriteX,
@@ -60,6 +61,7 @@ const TargetPane = ({
             stageSize={stageSize}
             onChangeSpriteDirection={onChangeSpriteDirection}
             onChangeSpriteName={onChangeSpriteName}
+            onChangeSpriteRotationStyle={onChangeSpriteRotationStyle}
             onChangeSpriteSize={onChangeSpriteSize}
             onChangeSpriteVisibility={onChangeSpriteVisibility}
             onChangeSpriteX={onChangeSpriteX}
@@ -128,6 +130,7 @@ TargetPane.propTypes = {
     }),
     onChangeSpriteDirection: PropTypes.func,
     onChangeSpriteName: PropTypes.func,
+    onChangeSpriteRotationStyle: PropTypes.func,
     onChangeSpriteSize: PropTypes.func,
     onChangeSpriteVisibility: PropTypes.func,
     onChangeSpriteX: PropTypes.func,
diff --git a/src/containers/direction-picker.jsx b/src/containers/direction-picker.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..a0643d706c8aaaa9600a08aea4ecd2c986ba5659
--- /dev/null
+++ b/src/containers/direction-picker.jsx
@@ -0,0 +1,62 @@
+import bindAll from 'lodash.bindall';
+import PropTypes from 'prop-types';
+import React from 'react';
+
+import DirectionComponent, {RotationStyles} from '../components/direction-picker/direction-picker.jsx';
+
+class DirectionPicker extends React.Component {
+    constructor (props) {
+        super(props);
+        bindAll(this, [
+            'handleOpenPopover',
+            'handleClosePopover',
+            'handleClickLeftRight',
+            'handleClickDontRotate',
+            'handleClickAllAround'
+        ]);
+        this.state = {
+            popoverOpen: false
+        };
+    }
+    handleOpenPopover () {
+        this.setState({popoverOpen: true});
+    }
+    handleClosePopover () {
+        this.setState({popoverOpen: false});
+    }
+    handleClickAllAround () {
+        this.props.onChangeRotationStyle(RotationStyles.ALL_AROUND);
+    }
+    handleClickLeftRight () {
+        this.props.onChangeRotationStyle(RotationStyles.LEFT_RIGHT);
+    }
+    handleClickDontRotate () {
+        this.props.onChangeRotationStyle(RotationStyles.DONT_ROTATE);
+    }
+    render () {
+        return (
+            <DirectionComponent
+                direction={this.props.direction}
+                disabled={this.props.disabled}
+                popoverOpen={this.state.popoverOpen && !this.props.disabled}
+                rotationStyle={this.props.rotationStyle}
+                onChangeDirection={this.props.onChangeDirection}
+                onClickAllAround={this.handleClickAllAround}
+                onClickDontRotate={this.handleClickDontRotate}
+                onClickLeftRight={this.handleClickLeftRight}
+                onClosePopover={this.handleClosePopover}
+                onOpenPopover={this.handleOpenPopover}
+            />
+        );
+    }
+}
+
+DirectionPicker.propTypes = {
+    direction: PropTypes.number,
+    disabled: PropTypes.bool,
+    onChangeDirection: PropTypes.func,
+    onChangeRotationStyle: PropTypes.func,
+    rotationStyle: PropTypes.string
+};
+
+export default DirectionPicker;
diff --git a/src/containers/target-pane.jsx b/src/containers/target-pane.jsx
index a116b3c0788127d6743e7555ecb1cdb34016d97d..b82d7c038cf15d2c6ec73feed0124e79b147ae5d 100644
--- a/src/containers/target-pane.jsx
+++ b/src/containers/target-pane.jsx
@@ -20,6 +20,7 @@ class TargetPane extends React.Component {
         super(props);
         bindAll(this, [
             'handleBlockDragEnd',
+            'handleChangeSpriteRotationStyle',
             'handleChangeSpriteDirection',
             'handleChangeSpriteName',
             'handleChangeSpriteSize',
@@ -48,6 +49,9 @@ class TargetPane extends React.Component {
     handleChangeSpriteDirection (direction) {
         this.props.vm.postSpriteInfo({direction});
     }
+    handleChangeSpriteRotationStyle (rotationStyle) {
+        this.props.vm.postSpriteInfo({rotationStyle});
+    }
     handleChangeSpriteName (name) {
         this.props.vm.renameSprite(this.props.editingTarget, name);
     }
@@ -167,6 +171,7 @@ class TargetPane extends React.Component {
                 fileInputRef={this.setFileInput}
                 onChangeSpriteDirection={this.handleChangeSpriteDirection}
                 onChangeSpriteName={this.handleChangeSpriteName}
+                onChangeSpriteRotationStyle={this.handleChangeSpriteRotationStyle}
                 onChangeSpriteSize={this.handleChangeSpriteSize}
                 onChangeSpriteVisibility={this.handleChangeSpriteVisibility}
                 onChangeSpriteX={this.handleChangeSpriteX}