{"id":25858487,"url":"https://github.com/yottahmd/furex","last_synced_at":"2025-03-22T15:08:51.272Z","repository":{"id":40485297,"uuid":"300657568","full_name":"yottahmd/furex","owner":"yottahmd","description":"A minimal GUI framework built on top of Ebitengine that provides support for the Flex Layout Algorithm, building UI from HTML, and user interaction components such as buttons.","archived":false,"fork":false,"pushed_at":"2024-09-23T02:19:35.000Z","size":1548,"stargazers_count":137,"open_issues_count":4,"forks_count":8,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-16T11:13:04.362Z","etag":null,"topics":["ebitengine","flex","flexbox","flexbox-layout","golang"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/yohamta/furex/v2","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yottahmd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-02T15:26:05.000Z","updated_at":"2025-02-26T00:24:04.000Z","dependencies_parsed_at":"2023-11-11T03:25:21.815Z","dependency_job_id":"7b45dea2-b3c7-4819-ad04-c3a7e454c38c","html_url":"https://github.com/yottahmd/furex","commit_stats":{"total_commits":301,"total_committers":4,"mean_commits":75.25,"dds":0.06312292358803984,"last_synced_commit":"324aa02f958b51b72413d5b2bb348162e85c84bd"},"previous_names":["yotahamada/furex","miyahoyo/furex","yottahmd/furex"],"tags_count":57,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yottahmd%2Ffurex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yottahmd%2Ffurex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yottahmd%2Ffurex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yottahmd%2Ffurex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yottahmd","download_url":"https://codeload.github.com/yottahmd/furex/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244973775,"owners_count":20541025,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ebitengine","flex","flexbox","flexbox-layout","golang"],"created_at":"2025-03-01T20:07:43.512Z","updated_at":"2025-03-22T15:08:51.249Z","avatar_url":"https://github.com/yottahmd.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1\u003eFurex\u003c/h1\u003e\n\nFurex is a minimal GUI framework built on top of [Ebitengine](https://ebiten.org/), a 2D game engine for Go. It provides support for the [Flex Layout Algorithm](https://www.w3.org/TR/css-flexbox-1/#layout-algorithm), a powerful tool for laying out items of different sizes and dimensions. Furex is not a component library, but rather a framework for positioning and stacking virtual widgets, handling button and touch events for mobile, and more. How these widgets are rendered is up to the user.\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/yohamta/furex.svg)](https://pkg.go.dev/github.com/yohamta/furex)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"480\" src=\"./assets/example.gif\"\u003e\n\u003c/p\u003e\n\nAssets by [Kenney](https://kenney.nl). Fonts by [00ff](http://www17.plala.or.jp/xxxxxxx/00ff/).\n\nFull source code of the example is [here](examples/game/main.go).\n\n## Contents\n\n- [Contents](#contents)\n- [Motivation](#motivation)\n- [Features](#features)\n- [Getting Started](#getting-started)\n- [Basic Usage](#basic-usage)\n- [Building UI with HTML](#building-ui-with-html)\n  - [CSS Properties](#css-properties)\n  - [HTML Attributes](#html-attributes)\n  - [Component Types](#component-types)\n  - [Global Components](#global-components)\n- [Debugging](#debugging)\n- [Contributions](#contributions)\n\n## Motivation\n\n[Flexbox](https://www.w3.org/TR/css-flexbox/) is a popular layout mechanism in web development, used for creating responsive and flexible user interfaces. With Furex, we can bring this same concept to game development using Go and Ebitengine. This library aims to make it easier for developers with experience in web or React projects to create dynamic, user-friendly game UI.\n\nIf you are not familiar with Flexbox Layout, you can learn about it at this [website](https://flexboxfroggy.com/).\n\n## Features\n\nHere are some of the key features of Furex:\n\n- Flexbox layout: The UI layout can be configured using the properties of [View](https://pkg.go.dev/github.com/yohamta/furex/v2#View) instances, which can be thought of as equivalent to `DIV` elements in HTML. These views can be stacked or nested to create complex layouts.\n\n- Custom widgets: `View` instances can receive a `Handler` which is responsible for drawing and updating the view. This allows users to create any type of UI component by implementing the appropriate handler interfaces, such as [Drawer](https://pkg.go.dev/github.com/yohamta/furex/v2#Drawer), [Updater](https://pkg.go.dev/github.com/yohamta/furex/v2#Updater), and more.\n\n- Button support: To create a button, users can implement the [ButtonHandler](https://pkg.go.dev/github.com/yohamta/furex/v2#ButtonHandler) interface. This supports both touch and mouse input for button actions. See the [Example Button](./examples/game/widgets/button.go) for more details.\n\n- Touch and mouse events: Furex provides support for handling touch events and positions using the [TouchHandler](https://pkg.go.dev/github.com/yohamta/furex/v2#TouchHandler) interface, and mouse click events using the [MouseLeftButtonHandler](https://pkg.go.dev/github.com/yohamta/furex/v2#MouseLeftButtonHandler) interface. It also offers support for detecting mouse position events using the [MouseHandler](https://pkg.go.dev/github.com/yohamta/furex/v2#MouseHandler) interface, and mouse enter/leave events using the [MouseEnterLeaveHandler](https://pkg.go.dev/github.com/yohamta/furex/v2#MouseEnterLeaveHandler) interface.\n\n- Swipe gestures: Users can detect swipe gestures by implementing the [SwipeHandler](https://pkg.go.dev/github.com/yohamta/furex/v2#SwipeHandler) interface.\n\nThese are just a few examples of the capabilities of Furex. For more information, be sure to check out the [GoDoc](https://pkg.go.dev/github.com/yohamta/furex/v2) documentation.\n\n## Getting Started\n\nTo get started with Furex, install Furex using the following command:\n\n```sh\ngo get github.com/yohamta/furex/v2\n```\n\n## Basic Usage\n\nHere's a simple example of how to use Furex to create an UI in your game:\n\n[Full source code of the example](examples/simple/main.go)\n\n```go\ntype Game struct {\n  initOnce sync.Once\n  screen   screen\n  gameUI   *furex.View\n}\n\nfunc (g *Game) Update() error {\n  g.initOnce.Do(func() {\n    g.setupUI()\n  })\n  return nil\n}\n\nfunc (g *Game) Draw(screen *ebiten.Image) {\n  g.gameUI.Draw(screen)\n}\n\nfunc (g *Game) setupUI() {\n  screen.Fill(color.RGBA{0x3d, 0x55, 0x0c, 0xff})\n  colors := []color.Color{\n    color.RGBA{0x3d, 0x55, 0x0c, 0xff},\n    color.RGBA{0x81, 0xb6, 0x22, 0xff},\n    color.RGBA{0xec, 0xf8, 0x7f, 0xff},\n  }\n\n  g.gameUI = \u0026furex.View{\n    Width:        g.screen.Width,\n    Height:       g.screen.Height,\n    Direction:    furex.Row,\n    Justify:      furex.JustifyCenter,\n    AlignItems:   furex.AlignItemCenter,\n    AlignContent: furex.AlignContentCenter,\n    Wrap:         furex.Wrap,\n  }\n\n  for i := 0; i \u003c 20; i++ {\n    g.gameUI.AddChild(\u0026furex.View{\n      Width:  100,\n      Height: 100,\n      Handler: \u0026Box{\n        Color: colors[i%len(colors)],\n      },\n    })\n  }\n}\n\ntype Box struct {\n  Color color.Color\n}\n\nvar _ furex.Drawer = (*Box)(nil)\n\nfunc (b *Box) Draw(screen *ebiten.Image, frame image.Rectangle, view *furex.View) {\n  graphic.FillRect(screen, \u0026graphic.FillRectOpts{\n    Rect: frame, Color: b.Color,\n  })\n}\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"592\" src=\"./assets/greens.png\"\u003e\n\u003c/p\u003e\n\n## Building UI with HTML\n\nSometimes making a complex UI tree in Go can be cumbersome. You can use HTML to construct the UI tree more easily.\n\nHere's how to create a view tree from HTML:\n\n- ui.html\n  ```html\n  \u003chtml\u003e\n    \u003chead\u003e\n      \u003cstyle\u003e\n        container {\n          align-items: center;\n          justify-content: center;\n        }\n        .sprite {\n          width: 64px;\n          height: 64px;\n        }\n      \u003c/style\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n      \u003ccontainer\u003e\n        \u003ccharacter class=\"sprite\"\u003e\u003c/character\u003e\n      \u003c/container\u003e\n    \u003c/body\u003e\n  \u003c/html\u003e\n  ```\n\n- ui.go\n\n  ```go\n  //go:embed assets/html/ui.html\n  var html string\n\n  view := furex.Parse(html, \u0026furex.ParseOptions{\n    Width: 480,\n    Height: 600,\n    Components: map[string]furex.Component{\n      \"character\": \u0026widgets.Sprite{SpriteID: \"mario.png\"},\n    },\n  })\n  ```\n\n  Note: The `\u003cbody\u003e` tag itself won't be converted as a `View`, but its children will be converted to `View` instances.\n\nThis example is equivalent to the following Go code. By using HTML for styling the UI, the code becomes more maintainable.\n\n```go\nview := (\u0026furex.View{\n  Width: 480,\n  Height: 600,\n  AlignItems: furex.AlignItemsCenter,\n  Justify: furex.JustifyCenter,\n}).AddChild(\n  \u0026furex.View{\n    Width: 64,\n    Height: 64,\n    Handler: \u0026widgets.Sprite{SpriteID: \"mario.png\"},\n  },\n)\n```\n\nFor a more extensive example, check out the [example here](examples/game/main.go) and the embedded [HTML file](examples/game/assets/html/main.html).\n\n### CSS Properties\n\nThe following table lists the available CSS properties:\n\n| CSS Property | Type         | Available Values          |\n| -------------- | ------------ | ------------------------- |\n| `left`         | int          | Any integer value         |\n| `right`        | int          | Any integer value         |\n| `top`          | int          | Any integer value         |\n| `bottom`       | int          | Any integer value         |\n| `width`        | int          | Any integer value or percentage |\n| `height`       | int          | Any integer value or percentage |\n| `margin-left`  | int          | Any integer value         |\n| `margin-top`   | int          | Any integer value         |\n| `margin-right` | int          | Any integer value         |\n| `margin-bottom`| int          | Any integer value         |\n| `position`     | Position     | `static`, `absolute`      |\n| `flex-direction` | Direction    | `row`, `column`           |\n| `flex-wrap`    | FlexWrap     | `no-wrap`, `wrap`, `wrap-reverse` |\n| `justify-content` | Justify      | `flex-start`, `flex-end`, `center`, `space-between`, `space-around` |\n| `align-items`  | AlignItem    | `stretch`, `flex-start`, `flex-end`, `center` |\n| `align-content`| AlignContent | `flex-start`, `flex-end`, `center`, `space-between`, `space-around`, `stretch` |\n| `flex-grow`    | float64      | Any float64 value         |\n| `flex-shrink`  | float64      | Any float64 value         |\n| `display`      | Display      | `flex`, `none`            |\n\n### HTML Attributes\n\nThe following table lists the available HTML attributes:\n\n| HTML Attribute | Type               | Available Values          |\n| -------------- | ------------------ | ------------------------- |\n| `id`           | string             | Any string value          |\n| `hidden`       | bool               | `true`, `false`           |\n\n### Component Types\n\nThere are three types of components you can create in Furex:\n\n- **Handler Instance**: A `furex.Handler` instance, such as `Drawer` or `Updater`.\n- **Factory Function**: A function that returns a `furex.Handler` instance. This is useful when you want to create separate handler instances for each HTML tag.\n- **Function Component**: A function that returns a `*furex.View` instance. This is an alternative way to create components that encapsulate their own behavior and styles.\n\n### Global Components\n\nTo register a custom component globally, use the furex.RegisterComponents function. For example:\n\n```go\n  func init() {\n  \tfurex.RegisterComponents(furex.ComponentsMap{\n  \t\t\"button\":  \u0026widgets.Button{},\n  \t\t\"sprite\": \u0026widgets.Sprite{},\n  \t})\n  }\n```\n## Debugging\n\nYou can enable Debug Mode by setting the variable below.\n\n```go\nfurex.Debug = true\n```\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"592\" src=\"./assets/debug.png\"\u003e\n\u003c/p\u003e\n\n## Contributions\n\nContributions are welcome! If you find a bug or have an idea for a new feature, feel free to open an issue or submit a pull request.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyottahmd%2Ffurex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyottahmd%2Ffurex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyottahmd%2Ffurex/lists"}