Skip to content
Draft
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
36 changes: 36 additions & 0 deletions examples/3005-coordinates.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
===== id
3005-coordinates

===== Name
Coordinates

===== DescriptionMD
Use the `coordinates` property to control how coordinates display on the board.

===== HTML
<div id="myBoard" style="padding: 40px; width: 400px"></div>

<button id="showCoordinatesBtn">Show Coordiantes</button>
<button id="hideCoordinatesBtn">Hide Coordinates</button>
<button id="toggleCoordinatesBtn">Toggle Coordinates</button>

===== JS
const boardConfig = {
coordinates: 'default',
// coordinates: 'bottom left'
// coordinates: ["left", "top", "right"]
position: 'start'
}
const board = Chessboard2('myBoard', boardConfig)

attachEvent('showCoordinatesBtn', 'click', () => {
board.showCoordinates()
})

attachEvent('hideCoordinatesBtn', 'click', () => {
board.hideCoordinates()
})

attachEvent('toggleCoordinatesBtn', 'click', () => {
board.toggleCoordinates()
})
1 change: 1 addition & 0 deletions scripts/website.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ const examplesGroups = [
'3023-set-random-position',
'3003-clear',
'3004-move-pieces',
'3005-coordinates',
'3008-analysis-arrows',
'3009-circles',
'3005-orientation',
Expand Down
12 changes: 11 additions & 1 deletion src-cljs/com/oakmac/chessboard2/config.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,18 @@
"black"
"white"))

(defn valid-js-coords? [c]
(cond
(= c "default") true
;; FIXME: validate the config here
:else false))

(def config-props
{:draggable
{:coordinates
{:default-val nil
:valid-fn valid-js-coords?}

:draggable
{:default-val false
:valid-fn boolean?}

Expand Down
114 changes: 74 additions & 40 deletions src-cljs/com/oakmac/chessboard2/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
;; FIXME: need "source" here
;; "source" "FIXME"
"square" square))
;; FIXME: add "file" and "rank" values here?
(catch js/Error err
(error-log "Runtime error with provided onDragStart function:" err)
nil))))]
Expand Down Expand Up @@ -161,7 +162,7 @@
;; return null
nil))

(defn on-mousedown-root-el
(defn on-mousedown-items-el
"This function fires on every 'mousedown' event inside the root DOM element"
[board-state js-evt]
(dom-util/safe-prevent-default js-evt)
Expand Down Expand Up @@ -203,7 +204,7 @@
;; return null
nil))

(defn on-mouseup-root-el
(defn on-mouseup-items-el
"This function fires on every 'mouseup' event inside the root DOM element"
[board-state js-evt]
(let [{:keys [onMouseupSquare orientation position square->square-ids]} @board-state
Expand Down Expand Up @@ -245,7 +246,7 @@

;; NOTE: this function has the potential to be a perf bottleneck
;; need to benchmark and optimize this function
(defn on-mousemove-root-el
(defn on-mousemove-items-el
[board-state js-evt]
(let [clientX (gobj/get js-evt "clientX")
clientY (gobj/get js-evt "clientY")
Expand Down Expand Up @@ -278,7 +279,7 @@
"fromSquare" (if prev-square prev-square "off-board"))]
(onMouseenterSquare js-board-info js-evt))))))

(defn on-mouseleave-root-el
(defn on-mouseleave-items-el
"Clear the current mouse position when the cursor leaves the board."
[board-state _js-evt]
(swap! board-state assoc :square-mouse-is-currently-hovering-over nil))
Expand Down Expand Up @@ -413,13 +414,14 @@
(fn [] (api/resize! board-state))
10)) ;; TODO: make this debounce value configurable

;; events on the root element
(.addEventListener root-el "mouseleave" (fn [js-evt] (on-mouseleave-root-el board-state js-evt)))
(.addEventListener root-el "mousemove" (fn [js-evt] (on-mousemove-root-el board-state js-evt)))
(.addEventListener root-el "mousedown" (fn [js-evt] (on-mousedown-root-el board-state js-evt)))
(.addEventListener root-el "mouseup" (fn [js-evt] (on-mouseup-root-el board-state js-evt)))
(.addEventListener root-el "touchstart" (fn [js-evt] (on-touch-start board-state js-evt)))
(.addEventListener root-el "transitionend" (fn [js-evt] (on-transition-end board-state js-evt))))
;; events on the Items Container element
(let [items-el (dom-util/get-element (:items-container-id @board-state))]
(.addEventListener items-el "mouseleave" (fn [js-evt] (on-mouseleave-items-el board-state js-evt)))
(.addEventListener items-el "mousemove" (fn [js-evt] (on-mousemove-items-el board-state js-evt)))
(.addEventListener items-el "mousedown" (fn [js-evt] (on-mousedown-items-el board-state js-evt)))
(.addEventListener items-el "mouseup" (fn [js-evt] (on-mouseup-items-el board-state js-evt)))
(.addEventListener items-el "touchstart" (fn [js-evt] (on-touch-start board-state js-evt)))
(.addEventListener items-el "transitionend" (fn [js-evt] (on-transition-end board-state js-evt)))))

