From a32254436d7a41aeb985163ef0ed911ed88e5a51 Mon Sep 17 00:00:00 2001 From: Jiang-Red <1343396474@qq.com> Date: Fri, 11 Oct 2024 23:15:07 +0800 Subject: [PATCH 1/5] new style --- rank.go | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 rank.go diff --git a/rank.go b/rank.go new file mode 100644 index 0000000..72a5323 --- /dev/null +++ b/rank.go @@ -0,0 +1,116 @@ +package rendercard + +import ( + "image" + "image/color" + "strconv" + "sync" + + "github.com/FloatTech/gg" +) + +// DrawRankingCard ... +func DrawRankingCard(fontdata []byte, title string, toplefttext, bottomlefttext, righttext []string, avatars []image.Image) (img image.Image, err error) { + line := len(avatars) + const w = 672 + h := 64 + (80+14)*line + 20 - 14 + canvas := gg.NewContext(w, h) + canvas.SetRGBA255(255, 255, 255, 255) + canvas.Clear() + + ac := gg.NewLinearGradient(16, float64(h)/2, w-16, float64(h)/2) + ac.AddColorStop(0, color.NRGBA{255, 255, 255, 95}) + ac.AddColorStop(0.167, color.NRGBA{255, 255, 255, 127}) + ac.AddColorStop(0.334, color.NRGBA{255, 255, 255, 159}) + ac.AddColorStop(0.5, color.NRGBA{255, 255, 255, 255}) + ac.AddColorStop(1, color.NRGBA{255, 255, 255, 255}) + + cardh, cardw := 80.0, 640.0 + cardspac := 14.0 + hspac := 64.0 + + wg := &sync.WaitGroup{} + wg.Add(line) + cardimgs := make([]image.Image, line) + for i := 0; i < line; i++ { + go func(i int) { + defer wg.Done() + card := gg.NewContext(w, h) + + card.NewSubPath() + + card.MoveTo(16+cardh/2, hspac+(cardspac+cardh)*float64(i)) + + card.LineTo(16+cardw-16, hspac+(cardspac+cardh)*float64(i)) + card.DrawArc(16+cardw-16, hspac+(cardspac+cardh)*float64(i)+16, 16, gg.Radians(-90), gg.Radians(0)) + card.LineTo(16+cardw, hspac+(cardspac+cardh)*float64(i)+cardh-16) + card.DrawArc(16+cardw-16, hspac+(cardspac+cardh)*float64(i)+cardh-16, 16, gg.Radians(0), gg.Radians(90)) + card.LineTo(16+cardh/2, hspac+(cardspac+cardh)*float64(i)+cardh) + + card.DrawArc(16+cardh/2, hspac+(cardspac+cardh)*float64(i)+cardh-cardh/2, cardh/2, gg.Radians(90), gg.Radians(270)) + + card.ClosePath() + + card.ClipPreserve() + + avatar := avatars[i] + + card.ScaleAbout(cardw/2/float64(avatar.Bounds().Dx()), cardw/2/float64(avatar.Bounds().Dy()), 16, hspac+(cardspac+cardh)*float64(i)+cardh/2) + + card.DrawImageAnchored(avatar, 16, int(hspac+(cardspac+cardh)*float64(i)+cardh/2), 0, 0.5) + card.Identity() + card.ResetClip() + + card.SetFillStyle(ac) + card.FillPreserve() + + card.SetRGBA255(0, 0, 0, 255) + card.Stroke() + + card.DrawCircle(16+10+30, hspac+(cardspac+cardh)*float64(i)+cardh/2, 30) + card.ClipPreserve() + card.ScaleAbout(60.0/float64(avatar.Bounds().Dx()), 60.0/float64(avatar.Bounds().Dy()), 16+10+30, hspac+(cardspac+cardh)*float64(i)+cardh/2) + card.DrawImageAnchored(avatar, 16+10+30, int(hspac+(cardspac+cardh)*float64(i)+cardh/2), 0.5, 0.5) + card.Identity() + + card.ResetClip() + card.Stroke() + + card.SetRGB255(RandJPColor()) + card.DrawCircle(w-16-8-25, hspac+(cardspac+cardh)*float64(i)+cardh/2, 25) + card.Fill() + cardimgs[i] = card.Image() + }(i) + } + + canvas.SetRGBA255(0, 0, 0, 255) + canvas.ParseFontFace(fontdata, 32) + canvas.DrawStringAnchored(title, w/2, 64/2, 0.5, 0.5) + + canvas.ParseFontFace(fontdata, 20) + wg.Wait() + for i := 0; i < 10; i++ { + canvas.DrawImage(cardimgs[i], 0, 0) + canvas.DrawStringAnchored(toplefttext[i], 16+10+60+10, hspac+(cardspac+cardh)*float64(i)+cardh*3/8, 0, 0.5) + } + + canvas.SetRGBA255(63, 63, 63, 255) + canvas.ParseFontFace(fontdata, 12) + for i := 0; i < 10; i++ { + canvas.DrawStringAnchored(bottomlefttext[i], 16+10+60+10, hspac+(cardspac+cardh)*float64(i)+cardh*5/8, 0, 0.5) + } + canvas.SetRGBA255(0, 0, 0, 255) + canvas.ParseFontFace(fontdata, 24) + for i := 0; i < 10; i++ { + canvas.DrawStringAnchored(righttext[i], w-16-8-50-8, hspac+(cardspac+cardh)*float64(i)+cardh/2, 1, 0.5) + } + + canvas.SetRGBA255(255, 255, 255, 255) + canvas.ParseFontFace(fontdata, 28) + for i := 0; i < 10; i++ { + canvas.DrawStringAnchored(strconv.Itoa(i+1), w-16-8-25, hspac+(cardspac+cardh)*float64(i)+cardh/2, 0.5, 0.5) + } + + img = canvas.Image() + return +} From 1da3061e5fb3c51419f82d24d4100f641b1574c9 Mon Sep 17 00:00:00 2001 From: Jiang-Red <1343396474@qq.com> Date: Fri, 11 Oct 2024 23:17:57 +0800 Subject: [PATCH 2/5] make lint happy --- rank.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/rank.go b/rank.go index 72a5323..36b44d6 100644 --- a/rank.go +++ b/rank.go @@ -87,7 +87,10 @@ func DrawRankingCard(fontdata []byte, title string, toplefttext, bottomlefttext, canvas.ParseFontFace(fontdata, 32) canvas.DrawStringAnchored(title, w/2, 64/2, 0.5, 0.5) - canvas.ParseFontFace(fontdata, 20) + err = canvas.ParseFontFace(fontdata, 20) + if err != nil { + return + } wg.Wait() for i := 0; i < 10; i++ { canvas.DrawImage(cardimgs[i], 0, 0) @@ -95,18 +98,27 @@ func DrawRankingCard(fontdata []byte, title string, toplefttext, bottomlefttext, } canvas.SetRGBA255(63, 63, 63, 255) - canvas.ParseFontFace(fontdata, 12) + err = canvas.ParseFontFace(fontdata, 12) + if err != nil { + return + } for i := 0; i < 10; i++ { canvas.DrawStringAnchored(bottomlefttext[i], 16+10+60+10, hspac+(cardspac+cardh)*float64(i)+cardh*5/8, 0, 0.5) } canvas.SetRGBA255(0, 0, 0, 255) - canvas.ParseFontFace(fontdata, 24) + err = canvas.ParseFontFace(fontdata, 24) + if err != nil { + return + } for i := 0; i < 10; i++ { canvas.DrawStringAnchored(righttext[i], w-16-8-50-8, hspac+(cardspac+cardh)*float64(i)+cardh/2, 1, 0.5) } canvas.SetRGBA255(255, 255, 255, 255) - canvas.ParseFontFace(fontdata, 28) + err = canvas.ParseFontFace(fontdata, 28) + if err != nil { + return + } for i := 0; i < 10; i++ { canvas.DrawStringAnchored(strconv.Itoa(i+1), w-16-8-25, hspac+(cardspac+cardh)*float64(i)+cardh/2, 0.5, 0.5) } From 1ecb6d087c6c41974c859fffc9bf8a7e6568af31 Mon Sep 17 00:00:00 2001 From: Jiang-Red <1343396474@qq.com> Date: Fri, 11 Oct 2024 23:19:24 +0800 Subject: [PATCH 3/5] make lint happy --- rank.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rank.go b/rank.go index 36b44d6..d3e7976 100644 --- a/rank.go +++ b/rank.go @@ -84,7 +84,10 @@ func DrawRankingCard(fontdata []byte, title string, toplefttext, bottomlefttext, } canvas.SetRGBA255(0, 0, 0, 255) - canvas.ParseFontFace(fontdata, 32) + err = canvas.ParseFontFace(fontdata, 32) + if err != nil { + return + } canvas.DrawStringAnchored(title, w/2, 64/2, 0.5, 0.5) err = canvas.ParseFontFace(fontdata, 20) From 22452e91b61ad7b68e28760abd6d0f58d95e530d Mon Sep 17 00:00:00 2001 From: Jiang-Red <1343396474@qq.com> Date: Sat, 12 Oct 2024 20:58:29 +0800 Subject: [PATCH 4/5] use struct & same index --- rank.go | 72 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/rank.go b/rank.go index d3e7976..012fbfb 100644 --- a/rank.go +++ b/rank.go @@ -9,9 +9,17 @@ import ( "github.com/FloatTech/gg" ) +// RankInfo ... +type RankInfo struct { + Avatar image.Image + TopLeftText string + BottomLeftText string + RightText string +} + // DrawRankingCard ... -func DrawRankingCard(fontdata []byte, title string, toplefttext, bottomlefttext, righttext []string, avatars []image.Image) (img image.Image, err error) { - line := len(avatars) +func DrawRankingCard(fontdata []byte, title string, rankinfo []*RankInfo) (img image.Image, err error) { + line := len(rankinfo) const w = 672 h := 64 + (80+14)*line + 20 - 14 canvas := gg.NewContext(w, h) @@ -25,9 +33,10 @@ func DrawRankingCard(fontdata []byte, title string, toplefttext, bottomlefttext, ac.AddColorStop(0.5, color.NRGBA{255, 255, 255, 255}) ac.AddColorStop(1, color.NRGBA{255, 255, 255, 255}) - cardh, cardw := 80.0, 640.0 - cardspac := 14.0 - hspac := 64.0 + cardh, cardw := 80, 640 + cardspac := 14 + hspac, wspac := 64.0, 16.0 + r := 16.0 wg := &sync.WaitGroup{} wg.Add(line) @@ -35,29 +44,27 @@ func DrawRankingCard(fontdata []byte, title string, toplefttext, bottomlefttext, for i := 0; i < line; i++ { go func(i int) { defer wg.Done() - card := gg.NewContext(w, h) + card := gg.NewContext(w, cardh) card.NewSubPath() + card.MoveTo(wspac+float64(cardh)/2, 0) - card.MoveTo(16+cardh/2, hspac+(cardspac+cardh)*float64(i)) - - card.LineTo(16+cardw-16, hspac+(cardspac+cardh)*float64(i)) - card.DrawArc(16+cardw-16, hspac+(cardspac+cardh)*float64(i)+16, 16, gg.Radians(-90), gg.Radians(0)) - card.LineTo(16+cardw, hspac+(cardspac+cardh)*float64(i)+cardh-16) - card.DrawArc(16+cardw-16, hspac+(cardspac+cardh)*float64(i)+cardh-16, 16, gg.Radians(0), gg.Radians(90)) - card.LineTo(16+cardh/2, hspac+(cardspac+cardh)*float64(i)+cardh) - - card.DrawArc(16+cardh/2, hspac+(cardspac+cardh)*float64(i)+cardh-cardh/2, cardh/2, gg.Radians(90), gg.Radians(270)) + card.LineTo(wspac+float64(cardw)-r, 0) + card.DrawArc(wspac+float64(cardw)-r, r, r, gg.Radians(-90), gg.Radians(0)) + card.LineTo(wspac+float64(cardw), float64(cardh)-r) + card.DrawArc(wspac+float64(cardw)-r, float64(cardh)-r, r, gg.Radians(0), gg.Radians(90)) + card.LineTo(wspac+float64(cardh)/2, float64(cardh)) + card.DrawArc(wspac+float64(cardh)/2, float64(cardh)/2, float64(cardh)/2, gg.Radians(90), gg.Radians(270)) card.ClosePath() card.ClipPreserve() - avatar := avatars[i] + avatar := rankinfo[i].Avatar - card.ScaleAbout(cardw/2/float64(avatar.Bounds().Dx()), cardw/2/float64(avatar.Bounds().Dy()), 16, hspac+(cardspac+cardh)*float64(i)+cardh/2) + card.ScaleAbout(float64(cardw)/2/float64(avatar.Bounds().Dx()), float64(cardw)/2/float64(avatar.Bounds().Dy()), wspac, float64(cardh)/2) - card.DrawImageAnchored(avatar, 16, int(hspac+(cardspac+cardh)*float64(i)+cardh/2), 0, 0.5) + card.DrawImageAnchored(avatar, 0, cardh/2, 0, 0.5) card.Identity() card.ResetClip() @@ -66,18 +73,21 @@ func DrawRankingCard(fontdata []byte, title string, toplefttext, bottomlefttext, card.SetRGBA255(0, 0, 0, 255) card.Stroke() + card.DrawLine(wspac+float64(cardh)/2, float64(cardh), wspac+float64(cardw)-r, float64(cardh)) + card.Stroke() - card.DrawCircle(16+10+30, hspac+(cardspac+cardh)*float64(i)+cardh/2, 30) + card.DrawCircle(wspac+10+30, float64(cardh)/2, 30) card.ClipPreserve() - card.ScaleAbout(60.0/float64(avatar.Bounds().Dx()), 60.0/float64(avatar.Bounds().Dy()), 16+10+30, hspac+(cardspac+cardh)*float64(i)+cardh/2) - card.DrawImageAnchored(avatar, 16+10+30, int(hspac+(cardspac+cardh)*float64(i)+cardh/2), 0.5, 0.5) + card.ScaleAbout(60.0/float64(avatar.Bounds().Dx()), 60.0/float64(avatar.Bounds().Dy()), wspac+10+30, float64(cardh)/2) + card.DrawImageAnchored(avatar, int(wspac)+10+30, cardh/2, 0.5, 0.5) card.Identity() card.ResetClip() + card.SetRGBA255(0, 0, 0, 127) card.Stroke() card.SetRGB255(RandJPColor()) - card.DrawCircle(w-16-8-25, hspac+(cardspac+cardh)*float64(i)+cardh/2, 25) + card.DrawCircle(wspac+float64(cardw-8-25), float64(cardh)/2, 25) card.Fill() cardimgs[i] = card.Image() }(i) @@ -95,9 +105,9 @@ func DrawRankingCard(fontdata []byte, title string, toplefttext, bottomlefttext, return } wg.Wait() - for i := 0; i < 10; i++ { - canvas.DrawImage(cardimgs[i], 0, 0) - canvas.DrawStringAnchored(toplefttext[i], 16+10+60+10, hspac+(cardspac+cardh)*float64(i)+cardh*3/8, 0, 0.5) + for i := 0; i < line; i++ { + canvas.DrawImageAnchored(cardimgs[i], w/2, int(hspac)+((cardh+cardspac)*i), 0.5, 0) + canvas.DrawStringAnchored(rankinfo[i].TopLeftText, wspac+10+60+10, hspac+float64((cardspac+cardh)*i+cardh*3/8), 0, 0.5) } canvas.SetRGBA255(63, 63, 63, 255) @@ -105,16 +115,16 @@ func DrawRankingCard(fontdata []byte, title string, toplefttext, bottomlefttext, if err != nil { return } - for i := 0; i < 10; i++ { - canvas.DrawStringAnchored(bottomlefttext[i], 16+10+60+10, hspac+(cardspac+cardh)*float64(i)+cardh*5/8, 0, 0.5) + for i := 0; i < line; i++ { + canvas.DrawStringAnchored(rankinfo[i].BottomLeftText, wspac+10+60+10, hspac+float64((cardspac+cardh)*i+cardh*5/8), 0, 0.5) } canvas.SetRGBA255(0, 0, 0, 255) err = canvas.ParseFontFace(fontdata, 24) if err != nil { return } - for i := 0; i < 10; i++ { - canvas.DrawStringAnchored(righttext[i], w-16-8-50-8, hspac+(cardspac+cardh)*float64(i)+cardh/2, 1, 0.5) + for i := 0; i < line; i++ { + canvas.DrawStringAnchored(rankinfo[i].RightText, w-wspac-8-50-8, hspac+float64((cardspac+cardh)*i+cardh/2), 1, 0.5) } canvas.SetRGBA255(255, 255, 255, 255) @@ -122,8 +132,8 @@ func DrawRankingCard(fontdata []byte, title string, toplefttext, bottomlefttext, if err != nil { return } - for i := 0; i < 10; i++ { - canvas.DrawStringAnchored(strconv.Itoa(i+1), w-16-8-25, hspac+(cardspac+cardh)*float64(i)+cardh/2, 0.5, 0.5) + for i := 0; i < line; i++ { + canvas.DrawStringAnchored(strconv.Itoa(i+1), w-wspac-8-25, hspac+float64((cardspac+cardh)*i+cardh/2), 0.5, 0.5) } img = canvas.Image() From 07bb3de96c151d5e4c412ecfb56d3c10e0d90ae7 Mon Sep 17 00:00:00 2001 From: Jiang-Red <1343396474@qq.com> Date: Sat, 12 Oct 2024 21:03:16 +0800 Subject: [PATCH 5/5] style adjust --- rank.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rank.go b/rank.go index 012fbfb..35a96b8 100644 --- a/rank.go +++ b/rank.go @@ -100,7 +100,7 @@ func DrawRankingCard(fontdata []byte, title string, rankinfo []*RankInfo) (img i } canvas.DrawStringAnchored(title, w/2, 64/2, 0.5, 0.5) - err = canvas.ParseFontFace(fontdata, 20) + err = canvas.ParseFontFace(fontdata, 22) if err != nil { return } @@ -119,7 +119,7 @@ func DrawRankingCard(fontdata []byte, title string, rankinfo []*RankInfo) (img i canvas.DrawStringAnchored(rankinfo[i].BottomLeftText, wspac+10+60+10, hspac+float64((cardspac+cardh)*i+cardh*5/8), 0, 0.5) } canvas.SetRGBA255(0, 0, 0, 255) - err = canvas.ParseFontFace(fontdata, 24) + err = canvas.ParseFontFace(fontdata, 20) if err != nil { return }