diff --git a/examples/3005-coordinates.example b/examples/3005-coordinates.example new file mode 100644 index 0000000..3f8e41e --- /dev/null +++ b/examples/3005-coordinates.example @@ -0,0 +1,36 @@ +===== id +3005-coordinates + +===== Name +Coordinates + +===== DescriptionMD +Use the `coordinates` property to control how coordinates display on the board. + +===== HTML +
+ + + + + +===== 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() +}) diff --git a/scripts/website.js b/scripts/website.js index 9fbde4c..61e3a04 100755 --- a/scripts/website.js +++ b/scripts/website.js @@ -129,6 +129,7 @@ const examplesGroups = [ '3023-set-random-position', '3003-clear', '3004-move-pieces', + '3005-coordinates', '3008-analysis-arrows', '3009-circles', '3005-orientation', diff --git a/src-cljs/com/oakmac/chessboard2/config.cljs b/src-cljs/com/oakmac/chessboard2/config.cljs index 6f5e75a..28dc5aa 100644 --- a/src-cljs/com/oakmac/chessboard2/config.cljs +++ b/src-cljs/com/oakmac/chessboard2/config.cljs @@ -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?} diff --git a/src-cljs/com/oakmac/chessboard2/core.cljs b/src-cljs/com/oakmac/chessboard2/core.cljs index fe749e9..db38872 100644 --- a/src-cljs/com/oakmac/chessboard2/core.cljs +++ b/src-cljs/com/oakmac/chessboard2/core.cljs @@ -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))))] @@ -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) @@ -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 @@ -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") @@ -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)) @@ -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] @@ -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