This repository was archived by the owner on Jul 19, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
Add Hashvatars #298
Merged
Merged
Add Hashvatars #298
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
module Color.Harmony exposing (..) | ||
|
||
import Color exposing (Color) | ||
import List.Extra as ListE | ||
|
||
|
||
harmonizesWith : Color -> List Color | ||
harmonizesWith color = | ||
let | ||
complementary_ = | ||
complementary color | ||
|
||
( analogousA, analogousB ) = | ||
analogous color | ||
|
||
( triadicA, triadicB ) = | ||
triadic color | ||
|
||
( splitA, splitB ) = | ||
splitComplementary color | ||
|
||
( squareA, squareB, squareC ) = | ||
square color | ||
|
||
( tetridicA, tetridicB, tetridicC ) = | ||
tetridic color | ||
|
||
harmonizesWith_ = | ||
[ complementary_ | ||
, analogousA | ||
, analogousB | ||
, triadicA | ||
, triadicB | ||
, splitA | ||
, splitB | ||
, squareA | ||
, squareB | ||
, squareC | ||
, tetridicA | ||
, tetridicB | ||
, tetridicC | ||
] | ||
in | ||
ListE.uniqueBy Color.toCssString harmonizesWith_ | ||
|
||
|
||
{-| RGB Difference <https://en.wikipedia.org/wiki/Color_difference> - alpha is disregarded | ||
-} | ||
difference : Color -> Color -> Float | ||
difference a b = | ||
let | ||
a_ = | ||
toRgb255 a | ||
|
||
b_ = | ||
toRgb255 b | ||
|
||
sum = | ||
toFloat (((a_.red - b_.red) ^ 2) + ((a_.blue - b_.blue) ^ 2) + ((a_.green - b_.green) ^ 2)) | ||
in | ||
sqrt sum | ||
|
||
|
||
toRgb255 : Color -> { red : Int, green : Int, blue : Int } | ||
toRgb255 c = | ||
let | ||
rgba = | ||
Color.toRgba c | ||
in | ||
{ red = floor (rgba.red * 255) | ||
, green = floor (rgba.red * 255) | ||
, blue = floor (rgba.blue * 255) | ||
} | ||
|
||
|
||
{-| Opposites on the color wheel | ||
-} | ||
complementary : Color -> Color | ||
complementary color = | ||
hueAdd 180 color | ||
|
||
|
||
{-| Adjacent colors on the color wheel | ||
-} | ||
analogous : Color -> ( Color, Color ) | ||
analogous color = | ||
( hueAdd 30 color | ||
, hueSubtract 30 color | ||
) | ||
|
||
|
||
triadic : Color -> ( Color, Color ) | ||
triadic color = | ||
( hueAdd 120 color | ||
, hueAdd 240 color | ||
) | ||
|
||
|
||
splitComplementary : Color -> ( Color, Color ) | ||
splitComplementary color = | ||
( hueAdd 150 color | ||
, hueAdd 210 color | ||
) | ||
|
||
|
||
square : Color -> ( Color, Color, Color ) | ||
square color = | ||
( hueAdd 90 color | ||
, hueAdd 180 color | ||
, hueAdd 270 color | ||
) | ||
|
||
|
||
tetridic : Color -> ( Color, Color, Color ) | ||
tetridic color = | ||
( hueAdd 60 color | ||
, hueAdd 180 color | ||
, hueAdd 240 color | ||
) | ||
|
||
|
||
|
||
-- Internal Helpers | ||
|
||
|
||
hueAdd : Int -> Color -> Color | ||
hueAdd num color = | ||
let | ||
hsla = | ||
Color.toHsla color | ||
|
||
hue = | ||
hsla.hue | ||
|> toAngle | ||
|> (+) num | ||
|> wrap360 | ||
|> toPt | ||
in | ||
Color.fromHsla { hsla | hue = hue } | ||
|
||
|
||
hueSubtract : Int -> Color -> Color | ||
hueSubtract num color = | ||
let | ||
hsla = | ||
Color.toHsla color | ||
|
||
hue = | ||
hsla.hue | ||
|> toAngle | ||
|> (-) num | ||
|> wrap360 | ||
|> toPt | ||
in | ||
Color.fromHsla { hsla | hue = hue } | ||
|
||
|
||
toAngle : Float -> Int | ||
toAngle pt = | ||
let | ||
a = | ||
floor (pt * 360) | ||
in | ||
if a > 360 then | ||
360 - (360 - a) | ||
|
||
else | ||
a | ||
|
||
|
||
toPt : Int -> Float | ||
toPt ang = | ||
toFloat ang / 360 | ||
|
||
|
||
wrap360 : Int -> Int | ||
wrap360 h = | ||
let | ||
x = | ||
modBy 360 h | ||
in | ||
if x < 0 then | ||
x + 360 | ||
|
||
else | ||
x |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
module Hashvatar exposing (..) | ||
|
||
import Hash exposing (Hash) | ||
import Hashvatar.HexGrid as HexGrid | ||
import Html exposing (Html, div) | ||
import Html.Attributes exposing (class) | ||
import List.Extra as ListE | ||
import String.Extra exposing (break) | ||
import UI.Color as Color exposing (Color) | ||
|
||
|
||
view : Hash -> Html msg | ||
view hash = | ||
let | ||
raw = | ||
hash |> Hash.toString |> String.replace "#" "" | ||
|
||
numSlots = | ||
5 | ||
|
||
partLength = | ||
String.length raw // numSlots | ||
|
||
parts = | ||
break partLength raw | ||
|
||
toCharCodeSum str = | ||
str | ||
|> String.toList | ||
|> List.foldl (\c acc -> acc + Char.toCode c) 0 | ||
|
||
grid = | ||
parts | ||
|> List.map toCharCodeSum | ||
|> toGrid | ||
|> Maybe.withDefault HexGrid.empty | ||
in | ||
div [ class "hashvatar" ] | ||
[ HexGrid.view grid | ||
] | ||
|
||
|
||
|
||
-- Helpers | ||
|
||
|
||
getIn : Int -> List Color -> Maybe Color | ||
getIn unmoddedIdx colors_ = | ||
ListE.getAt (modBy (List.length colors_) unmoddedIdx) colors_ | ||
|
||
|
||
toGrid : List Int -> Maybe HexGrid.HexGrid | ||
toGrid slots = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function feels a bit gnarly. Its mostly due to having to deal with optionality when getting elements in the list by index, even though we know the size of the list with a guarantee. |
||
let | ||
selectBg grid_ = | ||
let | ||
background = | ||
getIn grid_.background Color.darkNonGrays | ||
in | ||
Maybe.map | ||
(\bg -> | ||
{ background = bg | ||
, tendrils = grid_.tendrils | ||
, cell1 = grid_.cell1 | ||
, cell2 = grid_.cell2 | ||
, cell3 = grid_.cell3 | ||
} | ||
) | ||
background | ||
|
||
selectTendrils grid_ = | ||
let | ||
tendrils = | ||
getIn grid_.tendrils (Color.harmonizesWith grid_.background) | ||
in | ||
Maybe.map | ||
(\tr -> | ||
{ background = grid_.background | ||
, tendrils = tr | ||
, cell1 = grid_.cell1 | ||
, cell2 = grid_.cell2 | ||
, cell3 = grid_.cell3 | ||
} | ||
) | ||
tendrils | ||
|
||
selectCells grid_ = | ||
Maybe.map3 | ||
(\cell1 cell2 cell3 -> | ||
{ background = grid_.background | ||
, tendrils = grid_.tendrils | ||
, cell1 = cell1 | ||
, cell2 = cell2 | ||
, cell3 = cell3 | ||
} | ||
) | ||
(getIn grid_.cell1 (Color.harmonizesWith grid_.background)) | ||
(getIn grid_.cell2 (Color.harmonizesWith grid_.background)) | ||
(getIn grid_.cell3 (Color.harmonizesWith grid_.background)) | ||
in | ||
Maybe.map5 | ||
(\background tendrils cell1 cell2 cell3 -> | ||
{ background = background | ||
, tendrils = tendrils | ||
, cell1 = cell1 | ||
, cell2 = cell2 | ||
, cell3 = cell3 | ||
} | ||
) | ||
(ListE.getAt 0 slots) | ||
(ListE.getAt 1 slots) | ||
(ListE.getAt 2 slots) | ||
(ListE.getAt 3 slots) | ||
(ListE.getAt 4 slots) | ||
|> Maybe.andThen selectBg | ||
|> Maybe.andThen selectTendrils | ||
|> Maybe.andThen selectCells |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its not the most efficient thing to do every time we want to render an avatar, but realistically we wont have hundreds on a page at the same time.