Added anime image search by color

This commit is contained in:
Eduard Urbach 2018-03-21 22:57:06 +01:00
parent 663d93c188
commit aa6ba4c566
6 changed files with 118 additions and 0 deletions

View File

@ -6,6 +6,9 @@ component ExploreAnime(animeList []*arn.Anime, year string, status string, typ s
button.action(data-trigger="click", data-action="hideAddedAnime", title="Hide anime in my collection")
RawIcon("eye-slash")
a.button.ajax(href="/explore/color/any/anime", title="View colors")
RawIcon("paint-brush")
a.button.ajax(href="/genres", title="View genres")
RawIcon("clone")

View File

@ -0,0 +1,69 @@
package explorecolor
import (
"math"
"strconv"
"strings"
"github.com/aerogo/aero"
"github.com/animenotifier/arn"
"github.com/animenotifier/notify.moe/components"
"github.com/animenotifier/notify.moe/utils"
)
// AnimeByAverageColor returns all anime with an image in the given color.
func AnimeByAverageColor(ctx *aero.Context) string {
user := utils.GetUser(ctx)
color := ctx.Get("color")
animes := filterAnimeByColor(color)
arn.SortAnimeByQuality(animes)
return ctx.HTML(components.ExploreColor(animes, color, user))
}
func filterAnimeByColor(colorText string) []*arn.Anime {
if !strings.HasPrefix(colorText, "hsl:") {
return nil
}
colorText = colorText[len("hsl:"):]
parts := strings.Split(colorText, ",")
if len(parts) != 3 {
return nil
}
hue, err := strconv.ParseFloat(parts[0], 64)
if err != nil {
return nil
}
saturation, err := strconv.ParseFloat(parts[1], 64)
if err != nil {
return nil
}
lightness, err := strconv.ParseFloat(parts[2], 64)
if err != nil {
return nil
}
color := arn.HSLColor{
Hue: hue,
Saturation: saturation,
Lightness: lightness,
}
return arn.FilterAnime(func(anime *arn.Anime) bool {
animeColor := anime.Image.AverageColor
hueDifference := color.Hue - animeColor.Hue
saturationDifference := color.Saturation - animeColor.Saturation
lightnessDifference := color.Lightness - animeColor.Lightness
return math.Abs(hueDifference) < 0.05 && math.Abs(saturationDifference) < 0.125 && math.Abs(lightnessDifference) < 0.25
})
}

View File

@ -0,0 +1,18 @@
component ExploreColor(animes []*arn.Anime, color string, user *arn.User)
h1.page-title Explore anime by color
for saturation := 0.75; saturation >= 0.25; saturation -= 0.25
.tabs.color-stripes
for hue := 0.0; hue < 1.0; hue += 0.05
a.tab.color-stripe.action(href=fmt.Sprintf("/explore/color/hsl:%.3f,%.2f,0.5/anime", hue, saturation), data-action="diff", data-trigger="click", data-color=fmt.Sprintf("hsl(%.0f, %.0f%%, 50%%)", hue * 360, saturation * 100))
.explore-anime
if len(animes) == 0
if color == "any"
p.no-data.mountable Please choose a color.
else
p.no-data.mountable No anime found for the given color.
else
p.text-center.mountable= strconv.Itoa(len(animes)) + " anime."
AnimeGrid(animes, user)

View File

@ -0,0 +1,13 @@
.color-stripes
horizontal
justify-content center
margin-bottom 0
.color-stripe
width 2%
height 2rem
padding 0
border 1px solid transparent
&.active
border 1px solid theme-black

View File

@ -26,6 +26,7 @@ import (
"github.com/animenotifier/notify.moe/pages/embed"
"github.com/animenotifier/notify.moe/pages/episode"
"github.com/animenotifier/notify.moe/pages/explore"
"github.com/animenotifier/notify.moe/pages/explore/explorecolor"
"github.com/animenotifier/notify.moe/pages/forum"
"github.com/animenotifier/notify.moe/pages/genre"
"github.com/animenotifier/notify.moe/pages/genres"
@ -75,6 +76,7 @@ func Configure(app *aero.Application) {
l.Page("/", home.Get)
l.Page("/explore", explore.Get)
l.Page("/explore/anime/:year/:status/:type", explore.Filter)
l.Page("/explore/color/:color/anime", explorecolor.AnimeByAverageColor)
l.Page("/login", login.Get)
l.Page("/api", apiview.Get)
// l.Ajax("/dashboard", dashboard.Get)

View File

@ -163,6 +163,7 @@ export class AnimeNotifier {
Promise.resolve().then(() => this.assignActions()),
Promise.resolve().then(() => this.updatePushUI()),
Promise.resolve().then(() => this.dragAndDrop()),
Promise.resolve().then(() => this.colorStripes()),
Promise.resolve().then(() => this.countUp())
])
@ -346,6 +347,18 @@ export class AnimeNotifier {
}
}
colorStripes() {
if(!this.app.currentPath.includes("/explore/color/")) {
return
}
for(let element of findAll("color-stripe")) {
Diff.mutations.queue(() => {
element.style.backgroundColor = element.dataset.color
})
}
}
countUp() {
if(!this.app.currentPath.includes("/paypal/success")) {
return