前提
- 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()
}
线条(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()
}
问题1:定义线段的新起终点位置?
圆(Circle)
帆布圆形定义由指定颜色填充的圆形。您也可以设置StrokeWidth,从而设置不同的StrokeColor,如本例所示。
圆圈将填充通过调用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()
}
图像可以是基于位图的(如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()
}
如果您的像素数据存储在图像中,您可以通过NewRasterFromImage()函数加载它,该函数将加载图像以在屏幕上完美显示像素。
渐变(Gradient)
最后一个画布基元类型是渐变,可用作canvas.LinearGradient和canvas.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()
}
动画(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()
}
小结
当前的Fyne版本对于自绘制图像支持仍处于成熟的初期,这通过其对于线条、渐变及基本形状绘制函数的支持的灵活性方面即可判断出。Fyne绘图基于OpenGL框架,因此跨平台支持是没有问题的。相信随着版本的不断提升,其绘图支持能力会越来越强大。