All Projects → thi-ng → Color

thi-ng / Color

Licence: apache-2.0
CLJ/CLJS library for color conversion & manipulation

Programming Languages

shell
77523 projects

#+SETUPFILE: src/setup.org #+TITLE: thi.ng/color

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

  • Contents :toc_3_gh:
  • [[#about-the-project][About the project]]
    • [[#overview][Overview]]
    • [[#leiningen-coordinates][Leiningen coordinates]]
      • [[#stable][Stable]]
    • [[#status][Status]]
    • [[#example-usage][Example usage]]
  • [[#namespaces][Namespaces]]
  • [[#tests][Tests]]
  • [[#project-definition][Project definition]]
    • [[#injected-properties][Injected properties]]
    • [[#dependencies][Dependencies]]
      • [[#runtime][Runtime]]
      • [[#development][Development]]
    • [[#leiningen-coordinates][Leiningen coordinates]]
    • [[#building-this-project][Building this project]]
      • [[#testing][Testing]]
      • [[#working-with-the-repl][Working with the REPL]]
    • [[#leiningen-project-file][Leiningen project file]]
    • [[#clojurescript-html-harness][ClojureScript HTML harness]]
    • [[#accessing-library-version-during-runtime][Accessing library version during runtime]]
      • [[#version-namespace][Version namespace]]
    • [[#release-history][Release history]]
    • [[#contributors][Contributors]]
    • [[#license][License]]
  • 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 #+BEGIN_SRC clojure [thi.ng/color "1.4.0"] #+END_SRC

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

#+BEGIN_SRC clojure (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") #+END_SRC

  • Namespaces
  • [[./src/core.org][thi.ng.color.core]]
  • [[./src/gradients.org][thi.ng.color.gradients]]
  • [[./src/presets.org][thi.ng.color.presets]]
  • Tests
  • [[./test/core.org][thi.ng.color.test.core]]
  • Project definition ** Injected properties :noexport:

#+BEGIN_SRC clojure :noweb-ref version 1.4.0 #+END_SRC

#+BEGIN_SRC clojure :exports none :noweb-ref project-url http://thi.ng/color #+END_SRC

#+BEGIN_SRC clojure :exports none :noweb yes :noweb-ref cljs-artefact-path target/color-<>.js #+END_SRC

** Dependencies *** Runtime **** [[https://github.com/clojure/clojure][Clojure]] #+BEGIN_SRC clojure :noweb-ref dep-clj [org.clojure/clojure "1.9.0"] #+END_SRC **** [[https://github.com/clojure/clojurescript][ClojureScript]] #+BEGIN_SRC clojure :noweb-ref dep-cljs [org.clojure/clojurescript "1.10.339"] #+END_SRC **** [[https://github.com/thi-ng/math][thi.ng/math]] #+BEGIN_SRC clojure :noweb-ref dep-math [thi.ng/math "0.3.0"] #+END_SRC **** [[https://github.com/thi-ng/dstruct][thi.ng/dstruct]] #+BEGIN_SRC clojure :noweb-ref dep-dstruct [thi.ng/dstruct "0.2.0"] #+END_SRC **** [[https://github.com/thi-ng/typedarrays/][thi.ng/typedarrays]] #+NAME: dep-arrays #+BEGIN_SRC clojure [thi.ng/typedarrays "0.1.3"] #+END_SRC **** [[https://github.com/thi-ng/strf][thi.ng/strf]] #+BEGIN_SRC clojure :noweb-ref dep-strf [thi.ng/strf "0.2.2"] #+END_SRC **** [[https://github.com/thi-ng/xerror][thi.ng/xerror]] #+BEGIN_SRC clojure :noweb-ref dep-xerror [thi.ng/xerror "0.1.0"] #+END_SRC

*** Development **** [[https://github.com/hugoduncan/criterium][Criterium]] #+BEGIN_SRC clojure :noweb-ref dep-criterium [criterium "0.4.4"] #+END_SRC

**** [[https://github.com/cemerick/clojurescript.test][clojurescript.test]] #+BEGIN_SRC clojure :noweb-ref dep-cljs-test [com.cemerick/clojurescript.test "0.3.3"] #+END_SRC

**** [[https://github.com/emezeske/lein-cljsbuild][Cljsbuild]] #+BEGIN_SRC clojure :noweb-ref dep-cljsbuild [lein-cljsbuild "1.1.7"] #+END_SRC

** Leiningen coordinates

#+BEGIN_SRC clojure :noweb yes :noweb-ref lein-coords [thi.ng/color <>] #+END_SRC

** Building this project

This project is written in a literate programming format and requires [[https://www.gnu.org/software/emacs/][Emacs]] & [[http://orgmode.org][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=):

#+BEGIN_SRC bash git clone https://github.com/thi.ng/color.git cd color ./tangle.sh src/.org test/.org #+END_SRC

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.

#+BEGIN_SRC bash cd babel lein cleantest #+END_SRC

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 :noexport:

#+BEGIN_SRC clojure :tangle babel/project.clj :noweb yes :mkdirp yes :padline no (defproject thi.ng/color "<>" :description "Cross-platform CLJ/CLJS library for color conversion & manipulation." :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"]]])

#+END_SRC

** ClojureScript HTML harness :noexport:

#+BEGIN_SRC html :tangle babel/index.html :noweb yes :mkdirp yes :padline no

<title><> test</title> <script type="text/javascript" src="<>"></script> #+END_SRC

** Accessing library version during runtime

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

#+BEGIN_SRC clojure :noweb yes (use '[thi.ng.color.version])

(prn version) ; "<>" #+END_SRC

*** Version namespace :noexport:

#+BEGIN_SRC clojure :tangle babel/src/thi/ng/color/version.cljc :noweb yes :mkdirp yes :padline no :exports none (ns thi.ng.color.version)

(def version "<>") #+END_SRC

** Release history

| Version | Released | Description | Tagged GH URL | |-----------+------------+-----------------------------------------------------------+-----------------| | 1.2.1 | TBC | add opt gradient ramping | [[https://github.com/thi-ng/color/tree/1.2.1][1.2.1]] | | 1.2.0 | 2016-04-05 | update dstruct dep, refactor IBuffer impls, add tests | [[https://github.com/thi-ng/color/tree/1.2.0][1.2.0]] | | 1.1.2 | 2016-03-28 | add gradient presets | [[https://github.com/thi-ng/color/tree/1.1.2][1.1.2]] | | 1.1.1 | 2016-03-19 | fix dependencies | [[https://github.com/thi-ng/color/tree/1.1.1][1.1.1]] | | 1.1.0 | 2016-03-19 | defrecord impl, protocol updates, optimizations, bugfixes | [[https://github.com/thi-ng/color/tree/1.1.0][1.1.0]] | | 1.0.1 | 2015-12-25 | bugfix yuva & cie1931 rgba conversions | [[https://github.com/thi-ng/color/tree/1.0.1][1.0.1]] | | 1.0.0 | 2015-10-02 | complete rewrite using protocols | [[https://github.com/thi-ng/color/tree/1.0.0][1.0.0]] | | 0.3.1 | 2015-06-21 | add YCbCr & YUV conversion, update deps | [[https://github.com/thi-ng/color/tree/0.3.1][0.3.1]] | | 0.3.0 | 2015-06-15 | gradient ns, HSL/HCY/HCV color space support, bugfixes | [[https://github.com/thi-ng/color/tree/0.3.0][0.3.0]] | | 0.2.0 | 2015-05-26 | no more CLJX, CIE1931 color space support, doc updates | [[https://github.com/thi-ng/color/tree/0.2.0][0.2.0]] | | 0.1.3 | 2015-04-22 | bugfixes, conversion updates | [[https://github.com/thi-ng/color/tree/0.1.3][0.1.3]] | | 0.1.2 | 2015-03-15 | bugfixes | [[https://github.com/thi-ng/color/tree/0.1.2][0.1.2]] | | 0.1.1 | 2015-02-22 | updated presets, added conversions | [[https://github.com/thi-ng/color/tree/0.1.1][0.1.1]] | | 0.1.0 | 2015-01-20 | 1st public release | [[https://github.com/thi-ng/color/tree/0.1.0][0.1.0]] |

** Contributors

| Name | Role | Website | |-----------------+---------------------------------+-------------------------------------------| | [[mailto:[email protected]][Karsten Schmidt]] | initiator & principal developer | http://postspectacular.com, http://thi.ng |

** License

This project is open source and licensed under the [[http://www.apache.org/licenses/LICENSE-2.0][Apache Software License 2.0]].

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].