Add block drag reactions
This commit is contained in:
1 parent
fc388b63c8
commit
d51952f99f
10 files changed
+93
-4
No files matched your search
@@ -57,6 +57,7 @@ Selector.propTypes = {
|
||||
url: PropTypes.string,
|
||||
name: PropTypes.string.isRequired
|
||||
})),
|
||||
raiseSprites: PropTypes.bool,
|
||||
onDeleteClick: PropTypes.func,
|
||||
onItemClick: PropTypes.func.isRequired,
|
||||
selectedItemIndex: PropTypes.number.isRequired
|
||||
|
||||
@@ -65,3 +65,44 @@
|
||||
bottom: 0.75rem;
|
||||
right: 1rem;
|
||||
}
|
||||
|
||||
.raised {
|
||||
-webkit-box-shadow: 0px 0px 6px 2px rgba(0,222,7,1);
|
||||
-moz-box-shadow: 0px 0px 6px 2px rgba(0,222,7,1);
|
||||
box-shadow: 0px 0px 6px 2px rgba(0,222,7,1);
|
||||
}
|
||||
|
||||
.raised:hover {
|
||||
-webkit-animation-name: wiggle;
|
||||
-ms-animation-name: wiggle;
|
||||
-ms-animation-duration: 1000ms;
|
||||
-webkit-animation-duration: 1000ms;
|
||||
-webkit-animation-iteration-count: 1;
|
||||
-ms-animation-iteration-count: 1;
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
-ms-animation-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
@-webkit-keyframes wiggle {
|
||||
0% {-webkit-transform: rotate(10deg);}
|
||||
25% {-webkit-transform: rotate(-10deg);}
|
||||
50% {-webkit-transform: rotate(20deg);}
|
||||
75% {-webkit-transform: rotate(-5deg);}
|
||||
100% {-webkit-transform: rotate(0deg);}
|
||||
}
|
||||
|
||||
@-ms-keyframes wiggle {
|
||||
0% {-ms-transform: rotate(1deg);}
|
||||
25% {-ms-transform: rotate(-1deg);}
|
||||
50% {-ms-transform: rotate(1.5deg);}
|
||||
75% {-ms-transform: rotate(-5deg);}
|
||||
100% {-ms-transform: rotate(0deg);}
|
||||
}
|
||||
|
||||
@keyframes wiggle {
|
||||
0% {transform: rotate(10deg);}
|
||||
25% {transform: rotate(-10deg);}
|
||||
50% {transform: rotate(20deg);}
|
||||
75% {transform: rotate(-5deg);}
|
||||
100% {transform: rotate(0deg);}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import {defineMessages, injectIntl, intlShape} from 'react-intl';
|
||||
|
||||
import Box from '../box/box.jsx';
|
||||
@@ -31,6 +32,7 @@ const SpriteSelectorComponent = function (props) {
|
||||
onDuplicateSprite,
|
||||
onNewSpriteClick,
|
||||
onSelectSprite,
|
||||
raised,
|
||||
selectedId,
|
||||
sprites,
|
||||
...componentProps
|
||||
@@ -72,7 +74,10 @@ const SpriteSelectorComponent = function (props) {
|
||||
.map(sprite => (
|
||||
<SpriteSelectorItem
|
||||
assetId={sprite.costume && sprite.costume.assetId}
|
||||
className={styles.sprite}
|
||||
className={
|
||||
(raised && sprite.id !== selectedId) ?
|
||||
classNames(styles.sprite, styles.raised) : styles.sprite
|
||||
}
|
||||
id={sprite.id}
|
||||
key={sprite.id}
|
||||
name={sprite.name}
|
||||
@@ -107,6 +112,7 @@ SpriteSelectorComponent.propTypes = {
|
||||
onDuplicateSprite: PropTypes.func,
|
||||
onNewSpriteClick: PropTypes.func,
|
||||
onSelectSprite: PropTypes.func,
|
||||
raised: PropTypes.bool,
|
||||
selectedId: PropTypes.string,
|
||||
sprites: PropTypes.shape({
|
||||
id: PropTypes.shape({
|
||||
|
||||
@@ -32,6 +32,7 @@ const TargetPane = ({
|
||||
onRequestCloseSpriteLibrary,
|
||||
onRequestCloseBackdropLibrary,
|
||||
onSelectSprite,
|
||||
raiseSprites,
|
||||
stage,
|
||||
sprites,
|
||||
vm,
|
||||
@@ -43,6 +44,7 @@ const TargetPane = ({
|
||||
>
|
||||
|
||||
<SpriteSelectorComponent
|
||||
raised={raiseSprites}
|
||||
selectedId={editingTarget}
|
||||
sprites={sprites}
|
||||
onChangeSpriteDirection={onChangeSpriteDirection}
|
||||
@@ -120,6 +122,7 @@ TargetPane.propTypes = {
|
||||
onRequestCloseExtensionLibrary: PropTypes.func,
|
||||
onRequestCloseSpriteLibrary: PropTypes.func,
|
||||
onSelectSprite: PropTypes.func,
|
||||
raiseSprites: PropTypes.bool,
|
||||
spriteLibraryVisible: PropTypes.bool,
|
||||
sprites: PropTypes.objectOf(spriteShape),
|
||||
stage: spriteShape,
|
||||
|
||||
@@ -60,6 +60,7 @@ SpriteSelectorItem.propTypes = {
|
||||
onClick: PropTypes.func,
|
||||
onDeleteButtonClick: PropTypes.func,
|
||||
onDuplicateButtonClick: PropTypes.func,
|
||||
onHover: PropTypes.func,
|
||||
selected: PropTypes.bool
|
||||
};
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ const mapStateToProps = state => ({
|
||||
return sprites;
|
||||
}, {}),
|
||||
stage: state.targets.stage,
|
||||
raiseSprites: state.blockdrag,
|
||||
spriteLibraryVisible: state.modals.spriteLibrary,
|
||||
backdropLibraryVisible: state.modals.backdropLibrary
|
||||
});
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
<!-- Sentry error logging to help with finding bugs -->
|
||||
<script src="https://cdn.ravenjs.com/3.22.1/raven.min.js" crossorigin="anonymous"></script>
|
||||
<script>
|
||||
Raven.config('https://42b7d13da8ad4d68b13e57c5e54f9a23@sentry.io/273218').install();
|
||||
// Raven.config('https://42b7d13da8ad4d68b13e57c5e54f9a23@sentry.io/273218').install();
|
||||
</script>
|
||||
<!-- /Sentry -->
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import VM from 'scratch-vm';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {updateEditingTarget, updateTargets} from '../reducers/targets';
|
||||
import {updateBlockDrag} from '../reducers/blockdrag';
|
||||
import {updateMonitors} from '../reducers/monitors';
|
||||
|
||||
/*
|
||||
@@ -29,6 +30,7 @@ const vmListenerHOC = function (WrappedComponent) {
|
||||
// we need to start listening before mounting the wrapped component.
|
||||
this.props.vm.on('targetsUpdate', this.props.onTargetsUpdate);
|
||||
this.props.vm.on('MONITORS_UPDATE', this.props.onMonitorsUpdate);
|
||||
this.props.vm.on('BLOCK_DRAG_UPDATE', this.props.onBlockDragUpdate);
|
||||
|
||||
}
|
||||
componentDidMount () {
|
||||
@@ -86,10 +88,11 @@ const vmListenerHOC = function (WrappedComponent) {
|
||||
}
|
||||
VMListener.propTypes = {
|
||||
attachKeyboardEvents: PropTypes.bool,
|
||||
onBlockDragUpdate: PropTypes.func.isRequired,
|
||||
onKeyDown: PropTypes.func,
|
||||
onKeyUp: PropTypes.func,
|
||||
onMonitorsUpdate: PropTypes.func,
|
||||
onTargetsUpdate: PropTypes.func,
|
||||
onMonitorsUpdate: PropTypes.func.isRequired,
|
||||
onTargetsUpdate: PropTypes.func.isRequired,
|
||||
vm: PropTypes.instanceOf(VM).isRequired
|
||||
};
|
||||
VMListener.defaultProps = {
|
||||
@@ -105,6 +108,9 @@ const vmListenerHOC = function (WrappedComponent) {
|
||||
},
|
||||
onMonitorsUpdate: monitorList => {
|
||||
dispatch(updateMonitors(monitorList));
|
||||
},
|
||||
onBlockDragUpdate: areBlocksOverGui => {
|
||||
dispatch(updateBlockDrag(areBlocksOverGui));
|
||||
}
|
||||
});
|
||||
return connect(
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
const BLOCK_DRAG_UPDATE = 'scratch-gui/blockdrag/BLOCK_DRAG_UPDATE';
|
||||
|
||||
const initialState = false;
|
||||
|
||||
const reducer = function (state, action) {
|
||||
if (typeof state === 'undefined') state = initialState;
|
||||
switch (action.type) {
|
||||
case BLOCK_DRAG_UPDATE:
|
||||
return action.areBlocksOverGui;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
const updateBlockDrag = function (areBlocksOverGui) {
|
||||
return {
|
||||
type: BLOCK_DRAG_UPDATE,
|
||||
areBlocksOverGui: areBlocksOverGui,
|
||||
meta: {
|
||||
throttle: 30
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export {
|
||||
reducer as default,
|
||||
updateBlockDrag
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
import {combineReducers} from 'redux';
|
||||
import colorPickerReducer from './color-picker';
|
||||
import customProceduresReducer from './custom-procedures';
|
||||
import blockDragReducer from './blockdrag';
|
||||
import intlReducer from './intl';
|
||||
import modalReducer from './modals';
|
||||
import monitorReducer from './monitors';
|
||||
@@ -12,6 +13,7 @@ import stageSizeReducer from './stage-size';
|
||||
import {ScratchPaintReducer} from 'scratch-paint';
|
||||
|
||||
export default combineReducers({
|
||||
blockdrag: blockDragReducer,
|
||||
colorPicker: colorPickerReducer,
|
||||
customProcedures: customProceduresReducer,
|
||||
intl: intlReducer,
|
||||
|
||||
Reference in new issue
Block a user