首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >跟踪鼠标和渲染点在屏幕上的结束符/试剂?

跟踪鼠标和渲染点在屏幕上的结束符/试剂?
EN

Stack Overflow用户
提问于 2019-08-26 08:22:11
回答 1查看 522关注 0票数 1

我对结束语很陌生,也许这是一个微不足道的问题,但我还没有找到答案。

我期待着实现一个clojurescript来跟踪鼠标并在鼠标位置呈现一个点,如下所示:

https://jsbin.com/gejuz/1/edit?html,output

Js代码:

代码语言:javascript
复制
function() {
  "use strict";

  document.onmousemove = handleMouseMove;
  function handleMouseMove(event) {
  var dot, eventDoc, doc, body, pageX, pageY;

  event = event || window.event; // IE-ism

  // If pageX/Y aren't available and clientX/Y
  // are, calculate pageX/Y - logic taken from jQuery
        // Calculate pageX/Y if missing and clientX/Y available
  if (event.pageX == null && event.clientX != null) {
    eventDoc = (event.target && event.target.ownerDocument) || document;
    doc = eventDoc.documentElement;
    body = eventDoc.body;

    event.pageX = event.clientX +
      (doc && doc.scrollLeft || body && body.scrollLeft || 0) -
      (doc && doc.clientLeft || body && body.clientLeft || 0);
    event.pageY = event.clientY +
      (doc && doc.scrollTop  || body && body.scrollTop  || 0) -
      (doc && doc.clientTop  || body && body.clientTop  || 0 );
  }

  // Add a dot to follow the cursor
  dot = document.createElement('div');
  dot.className = "dot";
  dot.style.left = event.pageX + "px";
  dot.style.top = event.pageY + "px";
  document.body.appendChild(dot);
}

到目前为止,我确实获得了鼠标坐标(多亏了这个问题Tracking mouse in clojurescript / reagent / reagi?)。但是我没有在网页上渲染这个点。

文本代码:

代码语言:javascript
复制
(def mouse-coordinates (reagent/atom {:x 100 :y 100}))

(defn dot [x y]
  [:div {:style {:left (str x "px")
                 :top (str y "px")
                 :width "2px"
                 :height "2px"
                 :background-clor "black"
                 :position "absolute"}}])

(def do-dot (reagent/reactify-component dot))

(defn mouse-move []
  [:body
   {:onMouseMove (fn [event]
                   (swap! mouse-coordinates assoc :x (.-clientX event))
                   (swap! mouse-coordinates assoc :y (.-clientY event))
                   (reagent/create-element do-dot
                                           #js{:x (int (:x @mouse-coordinates))
                                               :y (int (:y @mouse-coordinates))})
                   )}
   [:p "x: " (int (:x @mouse-coordinates))]
   [:p "y: " (int (:y @mouse-coordinates))]
   ])


(reagent/render-component [mouse-move]
                          (. js/document (getElementById "app")))

任何帮助都是非常感谢的。提前谢谢你。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-26 21:39:24

与在onMouseMove事件中创建元素不同,您可以将dot组件作为呈现代码的一部分。它将获取对reagent/atom的更改,就像两个p元素所做的那样:

代码语言:javascript
复制
   [:p "x: " (int (:x @mouse-coordinates))]
   [:p "y: " (int (:y @mouse-coordinates))]
   [dot (int (:x @mouse-coordinates)) (int (:y @mouse-coordinates))]

还有一个错误::background-clor -> :background-color。这两个变化应该足以使点出现。

还有一些其他的事情可以帮助简化代码:

如果传入数字,style属性将默认为像素。

因此,可以这样编写dot组件:

代码语言:javascript
复制
(defn dot [x y]
  [:div {:style {:left             x
                 :top              y
                 :width            2
                 :height           2
                 :background-color "black"
                 :position         "absolute"}}])

reset!swap!

  • 由于mouse-coordinates具有非常特定的用途,所以在onMouseMove事件中使用reset!而不是swap!更简洁:
代码语言:javascript
复制
(reset! mouse-coordinates {:x (.-clientX event) :y (.-clientY event)})

以地图形式传递组件道具

代码语言:javascript
复制
(defn dot [{:keys [x y]}]
  ...)

[dot @mouse-coordinates]

最后的代码看起来如下所示:

代码语言:javascript
复制
(def mouse-coordinates (reagent/atom {:x 100 :y 100}))

(defn dot [{:keys [x y]}]
  [:div {:style {:left             x
                 :top              y
                 :width            2
                 :height           2
                 :background-color "black"
                 :position         "absolute"}}])

(defn mouse-move []
  [:body
   {:onMouseMove (fn [event]
                   (reset! mouse-coordinates {:x (.-clientX event) :y (.-clientY event)}))}
   [:p "x: " (:x @mouse-coordinates)]
   [:p "y: " (:y @mouse-coordinates)]
   [dot @mouse-coordinates]])

UPDATE:当我第一次回答这个问题时,我没有意识到每个点都应该是持久的。下面是关于如何实现这一目标的更新代码(附带注释):

使用坐标集合

代码语言:javascript
复制
(def mouse-coordinates (r/atom []))

(defn dot [{:keys [x y]}]
  [:div {:style {:left             x
                 :top              y
                 :width            2
                 :height           2
                 :background-color "black"
                 :position         "absolute"}}])

(defn mouse-move []
  [:div
   {:onMouseMove (fn [event]
                   (let [x (.-clientX event)
                         y (.-clientY event)
                         ;; If there's already a dot in an identical location, don't add it. This saves unnecessary work and
                         ;; means we can use [x y] as our unique key for our collection.
                         coords-already-exist? (not (empty? (filter #(and (= (:x %) x) (= (:y %) y)) @mouse-coordinates)))]
                     (when-not coords-already-exist?
                       ;; conj the new coordinate to the collection.
                       (swap! mouse-coordinates #(conj % {:x (.-clientX event) :y (.-clientY event)})))))}
   [:p "x: " (:x @mouse-coordinates)]
   [:p "y: " (:y @mouse-coordinates)]
   ;; Loop through the coordinates.
   (for [{:keys [x y]} @mouse-coordinates]
     [dot
      ;; Important: we give each dot a unique key.
      {:key [x y]
       :x   x
       :y   y}])])

正如注释中提到的,呈现集合的重要之处在于为每个项目提供一个唯一的键。这意味着在创建新的坐标时,React知道添加一个新的子元素,而不是重新呈现每个dot。更多信息可以在下面的React文档中找到:https://reactjs.org/docs/lists-and-keys.html#keys

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57654246

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档