109 lines
4.2 KiB
Plaintext
109 lines
4.2 KiB
Plaintext
;;;; raylib [core] example - 2d camera mouse zoom
|
|
;;;;
|
|
;;;; examples/core/core_2d_camera_mouse_zoom.c at the raylib 5.5 tag. It
|
|
;;;; needed rlgl's matrix stack: the grid is a 3D grid on the XZ plane, and the
|
|
;;;; C stands it up in the XY plane by pushing a matrix, translating, rotating
|
|
;;;; ninety degrees about X and drawing. vendor/rlgl binds that stack.
|
|
;;;;
|
|
;;;; One difference from the C. The mouse read-out is `TextFormat("[%i, %i]",
|
|
;;;; ...)` through DrawTextEx with a spacing of 2. TextFormat is variadic and
|
|
;;;; unbound, so the read-out is drawn in pieces with draw-text and
|
|
;;;; digits.flan's draw-int, which space the glyphs raylib's default way.
|
|
|
|
(import rl "vendor:raylib")
|
|
(import rlgl "vendor:rlgl")
|
|
(import d "digits.flan")
|
|
|
|
(defconst screen-width 800)
|
|
(defconst screen-height 450)
|
|
|
|
;; 0 zooms with the mouse wheel, 1 with a right-button drag.
|
|
(defonce zoom-mode i32)
|
|
(defonce camera rl/Camera2D)
|
|
|
|
;; Put the world point under the mouse at the camera's origin, and the origin
|
|
;; under the mouse, so a zoom that follows keeps that point still.
|
|
(defn anchor-at-mouse [] ()
|
|
(let [mouse-world (rl/get-screen-to-world-2d (rl/get-mouse-position) camera)]
|
|
(set (.offset camera) (rl/get-mouse-position))
|
|
(set (.target camera) mouse-world)))
|
|
|
|
;; One zoom step: `amount` is how far the input moved, and the direction is its
|
|
;; sign. The zoom stays between 1/8 and 64.
|
|
(defn zoom-by [amount f32 rate f32] ()
|
|
(let [factor (+ 1.0 (* rate (abs-f32 amount)))
|
|
factor (if (< amount 0.0) (/ 1.0 factor) factor)]
|
|
(set (.zoom camera) (clamp (* (.zoom camera) factor) 0.125 64.0))))
|
|
|
|
(defn main [] ()
|
|
(rl/init-window screen-width screen-height
|
|
"raylib [core] example - 2d camera mouse zoom")
|
|
(defer (rl/close-window))
|
|
|
|
;; A zero zoom makes the camera's transform singular.
|
|
(set camera (rl/Camera2D {.zoom 1.0}))
|
|
(set zoom-mode 0)
|
|
|
|
(rl/set-target-fps 60)
|
|
|
|
(until (rl/window-should-close?)
|
|
;; Update
|
|
(cond
|
|
(rl/key-pressed? :key-one) (set zoom-mode 0)
|
|
(rl/key-pressed? :key-two) (set zoom-mode 1))
|
|
|
|
;; Drag to move: the mouse's screen delta, scaled back into world units.
|
|
(when (rl/mouse-button-down? :mouse-left)
|
|
(let [delta (rl/v2-scale (rl/get-mouse-delta) (/ -1.0 (.zoom camera)))]
|
|
(set (.target camera) (rl/v2-add (.target camera) delta))))
|
|
|
|
(if (= zoom-mode 0)
|
|
(let [wheel (rl/get-mouse-wheel-move)]
|
|
(when (!= wheel 0.0)
|
|
(anchor-at-mouse)
|
|
(zoom-by wheel 0.25)))
|
|
(do
|
|
(when (rl/mouse-button-pressed? :mouse-right)
|
|
(anchor-at-mouse))
|
|
(when (rl/mouse-button-down? :mouse-right)
|
|
(zoom-by (.x (rl/get-mouse-delta)) 0.01))))
|
|
|
|
;; Draw
|
|
(rl/with-drawing
|
|
(rl/clear-background rl/raywhite)
|
|
|
|
(rl/begin-mode-2d camera)
|
|
;; The 3D grid, rotated ninety degrees and centred on the origin, so it
|
|
;; lies in the XY plane the 2D camera looks at.
|
|
(rlgl/push-matrix)
|
|
(rlgl/translate 0.0 (* 25.0 50.0) 0.0)
|
|
(rlgl/rotate 90.0 1.0 0.0 0.0)
|
|
(rl/draw-grid 100 50.0)
|
|
(rlgl/pop-matrix)
|
|
|
|
;; A reference circle.
|
|
(rl/draw-circle (/ (rl/get-screen-width) 2) (/ (rl/get-screen-height) 2)
|
|
50.0 rl/maroon)
|
|
(rl/end-mode-2d)
|
|
|
|
;; The mouse, and where it is in screen pixels.
|
|
(let [mouse (rl/get-mouse-position)
|
|
x (- (i32 (.x mouse)) 44)
|
|
y (- (i32 (.y mouse)) 24)]
|
|
(rl/draw-circle-v mouse 4.0 rl/darkgray)
|
|
(rl/draw-text "[" x y 20 rl/black)
|
|
(let [x (+ x (rl/measure-text "[" 20))
|
|
x (+ x (d/draw-int (rl/get-mouse-x) x y 20 rl/black))]
|
|
(rl/draw-text ", " x y 20 rl/black)
|
|
(let [x (+ x (rl/measure-text ", " 20))
|
|
x (+ x (d/draw-int (rl/get-mouse-y) x y 20 rl/black))]
|
|
(rl/draw-text "]" x y 20 rl/black))))
|
|
|
|
(rl/draw-text "[1][2] Select mouse zoom mode (Wheel or Move)"
|
|
20 20 20 rl/darkgray)
|
|
(if (= zoom-mode 0)
|
|
(rl/draw-text "Mouse left button drag to move, mouse wheel to zoom"
|
|
20 50 20 rl/darkgray)
|
|
(rl/draw-text "Mouse left button drag to move, mouse press and move to zoom"
|
|
20 50 20 rl/darkgray)))))
|