feat: initial circle arrow svg

This commit is contained in:
efim 2023-11-21 17:25:18 +00:00
parent b13a43aa71
commit 793eb16881
3 changed files with 168 additions and 80 deletions

View File

@ -62,6 +62,72 @@ func (r *roomTableData)Tangens() float64 {
return math.Tan(math.Pi / float64(r.Total())) // Math.tan(Math.PI/m); return math.Tan(math.Pi / float64(r.Total())) // Math.tan(Math.PI/m);
} }
type arrowData struct {
Height, Width int
Radius int
StartX, StartY int
EndX, EndY int
LargeArcFlag int
Angle1X, Angle1Y int
Angle2X, Angle2Y int
}
func (r *roomTableData)ArrowData() arrowData {
// TODO take total and indexes from room data
// also figure out size to be around the people
// and this is somewhat a win
height, width := 150.0, 150.0
centerX, centerY := height/2, width/2
total := 5 // 0 to 4
startSector := 1
endSector := 5
if endSector < startSector {
endSector += total
}
radius := 50.0
startAngle := 90 + float64(startSector) * ( 360.0 / float64(total) )
endAngle := 90 + float64(endSector) * ( 360.0 / float64(total) )
startAngleRad := startAngle * (math.Pi / float64(180))
endAngleRad := endAngle * (math.Pi / float64(180))
// endAngle is radius angle, so perpendicular gives direction of teh arrow
x1 := centerX + radius * math.Cos(startAngleRad)
y1 := centerY + radius * math.Sin(startAngleRad)
x2 := centerX + radius * math.Cos(endAngleRad)
y2 := centerY + radius * math.Sin(endAngleRad)
arrowAngleOffset := math.Pi / 4 // 45 degrees
arrowPointDirection := endAngleRad - math.Pi / 2
arrowheadLen := 10.0
line1Angle := arrowPointDirection - arrowAngleOffset
line2Angle := arrowPointDirection + arrowAngleOffset
line1EndX := x2 + arrowheadLen * math.Cos(line1Angle)
line1EndY := y2 + arrowheadLen * math.Sin(line1Angle)
line2EndX := x2 + arrowheadLen * math.Cos(line2Angle)
line2EndY := y2 + arrowheadLen * math.Sin(line2Angle)
// indicates that the shorter of the two possible arcs should be used.
largeArcFlag := 0
if math.Abs(float64(endSector) - float64(startSector)) > float64(total)/2.0 {
// specifies that the longer arc should be chosen.
largeArcFlag = 1
}
return arrowData{
Height: int(height),
Width: int(width),
Radius: int(radius),
StartX: int(x1),
StartY: int(y1),
EndX: int(x2),
EndY: int(y2),
LargeArcFlag: largeArcFlag,
Angle1X: int(line1EndX),
Angle1Y: int(line1EndY),
Angle2X: int(line2EndX),
Angle2Y: int(line2EndY),
}
}
func personDataFromRoom(room *roomTableData, pId rooms.PersonId) personData { func personDataFromRoom(room *roomTableData, pId rooms.PersonId) personData {
person, exists := room.AllKnownPeople[pId] person, exists := room.AllKnownPeople[pId]
if !exists || !slices.Contains(room.Paricipants, pId) { if !exists || !slices.Contains(room.Paricipants, pId) {

View File

@ -534,10 +534,22 @@ video {
--tw-backdrop-sepia: ; --tw-backdrop-sepia: ;
} }
.absolute {
position: absolute;
}
.relative { .relative {
position: relative; position: relative;
} }
.left-1\/2 {
left: 50%;
}
.top-1\/2 {
top: 50%;
}
.col-span-full { .col-span-full {
grid-column: 1 / -1; grid-column: 1 / -1;
} }
@ -592,6 +604,16 @@ video {
flex: none; flex: none;
} }
.-translate-x-1\/2 {
--tw-translate-x: -50%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-translate-y-1\/2 {
--tw-translate-y: -50%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
@keyframes pulse { @keyframes pulse {
50% { 50% {
opacity: .5; opacity: .5;

View File

@ -1,95 +1,95 @@
<h2>Single templates</h2> <h2>Single templates</h2>
{{ define "inactiveBrick" }} {{ define "inactiveBrick" }}
<div <div
class="h-[var(--brick-height)] w-20 border-[hsl(var(--brick-color))]/25 border bg-[hsl(var(--brick-color))]/5" class="h-[var(--brick-height)] w-20 border-[hsl(var(--brick-color))]/25 border bg-[hsl(var(--brick-color))]/5"
style="--brick-color: var({{.}}); --brick-height: calc(var(--d)/5)" style="--brick-color: var({{.}}); --brick-height: calc(var(--d)/5)"
></div> ></div>
{{ end }} {{ end }}
{{ define "raisedBrick" }}
{{ define "raisedBrick" }} <div
<div
class="h-[var(--brick-height)] w-20 border-[hsl(var(--brick-color))] border-2 bg-[hsl(var(--brick-color))]/25" class="h-[var(--brick-height)] w-20 border-[hsl(var(--brick-color))] border-2 bg-[hsl(var(--brick-color))]/25"
style="--brick-color: var({{.}}); --brick-height: calc(var(--d)/5)" style="--brick-color: var({{.}}); --brick-height: calc(var(--d)/5)"
></div> ></div>
{{ end }} {{ end }}
{{ define "speakerBrick" }}
{{ define "speakerBrick" }} <div
<div
class="h-[var(--brick-height)] w-20 border-[hsl(var(--brick-color))] border-2 bg-[hsl(var(--brick-color))]/50 shadow-[0_0_15px_rgba(0,_0,_0,_0.5)] shadow-[hsl(var(--brick-color))] animate-pulse" class="h-[var(--brick-height)] w-20 border-[hsl(var(--brick-color))] border-2 bg-[hsl(var(--brick-color))]/50 shadow-[0_0_15px_rgba(0,_0,_0,_0.5)] shadow-[hsl(var(--brick-color))] animate-pulse"
style="--brick-color: var({{.}}); --brick-height: calc(var(--d)/5)" style="--brick-color: var({{.}}); --brick-height: calc(var(--d)/5)"
></div> ></div>
{{ end }} {{ end }}
{{ define "markBrick" }}
{{ define "markBrick" }} <div
<div
class="h-[var(--brick-height)] w-20 border-[hsl(var(--brick-color))]/25 border bg-[hsl(var(--brick-color))]/5 grid place-content-center font-bold text-[hsl(var(--brick-color))]/50" class="h-[var(--brick-height)] w-20 border-[hsl(var(--brick-color))]/25 border bg-[hsl(var(--brick-color))]/5 grid place-content-center font-bold text-[hsl(var(--brick-color))]/50"
style="--brick-color: var({{.}}); --brick-height: calc(var(--d)/5)" style="--brick-color: var({{.}}); --brick-height: calc(var(--d)/5)"
> >
X X
</div> </div>
{{ end }} {{ end }}
<h2>For each type</h2> <h2>For each type</h2>
{{ range .Bricks }} {{ range .Bricks }}
<div class="border-2">for {{ .Name }}</div> <div class="border-2">for {{ .Name }}</div>
<div <div
class="border-2 p-3 flex flex-row gap-x-3" class="border-2 p-3 flex flex-row gap-x-3"
style="--brick-color: var({{ .ColorClass }})" style="--brick-color: var({{ .ColorClass }})"
> >
{{ template "inactiveBrick" .ColorClass }} {{ template "raisedBrick" {{ template "inactiveBrick" .ColorClass }} {{ template "raisedBrick"
.ColorClass }} {{ template "speakerBrick" .ColorClass }} {{ template .ColorClass }} {{ template "speakerBrick" .ColorClass }} {{ template
"markBrick" .ColorClass }} "markBrick" .ColorClass }}
</div> </div>
{{ end }} {{ end }}
<h2>Now for BrickData taking parametrized template name</h2> <h2>Now for BrickData taking parametrized template name</h2>
{{ define "brick" }} {{ define "brick" }}
{{ if eq .TemplateType "inactiveBrick" }} {{ if eq .TemplateType "inactiveBrick" }}
{{ template "inactiveBrick" .ColorClass }} {{ template "inactiveBrick" .ColorClass }}
{{ else if eq .TemplateType "raisedBrick" }} {{ else if eq .TemplateType "raisedBrick" }}
{{ template "raisedBrick" .ColorClass }} {{template "raisedBrick" .ColorClass }}
{{ else if eq .TemplateType "speakerBrick"}}
{{ else if eq .TemplateType "speakerBrick" }} {{ template "speakerBrick" .ColorClass }}
{{ template "speakerBrick" .ColorClass }}
{{ else if eq .TemplateType "markBrick" }} {{ else if eq .TemplateType "markBrick" }}
{{ template "markBrick" .ColorClass }} {{ template "markBrick" .ColorClass }}
{{ end }} {{ end }}
{{end}} {{end}}
<h2>Now for a person</h2> <h2>Now for a person</h2>
<p>expected to be called with personData</p> <p>expected to be called with personData</p>
{{ define "personBlocks" }} {{ define "personBlocks" }}
<div class="person-bricks" <div class="person-bricks" id="person-{{.Index}}" style="--i: {{ .Index }}">
id="person-{{.Index}}" {{ range .BricksForPerson }} {{ template "brick" . }} {{ end }}
style="--i: {{ .Index }}" <p>{{ .Name }}({{.Index}})</p>
>
{{ range .BricksForPerson }}
{{ template "brick" . }}
{{ end }}
<p>{{ .Name }}</p>
</div> </div>
{{ end }} {{ end }}
<h2>And now i'll want to get all persons for a room</h2> <h2>And now i'll want to get all persons for a room</h2>
<p>expected be called with room *roomTableData</p> <p>expected be called with room *roomTableData</p>
{{ define "roomPeople" }} {{ define "roomPeople" }}
<div <div
class="circle-container relative" class="circle-container relative"
style="--tan: {{ .Tangens }}; --m: {{ .Total }};" style="--tan: {{ .Tangens }}; --m: {{ .Total }};"
>
{{ with .ArrowData }}
<svg height="{{.Height}}" width="{{.Width}}"
class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"
> >
{{ range .Persons }} <g>
{{ template "personBlocks" . }} <rect height="{{.Height}}" width="{{.Width}}" fill="#EEE" />
<path
d="M {{.StartX}} {{.StartY}}
A {{.Radius}} {{.Radius}} 0, {{.LargeArcFlag}}, 1, {{.EndX}} {{.EndY}}"
stroke="tomato"
stroke-width="2"
fill="transparent"
/>
<line x1="{{.EndX}}" y1="{{.EndY}}" x2="{{.Angle1X}}" y2="{{.Angle1Y}}" stroke="tomato" stroke-width="2" />
<line x1="{{.EndX}}" y1="{{.EndY}}" x2="{{.Angle2X}}" y2="{{.Angle2Y}}" stroke="tomato" stroke-width="2" />
</g>
</svg>
{{ end }} {{ end }}
</div> {{ range .Persons }} {{ template "personBlocks" . }} {{ end }}
{{end}} </div>
{{end}}