yo35 / kokopu-react

A React-based library to create and display chessboard and chess-related components.
https://www.npmjs.com/package/kokopu-react
GNU Lesser General Public License v3.0
7 stars 1 forks source link

"animated" prop has no effect #9

Closed spaceC00kie closed 3 months ago

spaceC00kie commented 4 months ago

Setting "animated" to true or false currently has no impact on the appearance of moving pieces.

I'm consuming the Lichess TV API, and I want to display the game with the kokopu-react board.

This component displays the fen from Lichess:

<Chessboard position={fen} animated />

However, the transitions between moves are not being animated. I can provide more complete code if needed.

Thanks! I appreciate any help you can offer.

yo35 commented 4 months ago

Any error in the JavaScript console? Is the animation working in your browser on the demo page? (toggle the "Animation" button + play moves to see the difference with vs. without animation)

spaceC00kie commented 4 months ago

Yes, the animation on the demo page does work.

I created a fresh TypeScript/React app and set up an example with minimal code. There are no errors in the JavaScript console.

import { useEffect, useState } from "react"
import { Chessboard } from "kokopu-react"
// @ts-ignore
import ndjsonStream from "can-ndjson-stream"

export interface ChessStream {
  getReader: () => {
    read: () => Promise<Res>
  }
}

export interface Res {
  value: {
    t: string
    d: Featured | Move
  }
  done: boolean
}

export interface Featured {
  id: string
  orientation: "black" | "white"
  players: Player[]
  fen: string
  wc: number
  bc: number
}

export interface Move {
  fen: string
  lm: string
  wc: number
  bc: number
}

export interface Player {
  color: string
  user: {
    name: string
    id: string
    title?: string
  }
  rating: number
  seconds: number
}

function App() {
  const [fen, setFen] = useState(
    "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
  )

  const streamLichessTV = () => {
    const handleStream = (stream: ChessStream) => {
      const streamReader = stream.getReader()
      streamReader.read().then(async (res: Res) => {
        setFen(res.value.d.fen)
        while (!res || !res.done) {
          res = await streamReader.read()
          setFen(res.value.d.fen)
        }
      })
    }

    const callApi = () => {
      const url = "https://lichess.org/api/tv/feed"

      fetch(url, {
        method: "get",
      })
        .then(data => ndjsonStream(data.body))
        .then(handleStream)
        .catch(console.error)
    }

    callApi()
  }

  useEffect(streamLichessTV, [])

  return <Chessboard animated position={fen} />
}

export default App

I expected the position changes between the fens from the stream to animate, but they don't.

Thank you for responding so fast! I'm very grateful.

yo35 commented 4 months ago

You must use the move attribute of the Chessboard component. For instance:

<Chessboard position="rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" move="e4" animated />

Otherwise, the component cannot guess which piece should be animated.

spaceC00kie commented 3 months ago

Got it. Thanks!