penpot/frontend/src/uxbox/main/ui/workspace/rules.cljs
2019-07-19 12:32:31 +02:00

168 lines
4.9 KiB
Clojure

;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
;; Copyright (c) 2015-2017 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.main.ui.workspace.rules
(:require
[beicon.core :as rx]
[cuerdas.core :as str]
[rumext.alpha :as mf]
[uxbox.main.constants :as c]
[uxbox.main.refs :as refs]
[uxbox.main.store :as s]
[uxbox.util.dom :as dom]))
;; --- Constants & Helpers
(def step-padding 20)
(def step-size 10)
(defn big-ticks-mod [zoom] (/ 100 zoom))
(defn mid-ticks-mod [zoom] (/ 50 zoom))
(def +ticks+
(concat (range (- (/ c/viewport-width 1)) 0 step-size)
(range 0 (/ c/viewport-width 1) step-size)))
(def rule-padding 20)
(defn- make-vertical-tick
[zoom acc value]
(let [big-ticks-mod (big-ticks-mod zoom)
mid-ticks-mod (mid-ticks-mod zoom)
pos (+ (* value zoom)
rule-padding
(* c/canvas-start-x zoom)
c/canvas-scroll-padding)]
(cond
(< (mod value big-ticks-mod) step-size)
(conj acc (str/format "M %s %s L %s %s" pos 5 pos step-padding))
(< (mod value mid-ticks-mod) step-size)
(conj acc (str/format "M %s %s L %s %s" pos 10 pos step-padding))
:else
(conj acc (str/format "M %s %s L %s %s" pos 15 pos step-padding)))))
(defn- make-horizontal-tick
[zoom acc value]
(let [big-ticks-mod (big-ticks-mod zoom)
mid-ticks-mod (mid-ticks-mod zoom)
pos (+ (* value zoom)
(* c/canvas-start-x zoom)
c/canvas-scroll-padding)]
(cond
(< (mod value big-ticks-mod) step-size)
(conj acc (str/format "M %s %s L %s %s" 5 pos step-padding pos))
(< (mod value mid-ticks-mod) step-size)
(conj acc (str/format "M %s %s L %s %s" 10 pos step-padding pos))
:else
(conj acc (str/format "M %s %s L %s %s" 15 pos step-padding pos)))))
;; --- Horizontal Text Label
(mf/def horizontal-text-label
:key-fn second
:render
(fn [own [zoom value]]
(let [big-ticks-mod (big-ticks-mod zoom)
pos (+ (* value zoom)
rule-padding
(* c/canvas-start-x zoom)
c/canvas-scroll-padding)]
(when (< (mod value big-ticks-mod) step-size)
[:text {:x (+ pos 2)
:y 13
:key (str pos)
:fill "#9da2a6"
:style {:font-size "12px"}}
value]))))
;; --- Horizontal Text Label
(mf/def vertical-text-label
:key-fn second
:render
(fn [own [zoom value]]
(let [big-ticks-mod (big-ticks-mod zoom)
pos (+ (* value zoom)
(* c/canvas-start-x zoom)
c/canvas-scroll-padding)]
(when (< (mod value big-ticks-mod) step-size)
[:text {:y (- pos 3)
:x 5
:key (str pos)
:fill "#9da2a6"
:transform (str/format "rotate(90 0 %s)" pos)
:style {:font-size "12px"}}
value]))))
;; --- Horizontal Rule Ticks (Component)
(mf/def horizontal-rule-ticks
:mixins #{mf/static}
:render
(fn [own zoom]
(let [zoom (or zoom 1)
path (reduce (partial make-vertical-tick zoom) [] +ticks+)]
[:g
[:path {:d (str/join " " path)}]
(for [tick +ticks+]
(horizontal-text-label [zoom tick]))])))
;; --- Vertical Rule Ticks (Component)
(mf/def vertical-rule-ticks
:mixins #{mf/static}
:render
(fn [own zoom]
(let [zoom (or zoom 1)
path (reduce (partial make-horizontal-tick zoom) [] +ticks+)]
[:g
[:path {:d (str/join " " path)}]
(for [tick +ticks+]
(vertical-text-label [zoom tick]))])))
;; --- Horizontal Rule (Component)
(mf/def horizontal-rule
:mixins #{mf/static mf/reactive}
:render
(fn [own props]
(let [scroll (mf/react refs/workspace-scroll)
zoom (mf/react refs/selected-zoom)
scroll-x (:x scroll)
translate-x (- (- c/canvas-scroll-padding) (:x scroll))]
[:svg.horizontal-rule
{:width c/viewport-width
:height 20}
[:rect {:height 20
:width c/viewport-width}]
[:g {:transform (str "translate(" translate-x ", 0)")}
(horizontal-rule-ticks zoom)]])))
;; --- Vertical Rule (Component)
(mf/def vertical-rule
:mixins #{mf/static mf/reactive}
:render
(fn [own props]
(let [scroll (mf/react refs/workspace-scroll)
zoom (mf/react refs/selected-zoom)
scroll-y (:y scroll)
translate-y (- (- c/canvas-scroll-padding) (:y scroll))]
[:svg.vertical-rule
{:width 20
:height c/viewport-height}
[:g {:transform (str "translate(0, " translate-y ")")}
(vertical-rule-ticks zoom)]
[:rect {:x 0
:y 0
:height 20
:width 20}]])))