Skip to content

Commit

Permalink
Replace draggable plugin with sortable.js
Browse files Browse the repository at this point in the history
  • Loading branch information
oskarrough committed Mar 13, 2020
1 parent a174ba6 commit b7e03cf
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 5,141 deletions.
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -24,7 +24,8 @@
"@shopify/draggable": "^1.0.0-beta.8",
"esm": "^3.2.25",
"htm": "^3.0.3",
"immer": "^6.0.1"
"immer": "^6.0.1",
"sortablejs": "^1.10.2"
},
"ava": {
"require": [
Expand Down
88 changes: 47 additions & 41 deletions public/components/app.js
@@ -1,9 +1,15 @@
// Third party dependencies
import {html, Component} from '../web_modules/htm/preact/standalone.module.js'
import {Sortable, OnSpill} from '../web_modules/sortablejs/modular/sortable.core.esm.js'

// Game logic
import ActionManager from '../game/action-manager.js'
import actions from './../game/actions.js'
import {isCurrentRoomCompleted} from '../game/utils.js'
import {createSimpleDungeon} from '../game/dungeon-encounters.js'
import {createCard} from './../game/cards.js'

// Components
import {Player, Monster} from './player.js'
import Cards from './cards.js'
import History from './history.js'
Expand Down Expand Up @@ -54,50 +60,50 @@ export default class App extends Component {
}

enableDrop() {
// Enable drag and drop.
const dropzones = this.base.querySelectorAll('.dropzone')
const drop = new window.Sortable.default(dropzones, {
draggable: '.Card',
mirror: {constrainDimensions: true}
})
const self = this

drop.on('sortable:start', event => {
// Find the card object behind the DOM card we are dragging.
const card = this.state.hand.find(c => c.id === event.data.dragEvent.data.source.dataset.id)
if (card.energy > this.state.player.currentEnergy) {
event.cancel()
alert('Not enough energy to play this card.')
}
})
// Enable required plugin for the 'revertOnSpill' option.
Sortable.mount(OnSpill)

drop.on('sortable:sort', event => {
// Only allow dropping on elements with this class.
const el = event.dragEvent.data.overContainer
if (!el.classList.contains('is-cardTarget')) event.cancel()
})

drop.on('sortable:stop', event => {
const {newContainer, oldContainer, dragEvent} = event.data

// Should it be allowed to drop the card here?
const allowCardPlay =
newContainer.classList.contains('is-cardTarget') && newContainer !== oldContainer
if (!allowCardPlay) return

// If yes, use the DOM to find the played card.
const card = this.state.hand.find(c => c.id === dragEvent.originalSource.dataset.id)

// Also use the DOM to find who we dropped it on.
let target
if (newContainer.classList.contains('Player')) {
target = 'player'
} else {
const index = Array.from(newContainer.parentNode.children).indexOf(newContainer)
target = `enemy${index}`
// We want to be able to drag and drop cards in the hand.
new Sortable(this.base.querySelector('.Hand .Cards'), {
group: 'hand',
draggable: '.Card',
revertOnSpill: true,
// sort: false,
onMove: function(/**Event*/ event) {
const card = self.state.hand.find(c => c.id === event.dragged.dataset.id)
if (card.energy > self.state.player.currentEnergy) {
alert('Not enough energy to play this card.')
return false
}
}
// Play the card immediately
this.enqueue({type: 'playCard', target, card})
this.dequeue()
})
// And we want all the targets (player + monsters) to be droppable.
this.base.querySelectorAll('.Target').forEach(el => {
new Sortable(el, {
group: {
name: 'player',
put: ['hand']
},
draggable: '.TRICKYOUCANT',
onAdd: function(event) {
const card = self.state.hand.find(c => c.id === event.item.dataset.id)
let to = event.to
let target

if (to.classList.contains('Player')) {
target = 'player'
} else {
const index = Array.from(to.parentNode.children).indexOf(to)
target = `enemy${index}`
}

// Play the card immediately
self.enqueue({type: 'playCard', target, card})
self.dequeue()
}
})
})
}

Expand Down
2 changes: 1 addition & 1 deletion public/components/player.js
Expand Up @@ -10,7 +10,7 @@ export const Monster = props => html`

function Target({model, type, name}) {
return html`
<div class="Target Target--${type} dropzone is-cardTarget">
<div class="Target Target--${type}">
<h2>${name}</h2>
<${Healthbar} max=${model.maxHealth} value=${model.currentHealth} block=${model.block} />
<${Powers} powers=${model.powers} />
Expand Down
54 changes: 18 additions & 36 deletions public/index.css
Expand Up @@ -83,18 +83,12 @@ summary {
margin: 1rem 0 0.5rem;
}



.Split {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 5%;
}

summary .Cards {
overflow: auto;
}

.Cards {
min-height: var(--card-height);
display: grid;
Expand All @@ -111,6 +105,9 @@ summary .Cards {
margin-left: -3rem;
}

summary .Cards {
overflow: auto;
}

.Card {
display: flex;
Expand Down Expand Up @@ -141,17 +138,6 @@ summary .Cards {
border-width: 15px;
}

.dropzone .Card:hover {
z-index: 101;
cursor: grab;
}

.dropzone .Card:hover .Card-inner {
transition-duration: 60ms;
transform: translate3d(0, -1rem, 0) scale(1.25);
box-shadow: 0 0 0.75em gold;
}

.Card-title {
margin: 0;
padding: 0.5em 1em 0.5em;
Expand Down Expand Up @@ -207,20 +193,13 @@ summary .Cards {

.Target {
position: relative;
padding-bottom: 3rem;
padding-bottom: 2rem;
}

.Target h2 {
margin-left: 0.5rem;
}

/* How cards should look when you drag on a target */
.Target .Card {
position: absolute;
top: 2rem;
left: 50%;
}

.Healthbar {
position: relative;
border: 3px solid;
Expand Down Expand Up @@ -255,17 +234,6 @@ summary .Cards {
transition: width 400ms, background 200ms;
}

.draggable-source--is-dragging {
/* Hide the original card while dragging the copy. */
opacity: 0.5;
/* visibility: hidden; */
}

.Card.draggable-mirror {
width: var(--card-width);
z-index: 10;
}

[align-right] {
text-align: right;
}
Expand All @@ -280,3 +248,17 @@ summary .Cards {
margin: 2rem;
text-align: center;
}

.Hand .Card {
cursor: grab;
}

.Hand .Card:hover .Card-inner {
transition-duration: 60ms;
transform: translate3d(0, -1rem, 0) scale(1.25);
box-shadow: 0 0 0.75em gold;
}

.sortable-chosen {}
.sortable-ghost { opacity: 0.2; }

1 change: 0 additions & 1 deletion public/index.html
Expand Up @@ -8,7 +8,6 @@
<body>
<div id="root"></div>

<script src="vendor/sortable.js"></script>
<script async src="index.js" type="module"></script>
</body>
</html>

0 comments on commit b7e03cf

Please sign in to comment.