diff --git a/src/components/sprite-selector/sprite-selector.css b/src/components/sprite-selector/sprite-selector.css index 14a9661801be768fff0133fdfd518282b9fc945a..8b1e76df56f5788c24803ae2a9b50e680e5285a9 100644 --- a/src/components/sprite-selector/sprite-selector.css +++ b/src/components/sprite-selector/sprite-selector.css @@ -79,33 +79,13 @@ } .raised:hover { - -webkit-animation-name: wiggle; - -ms-animation-name: wiggle; - -ms-animation-duration: 500ms; - -webkit-animation-duration: 500ms; - -webkit-animation-iteration-count: 1; - -ms-animation-iteration-count: 1; - -webkit-animation-timing-function: ease-in-out; - -ms-animation-timing-function: ease-in-out; + animation-name: wiggle; + animation-duration: 500ms; + animation-iteration-count: 1; + animation-timing-function: ease-in-out; background-color: #8cbcff; } -@-webkit-keyframes wiggle { - 0% {-webkit-transform: rotate(3deg) scale(1.05);} - 25% {-webkit-transform: rotate(-3deg) scale(1.05);} - 50% {-webkit-transform: rotate(5deg) scale(1.05);} - 75% {-webkit-transform: rotate(-2deg) scale(1.05);} - 100% {-webkit-transform: rotate(0deg) scale(1.05);} -} - -@-ms-keyframes wiggle { - 0% {-ms-transform: rotate(3deg) scale(1.05);} - 25% {-ms-transform: rotate(-3deg) scale(1.05);} - 50% {-ms-transform: rotate(5deg) scale(1.05);} - 75% {-ms-transform: rotate(-2deg) scale(1.05);} - 100% {-ms-transform: rotate(0deg) scale(1.05);} -} - @keyframes wiggle { 0% {transform: rotate(3deg) scale(1.05);} 25% {transform: rotate(-3deg) scale(1.05);} @@ -115,30 +95,9 @@ } .receivedBlocks { - -webkit-animation: glowing 250ms; - -moz-animation: glowing 250ms; - -o-animation: glowing 250ms; animation: glowing 250ms; } -@-webkit-keyframes glowing { - 10% { -webkit-box-shadow: 0 0 10px #7fff1e; } - 90% { -webkit-box-shadow: 0 0 10px #7fff1e; } - 100% { -webkit-box-shadow: none; } -} - -@-moz-keyframes glowing { - 10% { -moz-box-shadow: 0 0 10px #7fff1e; } - 90% { -moz-box-shadow: 0 0 10px #7fff1e; } - 100% { -moz-box-shadow: none; } -} - -@-o-keyframes glowing { - 10% { box-shadow: 0 0 10px #7fff1e; } - 90% { box-shadow: 0 0 10px #7fff1e; } - 100% { box-shadow: none; } -} - @keyframes glowing { 10% { box-shadow: 0 0 10px #7fff1e; } 90% { box-shadow: 0 0 10px #7fff1e; } diff --git a/src/components/stage-selector/stage-selector.css b/src/components/stage-selector/stage-selector.css index c3d51208716cf629ecbf2d875800f90133935b65..b8ae410bb5e4c338a26a72045c9de7283344f1cd 100644 --- a/src/components/stage-selector/stage-selector.css +++ b/src/components/stage-selector/stage-selector.css @@ -80,3 +80,22 @@ $header-height: calc($stage-menu-height - 2px); position: absolute; bottom: 0.75rem; } + +.raised, .raised .header { + background-color: #8cbcff; + transition: all 0.25s ease; +} + +.raised:hover { + transform: scale(1.05); +} + +.receivedBlocks { + animation: glowing 250ms; +} + +@keyframes glowing { + 10% { box-shadow: 0 0 10px #7fff1e; } + 90% { box-shadow: 0 0 10px #7fff1e; } + 100% { box-shadow: none; } +} diff --git a/src/components/stage-selector/stage-selector.jsx b/src/components/stage-selector/stage-selector.jsx index d08cf353fa9825614b495abeb94ffdfae2c08cfa..5399057c9cf754de376a58e9cbceb30af5b1d258 100644 --- a/src/components/stage-selector/stage-selector.jsx +++ b/src/components/stage-selector/stage-selector.jsx @@ -42,10 +42,14 @@ const StageSelector = props => { fileInputRef, intl, selected, + raised, + receivedBlocks, url, onBackdropFileUploadClick, onBackdropFileUpload, onClick, + onMouseEnter, + onMouseLeave, onNewBackdropClick, onSurpriseBackdropClick, onEmptyBackdropClick, @@ -54,9 +58,13 @@ const StageSelector = props => { return ( <Box className={classNames(styles.stageSelector, { - [styles.isSelected]: selected + [styles.isSelected]: selected, + [styles.raised]: raised, + [styles.receivedBlocks]: receivedBlocks })} onClick={onClick} + onMouseEnter={onMouseEnter} + onMouseLeave={onMouseLeave} {...componentProps} > <div className={styles.header}> @@ -121,8 +129,12 @@ StageSelector.propTypes = { onBackdropFileUploadClick: PropTypes.func, onClick: PropTypes.func, onEmptyBackdropClick: PropTypes.func, + onMouseEnter: PropTypes.func, + onMouseLeave: PropTypes.func, onNewBackdropClick: PropTypes.func, onSurpriseBackdropClick: PropTypes.func, + raised: PropTypes.bool.isRequired, + receivedBlocks: PropTypes.bool.isRequired, selected: PropTypes.bool.isRequired, url: PropTypes.string }; diff --git a/src/containers/stage-selector.jsx b/src/containers/stage-selector.jsx index a2039796f5e6379cc3bbb4be44447bdfc3890efe..4d84746000ba09fb846937323d7dec216eab409a 100644 --- a/src/containers/stage-selector.jsx +++ b/src/containers/stage-selector.jsx @@ -5,6 +5,7 @@ import React from 'react'; import {connect} from 'react-redux'; import {openBackdropLibrary} from '../reducers/modals'; import {activateTab, COSTUMES_TAB_INDEX} from '../reducers/editor-tab'; +import {setHoveredSprite} from '../reducers/hovered-target'; import StageSelectorComponent from '../components/stage-selector/stage-selector.jsx'; @@ -23,6 +24,8 @@ class StageSelector extends React.Component { 'addBackdropFromLibraryItem', 'handleFileUploadClick', 'handleBackdropUpload', + 'handleMouseEnter', + 'handleMouseLeave', 'setFileInput' ]); } @@ -65,6 +68,12 @@ class StageSelector extends React.Component { handleFileUploadClick () { this.fileInput.click(); } + handleMouseEnter () { + this.props.dispatchSetHoveredSprite(this.props.id); + } + handleMouseLeave () { + this.props.dispatchSetHoveredSprite(null); + } setFileInput (input) { this.fileInput = input; } @@ -85,6 +94,8 @@ class StageSelector extends React.Component { onBackdropFileUploadClick={this.handleFileUploadClick} onClick={this.handleClick} onEmptyBackdropClick={this.handleEmptyBackdrop} + onMouseEnter={this.handleMouseEnter} + onMouseLeave={this.handleMouseLeave} onSurpriseBackdropClick={this.handleSurpriseBackdrop} {...componentProps} @@ -98,9 +109,12 @@ StageSelector.propTypes = { onSelect: PropTypes.func }; -const mapStateToProps = (state, {assetId}) => ({ +const mapStateToProps = (state, {assetId, id}) => ({ url: assetId && state.scratchGui.vm.runtime.storage.get(assetId).encodeDataURI(), - vm: state.scratchGui.vm + vm: state.scratchGui.vm, + receivedBlocks: state.scratchGui.hoveredTarget.receivedBlocks && + state.scratchGui.hoveredTarget.sprite === id, + raised: state.scratchGui.blockDrag }); const mapDispatchToProps = dispatch => ({ @@ -111,6 +125,9 @@ const mapDispatchToProps = dispatch => ({ }, onActivateTab: tabIndex => { dispatch(activateTab(tabIndex)); + }, + dispatchSetHoveredSprite: spriteId => { + dispatch(setHoveredSprite(spriteId)); } });