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 OpenRawResource function
|
||||
* 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
|
||||
* 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 с помощью функции 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
|
||||
|
||||
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:
|
||||
|
||||
|
|
|
@ -2136,3 +2136,11 @@ function setCssVar(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
|
||||
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(path Path)
|
||||
// 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) {
|
||||
path.create(canvas.session)
|
||||
canvas.session.callCanvasFunc("clip")
|
||||
canvas.session.callCanvasFunc("clip", path.obj())
|
||||
}
|
||||
|
||||
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) {
|
||||
path.create(canvas.session)
|
||||
canvas.session.callCanvasFunc("fill")
|
||||
canvas.session.callCanvasFunc("fill", path.obj())
|
||||
}
|
||||
|
||||
func (canvas *canvasData) StrokePath(path Path) {
|
||||
path.create(canvas.session)
|
||||
canvas.session.callCanvasFunc("stroke")
|
||||
canvas.session.callCanvasFunc("stroke", path.obj())
|
||||
}
|
||||
|
||||
func (canvas *canvasData) FillAndStrokePath(path Path) {
|
||||
path.create(canvas.session)
|
||||
canvas.session.callCanvasFunc("fill")
|
||||
canvas.session.callCanvasFunc("stroke")
|
||||
canvas.session.callCanvasFunc("fill", path.obj())
|
||||
canvas.session.callCanvasFunc("stroke", path.obj())
|
||||
}
|
||||
|
||||
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) {
|
||||
if object.property == nil || len(object.property) == 0 {
|
||||
if len(object.property) == 0 {
|
||||
object.property = []DataNode{node}
|
||||
} else {
|
||||
tag := node.Tag()
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//go:build !wasm
|
||||
|
||||
package rui
|
||||
|
||||
import (
|
||||
|
@ -39,6 +41,7 @@ Example for echo:
|
|||
}
|
||||
})
|
||||
*/
|
||||
|
||||
func NewHandler(urlPrefix string, createContentFunc func(Session) SessionContent, params AppParams) *httpHandler {
|
||||
app := new(application)
|
||||
app.params = params
|
||||
|
|
54
path.go
54
path.go
|
@ -2,9 +2,6 @@ package rui
|
|||
|
||||
// Path is a 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(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.
|
||||
Close()
|
||||
|
||||
create(session Session)
|
||||
}
|
||||
|
||||
type pathElement struct {
|
||||
funcName string
|
||||
args []any
|
||||
//create(session Session)
|
||||
obj() any
|
||||
}
|
||||
|
||||
type pathData struct {
|
||||
elements []pathElement
|
||||
session Session
|
||||
varName any
|
||||
}
|
||||
|
||||
// NewPath creates a new empty Path
|
||||
func NewPath() Path {
|
||||
func (canvas *canvasData) NewPath() Path {
|
||||
path := new(pathData)
|
||||
path.Reset()
|
||||
path.session = canvas.session
|
||||
path.varName = canvas.session.createPath("")
|
||||
return path
|
||||
}
|
||||
|
||||
func (path *pathData) Reset() {
|
||||
path.elements = []pathElement{
|
||||
{funcName: "beginPath", args: []any{}},
|
||||
}
|
||||
func (canvas *canvasData) NewPathFromSvg(data string) Path {
|
||||
path := new(pathData)
|
||||
path.session = canvas.session
|
||||
path.varName = canvas.session.createPath(data)
|
||||
return path
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
if radius > 0 {
|
||||
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 {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
if radiusX > 0 && radiusY > 0 {
|
||||
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 {
|
||||
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() {
|
||||
path.elements = append(path.elements, pathElement{funcName: "close", args: []any{}})
|
||||
path.session.callCanvasVarFunc(path.varName, "close")
|
||||
}
|
||||
|
||||
func (path *pathData) create(session Session) {
|
||||
for _, element := range path.elements {
|
||||
session.callCanvasFunc(element.funcName, element.args...)
|
||||
}
|
||||
func (path *pathData) obj() any {
|
||||
return path.varName
|
||||
}
|
||||
|
|
2
popup.go
2
popup.go
|
@ -683,7 +683,7 @@ func (manager *popupManager) showPopup(popup Popup) {
|
|||
}
|
||||
|
||||
session := popup.Session()
|
||||
if manager.popups == nil || len(manager.popups) == 0 {
|
||||
if len(manager.popups) == 0 {
|
||||
manager.popups = []Popup{popup}
|
||||
} else {
|
||||
manager.popups = append(manager.popups, popup)
|
||||
|
|
|
@ -24,6 +24,7 @@ type bridge interface {
|
|||
callCanvasVarFunc(v any, funcName string, args ...any)
|
||||
callCanvasImageFunc(url string, property string, funcName string, args ...any)
|
||||
createCanvasVar(funcName string, args ...any) any
|
||||
createPath2D(arg string) any
|
||||
updateCanvasProperty(property string, value any)
|
||||
canvasFinish()
|
||||
canvasTextMetrics(htmlID, font, text string) TextMetrics
|
||||
|
@ -151,6 +152,7 @@ type Session interface {
|
|||
canvasStart(htmlID string) bool
|
||||
callCanvasFunc(funcName string, args ...any)
|
||||
createCanvasVar(funcName string, args ...any) any
|
||||
createPath(arg string) any
|
||||
callCanvasVarFunc(v any, funcName string, args ...any)
|
||||
callCanvasImageFunc(url string, property string, funcName string, args ...any)
|
||||
updateCanvasProperty(property string, value any)
|
||||
|
@ -561,6 +563,13 @@ func (session *sessionData) createCanvasVar(funcName string, args ...any) any {
|
|||
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) {
|
||||
if session.bridge != nil && v != nil {
|
||||
session.bridge.callCanvasVarFunc(v, funcName, args...)
|
||||
|
|
|
@ -313,7 +313,7 @@ func (session *sessionData) Language() string {
|
|||
return session.language
|
||||
}
|
||||
|
||||
if session.languages != nil && len(session.languages) > 0 {
|
||||
if len(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 {
|
||||
if clip.points == nil || len(clip.points) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
return len(clip.points) > 0
|
||||
}
|
||||
|
||||
func parseClipShape(obj DataObject) ClipShape {
|
||||
|
|
|
@ -66,7 +66,7 @@ func (container *viewsContainerData) Append(view View) {
|
|||
if view != nil {
|
||||
htmlID := container.htmlID()
|
||||
view.setParentID(htmlID)
|
||||
if container.views == nil || len(container.views) == 0 {
|
||||
if len(container.views) == 0 {
|
||||
container.views = []View{view}
|
||||
} else {
|
||||
container.views = append(container.views, view)
|
||||
|
|
|
@ -193,6 +193,17 @@ func (bridge *wasmBridge) createCanvasVar(funcName string, args ...any) any {
|
|||
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) {
|
||||
if !bridge.canvas.IsNull() {
|
||||
if ProtocolInDebugLog {
|
||||
|
|
14
webBridge.go
14
webBridge.go
|
@ -350,6 +350,20 @@ func (bridge *webBridge) createCanvasVar(funcName string, args ...any) any {
|
|||
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) {
|
||||
varName, ok := v.(canvasVar)
|
||||
if !ok {
|
||||
|
|
Loading…
Reference in New Issue