From e021d074b1c543e425505b643f69399015845394 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sun, 10 Jul 2016 22:10:59 +0300 Subject: [PATCH] Add initial implementation of interactions animations. With inital support for :moveby and :gotourl. --- src/uxbox/main/ui/shapes/circle.cljs | 2 +- src/uxbox/main/ui/shapes/group.cljs | 2 +- src/uxbox/main/ui/shapes/icon.cljs | 2 +- src/uxbox/main/ui/shapes/line.cljs | 2 +- src/uxbox/main/ui/shapes/rect.cljs | 2 +- src/uxbox/main/ui/shapes/text.cljs | 2 +- .../sidebar/options/interactions.cljs | 31 ++++++- src/uxbox/view/ui/viewer/interactions.cljs | 82 +++++++++++++++++++ src/uxbox/view/ui/viewer/nav.cljs | 6 +- src/uxbox/view/ui/viewer/shapes.cljs | 16 ++-- 10 files changed, 125 insertions(+), 22 deletions(-) create mode 100644 src/uxbox/view/ui/viewer/interactions.cljs diff --git a/src/uxbox/main/ui/shapes/circle.cljs b/src/uxbox/main/ui/shapes/circle.cljs index 6834f7db3..c53249c6b 100644 --- a/src/uxbox/main/ui/shapes/circle.cljs +++ b/src/uxbox/main/ui/shapes/circle.cljs @@ -40,7 +40,7 @@ (defn- circle-shape-render [own {:keys [id] :as shape}] - (let [key (str id) + (let [key (str "shape-" id) rfm (geom/transformation-matrix shape) props (select-keys shape [:cx :cy :rx :ry]) attrs (-> (attrs/extract-style-attrs shape) diff --git a/src/uxbox/main/ui/shapes/group.cljs b/src/uxbox/main/ui/shapes/group.cljs index 7885ad9ab..0299e22e1 100644 --- a/src/uxbox/main/ui/shapes/group.cljs +++ b/src/uxbox/main/ui/shapes/group.cljs @@ -61,7 +61,7 @@ (defn- group-shape-render [own {:keys [items id dx dy rotation] :as shape} factory] - (let [key (str "group-" id) + (let [key (str "shape-" id) rfm (geom/transformation-matrix shape) attrs (merge {:id key :key key :transform (str rfm)} (attrs/extract-style-attrs shape) diff --git a/src/uxbox/main/ui/shapes/icon.cljs b/src/uxbox/main/ui/shapes/icon.cljs index 1e65cf7a1..0bc95ccbe 100644 --- a/src/uxbox/main/ui/shapes/icon.cljs +++ b/src/uxbox/main/ui/shapes/icon.cljs @@ -39,7 +39,7 @@ (defn- icon-shape-render [own {:keys [data id] :as shape} factory] - (let [key (str id) + (let [key (str "shape-" id) rfm (geom/transformation-matrix shape) attrs (merge {:id key :key key :transform (str rfm)} (attrs/extract-style-attrs shape) diff --git a/src/uxbox/main/ui/shapes/line.cljs b/src/uxbox/main/ui/shapes/line.cljs index 3ab7a7ad1..c3788b2de 100644 --- a/src/uxbox/main/ui/shapes/line.cljs +++ b/src/uxbox/main/ui/shapes/line.cljs @@ -39,7 +39,7 @@ (defn- line-shape-render [own {:keys [id x1 y1 x2 y2] :as shape}] - (let [key (str id) + (let [key (str "shape-" id) props (select-keys shape [:x1 :x2 :y2 :y1]) attrs (-> (attrs/extract-style-attrs shape) (merge {:id key :key key}) diff --git a/src/uxbox/main/ui/shapes/rect.cljs b/src/uxbox/main/ui/shapes/rect.cljs index 181d85967..2705361f3 100644 --- a/src/uxbox/main/ui/shapes/rect.cljs +++ b/src/uxbox/main/ui/shapes/rect.cljs @@ -40,7 +40,7 @@ (mx/defc rect-shape [{:keys [id x1 y1 x2 y2] :as shape}] - (let [key (str id) + (let [key (str "shape-" id) rfm (geom/transformation-matrix shape) size (geom/size shape) props {:x x1 :y y1 :id key :key key :transform (str rfm)} diff --git a/src/uxbox/main/ui/shapes/text.cljs b/src/uxbox/main/ui/shapes/text.cljs index 0fbdb5207..f383a22b8 100644 --- a/src/uxbox/main/ui/shapes/text.cljs +++ b/src/uxbox/main/ui/shapes/text.cljs @@ -148,7 +148,7 @@ (defn- text-shape-render [own {:keys [id x1 y1 content] :as shape}] - (let [key (str id) + (let [key (str "shape-" id) rfm (geom/transformation-matrix shape) size (geom/size shape) props {:x x1 :y y1 diff --git a/src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs b/src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs index 79a9ac283..bfbc9cbf0 100644 --- a/src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs +++ b/src/uxbox/main/ui/workspace/sidebar/options/interactions.cljs @@ -248,6 +248,34 @@ {:render moveto-input-render :name "moveto-input"})) +;; --- MoveBy Input + +(defn- moveby-input-render + [own form-ref] + (when-not (:moveby-x @form-ref) + (swap! form-ref assoc :moveby-x 0)) + (when-not (:moveby-y @form-ref) + (swap! form-ref assoc :moveby-y 0)) + (html + [:div + [:span "Move to position (px)"] + [:div.row-flex + [:input.input-text + {:placeholder "X" + :on-change (partial on-change form-ref :moveby-x) + :type "number" + :value (:moveby-x @form-ref)}] + [:input.input-text + {:placeholder "Y" + :on-change (partial on-change form-ref :moveby-y) + :type "number" + :value (:moveby-y @form-ref)}]]])) + +(def moveby-input + (mx/component + {:render moveby-input-render + :name "moveby-input"})) + ;; --- Opacity Input (defn- opacity-input-render @@ -459,7 +487,7 @@ [:option {:value ":hide"} "Hide"] [:option {:value ":toggle"} "Toggle"] [:option {:value ":moveto"} "Move to"] - #_[:option {:value ":moveby"} "Move by"] + [:option {:value ":moveby"} "Move by"] [:option {:value ":opacity"} "Opacity"] [:option {:value ":size"} "Size"] [:option {:value ":color"} "Color"] @@ -476,6 +504,7 @@ :rotate (rotate-input form-ref) :size (resize-input form-ref) :moveto (moveto-input form-ref) + :moveby (moveby-input form-ref) :opacity (opacity-input form-ref) nil) diff --git a/src/uxbox/view/ui/viewer/interactions.cljs b/src/uxbox/view/ui/viewer/interactions.cljs new file mode 100644 index 000000000..8ff2d41db --- /dev/null +++ b/src/uxbox/view/ui/viewer/interactions.cljs @@ -0,0 +1,82 @@ +;; 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) 2016 Andrey Antukh + +(ns uxbox.view.ui.viewer.interactions + (:require [uxbox.util.dom :as dom] + [vendor.animejs])) + +(defn- translate-trigger + "Translates the interaction trigger name (keyword) into + approriate dom event name (keyword)." + [trigger] + {:pre [(keyword? trigger)] + :post [(keyword? %)]} + (case trigger + :click :on-click + :hover :on-hover + (throw (ex-info "not supported at this moment" {:trigger trigger})))) + +(defn- translate-ease + "Translates the uxbox ease settings to one + that are compatible with anime.js library." + [ease] + {:pre [(keyword? ease)] + :post [(string? %)]} + (case ease + :easein "easeInCubic" + :easeout "easeOutCubic" + :easeinout "easeInOutCubic" + (name ease))) + +;; --- Interactions to Animation Compilation + +(defn- build-moveby-interaction + [{:keys [element moveby-x moveby-y easing delay duration]}] + (let [opts (clj->js {:targets [(str "#shape-" element)] + :translateX (str moveby-x "px") + :translateY (str moveby-y "px") + :easing (translate-ease easing) + :delay delay + :duration duration + :loop false})] + #(js/anime opts))) + +(defn- build-gotourl-interaction + [{:keys [url]}] + #(set! (.-href js/location) url)) + +(defn- build-interaction + "Given an interaction data structure return + a precompiled animation." + [{:keys [action] :as itx}] + (case action + :moveby (build-moveby-interaction itx) + :gotourl (build-gotourl-interaction itx) + (throw (ex-info "undefined interaction" {:action action})))) + +;; --- Main Api + +(defn- default-callback + "A default user action callback that prevents default event." + [itx event] + (dom/prevent-default event) + (itx)) + +(defn- build-attr + "A reducer function that compiles interaction data structures + into apropriate event handler attributes." + [acc {:keys [trigger] :as interaction}] + (let [evt (translate-trigger trigger) + itx (build-interaction interaction)] + (assoc acc evt (partial default-callback itx)))) + +(defn build-attrs + "Compile a sequence of interactions into a hash-map of event-handlers." + [items] + (reduce build-attr {} items)) + + + diff --git a/src/uxbox/view/ui/viewer/nav.cljs b/src/uxbox/view/ui/viewer/nav.cljs index f4385b0ad..9e5ae8292 100644 --- a/src/uxbox/view/ui/viewer/nav.cljs +++ b/src/uxbox/view/ui/viewer/nav.cljs @@ -6,13 +6,9 @@ ;; Copyright (c) 2016 Juan de la Cruz (ns uxbox.view.ui.viewer.nav - (:require [sablono.core :refer-macros [html]] - [lentes.core :as l] - [rum.core :as rum] - [uxbox.util.mixins :as mx :include-macros true] + (:require [uxbox.util.mixins :as mx :include-macros true] [uxbox.util.rstore :as rs] [uxbox.main.ui.icons :as i] - [uxbox.main.state :as st] [uxbox.view.data.viewer :as dv])) (mx/defc nav diff --git a/src/uxbox/view/ui/viewer/shapes.cljs b/src/uxbox/view/ui/viewer/shapes.cljs index c0781abc7..20bacf3ff 100644 --- a/src/uxbox/view/ui/viewer/shapes.cljs +++ b/src/uxbox/view/ui/viewer/shapes.cljs @@ -5,27 +5,23 @@ ;; Copyright (c) 2016 Andrey Antukh (ns uxbox.view.ui.viewer.shapes - (:require [sablono.core :refer-macros [html]] - [lentes.core :as l] - [rum.core :as rum] - [uxbox.util.mixins :as mx :include-macros true] - [uxbox.util.data :refer (parse-int)] + (:require [uxbox.util.mixins :as mx :include-macros true] [uxbox.main.state :as st] - [uxbox.main.ui.shapes :as uus] - [uxbox.main.ui.icons :as i] [uxbox.main.ui.shapes.rect :refer (rect-shape)] [uxbox.main.ui.shapes.icon :refer (icon-shape)] [uxbox.main.ui.shapes.text :refer (text-shape)] [uxbox.main.ui.shapes.group :refer (group-shape)] [uxbox.main.ui.shapes.line :refer (line-shape)] - [uxbox.main.ui.shapes.circle :refer (circle-shape)])) + [uxbox.main.ui.shapes.circle :refer (circle-shape)] + [uxbox.view.ui.viewer.interactions :as itx :refer (build-attrs)])) ;; --- Interactions Wrapper (mx/defc interactions-wrapper [shape factory] - (let [interactions (:interactions shape)] - [:g (factory shape)])) + (let [interactions (vals (:interactions shape)) + attrs (itx/build-attrs interactions)] + [:g attrs (factory shape)])) ;; --- Shapes