Skip to content
This repository was archived by the owner on Feb 18, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
npm-debug.log

/.idea

/build

/appconfig.*.json
Expand Down
6 changes: 5 additions & 1 deletion src/chessground/Chessground.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ export default class Chessground {
if (!isViewOnly) {
board.addEventListener('touchstart', (e: TouchEvent) => drag.start(this, e))
board.addEventListener('touchmove', (e: TouchEvent) => drag.move(this, e))
board.addEventListener('touchend', (e: TouchEvent) => drag.end(this, e))
board.addEventListener('touchend', (e: TouchEvent) => {
const { clientX, clientY } = e.changedTouches[0]
drag.placePieceInHand(this, [clientX, clientY], bounds)
drag.end(this, e)
})
board.addEventListener('touchcancel', () => drag.cancel(this))
}

Expand Down
8 changes: 6 additions & 2 deletions src/chessground/board.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ export function apiMove(state: State, orig: Key, dest: Key): boolean {
return baseMove(state, orig, dest)
}

export function apiNewPiece(state: State, piece: Piece, key: Key): boolean {
return baseNewPiece(state, piece, key)
export function apiNewPiece(state: State, piece: Piece, key: Key, force = false): boolean {
return baseNewPiece(state, piece, key, force)
}

export function userMove(state: State, orig: Key, dest: Key): boolean {
Expand Down Expand Up @@ -136,6 +136,10 @@ export function unselect(state: State): void {
state.premovable.dests = null
}

export function setPieceInHand(state: State, piece: Piece | null, force = false): void {
state.pieceInHand = piece ? { ...piece, force } : null
}

export function isMovable(state: State, orig: Key): boolean {
const piece = state.pieces.get(orig)
return !!piece && (
Expand Down
17 changes: 17 additions & 0 deletions src/chessground/drag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Chessground from './Chessground'
import * as board from './board'
import * as util from './util'
import { anim } from './anim'
import {apiNewPiece} from './board'

export interface DragCurrent {
orig: Key // orig key of dragging piece
Expand Down Expand Up @@ -207,6 +208,22 @@ export function cancel(ctrl: Chessground) {
}
}

export function placePieceInHand(ctrl: Chessground, position: NumberPair, bounds: ClientRect) {
const state = ctrl.state

if (state.pieceInHand) {
const [x, y] = position
const key = getKeyAtDomPos(state, [x, y], bounds)

if (key) {
apiNewPiece(state, state.pieceInHand, key, state.pieceInHand.force)
}
state.pieceInHand = null

ctrl.redraw()
}
}

function getKeyAtDomPos(state: State, pos: NumberPair, bounds: ClientRect): Key | null {
if (typeof bounds !== 'object') {
throw new Error('function getKeyAtDomPos require bounds object arg')
Expand Down
2 changes: 2 additions & 0 deletions src/chessground/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { DragCurrent } from './drag'

export interface State {
pieces: cg.Pieces
pieceInHand: Piece & { force: boolean } | null
orientation: Color // board orientation. white | black
turnColor: Color // turn to play. white | black
check: Key | null // square currently in check "a2"
Expand Down Expand Up @@ -85,6 +86,7 @@ export interface State {
export function makeDefaults(): State {
return {
pieces: new Map(),
pieceInHand: null,
orientation: 'white' as Color,
turnColor: 'white' as Color,
check: null,
Expand Down
24 changes: 23 additions & 1 deletion src/ui/editor/EditorCtrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import continuePopup, { Controller as ContinuePopupCtrl } from '../shared/contin
import i18n from '../../i18n'
import drag from './drag'
import { EditorState, BoardPosition, BoardPositionCategory, CastlingToggle, CastlingToggles, CASTLING_TOGGLES } from './interfaces'
import {setPieceInHand} from '../../chessground/board'

export default class EditorCtrl {
public menu: MenuInterface
Expand Down Expand Up @@ -121,8 +122,29 @@ export default class EditorCtrl {
redraw()
}

public onstart = (e: TouchEvent): void => drag(this, e)

private pickUp = (e: TouchEvent) => {
if (e.touches && e.touches.length > 1) return // support one finger touch only
const role = (e.target as HTMLElement).getAttribute('data-role'),
color = (e.target as HTMLElement).getAttribute('data-color')
if (!role || !color) return
e.stopPropagation()
e.preventDefault()

const piece = {
role: (role as Role),
color: (color as Color)
}

setPieceInHand(this.chessground.state, piece, true)
}

public onstart = (e: TouchEvent): void => {
this.pickUp(e)
drag(this, e)
}
public onmove = (e: TouchEvent): void => cgDrag.move(this.chessground, e)

public onend = (e: TouchEvent): void => cgDrag.end(this.chessground, e)

public editorOnCreate = (vn: Mithril.VnodeDOM): void => {
Expand Down