前提

  • OS:Mac Catalina
  • Fyne version:2.4.1


文本(Text)

canvas.NewText用于Fyne中的所有文本渲染。它是通过指定文本和文本的颜色来创建的。文本使用当前主题指定的默认字体呈现。

text对象允许某些配置,如Alignment和TextStyle字段。如这里的示例所示。要使用等宽字体,可以指定fyne.TextStyle{Monospace:true}。

package main

import (
    "image/color"

    "fyne.io/fyne/v2"
    "fyne.io/fyne/v2/app"
    "fyne.io/fyne/v2/canvas"
    "fyne.io/fyne/v2/container"
    "fyne.io/fyne/v2/layout"
)

func main() {
    myApp := app.New()
    w := myApp.NewWindow("Text")
    text1 := canvas.NewText("Hello", color.NRGBA{R: 255, G: 128, B: 0, A: 255})
    text2 := canvas.NewText("There", color.NRGBA{R: 0, G: 128, B: 255, A: 255})
    text3 := canvas.NewText("(right)", color.NRGBA{R: 0, G: 128, B: 0, A: 255})
    content := container.New(layout.NewHBoxLayout(), text1, text2, layout.NewSpacer(), text3)

    text := canvas.NewText("Text Object", color.NRGBA{R: 255, G: 128, B: 0, A: 255})
    text.Alignment = fyne.TextAlignCenter
    text.TextSize = 96
    text.TextStyle = fyne.TextStyle{Bold: true, Italic: true}

        w.SetContent(container.New(layout.NewVBoxLayout(), content, text))
        //w.SetContent(text)
        w.Resize(fyne.NewSize(800, 600))
        w.ShowAndRun()
    }

Go语言开源跨平台GUI框架Fyne小教程|绘图篇_跨平台



线条(Line)

canvas.NewLine绘制一条从Position1(默认为左上角)到Position2(默认为右下角)的线。您可以指定其颜色,并可以更改笔划宽度,否则默认为1。

可以使用Position1或Position2字段或使用Move()和Resize()函数来操纵线位置。例如,0宽度的区域将显示一条垂直线,而0高度将是水平的。

package main

import (
    "image/color"

    "fyne.io/fyne/v2"
    "fyne.io/fyne/v2/app"
    "fyne.io/fyne/v2/canvas"
)

func main() {
    myApp := app.New()
    w := myApp.NewWindow("Line")

    // line := canvas.NewLine(color.Black)
    line := canvas.NewLine(color.NRGBA{255, 128, 0, 255})
    // line.Position = fyne.NewPos(0, 0)
    // line.Position2 = fyne.NewPos(240, 160)
    line.StrokeWidth = 5
    line.Refresh()
    w.SetContent(line)

    w.Resize(fyne.NewSize(480, 320))
    w.ShowAndRun()
}

Go语言开源跨平台GUI框架Fyne小教程|绘图篇_Fyne_02

问题1:定义线段的新起终点位置?


圆(Circle)

帆布圆形定义由指定颜色填充的圆形。您也可以设置StrokeWidth,从而设置不同的StrokeColor,如本例所示。

Go语言开源跨平台GUI框架Fyne小教程|绘图篇_跨平台_03

圆圈将填充通过调用Resize()或由其控制的布局指定的空间。由于示例将圆圈设置为窗口内容,它将在基本填充(由主题控制)内调整大小以填充窗口。

package main

import (
    "image/color"

    "fyne.io/fyne/v2"
    "fyne.io/fyne/v2/app"
    "fyne.io/fyne/v2/canvas"
)

func main() {
    myApp := app.New()
    w := myApp.NewWindow("Circle")

    circle := canvas.NewCircle(color.NRGBA{255, 128, 0, 255})
    circle.StrokeColor = color.Gray{0x99}
    circle.StrokeWidth = 5
    w.SetContent(circle)

    w.Resize(fyne.NewSize(400, 300))
    w.ShowAndRun()
}


图像(Image)

canvas.Image表示Fyne中的可扩展图像资源。它可以从资源(如示例所示)、图像文件、包含图像的URI位置、io.Reader或Go image.Image加载内存中的图像。

默认的图像填充模式是canvas.ImageFillStretch,它将使其填充指定的空间(通过Resize()或布局)。或者,您可以使用canvas.ImageFillContain以确保保持纵横比并且图像在边界内。除此之外,您还可以使用canvas.ImageFillOriginal(如这里的示例中所使用的),它确保它的最小大小也将等于原始图像大小。

package main

import (
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
)

func main() {
	myApp := app.New()
	w := myApp.NewWindow("Image")

	// image := canvas.NewImageFromResource(theme.FyneLogo())
	// image := canvas.NewImageFromURI(uri)
	// image := canvas.NewImageFromImage(src)
	// image := canvas.NewImageFromReader(reader, name)
	image := canvas.NewImageFromFile("assets/girl1.jpg")
	image.FillMode = canvas.ImageFillOriginal
	w.SetContent(image)

	w.ShowAndRun()
}

Go语言开源跨平台GUI框架Fyne小教程|绘图篇_GO语言_04

图像可以是基于位图的(如PNG和JPEG),也可以是基于矢量的(如SVG)。在可能的情况下,我们建议使用可缩放的图像,因为它们将随着大小的变化而继续渲染。使用原始图像大小时要小心,因为在不同的用户界面比例下,它们的行为可能与预期不完全一样。由于Fyne允许整个用户界面缩放,因此,25像素的图像文件可能与25高度的Fyne对象的高度不同。

