feat: initial circle arrow svg
This commit is contained in:
parent
b13a43aa71
commit
793eb16881
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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}}
|
||||||
|
|
Loading…
Reference in New Issue