2021-09-09 12:08:31 +03:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math"
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
"github.com/anoshenko/rui"
|
|
|
|
)
|
|
|
|
|
|
|
|
const canvasDemoText = `
|
|
|
|
GridLayout {
|
|
|
|
width = 100%, height = 100%, cell-height = "auto, 1fr",
|
|
|
|
content = [
|
|
|
|
DropDownList {
|
|
|
|
id = canvasType, current = 0, margin = 8px,
|
|
|
|
items = ["Image", "Rectangles & ellipse", "Text style", "Text align", "Line style", "Transformations"]
|
|
|
|
},
|
|
|
|
CanvasView {
|
|
|
|
id = canvas, row = 1, width = 100%, height = 100%,
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
`
|
|
|
|
|
|
|
|
var sampleImage rui.Image
|
|
|
|
|
|
|
|
func rectangleCanvasDemo(canvas rui.Canvas) {
|
|
|
|
width := canvas.Width()
|
|
|
|
height := canvas.Height()
|
|
|
|
|
|
|
|
canvas.Save()
|
|
|
|
|
|
|
|
canvas.SetSolidColorFillStyle(0xFF008000)
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFFFF0000)
|
|
|
|
w2 := width / 2
|
|
|
|
h2 := height / 2
|
|
|
|
canvas.FillRect(10, 10, w2-20, h2-20)
|
|
|
|
canvas.StrokeRect(9.5, 9.5, w2-19, h2-19)
|
|
|
|
|
|
|
|
canvas.SetLinearGradientFillStyle(w2+10, 10, 0xFFFF0000, width-20, 10, 0xFF0000FF, []rui.GradientPoint{
|
|
|
|
{Offset: 0.3, Color: 0xFFFFFF00},
|
|
|
|
{Offset: 0.5, Color: 0xFF00FF00},
|
|
|
|
{Offset: 0.7, Color: 0xFF00FFFF},
|
|
|
|
})
|
|
|
|
canvas.SetLinearGradientStrokeStyle(10, 10, 0xFFFF00FF, 10, h2-20, 0xFF00FFFF, []rui.GradientPoint{
|
|
|
|
{Offset: 0.5, Color: 0xFF00FF00},
|
|
|
|
})
|
|
|
|
canvas.SetLineWidth(5)
|
|
|
|
canvas.FillAndStrokeRoundedRect(w2+7.5, 7.5, w2-15, h2-15, 20)
|
|
|
|
|
|
|
|
canvas.SetRadialGradientFillStyle(w2/2-20, h2+h2/2-20, 10, 0xFFFF0000, w2/2+20, h2+h2/2+20, w2/2, 0xFF0000FF, []rui.GradientPoint{
|
|
|
|
{Offset: 0.3, Color: 0xFFFFFF00},
|
|
|
|
{Offset: 0.5, Color: 0xFF00FF00},
|
|
|
|
{Offset: 0.7, Color: 0xFF00FFFF},
|
|
|
|
})
|
|
|
|
canvas.SetRadialGradientStrokeStyle(w2/2, h2+h2/2, h2/2, 0xFFFFFF00, w2/2, h2+h2/2, h2, 0xFF00FFFF, []rui.GradientPoint{
|
|
|
|
{Offset: 0.5, Color: 0xFF00FF00},
|
|
|
|
})
|
|
|
|
canvas.SetLineWidth(7)
|
|
|
|
canvas.FillAndStrokeRect(10, h2+10, w2-20, h2-20)
|
|
|
|
|
|
|
|
//canvas.SetSolidColorFillStyle(0xFF00FFFF)
|
|
|
|
canvas.SetImageFillStyle(sampleImage, rui.RepeatXY)
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFF0000FF)
|
|
|
|
canvas.SetLineWidth(4)
|
|
|
|
canvas.FillAndStrokeEllipse(w2+w2/2, h2+h2/2, w2/2-10, h2/2-10, 0)
|
|
|
|
|
|
|
|
canvas.Restore()
|
|
|
|
}
|
|
|
|
|
|
|
|
func textCanvasDemo(canvas rui.Canvas) {
|
|
|
|
|
|
|
|
canvas.Save()
|
|
|
|
canvas.SetTextAlign(rui.LeftAlign)
|
|
|
|
canvas.SetTextBaseline(rui.TopBaseline)
|
|
|
|
|
2022-01-29 19:20:05 +03:00
|
|
|
if canvas.View().Session().DarkTheme() {
|
|
|
|
canvas.SetSolidColorFillStyle(0xFFFFFFFF)
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFFFFFFFF)
|
|
|
|
} else {
|
|
|
|
canvas.SetSolidColorFillStyle(0xFF000000)
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFF000000)
|
|
|
|
}
|
2021-09-09 12:08:31 +03:00
|
|
|
canvas.FillText(10, 10, "Default font")
|
|
|
|
canvas.StrokeText(300, 10, "Default font")
|
|
|
|
|
|
|
|
canvas.SetSolidColorFillStyle(0xFF800000)
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFF800080)
|
|
|
|
canvas.SetFont("courier", rui.Pt(12))
|
|
|
|
canvas.FillText(10, 30, "courier, 12pt")
|
|
|
|
canvas.StrokeText(300, 30, "courier, 12pt")
|
|
|
|
|
|
|
|
canvas.SetSolidColorFillStyle(0xFF008000)
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFF008080)
|
|
|
|
canvas.SetFontWithParams("Courier new, courier", rui.Pt(12), rui.FontParams{
|
|
|
|
Italic: true,
|
|
|
|
})
|
|
|
|
canvas.FillText(10, 50, `Courier new, 12pt, italic`)
|
|
|
|
canvas.StrokeText(300, 50, `Courier new, 12pt, italic`)
|
|
|
|
|
|
|
|
canvas.SetSolidColorFillStyle(0xFF000080)
|
|
|
|
canvas.SetLinearGradientStrokeStyle(10, 70, 0xFF00FF00, 10, 90, 0xFFFF00FF, nil)
|
|
|
|
canvas.SetFontWithParams("sans-serif", rui.Pt(12), rui.FontParams{
|
|
|
|
SmallCaps: true,
|
|
|
|
})
|
|
|
|
canvas.FillText(10, 70, "sans-serif, 12pt, small-caps")
|
|
|
|
canvas.StrokeText(300, 70, "sans-serif, 12pt, small-caps")
|
|
|
|
|
|
|
|
canvas.SetLinearGradientFillStyle(10, 90, 0xFFFF0000, 10, 110, 0xFF0000FF, nil)
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFF800080)
|
|
|
|
canvas.SetFontWithParams("serif", rui.Pt(12), rui.FontParams{
|
|
|
|
Weight: 7,
|
|
|
|
})
|
|
|
|
canvas.FillText(10, 90, "serif, 12pt, weight: 7(bold)")
|
|
|
|
canvas.StrokeText(300, 90, "serif, 12pt, weight: 7(bold)")
|
|
|
|
|
|
|
|
widthSample := "Text width sample"
|
|
|
|
w := canvas.TextWidth(widthSample, "sans-serif", rui.Px(20))
|
|
|
|
canvas.SetFont("sans-serif", rui.Px(20))
|
|
|
|
canvas.SetSolidColorFillStyle(rui.Blue)
|
|
|
|
canvas.SetTextBaseline(rui.BottomBaseline)
|
|
|
|
canvas.FillText(10, 150, widthSample)
|
|
|
|
|
|
|
|
canvas.SetSolidColorStrokeStyle(rui.Black)
|
|
|
|
canvas.SetLineWidth(1)
|
|
|
|
canvas.DrawLine(10, 150, 10, 170)
|
|
|
|
canvas.DrawLine(10+w, 150, 10+w, 170)
|
|
|
|
canvas.DrawLine(10, 168, 10+w, 168)
|
|
|
|
canvas.DrawLine(10, 168, 20, 165)
|
|
|
|
canvas.DrawLine(10, 168, 20, 171)
|
|
|
|
canvas.DrawLine(10+w, 168, w, 165)
|
|
|
|
canvas.DrawLine(10+w, 168, w, 171)
|
|
|
|
|
|
|
|
canvas.SetSolidColorFillStyle(rui.Black)
|
|
|
|
canvas.SetFont("sans-serif", rui.Px(8))
|
|
|
|
canvas.SetTextAlign(rui.CenterAlign)
|
|
|
|
canvas.FillText(10+w/2, 167, strconv.FormatFloat(w, 'g', -1, 64))
|
|
|
|
|
|
|
|
canvas.Restore()
|
|
|
|
}
|
|
|
|
|
|
|
|
func textAlignCanvasDemo(canvas rui.Canvas) {
|
|
|
|
canvas.Save()
|
|
|
|
canvas.SetFont("sans-serif", rui.Pt(10))
|
2022-01-29 19:20:05 +03:00
|
|
|
if canvas.View().Session().DarkTheme() {
|
|
|
|
canvas.SetSolidColorFillStyle(0xFFFFFFFF)
|
|
|
|
} else {
|
|
|
|
canvas.SetSolidColorFillStyle(0xFF000000)
|
|
|
|
}
|
2021-09-09 12:08:31 +03:00
|
|
|
canvas.SetSolidColorStrokeStyle(0xFF00FFFF)
|
|
|
|
|
|
|
|
baseline := []string{"Alphabetic", "Top", "Middle", "Bottom", "Hanging", "Ideographic"}
|
|
|
|
align := []string{"Left", "Right", "Center", "Start", "End"}
|
|
|
|
center := []float64{20, 120, 70, 20, 120}
|
|
|
|
for b, bText := range baseline {
|
|
|
|
for a, aText := range align {
|
|
|
|
canvas.SetTextAlign(a)
|
|
|
|
canvas.SetTextBaseline(b)
|
|
|
|
x := float64(a * 140)
|
|
|
|
y := float64(b * 40)
|
|
|
|
|
|
|
|
canvas.DrawLine(x+4, y+20, x+132, y+20)
|
|
|
|
canvas.DrawLine(x+center[a], y+2, x+center[a], y+38)
|
|
|
|
canvas.FillText(x+center[a], y+20, bText+","+aText)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
canvas.Restore()
|
|
|
|
}
|
|
|
|
|
|
|
|
func lineStyleCanvasDemo(canvas rui.Canvas) {
|
|
|
|
canvas.Save()
|
|
|
|
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFF00FFFF)
|
|
|
|
canvas.SetLineWidth(1)
|
|
|
|
canvas.DrawLine(20, 30, 20, 90)
|
|
|
|
canvas.DrawLine(170, 30, 170, 90)
|
|
|
|
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFF0000FF)
|
|
|
|
canvas.SetFont("courier", rui.Pt(12))
|
|
|
|
canvas.SetTextBaseline(rui.MiddleBaseline)
|
|
|
|
canvas.FillText(80, 15, "SetLineCap(...)")
|
|
|
|
|
|
|
|
canvas.SetFont("courier", rui.Pt(10))
|
|
|
|
for i, cap := range []string{"ButtCap", "RoundCap", "SquareCap"} {
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFF00FFFF)
|
|
|
|
canvas.SetLineWidth(1)
|
|
|
|
y := float64(40 + 20*i)
|
|
|
|
canvas.DrawLine(10, y, 180, y)
|
2022-01-29 19:20:05 +03:00
|
|
|
if canvas.View().Session().DarkTheme() {
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFFFFFFFF)
|
|
|
|
} else {
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFF000000)
|
|
|
|
}
|
|
|
|
|
2021-09-09 12:08:31 +03:00
|
|
|
canvas.SetLineWidth(10)
|
|
|
|
canvas.SetLineCap(i)
|
|
|
|
canvas.DrawLine(20, y, 170, y)
|
|
|
|
canvas.FillText(200, y, cap)
|
|
|
|
}
|
|
|
|
|
2022-01-29 19:20:05 +03:00
|
|
|
if canvas.View().Session().DarkTheme() {
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFFFFFFFF)
|
|
|
|
canvas.SetSolidColorFillStyle(0xFF00FFFF)
|
|
|
|
} else {
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFF000000)
|
|
|
|
canvas.SetSolidColorFillStyle(0xFF0000FF)
|
|
|
|
}
|
2021-09-09 12:08:31 +03:00
|
|
|
canvas.SetFont("courier", rui.Pt(12))
|
|
|
|
canvas.FillText(80, 115, "SetLineJoin(...)")
|
|
|
|
|
|
|
|
canvas.SetLineWidth(10)
|
|
|
|
canvas.SetLineCap(rui.ButtCap)
|
|
|
|
|
|
|
|
canvas.SetFont("courier", rui.Pt(10))
|
|
|
|
for i, join := range []string{"MiterJoin", "RoundJoin", "BevelJoin"} {
|
|
|
|
y := float64(140 + 40*i)
|
|
|
|
path := rui.NewPath()
|
|
|
|
path.MoveTo(20, y)
|
|
|
|
path.LineTo(50, y+40)
|
|
|
|
path.LineTo(80, y)
|
|
|
|
path.LineTo(110, y+40)
|
|
|
|
path.LineTo(140, y)
|
|
|
|
path.LineTo(170, y+40)
|
|
|
|
path.LineTo(200, y)
|
|
|
|
canvas.SetLineJoin(i)
|
|
|
|
canvas.StrokePath(path)
|
|
|
|
canvas.FillText(210, y+20, join)
|
|
|
|
}
|
|
|
|
canvas.SetFont("courier", rui.Pt(12))
|
|
|
|
canvas.FillText(20, 300, "SetLineDash([]float64{16, 8, 4, 8}, ...)")
|
|
|
|
|
|
|
|
canvas.SetFont("courier", rui.Pt(10))
|
|
|
|
canvas.SetLineDash([]float64{16, 8, 4, 8}, 0)
|
|
|
|
canvas.SetLineWidth(4)
|
|
|
|
|
|
|
|
canvas.SetLineCap(rui.ButtCap)
|
|
|
|
canvas.DrawLine(20, 330, 200, 330)
|
|
|
|
canvas.FillText(220, 330, "SetLineCap(ButtCap)")
|
|
|
|
|
|
|
|
canvas.SetLineDash([]float64{16, 8, 4, 8}, 4)
|
|
|
|
canvas.DrawLine(20, 360, 200, 360)
|
|
|
|
canvas.FillText(220, 360, "offset = 4")
|
|
|
|
|
|
|
|
canvas.SetLineDash([]float64{16, 8, 4, 8}, 0)
|
|
|
|
canvas.SetLineCap(rui.RoundCap)
|
|
|
|
canvas.SetShadow(4, 4, 2, 0xFF808080)
|
|
|
|
canvas.DrawLine(20, 390, 200, 390)
|
|
|
|
canvas.ResetShadow()
|
|
|
|
canvas.FillText(220, 390, "SetLineCap(RoundCap)")
|
|
|
|
|
|
|
|
canvas.Restore()
|
|
|
|
}
|
|
|
|
|
|
|
|
func transformCanvasDemo(canvas rui.Canvas) {
|
|
|
|
drawFigure := func() {
|
|
|
|
w := int(canvas.Width() / 2)
|
|
|
|
h := int(canvas.Height() / 2)
|
|
|
|
nx := (w/2)/20 + 1
|
|
|
|
ny := (h/2)/20 + 1
|
|
|
|
x0 := float64((w - nx*20) / 2)
|
|
|
|
y0 := float64((h - ny*20) / 2)
|
|
|
|
x1 := x0 + float64((nx-1)*20)
|
|
|
|
y1 := y0 + float64((ny-1)*20)
|
|
|
|
|
|
|
|
canvas.SetFont("serif", rui.Pt(10))
|
2022-01-29 19:20:05 +03:00
|
|
|
if canvas.View().Session().DarkTheme() {
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFFFFFFFF)
|
|
|
|
canvas.SetSolidColorFillStyle(0xFFFFFFFF)
|
|
|
|
} else {
|
|
|
|
canvas.SetSolidColorStrokeStyle(0xFF000000)
|
|
|
|
canvas.SetSolidColorFillStyle(0xFF000000)
|
|
|
|
}
|
2021-09-09 12:08:31 +03:00
|
|
|
canvas.SetTextAlign(rui.CenterAlign)
|
|
|
|
canvas.SetTextBaseline(rui.BottomBaseline)
|
|
|
|
for i := 0; i < nx; i++ {
|
|
|
|
x := x0 + float64(i*20)
|
|
|
|
canvas.DrawLine(x, y0, x, y1)
|
|
|
|
canvas.FillText(x, y0-4, strconv.Itoa(i))
|
|
|
|
}
|
|
|
|
|
|
|
|
canvas.SetTextAlign(rui.RightAlign)
|
|
|
|
canvas.SetTextBaseline(rui.MiddleBaseline)
|
|
|
|
for i := 0; i < ny; i++ {
|
|
|
|
y := y0 + float64(i*20)
|
|
|
|
canvas.DrawLine(x0, y, x1, y)
|
|
|
|
canvas.FillText(x0-4, y, strconv.Itoa(i))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
canvas.SetFont("courier", rui.Pt(14))
|
2022-01-29 19:20:05 +03:00
|
|
|
if canvas.View().Session().DarkTheme() {
|
|
|
|
canvas.SetSolidColorFillStyle(0xFFFFFFFF)
|
|
|
|
} else {
|
|
|
|
canvas.SetSolidColorFillStyle(0xFF000000)
|
|
|
|
}
|
2021-09-09 12:08:31 +03:00
|
|
|
canvas.SetTextAlign(rui.CenterAlign)
|
|
|
|
canvas.SetTextBaseline(rui.TopBaseline)
|
|
|
|
|
|
|
|
canvas.FillText(canvas.Width()/4, 8, "Original")
|
|
|
|
canvas.FillText(canvas.Width()*3/4, 8, "SetScale(1.2, 0.8)")
|
|
|
|
canvas.FillText(canvas.Width()/4, canvas.Height()/2+8, "SetRotation(math.Pi / 6)")
|
|
|
|
canvas.FillText(canvas.Width()*3/4, canvas.Height()/2+8, "SetTransformation(0.8, 1.2, 0.2, 0.4, ...)")
|
|
|
|
|
|
|
|
drawFigure()
|
|
|
|
|
|
|
|
canvas.SetScale(1.2, 0.8)
|
|
|
|
canvas.SetTranslation(canvas.Width()/2.4, 0)
|
|
|
|
drawFigure()
|
|
|
|
|
|
|
|
canvas.ResetTransformation()
|
|
|
|
canvas.SetTranslation(canvas.Width()/8, canvas.Height()/2-canvas.Height()/8)
|
|
|
|
canvas.SetRotation(math.Pi / 6)
|
|
|
|
drawFigure()
|
|
|
|
|
|
|
|
canvas.ResetTransformation()
|
|
|
|
//canvas.SetTranslation(canvas.Width()/2, canvas.Height()/2)
|
|
|
|
canvas.SetTransformation(0.8, 1.2, 0.2, 0.4, canvas.Width()/(2*0.8)-canvas.Width()/8, canvas.Height()/(2*1.2)-canvas.Height()/16)
|
|
|
|
drawFigure()
|
|
|
|
}
|
|
|
|
|
|
|
|
var image rui.Image
|
|
|
|
|
|
|
|
func imageCanvasDemo(canvas rui.Canvas) {
|
|
|
|
if image != nil {
|
|
|
|
canvas.DrawImage(50, 20, image)
|
|
|
|
} else {
|
|
|
|
image = rui.LoadImage("tile00.svg", func(img rui.Image) {
|
|
|
|
if img.LoadingStatus() == rui.ImageReady {
|
|
|
|
canvas.View().Redraw()
|
|
|
|
}
|
|
|
|
}, canvas.View().Session())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func createCanvasDemo(session rui.Session) rui.View {
|
|
|
|
view := rui.CreateViewFromText(session, canvasDemoText)
|
|
|
|
if view == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
rui.Set(view, "canvas", rui.DrawFunction, imageCanvasDemo)
|
|
|
|
|
|
|
|
rui.Set(view, "canvasType", rui.DropDownEvent, func(list rui.DropDownList, number int) {
|
|
|
|
drawFuncs := []func(rui.Canvas){
|
|
|
|
imageCanvasDemo,
|
|
|
|
rectangleCanvasDemo,
|
|
|
|
textCanvasDemo,
|
|
|
|
textAlignCanvasDemo,
|
|
|
|
lineStyleCanvasDemo,
|
|
|
|
transformCanvasDemo,
|
|
|
|
}
|
|
|
|
if number >= 0 && number < len(drawFuncs) {
|
|
|
|
rui.Set(view, "canvas", rui.DrawFunction, drawFuncs[number])
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
sampleImage = rui.LoadImage("image_sample.png", nil, session)
|
|
|
|
|
|
|
|
return view
|
|
|
|
}
|