CLJ/CLJS library for color conversion & manipulation
Shell
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
src
test
.gitignore
LICENSE
README.org
tangle-all.sh
tangle.sh

README.org

thi.ng/color

http://media.thi.ng/color/presets/rainbow1.svg

Contents

About the project

Overview

Cross-platform CLJ/CLJS library for color conversion & manipulation. The library supports any-to-any conversions and color manipulations for the following color spaces:

  • RGBA (floats, packed int24/int32)
  • HSVA
  • HSLA
  • CMYKA
  • HCYA
  • HCVA
  • CIE1931A
  • CSS(A) (hex 3/6-digit & long forms)

The library also provides a protocol wrapper for other, user supplied color spaces to proxy all operations via intermediate RGBA conversions. Users will only need to provide two functions to convert from/to RGBA.

All color types are completely protocol based with optimized implementations for each. The current set of color operations includes:

  • channel accessors for all supported color spaces
  • hue rotation
  • brightness/saturation/alpha adjustments
  • analog/complementary/inverse colors
  • hue matching
  • blending
  • distance calculations in RGB/HSV

Furthermore the library includes namespaces to generate procedural gradients and features 100+ CSS named color & gradient presets as well as D3’s & Cynthia Brewer’s categorical color schemes originally intented for geo mapping and other data visualization applications.

Leiningen coordinates

Stable

[thi.ng/color "1.3.0"]

Note: This library relies on the new conditional reader syntax of recent Clojure & Clojurescript versions and therefore is **not compatible with Clojure versions < 1.7.0

Status

STABLE & under regular development, 170+ tests

Example usage

