2017-02-24 8 views
0

私は、HTML Canvas要素がいくつかの絶対ピクセルサイズを持つ必要があるという事実を抽象化した試薬コンポーネントを作成しようとしています。むしろ最大解像度で常にキャンバスを使用したいと思っています。試薬キャンバスコンポーネント

最後に、私はこのようなコンポーネントを使用したい:

[Canvas {:width "100%" 
     :height "100%" 
     :render (fn [ctx [w h]] 
        (.fillRect ctx 0 0 (/ w 2) (/ h 2)))}] 

そしてここでは、私のアプローチです:

(defn Canvas [{:keys [width height render]}] 
    (let [state (r/atom {:size nil}) 
     update-size (fn [el] 
         (when el 
         (let [size (get-real-size el) 
           ctx (.getContext el "2d")] 
          (swap! state assoc :size size) 
          (render ctx size))))] 
    (fn [] 
     (let [{:keys [size]} @state] 
     [:canvas {:style {:width width :height height} 
        :ref update-size 
        :width (nth size 0) 
        :height (nth size 1)}])))) 

に対し:キャンバスが正しくレンダリングされるように思わ

(defn get-real-size [el] 
    (let [bb (.getBoundingClientRect el)] 
    [(.-width bb) (.-height bb)])) 

対応するサイズで表示されます。しかし、レンダー機能は何も描画しません。誰かがこれを修正/処理する方法を知っていますか?

答えて

2

あなたが描画を取得しない理由は、コンポーネントがマウントされる前にレンダリングされるためです。これを修正するためには、マウントされた後にもう一度レンダリングを行う必要があります。

ここにあるのはreagent manual explains thisです。ウィンドウの寸法が変更された後の再描画の問題に対する解決策を提示しますが、その解決策もあなたに適用されます。

あなたの場合、アトミック逆参照によって簡単に再レンダリングをトリガーできます。

(defn Canvas [{:keys [width height render]}] 
    (let [state (atom nil)] 
     (reagent/create-class 
      {:reagent-render  (fn [] 
             (let [update-size (fn [el] 
                  (when el 
                   (let [size (get-real-size el) 
                     ctx (.getContext el "2d")] 
                    (swap! state assoc :size size) 
                    (render ctx size))))] 
              (fn [] (let [{:keys [size]} @state] 
                [:canvas {:style {:width width :height height} 
                   :ref update-size 
                   :width (nth size 0) 
                   :height (nth size 1)}])))) 
      :component-did-mount (fn [] (reset! state {:size nil})) 
      }))) 
関連する問題