mirror of https://github.com/anoshenko/rui.git
Updated Path
* Added NewPath and NewPathFromSvg methods to Canvas interface * Removed NewPath function * Removed Reset methods from Path interface
This commit is contained in:
parent
2708c7ceb6
commit
87148836c0
|
@ -5,6 +5,9 @@
|
||||||
* Added "transform" property and Transform interface
|
* Added "transform" property and Transform interface
|
||||||
* Added OpenRawResource function
|
* Added OpenRawResource function
|
||||||
* Added RemoveClientItem method to Session interface
|
* Added RemoveClientItem method to Session interface
|
||||||
|
* Added NewPath and NewPathFromSvg methods to Canvas interface
|
||||||
|
* Removed NewPath function
|
||||||
|
* Removed Reset methods from Path interface
|
||||||
|
|
||||||
# v0.16.0
|
# v0.16.0
|
||||||
* Can use ListAdapter as "content" property value of ListLayout
|
* Can use ListAdapter as "content" property value of ListLayout
|
||||||
|
|
12
README-ru.md
12
README-ru.md
|
@ -4443,7 +4443,17 @@ rotation - угол поворота эллипса относительно ц
|
||||||
|
|
||||||
#### Path
|
#### Path
|
||||||
|
|
||||||
Интерфейс Path позволяет описать сложную фигуру. Создается Path с помощью функции NewPath().
|
Интерфейс Path позволяет описать сложную фигуру. Для создания объекта Path используются два метода Canvas:
|
||||||
|
|
||||||
|
NewPath() Path
|
||||||
|
NewPathFromSvg(data string) Path
|
||||||
|
|
||||||
|
Метод NewPath() создает пустую фигуру. Далее вы должны описать фигуру используя методы интерфейса Path
|
||||||
|
|
||||||
|
Метод NewPathFromSvg(data string) Path создает фигуру описанную в параметре data.
|
||||||
|
Параметр data является описанием фигуры в формате елемента <path> svg изображения. Например
|
||||||
|
|
||||||
|
path := canvas.NewPathFromSvg("m 305,77.362183 c 0,0 -3,8.648649 -13,21.621616 -10,12.972981 -17,18.378381 -17,18.378381 0,0 6,4.32433 17,18.37838 11,14.05406 13,21.62162 13,21.62162 0,0 7.83867,-14.92584 13,-21.62162 10,-12.97297 17,-18.37838 17,-18.37838 0,0 -7,-5.4054 -17,-18.378381 C 308,86.010832 305,77.362183 305,77.362183 Z")
|
||||||
|
|
||||||
После создания вы должны описать фигуру. Для этого могут использоваться следующие функции интерфейса:
|
После создания вы должны описать фигуру. Для этого могут использоваться следующие функции интерфейса:
|
||||||
|
|
||||||
|
|
12
README.md
12
README.md
|
@ -4411,7 +4411,17 @@ rotation - the angle of rotation of the ellipse relative to the center in radian
|
||||||
|
|
||||||
#### Path
|
#### Path
|
||||||
|
|
||||||
The Path interface allows you to describe a complex shape. Path is created using the NewPath () function.
|
The Path interface allows you to describe a complex shape. Two Canvas methods are used to create a Path object:
|
||||||
|
|
||||||
|
NewPath() Path
|
||||||
|
NewPathFromSvg(data string) Path
|
||||||
|
|
||||||
|
The NewPath() method creates an empty shape. Next, you must describe the shape using the methods of the Path interface
|
||||||
|
|
||||||
|
The NewPathFromSvg(data string) Path method creates the shape described in the data parameter.
|
||||||
|
The data parameter is a description of the shape in the format of a <path> svg image element. For example
|
||||||
|
|
||||||
|
path := canvas.NewPathFromSvg("m 305,77.362183 c 0,0 -3,8.648649 -13,21.621616 -10,12.972981 -17,18.378381 -17,18.378381 0,0 6,4.32433 17,18.37838 11,14.05406 13,21.62162 13,21.62162 0,0 7.83867,-14.92584 13,-21.62162 10,-12.97297 17,-18.37838 17,-18.37838 0,0 -7,-5.4054 -17,-18.378381 C 308,86.010832 305,77.362183 305,77.362183 Z")
|
||||||
|
|
||||||
Once created, you must describe the shape. For this, the following interface functions can be used:
|
Once created, you must describe the shape. For this, the following interface functions can be used:
|
||||||
|
|
||||||
|
|
|
@ -2136,3 +2136,11 @@ function setCssVar(tag, value) {
|
||||||
root.style.setProperty(tag, value);
|
root.style.setProperty(tag, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createPath2D(svg) {
|
||||||
|
if (svg) {
|
||||||
|
return new Path2D(svg);
|
||||||
|
} else {
|
||||||
|
return new Path2D();
|
||||||
|
}
|
||||||
|
}
|
19
canvas.go
19
canvas.go
|
@ -263,6 +263,11 @@ type Canvas interface {
|
||||||
// and is stroked (outlined) according to the current strokeStyle and other context settings
|
// and is stroked (outlined) according to the current strokeStyle and other context settings
|
||||||
FillAndStrokeEllipse(x, y, radiusX, radiusY, rotation float64)
|
FillAndStrokeEllipse(x, y, radiusX, radiusY, rotation float64)
|
||||||
|
|
||||||
|
// NewPath creates a new Path object
|
||||||
|
NewPath() Path
|
||||||
|
// NewPathFromSvg creates a new Path and initialize it by a string consisting of SVG path data
|
||||||
|
NewPathFromSvg(data string) Path
|
||||||
|
|
||||||
// FillPath draws a path that is filled according to the current FillStyle.
|
// FillPath draws a path that is filled according to the current FillStyle.
|
||||||
FillPath(path Path)
|
FillPath(path Path)
|
||||||
// StrokePath draws a path that is stroked (outlined) according to the current strokeStyle
|
// StrokePath draws a path that is stroked (outlined) according to the current strokeStyle
|
||||||
|
@ -346,8 +351,7 @@ func (canvas *canvasData) ClipRect(x, y, width, height float64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (canvas *canvasData) ClipPath(path Path) {
|
func (canvas *canvasData) ClipPath(path Path) {
|
||||||
path.create(canvas.session)
|
canvas.session.callCanvasFunc("clip", path.obj())
|
||||||
canvas.session.callCanvasFunc("clip")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (canvas *canvasData) SetScale(x, y float64) {
|
func (canvas *canvasData) SetScale(x, y float64) {
|
||||||
|
@ -779,19 +783,16 @@ func (canvas *canvasData) StrokeText(x, y float64, text string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (canvas *canvasData) FillPath(path Path) {
|
func (canvas *canvasData) FillPath(path Path) {
|
||||||
path.create(canvas.session)
|
canvas.session.callCanvasFunc("fill", path.obj())
|
||||||
canvas.session.callCanvasFunc("fill")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (canvas *canvasData) StrokePath(path Path) {
|
func (canvas *canvasData) StrokePath(path Path) {
|
||||||
path.create(canvas.session)
|
canvas.session.callCanvasFunc("stroke", path.obj())
|
||||||
canvas.session.callCanvasFunc("stroke")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (canvas *canvasData) FillAndStrokePath(path Path) {
|
func (canvas *canvasData) FillAndStrokePath(path Path) {
|
||||||
path.create(canvas.session)
|
canvas.session.callCanvasFunc("fill", path.obj())
|
||||||
canvas.session.callCanvasFunc("fill")
|
canvas.session.callCanvasFunc("stroke", path.obj())
|
||||||
canvas.session.callCanvasFunc("stroke")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (canvas *canvasData) DrawLine(x0, y0, x1, y1 float64) {
|
func (canvas *canvasData) DrawLine(x0, y0, x1, y1 float64) {
|
||||||
|
|
2
data.go
2
data.go
|
@ -134,7 +134,7 @@ func (object *dataObject) PropertyObject(tag string) DataObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (object *dataObject) setNode(node DataNode) {
|
func (object *dataObject) setNode(node DataNode) {
|
||||||
if object.property == nil || len(object.property) == 0 {
|
if len(object.property) == 0 {
|
||||||
object.property = []DataNode{node}
|
object.property = []DataNode{node}
|
||||||
} else {
|
} else {
|
||||||
tag := node.Tag()
|
tag := node.Tag()
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
//go:build !wasm
|
||||||
|
|
||||||
package rui
|
package rui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -39,6 +41,7 @@ Example for echo:
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func NewHandler(urlPrefix string, createContentFunc func(Session) SessionContent, params AppParams) *httpHandler {
|
func NewHandler(urlPrefix string, createContentFunc func(Session) SessionContent, params AppParams) *httpHandler {
|
||||||
app := new(application)
|
app := new(application)
|
||||||
app.params = params
|
app.params = params
|
||||||
|
|
54
path.go
54
path.go
|
@ -2,9 +2,6 @@ package rui
|
||||||
|
|
||||||
// Path is a path interface
|
// Path is a path interface
|
||||||
type Path interface {
|
type Path interface {
|
||||||
// Reset erases the Path
|
|
||||||
Reset()
|
|
||||||
|
|
||||||
// MoveTo begins a new sub-path at the point specified by the given (x, y) coordinates
|
// MoveTo begins a new sub-path at the point specified by the given (x, y) coordinates
|
||||||
MoveTo(x, y float64)
|
MoveTo(x, y float64)
|
||||||
|
|
||||||
|
@ -58,79 +55,76 @@ type Path interface {
|
||||||
// If the shape has already been closed or has only one point, this function does nothing.
|
// If the shape has already been closed or has only one point, this function does nothing.
|
||||||
Close()
|
Close()
|
||||||
|
|
||||||
create(session Session)
|
//create(session Session)
|
||||||
}
|
obj() any
|
||||||
|
|
||||||
type pathElement struct {
|
|
||||||
funcName string
|
|
||||||
args []any
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type pathData struct {
|
type pathData struct {
|
||||||
elements []pathElement
|
session Session
|
||||||
|
varName any
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPath creates a new empty Path
|
// NewPath creates a new empty Path
|
||||||
func NewPath() Path {
|
func (canvas *canvasData) NewPath() Path {
|
||||||
path := new(pathData)
|
path := new(pathData)
|
||||||
path.Reset()
|
path.session = canvas.session
|
||||||
|
path.varName = canvas.session.createPath("")
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
func (path *pathData) Reset() {
|
func (canvas *canvasData) NewPathFromSvg(data string) Path {
|
||||||
path.elements = []pathElement{
|
path := new(pathData)
|
||||||
{funcName: "beginPath", args: []any{}},
|
path.session = canvas.session
|
||||||
}
|
path.varName = canvas.session.createPath(data)
|
||||||
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
func (path *pathData) MoveTo(x, y float64) {
|
func (path *pathData) MoveTo(x, y float64) {
|
||||||
path.elements = append(path.elements, pathElement{funcName: "moveTo", args: []any{x, y}})
|
path.session.callCanvasVarFunc(path.varName, "moveTo", x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (path *pathData) LineTo(x, y float64) {
|
func (path *pathData) LineTo(x, y float64) {
|
||||||
path.elements = append(path.elements, pathElement{funcName: "lineTo", args: []any{x, y}})
|
path.session.callCanvasVarFunc(path.varName, "lineTo", x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (path *pathData) ArcTo(x0, y0, x1, y1, radius float64) {
|
func (path *pathData) ArcTo(x0, y0, x1, y1, radius float64) {
|
||||||
if radius > 0 {
|
if radius > 0 {
|
||||||
path.elements = append(path.elements, pathElement{funcName: "arcTo", args: []any{x0, y0, x1, y1, radius}})
|
path.session.callCanvasVarFunc(path.varName, "arcTo", x0, y0, x1, y1, radius)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (path *pathData) Arc(x, y, radius, startAngle, endAngle float64, clockwise bool) {
|
func (path *pathData) Arc(x, y, radius, startAngle, endAngle float64, clockwise bool) {
|
||||||
if radius > 0 {
|
if radius > 0 {
|
||||||
if !clockwise {
|
if !clockwise {
|
||||||
path.elements = append(path.elements, pathElement{funcName: "arc", args: []any{x, y, radius, startAngle, endAngle, true}})
|
path.session.callCanvasVarFunc(path.varName, "arc", x, y, radius, startAngle, endAngle, true)
|
||||||
} else {
|
} else {
|
||||||
path.elements = append(path.elements, pathElement{funcName: "arc", args: []any{x, y, radius, startAngle, endAngle}})
|
path.session.callCanvasVarFunc(path.varName, "arc", x, y, radius, startAngle, endAngle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (path *pathData) BezierCurveTo(cp0x, cp0y, cp1x, cp1y, x, y float64) {
|
func (path *pathData) BezierCurveTo(cp0x, cp0y, cp1x, cp1y, x, y float64) {
|
||||||
path.elements = append(path.elements, pathElement{funcName: "bezierCurveTo", args: []any{cp0x, cp0y, cp1x, cp1y, x, y}})
|
path.session.callCanvasVarFunc(path.varName, "bezierCurveTo", cp0x, cp0y, cp1x, cp1y, x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (path *pathData) QuadraticCurveTo(cpx, cpy, x, y float64) {
|
func (path *pathData) QuadraticCurveTo(cpx, cpy, x, y float64) {
|
||||||
path.elements = append(path.elements, pathElement{funcName: "quadraticCurveTo", args: []any{cpx, cpy, x, y}})
|
path.session.callCanvasVarFunc(path.varName, "quadraticCurveTo", cpx, cpy, x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (path *pathData) Ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle float64, clockwise bool) {
|
func (path *pathData) Ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle float64, clockwise bool) {
|
||||||
if radiusX > 0 && radiusY > 0 {
|
if radiusX > 0 && radiusY > 0 {
|
||||||
if !clockwise {
|
if !clockwise {
|
||||||
path.elements = append(path.elements, pathElement{funcName: "ellipse", args: []any{x, y, radiusX, radiusY, rotation, startAngle, endAngle, true}})
|
path.session.callCanvasVarFunc(path.varName, "ellipse", x, y, radiusX, radiusY, rotation, startAngle, endAngle, true)
|
||||||
} else {
|
} else {
|
||||||
path.elements = append(path.elements, pathElement{funcName: "ellipse", args: []any{x, y, radiusX, radiusY, rotation, startAngle, endAngle}})
|
path.session.callCanvasVarFunc(path.varName, "ellipse", x, y, radiusX, radiusY, rotation, startAngle, endAngle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (path *pathData) Close() {
|
func (path *pathData) Close() {
|
||||||
path.elements = append(path.elements, pathElement{funcName: "close", args: []any{}})
|
path.session.callCanvasVarFunc(path.varName, "close")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (path *pathData) create(session Session) {
|
func (path *pathData) obj() any {
|
||||||
for _, element := range path.elements {
|
return path.varName
|
||||||
session.callCanvasFunc(element.funcName, element.args...)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
2
popup.go
2
popup.go
|
@ -683,7 +683,7 @@ func (manager *popupManager) showPopup(popup Popup) {
|
||||||
}
|
}
|
||||||
|
|
||||||
session := popup.Session()
|
session := popup.Session()
|
||||||
if manager.popups == nil || len(manager.popups) == 0 {
|
if len(manager.popups) == 0 {
|
||||||
manager.popups = []Popup{popup}
|
manager.popups = []Popup{popup}
|
||||||
} else {
|
} else {
|
||||||
manager.popups = append(manager.popups, popup)
|
manager.popups = append(manager.popups, popup)
|
||||||
|
|
|
@ -24,6 +24,7 @@ type bridge interface {
|
||||||
callCanvasVarFunc(v any, funcName string, args ...any)
|
callCanvasVarFunc(v any, funcName string, args ...any)
|
||||||
callCanvasImageFunc(url string, property string, funcName string, args ...any)
|
callCanvasImageFunc(url string, property string, funcName string, args ...any)
|
||||||
createCanvasVar(funcName string, args ...any) any
|
createCanvasVar(funcName string, args ...any) any
|
||||||
|
createPath2D(arg string) any
|
||||||
updateCanvasProperty(property string, value any)
|
updateCanvasProperty(property string, value any)
|
||||||
canvasFinish()
|
canvasFinish()
|
||||||
canvasTextMetrics(htmlID, font, text string) TextMetrics
|
canvasTextMetrics(htmlID, font, text string) TextMetrics
|
||||||
|
@ -151,6 +152,7 @@ type Session interface {
|
||||||
canvasStart(htmlID string) bool
|
canvasStart(htmlID string) bool
|
||||||
callCanvasFunc(funcName string, args ...any)
|
callCanvasFunc(funcName string, args ...any)
|
||||||
createCanvasVar(funcName string, args ...any) any
|
createCanvasVar(funcName string, args ...any) any
|
||||||
|
createPath(arg string) any
|
||||||
callCanvasVarFunc(v any, funcName string, args ...any)
|
callCanvasVarFunc(v any, funcName string, args ...any)
|
||||||
callCanvasImageFunc(url string, property string, funcName string, args ...any)
|
callCanvasImageFunc(url string, property string, funcName string, args ...any)
|
||||||
updateCanvasProperty(property string, value any)
|
updateCanvasProperty(property string, value any)
|
||||||
|
@ -561,6 +563,13 @@ func (session *sessionData) createCanvasVar(funcName string, args ...any) any {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (session *sessionData) createPath(arg string) any {
|
||||||
|
if session.bridge != nil {
|
||||||
|
return session.bridge.createPath2D(arg)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (session *sessionData) callCanvasVarFunc(v any, funcName string, args ...any) {
|
func (session *sessionData) callCanvasVarFunc(v any, funcName string, args ...any) {
|
||||||
if session.bridge != nil && v != nil {
|
if session.bridge != nil && v != nil {
|
||||||
session.bridge.callCanvasVarFunc(v, funcName, args...)
|
session.bridge.callCanvasVarFunc(v, funcName, args...)
|
||||||
|
|
|
@ -313,7 +313,7 @@ func (session *sessionData) Language() string {
|
||||||
return session.language
|
return session.language
|
||||||
}
|
}
|
||||||
|
|
||||||
if session.languages != nil && len(session.languages) > 0 {
|
if len(session.languages) > 0 {
|
||||||
return session.languages[0]
|
return session.languages[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -454,11 +454,7 @@ func (clip *polygonClip) cssStyle(session Session) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (clip *polygonClip) valid(session Session) bool {
|
func (clip *polygonClip) valid(session Session) bool {
|
||||||
if clip.points == nil || len(clip.points) == 0 {
|
return len(clip.points) > 0
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseClipShape(obj DataObject) ClipShape {
|
func parseClipShape(obj DataObject) ClipShape {
|
||||||
|
|
|
@ -66,7 +66,7 @@ func (container *viewsContainerData) Append(view View) {
|
||||||
if view != nil {
|
if view != nil {
|
||||||
htmlID := container.htmlID()
|
htmlID := container.htmlID()
|
||||||
view.setParentID(htmlID)
|
view.setParentID(htmlID)
|
||||||
if container.views == nil || len(container.views) == 0 {
|
if len(container.views) == 0 {
|
||||||
container.views = []View{view}
|
container.views = []View{view}
|
||||||
} else {
|
} else {
|
||||||
container.views = append(container.views, view)
|
container.views = append(container.views, view)
|
||||||
|
|
|
@ -193,6 +193,17 @@ func (bridge *wasmBridge) createCanvasVar(funcName string, args ...any) any {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bridge *wasmBridge) createPath2D(arg string) any {
|
||||||
|
if arg != "" {
|
||||||
|
result := bridge.canvas.Call("createPath2D", arg)
|
||||||
|
bridge.printFuncToLog("var "+result.String()+" = new Path2D", arg)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
result := bridge.canvas.Call("createPath2D")
|
||||||
|
bridge.printFuncToLog("var " + result.String() + " = new Path2D")
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func (bridge *wasmBridge) updateCanvasProperty(property string, value any) {
|
func (bridge *wasmBridge) updateCanvasProperty(property string, value any) {
|
||||||
if !bridge.canvas.IsNull() {
|
if !bridge.canvas.IsNull() {
|
||||||
if ProtocolInDebugLog {
|
if ProtocolInDebugLog {
|
||||||
|
|
14
webBridge.go
14
webBridge.go
|
@ -350,6 +350,20 @@ func (bridge *webBridge) createCanvasVar(funcName string, args ...any) any {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bridge *webBridge) createPath2D(arg string) any {
|
||||||
|
bridge.canvasVarNumber++
|
||||||
|
result := canvasVar{name: fmt.Sprintf("v%d", bridge.canvasVarNumber)}
|
||||||
|
bridge.canvasBuffer.WriteString("\nlet ")
|
||||||
|
bridge.canvasBuffer.WriteString(result.name)
|
||||||
|
bridge.canvasBuffer.WriteString(` = new Path2D(`)
|
||||||
|
if arg != "" {
|
||||||
|
argText, _ := bridge.argToString(arg)
|
||||||
|
bridge.canvasBuffer.WriteString(argText)
|
||||||
|
}
|
||||||
|
bridge.canvasBuffer.WriteString(`);`)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func (bridge *webBridge) callCanvasVarFunc(v any, funcName string, args ...any) {
|
func (bridge *webBridge) callCanvasVarFunc(v any, funcName string, args ...any) {
|
||||||
varName, ok := v.(canvasVar)
|
varName, ok := v.(canvasVar)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
Loading…
Reference in New Issue