(require '[thi.ng.color.core :as col])

(col/rgba 1 0 0 0.5)
;; #thi.ng.color.core.RGBA [1.0 0.0 0.0 0.5]

(col/hsva 0.5 1 1)
;; #thi.ng.color.core.HSVA [0.5 1.0 1.0 1.0]

(col/as-cmyka (col/hsva 0.5 1 1))
;; #thi.ng.color.core.CMYKA [1.0 0.0 0.0 0.0 1.0]

;; use deref to obtain the wrapped color values
@(col/as-css (col/hsla 1/6 1 0.5 0.25))
;; "hsla(60,100%,50%,0.25)"

;; parse CSS colors into any target space
@(col/as-rgba (col/css "hsla(60,100%,50%,0.25)"))
;; [0.9999999999999998 1.0 0.0 0.25]

(= 0xffff00 @(col/as-int24 (col/css "hsla(60,100%,50%,0.25)")))

;; compact CSS colors
@(-> "hsla(60,100%,50%,0.25)" col/css col/as-int24 col/as-css)
;; "#ffff00"

;; create controlled color variations (e.g. to create hover state colors)
@(-> (col/css "#f04") (col/analog 0.0 -0.2 0.4) col/as-int24 col/as-css)
"#ff3369"

@(-> (col/rgba 1 0 0.25 0.8) (col/random-analog 0.05 0.1 0.2) col/as-css)
;; "rgba(255,8,63,0.8)"

;; All color types implement the IIinterpolate protocol defined in thi.ng.math.core (1.1.0+ only)
;; For previous versions use (col/blend ...) (same API as m/mix)
(require '[thi.ng.math.core :as m])
;; blend with any color space (result is in color space of first color)
(m/mix (col/hsva 0 1 1) (col/rgba 0 1 0 0.5) 0.5)
;; #thi.ng.color.core.HSVA [0.16666666666666666 1.0 1.0 0.75]

;; sort colors by proximity to a target color
(->> (repeatedly 10 col/random-rgb)
     (sort-by #(col/dist-hsv col/RED %)) ;; use HSV distance
     (map (comp deref col/as-css col/as-int24)))
;; ("#d8756c" "#ca6709" "#f67e9c" "#bf984e" "#6e400d" "#d602af" "#c52fd2" "#93759d" "#3710d1" "#06a1c3")

Namespaces

Tests

Project definition

Injected properties

1.3.0

Dependencies

Runtime

Clojure

[org.clojure/clojure "1.9.0"]

ClojureScript

[org.clojure/clojurescript "1.10.339"]

thi.ng/math

[thi.ng/math "0.2.1"]

thi.ng/dstruct

[thi.ng/dstruct "0.2.0"]

thi.ng/typedarrays

[thi.ng/typedarrays "0.1.3"]

thi.ng/strf

[thi.ng/strf "0.2.2"]

thi.ng/xerror

[thi.ng/xerror "0.1.0"]

Development

Criterium

[criterium "0.4.4"]

clojurescript.test

[com.cemerick/clojurescript.test "0.3.3"]

Cljsbuild

[lein-cljsbuild "1.1.7"]

Leiningen coordinates

[thi.ng/color <<version>>]

Building this project

This project is written in a literate programming format and requires Emacs & Org-mode to generate usable source code. Assuming both tools are installed, the easiest way to generate a working project is via command line (make sure emacs is on your path or else edit its path in tangle.sh):

git clone https://github.com/thi.ng/color.git
cd color
./tangle.sh src/*.org test/*.org

Tangling is the process of extracting & combining source blocks from .org files into an actual working project/source tree. Once tangling is complete, you can cd into the generated project directory (babel) and then use lein as usual.

Testing

The project.clj file defines an alias to trigger a complete build & tests for both CLJ & CLJS versions.

cd babel
lein cleantest

To build the Clojurescript version simply run lein cljsbuild test from the same directory. A small HTML harness for the resulting JS file is also located in that folder (babel/index.html), allowing for further experimentation in the browser.

Working with the REPL

Editing code blocks or files in Org-mode, then re-loading & testing changes is quite trivial. Simply launch a REPL (via lein or Emacs) as usual. Everytime you’ve made changes to an .org file, re-tangle it from Emacs (C-c C-v t) or tangle.sh, then reload the namespace in the REPL via (require 'thi.ng.color... :reload) or similar.

Leiningen project file

(defproject thi.ng/color "<<version>>"
  :description  "Cross-platform CLJ/CLJS library for color conversion & manipulation."
  :url          "<<project-url>>"
  :license      {:name "Apache Software License 2.0"
                 :url "http://www.apache.org/licenses/LICENSE-2.0"
                 :distribution :repo}
  :scm          {:name "git"
                 :url  "https://github.com/thi-ng/color"}

  :min-lein-version "2.4.0"

  :dependencies [<<dep-clj>>
                 <<dep-cljs>>
                 <<dep-math>>
                 <<dep-dstruct>>
                 <<dep-arrays>>
                 <<dep-strf>>
                 <<dep-xerror>>]

  :profiles     {:dev {:dependencies [<<dep-criterium>>]
                       :plugins      [<<dep-cljsbuild>>
                                      <<dep-cljs-test>>]
                       :global-vars {*warn-on-reflection* true}
                       :jvm-opts ^:replace []
                       :aliases {"cleantest" ["do" "clean," "test," "cljsbuild" "test"]}}}

  :cljsbuild    {:builds [{:source-paths ["src" "test"]
                           :id "simple"
                           :compiler {:output-to "<<cljs-artefact-path>>"
                                      :optimizations :whitespace
                                      :pretty-print true}}]
                 :test-commands {"unit-tests" ["phantomjs" :runner "<<cljs-artefact-path>>"]}}

  :pom-addition [:developers [:developer
                              [:name "Karsten Schmidt"]
                              [:url "http://postspectacular.com"]
                              [:timezone "0"]]])

ClojureScript HTML harness

<!DOCTYPE html>
<html lang="en">
  <head>
    <title><<lein-coords>> test</title>
  </head>
  <body>
    <script type="text/javascript" src="<<cljs-artefact-path>>"></script>
  </body>
</html>

Accessing library version during runtime

The autogenerated namespace thi.ng.color.version contains a single symbol version holding the version string defined above:

(use '[thi.ng.color.version])

(prn version)
; "<<version>>"

Version namespace

Release history

VersionReleasedDescriptionTagged GH URL
1.2.1TBCadd opt gradient ramping1.2.1
1.2.02016-04-05update dstruct dep, refactor IBuffer impls, add tests1.2.0
1.1.22016-03-28add gradient presets1.1.2
1.1.12016-03-19fix dependencies1.1.1
1.1.02016-03-19defrecord impl, protocol updates, optimizations, bugfixes1.1.0
1.0.12015-12-25bugfix yuva & cie1931 rgba conversions1.0.1
1.0.02015-10-02complete rewrite using protocols1.0.0
0.3.12015-06-21add YCbCr & YUV conversion, update deps0.3.1
0.3.02015-06-15gradient ns, HSL/HCY/HCV color space support, bugfixes0.3.0
0.2.02015-05-26no more CLJX, CIE1931 color space support, doc updates0.2.0
0.1.32015-04-22bugfixes, conversion updates0.1.3
0.1.22015-03-15bugfixes0.1.2
0.1.12015-02-22updated presets, added conversions0.1.1
0.1.02015-01-201st public release0.1.0

Contributors

NameRoleWebsite
Karsten Schmidtinitiator & principal developerhttp://postspectacular.com, http://thi.ng

License

This project is open source and licensed under the Apache Software License 2.0.