从远程URI下载并显示图像文件的代码:

urls, err := storage.ParseURI("https://img-blog.csdnimg.cn/img_convert/ffed26180da500aac26792ff3b81b099.png") //解析url字符串

if err != nil {

log.Fatal(err)

return

}

image := canvas.NewImageFromURI(urls)


栅格(Raster)

canvas.Raster就像一个图像,但为屏幕上的每个像素绘制了一个点。这意味着,随着用户界面的缩放或图像大小的调整,将需要更多的像素来填充空间。为此,我们使用Generator本示例中所示的函数 - 它将用于返回每个像素的颜色。

生成器函数可以是基于像素的(如本例中我们为每个像素生成新的随机颜色)或基于完整图像。生成完整的图像(使用canvas.NewRaster())更有效,但有时直接控制像素更方便。


package main

import (
	"image/color"
	"math/rand"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
)

func main() {
	myApp := app.New()
	w := myApp.NewWindow("Raster")

	raster := canvas.NewRasterWithPixels(
		func(_, _, w, h int) color.Color {
			return color.RGBA{uint8(rand.Intn(255)),
				uint8(rand.Intn(255)),
				uint8(rand.Intn(255)), 0xff}
		})
	// raster := canvas.NewRasterFromImage(img image.Image)
	w.SetContent(raster)
	w.Resize(fyne.NewSize(120, 100))
	w.ShowAndRun()
}

Go语言开源跨平台GUI框架Fyne小教程|绘图篇_跨平台_05

如果您的像素数据存储在图像中,您可以通过NewRasterFromImage()函数加载它,该函数将加载图像以在屏幕上完美显示像素。

渐变(Gradient)

最后一个画布基元类型是渐变,可用作canvas.LinearGradientcanvas.RadialGradient,用于以各种图案绘制从一种颜色到另一种颜色的渐变。可以使用NewHorizontalGradient()、NewVerticalGradient()或者NewRadialGradient()来创建渐变。

要创建渐变,你需要一个开始和结束的颜色——中间的每一种颜色都是由画布计算的。在这个例子中,我们使用color.Transparent显示渐变(或任何其他类型)如何使用alpha值对后面的内容半透明。

package main

import (
	"image/color"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
)

func main() {
	myApp := app.New()
	w := myApp.NewWindow("Gradient")

	// gradient := canvas.NewHorizontalGradient(color.NRGBA{R: 255, G: 0, B: 128, A: 255}, color.Transparent)
	// gradient := canvas.NewVerticalGradient(color.NRGBA{R: 255, G: 0, B: 128, A: 255}, color.NRGBA{R: 0, G: 0, B: 128, A: 255})
	gradient := canvas.NewLinearGradient(
		color.NRGBA{R: 255, G: 0, B: 128, A: 255},
		color.NRGBA{R: 0, G: 0, B: 0, A: 255},
		45,
	)
	// gradient := canvas.NewRadialGradient(color.NRGBA{R: 255, G: 0, B: 128, A: 255}, color.NRGBA{R: 0, G: 0, B: 128, A: 255})
	w.SetContent(gradient)

	w.Resize(fyne.NewSize(800, 200))
	w.ShowAndRun()
}

Go语言开源跨平台GUI框架Fyne小教程|绘图篇_GO语言_06

动画(Animation)

Fyne提供了对于任意对象的基本的属性动画支持。Fyne包含一个动画框架,允许您随着时间的推移将画布属性从一个值平滑地转换到另一个值。动画可以包含任何代码,这意味着:可以管理任何类型的对象属性,但也有内置的大小、位置和颜色动画。

动画通常使用画布包的内置辅助对象(如NewSizeAnimation)创建,并对创建的动画调用Start()。您可以将动画设置为重复或自动反转,如下所示。

让我们首先来看一个颜色动画,它逐渐改变矩形的填充颜色。在下面的代码示例中,我们将一个矩形设置为窗口的内容,就像我们在前面的代码示例所做的那样。最大的区别是我们在显示窗口之前开始的动画。动画是使用NewColorRGBAAnimation创建的,它将使颜色通道从定义的红色状态过渡到蓝色,这需要2秒(指定的持续时间)。

package main

import (
	"image/color"
	"time"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
)

func main() {
	a := app.New()
	w := a.NewWindow("Hello")

	obj := canvas.NewRectangle(color.Black)
	obj.Resize(fyne.NewSize(50, 50))
	w.SetContent(container.NewWithoutLayout(obj))

	red := color.NRGBA{R: 0xff, A: 0xff}
	blue := color.NRGBA{B: 0xff, A: 0xff}
	canvas.NewColorRGBAAnimation(red, blue, time.Second*2, func(c color.Color) {
		obj.FillColor = c
		canvas.Refresh(obj)
	}).Start()

	move := canvas.NewPositionAnimation(fyne.NewPos(0, 0), fyne.NewPos(200, 0), time.Second, obj.Move)
	move.AutoReverse = true
	move.Start()

	w.Resize(fyne.NewSize(250, 50))
	w.SetPadded(false)
	w.ShowAndRun()
}

Go语言开源跨平台GUI框架Fyne小教程|绘图篇_Fyne_07

小结

当前的Fyne版本对于自绘制图像支持仍处于成熟的初期,这通过其对于线条、渐变及基本形状绘制函数的支持的灵活性方面即可判断出。Fyne绘图基于OpenGL框架,因此跨平台支持是没有问题的。相信随着版本的不断提升,其绘图支持能力会越来越强大。


引用

https://developer.fyne.io/canvas/line