1
0
Fork 0
mirror of https://github.com/heyarne/airsonic-ui.git synced 2026-05-07 02:33:39 +02:00

Implement responsive generated covers with SVG

This commit is contained in:
Arne Schlüter 2019-01-23 12:21:00 +01:00
commit 3de5560907
2 changed files with 18 additions and 27 deletions

View file

@ -1,7 +1,6 @@
(ns airsonic-ui.views.cover (ns airsonic-ui.views.cover
(:require [re-frame.core :refer [subscribe]] (:require [re-frame.core :refer [subscribe]]
[airsonic-ui.subs :as subs] [airsonic-ui.subs :as subs]
[airsonic-ui.components.highres-canvas.views :refer [canvas]]
["@hugojosefson/color-hash" :as ColorHash])) ["@hugojosefson/color-hash" :as ColorHash]))
(def color-hash (ColorHash.)) (def color-hash (ColorHash.))
@ -10,36 +9,28 @@
(str "hsl(" h "," (* 100 s) "%," (* 100 l) "%)")) (str "hsl(" h "," (* 100 s) "%," (* 100 l) "%)"))
(defn palette (defn palette
"Generate a hsl palette of two colors that's unique for a given item" "Generate a unique hsl palette of two colors"
[item] [identifier]
(let [identifier (str (:artistId item) "-" (or (:albumId item) (:id item))) (let [[h s l] (js->clj (.hsl color-hash identifier))]
[h s l] (js->clj (.hsl color-hash identifier))]
[(hsl->css h s l) [(hsl->css h s l)
(hsl->css (mod (+ h (* h 0.3) 10) 360) s l)])) (hsl->css (mod (+ h (* h 0.3) 10) 360) s l)]))
(defn generate-cover [ctx item]
(let [[a b] (palette item)
size (.. ctx -canvas -offsetWidth)
pad (* 0.02 size)
gradient (doto (.createLinearGradient ctx pad 0 (- size pad) size)
(.addColorStop 0 a)
(.addColorStop 1 b))]
(set! (.. ctx -canvas -height) (.. ctx -canvas -width))
(set! (.. ctx -canvas -style -height) (.. ctx -canvas -style -width))
;; we have to re-scale everything because resizing messes with the content
(.scale ctx (.-devicePixelRatio js/window) (.-devicePixelRatio js/window))
(set! (.-fillStyle ctx) gradient)
(.fillRect ctx 0 0 (.. ctx -canvas -width) (.. ctx -canvas -height))))
(defn missing-cover (defn missing-cover
[item size] [item size]
[canvas {:class "missing-cover" (let [identifier (str (:artistId item) "-" (or (:albumId item) (:id item)))
:draw #(generate-cover % item)}]) [color-a color-b] (palette identifier)]
[:svg.missing-cover {:viewBox "0 0 256 256"
:xmlns "http://www.w3.org/2000/svg"}
[:defs [:linearGradient {:id (str "cover-gradient-" identifier)
:x1 0, :y1 0,
:x2 1, :y2 1}
[:stop {:offset "2%", :stop-color color-a}]
[:stop {:offset "98%", :stop-color color-b}]]]
[:rect {:x 0, :y 0, :width 256, :height 256
:fill (str "url(#cover-gradient-" identifier ")")}]]))
(defn has-cover? [item] (defn has-cover? [item]
(:coverArt item)) (some? (:coverArt item)))
;; FIXME: The direct dependency on these subs is a bit ugly
(defn cover (defn cover
[item size] [item size]

View file

@ -164,15 +164,15 @@
&.is-48x48 .missing-cover &.is-48x48 .missing-cover
width: 48px width: 48px
height: 48px height: auto
&.is-128x128 .missing-cover &.is-128x128 .missing-cover
width: 128px width: 128px
height: 128px height: auto
&.is-256x256 .missing-cover &.is-256x256 .missing-cover
width: 256px width: 256px
height: 256px height: auto
// occurs in album detail view // occurs in album detail view
.table .table