;; TODO: move this to util ns
(defn toggle-orientation [o]
Expand Down Expand Up @@ -855,43 +857,78 @@

(defn hide-coordinates!
[board-state]
(swap! board-state assoc :show-coords? false))
; (let [container-id (:container-id @board-state)]
; (add-class! (dom-util/get-element container-id) "hide-notation-cbe71")
; (swap! board-state assoc :show-notation? false)))
(swap! board-state update :coords
(fn [coords-map]
(reduce
(fn [new-coords [position cfg]]
(assoc new-coords position (assoc cfg :show? false)))
{}
coords-map))))

(defn show-coordinates!
[board-state]
(swap! board-state assoc :show-coords? true))
; (let [container-id (:container-id @board-state)]
; (remove-class! (dom-util/get-element container-id) "hide-notation-cbe71")
; (swap! board-state assoc :show-notation? true)))
(swap! board-state update :coords
(fn [coords-map]
(reduce
(fn [new-coords [position cfg]]
(assoc new-coords position (assoc cfg :show? true)))
{}
coords-map))))

(defn toggle-coordinates!
[board-state]
(swap! board-state update :show-coords? not))
; (if (:show-notation? @board-state)
; (hide-coordinates! board-state)
; (show-coordinates! board-state)))
(swap! board-state update :coords
(fn [coords-map]
(reduce
(fn [new-coords [position cfg]]
(assoc new-coords position (update cfg :show? not)))
{}
coords-map))))

;; -----------------------------------------------------------------------------
;; Constructor

;; Notes on Coordinates:
;; * recommend they style the coordinate text using CSS
;; * chessboard2 API can support show / hide
;; * TRBL positioning options
;; * "style" can be String, Map, or Function
;; * "renderHTML" can be String or Function
(def default-coords
{:top {:show? false, :type "files", :style ""}
:right {:show? false, :type "ranks", :style ""}
:bottom {:show? false, :type "files", :style ""}
:left {:show? false, :type "ranks", :style ""}})

;; TODO: move this to DOM ops?
(defn update-coords!
"Update the DOM to match the coordinate config."
[board-state coords-config]
; (js/console.log "updating coords:" (pr-str coords-config))
(let [{:keys [container-id] :as _board-state} @board-state
board-container-sel (str "#" container-id " .board-container-41a68")
board-container-el (dom-util/get-element board-container-sel)
_ (when flags/runtime-checks?
(when-not board-container-el
(error-log "Unable to find board-container-el in update-coords!")))]
(doseq [[position-trbl css-class] css/coords->css]
(let [sel (str "#" container-id " ." css-class)
el (dom-util/get-element sel)
cfg (get coords-config position-trbl)
show? (true? (:show? cfg))]
(dom-util/remove-element! el)
(when show?
;; FIXME: Pass their custom formatting fn here
(dom-util/append-html! board-container-el (html/CoordinateRow position-trbl)))))))

(defn init-dom!
[board-state]
(let [{:keys [root-el] :as board-cfg} @board-state]
(let [{:keys [coords root-el] :as board-cfg} @board-state]
;; write the container <div>s to the DOM
(dom-util/set-inner-html! root-el (html/BoardContainer board-cfg))
;; calculate width / height
(api/resize! board-state)))

;; recommend they style the coordinate text using CSS
;; the chessboard API can support the "on/off" and position stuff
(def default-coords
{:bottom {:position "outside", :show? false, :type "letters"}
:left {:position "outside", :show? false, :type "numbers"}
:right {:position "outside", :show? false, :type "numbers"}
:top {:position "outside", :show? false, :type "letters"}})
(api/resize! board-state)
(update-coords! board-state coords)))

