|
19 | 19 | [renderer.utils.extra :refer [partial-right]]
|
20 | 20 | [renderer.utils.hiccup :as hiccup]
|
21 | 21 | [renderer.utils.map :as map]
|
| 22 | + [renderer.utils.math :as math :refer [Vec2D]] |
22 | 23 | [renderer.utils.path :as path]
|
23 | 24 | [renderer.utils.vec :as vec]))
|
24 | 25 |
|
|
499 | 500 | (set-parent parent-id id)
|
500 | 501 | (update-prop parent-id :children vec/move last-index i))))
|
501 | 502 |
|
| 503 | +(m/=> hovered-svg [:-> App Element]) |
502 | 504 | (defn hovered-svg
|
503 | 505 | [db]
|
504 | 506 | (let [svgs (reverse (root-svgs db))
|
|
507 | 509 | (some #(when (bounds/contained-point? (:bounds %) pointer-pos) %) svgs)
|
508 | 510 | (root db))))
|
509 | 511 |
|
| 512 | +(m/=> translate [:function |
| 513 | + [:-> App Vec2D App] |
| 514 | + [:-> App uuid? Vec2D App]]) |
510 | 515 | (defn translate
|
| 516 | + "Moves elements by a given offset." |
511 | 517 | ([db offset]
|
512 | 518 | (reduce (partial-right translate offset) db (top-ancestor-ids db)))
|
513 | 519 | ([db id offset]
|
514 | 520 | (update-el db id hierarchy/translate offset)))
|
515 | 521 |
|
| 522 | +(m/=> place [:function |
| 523 | + [:-> App Vec2D App] |
| 524 | + [:-> App uuid? Vec2D App]]) |
516 | 525 | (defn place
|
517 |
| - ([db pos] |
518 |
| - (reduce (partial-right place pos) db (top-ancestor-ids db))) |
519 |
| - ([db id pos] |
520 |
| - (update-el db id hierarchy/place pos))) |
| 526 | + "Positions elements to a given global position." |
| 527 | + ([db position] |
| 528 | + (reduce (partial-right place position) db (top-ancestor-ids db))) |
| 529 | + ([db id position] |
| 530 | + (let [el (entity db id) |
| 531 | + center (bounds/center (hierarchy/bounds el)) |
| 532 | + offset (mat/sub position center)] |
| 533 | + (update-el db id hierarchy/translate offset)))) |
521 | 534 |
|
| 535 | +(m/=> scale [:-> App Vec2D Vec2D boolean? App]) |
522 | 536 | (defn scale
|
523 | 537 | [db ratio pivot-point recursive]
|
524 | 538 | (let [ids-to-scale (cond-> (selected-ids db) recursive (set/union (descendant-ids db)))]
|
|
529 | 543 | db
|
530 | 544 | ids-to-scale)))
|
531 | 545 |
|
| 546 | +(def Direction |
| 547 | + [:enum :top :center-vertical :bottom :left :center-horizontal :right]) |
| 548 | + |
| 549 | +(m/=> parent [:function |
| 550 | + [:-> App Direction App] |
| 551 | + [:-> App uuid? Direction App]]) |
532 | 552 | (defn align
|
533 | 553 | ([db direction]
|
534 | 554 | (reduce (partial-right align direction) db (selected-ids db)))
|
|
547 | 567 | :center-horizontal [cx 0]
|
548 | 568 | :right [x2 0])))))
|
549 | 569 |
|
| 570 | +(m/=> ->path [:function |
| 571 | + [:-> App App] |
| 572 | + [:-> App uuid? App]]) |
550 | 573 | (defn ->path
|
| 574 | + "Converts elements to paths." |
551 | 575 | ([db]
|
552 | 576 | (reduce ->path db (selected-ids db)))
|
553 | 577 | ([db id]
|
554 | 578 | (update-el db id element/->path)))
|
555 | 579 |
|
| 580 | +(m/=> stroke->path [:function |
| 581 | + [:-> App App] |
| 582 | + [:-> App uuid? App]]) |
556 | 583 | (defn stroke->path
|
| 584 | + "Converts the stroke of elements to paths." |
557 | 585 | ([db]
|
558 | 586 | (reduce stroke->path db (selected-ids db)))
|
559 | 587 | ([db id]
|
560 | 588 | (update-el db id element/stroke->path)))
|
561 | 589 |
|
| 590 | +(m/=> overlapping-svg [:-> App Bounds App]) |
562 | 591 | (defn overlapping-svg
|
563 | 592 | [db el-bounds]
|
564 | 593 | (let [svgs (reverse (root-svgs db))] ; Reverse to select top svgs first.
|
|
567 | 596 | (some #(when (bounds/intersect? el-bounds (:bounds %)) %) svgs)
|
568 | 597 | (root db))))
|
569 | 598 |
|
570 |
| -(defn create-parent-id |
| 599 | +(m/=> assoc-parent-id [:-> App Element Element]) |
| 600 | +(defn assoc-parent-id |
571 | 601 | [db el]
|
572 | 602 | (cond-> el
|
573 |
| - (not (element/root? el)) |
574 |
| - (assoc :parent (or (:parent el) |
575 |
| - (:id (if (element/svg? el) |
576 |
| - (root db) |
577 |
| - (overlapping-svg db (hierarchy/bounds el)))))))) |
| 603 | + (not (or (element/root? el) (:parent el))) |
| 604 | + (assoc :parent (:id (if (element/svg? el) |
| 605 | + (root db) |
| 606 | + (overlapping-svg db (hierarchy/bounds el))))))) |
578 | 607 |
|
| 608 | +(m/=> create [:-> App map? App]) |
579 | 609 | (defn create
|
580 | 610 | [db el]
|
581 | 611 | (let [id (random-uuid) ; REVIEW: Hard to use a coeffect because of recursion.
|
582 | 612 | new-el (->> (cond-> el (not (string? (:content el))) (dissoc :content))
|
583 | 613 | (map/remove-nils)
|
584 | 614 | (element/normalize-attrs)
|
585 |
| - (create-parent-id db)) |
| 615 | + (assoc-parent-id db)) |
586 | 616 | new-el (merge new-el db/default {:id id})
|
587 | 617 | child-els (-> (entities db (set (:children el))) vals (concat (:content el)))
|
588 | 618 | [x1 y1] (hierarchy/bounds (entity db (:parent new-el)))
|
|
610 | 640 | child-els
|
611 | 641 | (add-children child-els)))))
|
612 | 642 |
|
| 643 | +(m/=> create-default-canvas [:-> App Vec2D App]) |
613 | 644 | (defn create-default-canvas
|
614 | 645 | [db size]
|
615 | 646 | (cond-> db
|
|
0 commit comments