tfriedel6 / canvas Goto Github PK
View Code? Open in Web Editor NEWCanvas is a Go drawing library based on OpenGL or using software rendering that is very similar to the HTML5 canvas API
License: BSD 3-Clause "New" or "Revised" License
Canvas is a Go drawing library based on OpenGL or using software rendering that is very similar to the HTML5 canvas API
License: BSD 3-Clause "New" or "Revised" License
As the title says, Can the following features be supported?
Sorry, how does it require to install the SDL if I do not use the program for writing on c / c ++?
i could not see any examples with events yet ?
Maybe i missed it, but any plans for that.
hello o/ my reasoning for this is that i wanted to use this multiface package to support font fallback but realized i couldnt use it since canvas basically only supports truetype.Font and the multiface package implements font.Face
i'm not sure how hard (or easy) this would be. if you have an alternate way to be able to draw text with fallbacks fonts that would be fine too.
[please close/delete]
Every thing I've tried (while studying the parseColor function, line 83 color.go) it chokes on the Alpha number.
I can't quite figure out what type it expects for that fourth value.
I would love to just send it a string like SetFillStyle("rgba(240, 236, 206, .5)") and it looks like it's supposed to be able to do that, but it doesn't seem to work.
Sending it a string like "rgb(240, 236, 206)" DOES work, so I'm thinking there might be a problem with line 209 on color.go.
I don't know if it's a bug or if I'm just stupid.
Can you update the readme with desktop/mobile support?
Looks like Win, Linux, and Mac: https://github.com/veandco/go-sdl2#requirements
'
wnd.KeyDown = func(scancode int, rn rune, name string) {
switch name {
//french Keyboard
case "Digit1":
//print("digit1\n")
buttonUtility(name, souris.X, souris.Y)
case "Digit2":
//print("digit2\n")
buttonUtility(name, souris.X, souris.Y)
case "Digit3":
print("digit3\n")
buttonUtility(name, souris.X, souris.Y)
case "KeyW":
//print(" z\n")
thisPlayer.H = true
thisPlayer.B = false
case "KeyA":
//print(" q\n")
thisPlayer.G = true
thisPlayer.D = false
case "KeyS":
//print(" s\n")
thisPlayer.B = true
thisPlayer.H = false
case "KeyD":
//print(" d\n")
thisPlayer.Droite = true
thisPlayer.Gauche = false
}'
all my programm run correctly, execpt some event:
someone know why that don't work?
If I leave the code bellow running for a while, I can see it has a memory leak... If I replace the DrawImage call with PutImageData, the leakage goes away. It happens with when using glfwcanvas
and sdlcanvas
.
OS: macOS Mohave
OpenGL: native? (didn't have to install anything)
SDL installed with brew install sdl2
package main
import (
"image"
"image/color"
"math/rand"
"time"
"github.com/tfriedel6/canvas/glfwcanvas"
)
var (
first = true
bla = time.Now()
limg *image.RGBA
)
func clientScreen() (image.Image, int64) {
if !first && rand.Float64() < 0.99 {
return limg, bla.UnixNano()
}
first = false
rgba := image.NewRGBA(image.Rect(0, 0, 800, 800))
for y := 0; y < 800; y++ {
for x := 0; x < 800; x++ {
rgba.Set(x, y, color.RGBA{
R: byte(rand.Intn(256)),
G: byte(rand.Intn(256)),
B: byte(rand.Intn(256)),
A: 255,
})
}
}
bla = time.Now()
limg = rgba
return rgba, bla.UnixNano()
}
func main() {
win, cv, err := glfwcanvas.CreateWindow(800, 800, "hello")
if err != nil {
panic(err)
}
var lastRefresh int64
win.MainLoop(func() {
// This call returns a new image and the last timestamp it was updated
img, lastUpdate := clientScreen()
// If there were no changes, terminate loop
if lastRefresh == lastUpdate {
return
}
// Process screen updates
// cv.PutImageData(img.(*image.RGBA), 0, 0)
cv.DrawImage(img, 0, 0)
lastRefresh = lastUpdate
})
}
Hi there, thanks for your awesome library! It is refreshingly easy to use!
I'm trying to use it to render a sequence of images in a glfwcanvas
, but when I update the image with a new one, it keeps switching between the new and the old image. Here's a snippet of my code:
win, cv, err := glfwcanvas.CreateWindow(defaultWidth, defaultHeight, windowTitle)
if err != nil {
panic(err)
}
var lastRefresh int64
win.MainLoop(func() {
// This call returns a new image and the last timestamp it was updated
img, lastUpdate := client.Screen()
imgWidth := img.Bounds().Max.X
imgHeight := img.Bounds().Max.Y
// If the image is empty, terminate loop
if imgWidth == 0 || imgHeight == 0 {
return
}
// If there were no changes, terminate loop
if lastRefresh == lastUpdate {
return
}
// Process screen updates
cv.PutImageData(img.(*image.RGBA), 0, 0)
lastRefresh = lastUpdate
})
I tried to use cv.DrawImage()
but then it does not show anything. What am I doing wrong?
Hello,
I think it would be great if this lib had some way to play a video on the canvas. Maybe something like in HTML5 Canvas where you can drawImage a video, or something even better w/ sound support?
Thoughts?
Hello! I have a somewhat text-heavy use case and I think I'm noticing that text rendering seems to be pretty slow -- with a couple hundred characters on the screen I get about 20fps and it only goes down from there.
I glanced through the code and it seems it's building up a bitmap of the text to draw every frame with image.Draw
, and then copying that to the destination buffer. Is that right? Is there some caching or a fast-path somewhere I can exploit?
I hope there's a folder called examples that contains more API to explore.
I want save canvas as png photo.
But the background is always black.
fDst, err := os.Create("out2.png")
if err != nil {
log.Fatal(err)
}
defer fDst.Close()
err = png.Encode(fDst, cv.GetImageData(0, 0, cv.Width(), cv.Height()))
if err != nil {
log.Fatal(err)
}
wnd.Close()
Trying to use this on the latest macOS release (Big Sur) and when running, I get the following error message:
failed to compile vertex shader:
ERROR: 0:2: '' : #version required and missing.
ERROR: 0:2: 'attribute' : syntax error: syntax error
I'm using an OpenGLView directly, rather than some other framework, like glfw or sdl. Is there some special setup I need to do in order to get things to work that those libraries are doing (I'm assuming they work, but I haven't yet tried them to verify)?
For reference, here are some code snippets showing the setup being done for the view:
When creating the view:
NSViewPtr nsNewOpenGLView() {
NSOpenGLPixelFormatAttribute attr[] = {
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFADepthSize, 16,
NSOpenGLPFAAccelerated,
// Opt-in to automatic GPU switching. CGL-only property.
kCGLPFASupportsAutomaticGraphicsSwitching,
NSOpenGLPFAAllowOfflineRenderers,
0
};
id pixFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
NSRect frame = NSMakeRect(0, 0, 0, 0);
OpenGLView *view = [[OpenGLView alloc] initWithFrame:frame pixelFormat:pixFormat];
[view setWantsBestResolutionOpenGLSurface:YES];
[view setWantsLayer:YES];
return (NSViewPtr)view;
}
The override for prepareOpenGL:
-(void)prepareOpenGL {
[super prepareOpenGL];
// Bind a default VBA to emulate OpenGL ES 2.
GLuint defVBA;
glGenVertexArrays(1, &defVBA);
glBindVertexArray(defVBA);
glEnable(GL_FRAMEBUFFER_SRGB);
}
I used canvas in WSL2 on win10.
When I call sdlcanvas.CreateWindow
, it failed with error:
Error initializing SDL: No available video device
Then I switched to glfwcanvas.CreateWindow
it also emit an error:
2022/01/17 15:27:59 PlatformError: X11: The DISPLAY environment variable is missing
panic: NotInitialized: The GLFW library is not initialized
Hello, I noticed that when using fillText
& strokeText
, the displayed text is pixelated.
Is there some trick or other to overcome this problem?
For some reason, my canvas is not the same size as the initial values i had originally passed to sdlcanvas.CreateWindow()
.
Here is some sample code.
package main
import(
"fmt"
"github.com/tfriedel6/canvas"
"github.com/tfriedel6/canvas/sdlcanvas"
"github.com/tfriedel6/canvas/backend/softwarebackend"
)
func main() {
// The size i would like my window to be
screenW := 1600
screenH := 900
// The size i would like the draggable square in the center to be.
squareSize := 128
wnd, cv, err := sdlcanvas.CreateWindow(screenW, screenH, "Example")
if err != nil {
panic(err)
}
fmt.Printf("Desired: %v w x %v h\n", screenW, screenH)
fmt.Printf("Actual: %v w x %v h\n", cv.Width(), cv.Height())
// Create a square. This square will be displayed in the center
// of the window and should be draggable.
backend := softwarebackend.New(squareSize, squareSize)
cvImg := canvas.New(backend)
cvImg.SetFillStyle("#FFF")
cvImg.Rect(0, 0, 64, 64)
cvImg.Fill()
img := cvImg.GetImageData(0, 0, squareSize, squareSize)
// Load the square into the main canvas as an image.
imgFinal, err := cv.LoadImage(img)
if err != nil {
panic(err)
}
// Starting position for the square
xStartPos := (screenW / 2) - (squareSize / 2)
yStartPos := (screenH / 2) - (squareSize / 2)
// Active position for the square
xPos := xStartPos
yPos := yStartPos
// Basic properties for tracking the cursor
followMouse := false
// When the mouse is released, stop following it and
// snap the square back to it's original pos.
wnd.MouseUp = func(b, x, y int) {
followMouse = false
xPos = xStartPos
yPos = yStartPos
}
// Only begin following the cursor if the square is clicked.
wnd.MouseDown = func(b, x, y int) {
if x > xStartPos && x < xStartPos + squareSize {
if y > yStartPos && y < yStartPos + squareSize {
followMouse = true
}
}
}
// When the mouse is moved, if we should be following the cursor
// update the location of the square to match that of the cursor.
wnd.MouseMove = func(x, y int) {
if followMouse {
xPos = x - (squareSize / 2)
yPos = y - (squareSize / 2)
}
}
defer wnd.Destroy()
// Start the main loop for rendering.
wnd.MainLoop(func() {
// I've been able to determine that for some reason, my canvas
// is not the same size as the initial values i had originally
// passed to sdlcanvas.CreateWindow().
// This seems to properly fill the entire canvas
w, h := float64(cv.Width()), float64(cv.Height())
cv.SetFillStyle("#fff")
cv.FillRect(0, 0, w, h)
// This does not fill the entire canvas.
w2, h2 := float64(screenW), float64(screenH)
cv.SetFillStyle("#000")
cv.FillRect(0, 0, w2, h2)
// This should be in the center of the window when it is first
// spawned but instead is is in the center of the top left
// quadrant of the window, which happens to be the center of
// the true canvas.
cv.DrawImage(imgFinal, float64(xPos),
float64(yPos),
float64(squareSize),
float64(squareSize))
})
}
When I run it, I get this output:
$ go run main.go
Desired: 1600 w x 900 h
Actual: 3200 w x 1800 h
I'm wondering if this has something to do with macOS' scaling features?
--
After doing some more testing, I've found that if I change my display to "default for display", I get a different "actual" value.
Desired: 1600 w x 900 h
Actual: 2048 w x 1090 h
I'm confident now that this has at least something to do with macOS' scaling features.
This testing was all done on a Late 2015 Mac Book Pro.
Hi,
How to convert canvas to png?
Hi,
Can this library be used to directly draw on a HTML5 Canvas when writing a Webassembly program?
Is there any plan to support Ellipse for Path2D, or could you show me some code snippets to implement it with current API? I just found it was commented or unimplemented.
https://github.com/tfriedel6/canvas/blob/master/path2d.go#L289-L292.
Thanks.
Example both here: https://github.com/5k3105/slowdraw1 and here: https://github.com/5k3105/tilemap4
Artifacts remain on screen after scale/clear/redraw. This is windows 7.
Hi,
Do you have an option to apply an anti-aliasing filter (like described here: https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing)?
I'm just trying to display a rectangle like the white line below:
It can be seen here that there is no sufficient anti-aliasing.
Thank you !
I'm running the examples on macOS Mojave 10.14.3, and all throw me the same error:
# github.com/tfriedel6/canvas/backend/gogl/gl
ld: framework not found OpenGLES
clang: error: linker command failed with exit code 1 (use -v to see invocation)
After changing line 19 of backend/gogl/gl/package.go
from
// #cgo darwin LDFLAGS: -framework OpenGLES
to
// #cgo darwin LDFLAGS: -framework OpenGL
the examples now run successfully. As Apple's OpenGL ES documentation only mentions iOS and tvOS, but no macOS, should OpenGL be used to build on macOS?
haloo I try to install this, but I can not to do it, I try many things, but still:
In file included from ..\github.com\veandco\go-sdl2\sdl\audio.go:4:
./sdl_wrapper.h:2:11: fatal error: SDL2/SDL.h: No such file or directory
#include <SDL2/SDL.h>
^~~~~~~~~~~~
compilation terminated.
Window size is almost two times bigger than canvas size but width and height are constants that are provided to both canvas and window
Hello again,
Was just experimenting with rect shadows and found out that:
For the bug, here's a screenshot:
what's excepted:
Here's the code used to draw the rect
cnv.Rect(this.X, this.Y, this.W, this.H)
cnv.SetFillStyle(this.Color)
cnv.SetShadowColor(this.ShadowColor)
cnv.SetShadowBlur(this.ShadowBlur)
cnv.SetShadowOffsetX(this.ShadowOffX)
cnv.SetShadowOffsetY(this.ShadowOffY)
cnv.Fill()
Are font sizes passed to FillText/MeasureText in pixels or points?
If I use MeasureText
it'll return the width, is the height of the text in pixels the font size?
edit: I've since checked the Web API and can see they've added bounding box ascent/descent measurements.
Hi, I have this blank red screen when I try to render something on screen. Weirdly, the only things that are rendered properly are images (DrawImage)
This is a screenshot from the drawing example
I'm using
go version go1.14 darwin/amd64
macOS Catalina Version 10.15.4
Do you guys have any idea what might be a problem?
Would you be open to a contribution that manages mobile canvas display contexts via gomobile's App
interface filters?
There's currently a lot of ceremony required for using canvas with gomobile. By contrast, you can set up a canvas via sdl or glfw in about 3 lines.
I've implemented an App Filter that removes all the manual bookkeeping from using canvas with gomobile via RegisterFilter
. This is how it's used:
package main
import (
"golang.org/x/mobile/app"
"golang.org/x/mobile/event/lifecycle"
"golang.org/x/mobile/event/paint"
"github.com/hunterloftis/snake/game"
)
func main() {
app.Main(func(a app.App) {
disp := &Display{}
view := &game.View{}
// the event filter handles lifecycle bookkeeping
a.RegisterFilter(disp.Filter)
for e := range a.Events() {
switch e := a.Filter(e).(type) {
case lifecycle.Event:
if lifecycle.CrossOn == e.Crosses(lifecycle.StageVisible) {
a.Send(paint.Event{})
}
case paint.Event:
cv := disp.Canvas()
if cv == nil || e.External {
continue
}
view.DrawOn(cv)
disp.Paint()
a.Publish()
a.Send(paint.Event{})
}
}
})
}
Hi,
Based on your event example -- project at: https://github.com/5k3105/tilemap3
Updated sdlcanvas to include MouseWheelEvent:
MouseWheel func(x, y int)
...
case *sdl.MouseWheelEvent:
if wnd.MouseWheel != nil {
wnd.MouseWheel(int(e.X), int(e.Y))
handled = true
}
then included it in project:
wnd.MouseWheel = func(x, y int) {
action = 1
if y == 1 {
cscale /= cmultiplier
}
if y == -1 {
cscale *= cmultiplier
}
cv.Scale(cscale, cscale)
println("y: ", y)
}
this does zoom (my code is buggy..) what I've drawn with lines but the Images (from PutImageData) are not zoomed. I believe this is by design based on this article: https://stackoverflow.com/questions/3420975/html5-canvas-zooming#3422425
Is it possible to include a function which scales the whole canvas/window?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.