(def default-animate-speed-ms 80)
; (def default-animate-speed-ms 2500)
Expand All @@ -904,12 +941,9 @@
(if (= "white" (:orientation new-state))
(set-white-orientation! board-atom)
(set-black-orientation! board-atom)))
;; FIXME: coordinate config change
;; show / hide coordinates
(when-not (= (:show-coords? old-state) (:show-coords? new-state))
(if (:show-coords? new-state)
(remove-class! (dom-util/get-element (:container-id new-state)) "hide-notation-cbe71")
(add-class! (dom-util/get-element (:container-id new-state)) "hide-notation-cbe71")))
;; coordinate config change
(when-not (= (:coords old-state) (:coords new-state))
(update-coords! board-atom (:coords new-state)))
;; fire their onChange event
(let [on-change-fn (:onChange new-state)
old-position (:position old-state)
Expand Down Expand Up @@ -1019,7 +1053,7 @@
;; FIXME: implement these
;; https://github.com/oakmac/chessboard2/issues/25
"coordinates" #() ;; FIXME: returns the current state with 0 arg, allows changing with other args
"getCoordinates" #() ;; FIXME: returns the config object
"getCoordinates" (partial js-api/get-coordinates board-state)
"hideCoordinates" (partial hide-coordinates! board-state)
"setCoordinates" #() ;; FIXME: sets the config object (do we need this? just use .setConfig() ?)
"showCoordinates" (partial show-coordinates! board-state)
Expand Down
6 changes: 6 additions & 0 deletions src-cljs/com/oakmac/chessboard2/css.cljs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
(ns com.oakmac.chessboard2.css)

(def coords->css
{:top "coordinates-top-f30c9"
:right "coordinates-right-7fc08"
:bottom "coordinates-bottom-ac241"
:left "coordinates-left-183e9"})

;; TODO: probably convert this to a map

(def orientation-white "orientation-white-4de03")
Expand Down
57 changes: 41 additions & 16 deletions src-cljs/com/oakmac/chessboard2/html.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,38 @@

(declare piece->imgsrc)

(defn NotationFiles
[_cfg]
(defn FileCoordinates
[position custom-fn]
(let [num-files 8
files (range 0 num-files)]
files (range 0 num-files)
html-fn (if (fn? custom-fn)
custom-fn
str)]
(->> files
(map
(fn [f]
(str "<div class='file-44ae4'>" (idx->alpha f) "</div>")))
(template
(str "<div class='file-44ae4' data-file='{file}'>{fileHTML}</div>")
{:file (idx->alpha f)
;; FIXME: this function also should receive the position (top, right, bottom, left)
:fileHTML (html-fn (idx->alpha f))})))
(apply str))))

(defn NotationRanks
[_cfg]
(defn RankCoordinates
[position custom-fn]
(let [num-ranks 8
ranks (range 0 num-ranks)]
ranks (reverse (range 1 (inc num-ranks)))
html-fn (if (fn? custom-fn)
custom-fn
str)]
(->> ranks
(map
(fn [r]
(str "<div class='rank-3d54c'>" r "</div>")))
(template
(str "<div class='rank-3d54c' data-rank='{rank}'>{rankHTML}</div>")
{:rank r
;; FIXME: this function also should receive the position (top, right, bottom, left)
:rankHTML (html-fn r)})))
(apply str))))

(defn DraggingPiece
Expand Down Expand Up @@ -204,11 +218,11 @@
@html))

(defn BoardContainer
[{:keys [container-id orientation show-notation? items-container-id squares-container-id] :as opts}]
[{:keys [container-id orientation items-container-id squares-container-id] :as opts}]
(template
(str
"<div class='chessboard-21da3{show-notation}' id='{container-id}'>"
"<div class=board-container-41a68>"
"<div class='chessboard-21da3' id='{container-id}'>"
"<div class='board-container-41a68'>"
"<div id='{items-container-id}' class='items-container-c9182'></div>"
"<div id='{squares-container-id}' class='" css/squares " "
(if (= orientation "white")
Expand All @@ -217,14 +231,25 @@
;; NOTE: Squares container starts off with zero height and then is adjusted
"' style='height:0'>{Squares}"
"</div>" ;; end .squares-2dea6
"<div class='notation-files-c3c0a'>{NotationFiles}</div>"
"<div class='notation-ranks-d3f97'>{NotationRanks}</div>"
; "<div class='coordinates-top-f30c9'>{FileCoordinates}</div>"
; "<div class='coordinates-right-7fc08'>{RankCoordinates}</div>"
; "<div class='coordinates-bottom-ac241'>{FileCoordinates}</div>"
; "<div class='coordinates-left-183e9'>{RankCoordinates}</div>"
"</div>" ;; end .board-container-41a68
"</div>") ;; end .chessboard-21da3
{:container-id container-id
; :FileCoordinates (FileCoordinates opts)
:items-container-id items-container-id
:NotationFiles (NotationFiles opts)
:NotationRanks (NotationRanks opts)
:show-notation (if show-notation? "" " hide-notation-cbe71")
; :RankCoordinates (RankCoordinates opts)
:Squares (Squares opts)
:squares-container-id squares-container-id}))

;; TODO: pass their custom rank / file function here
(defn CoordinateRow
[trbl-position]
(template
"<div class={cssClass}>{items}</div>"
{:cssClass (get css/coords->css trbl-position)
:items (case trbl-position
(:top :bottom) (FileCoordinates (name trbl-position) nil)
(:left :right) (RankCoordinates (name trbl-position) nil))}))
Loading