mirror of https://github.com/anoshenko/rui.git
Bug fixing
This commit is contained in:
parent
9f084cc3f2
commit
ecbcda7a53
|
@ -4581,7 +4581,7 @@ onNo или onCancel (если она не nil).
|
|||
|
||||
### Интерфейс Animation
|
||||
|
||||
Для задания параметров анимации мспользуется интерфейс Animation. Он расширяет интерфейс Properties.
|
||||
Для задания параметров анимации используется интерфейс Animation. Он расширяет интерфейс Properties.
|
||||
Интерфейс создается с помощью функции:
|
||||
|
||||
func NewAnimation(params Params) Animation
|
||||
|
@ -4751,7 +4751,7 @@ KeyFrames - промежуточные значения свойства (клю
|
|||
|
||||
Обязательными являются поля Tag, From, To. Поле KeyFrames опционально, может быть nil.
|
||||
|
||||
Поле KeyFrames описывает ключавые кадры. В качестве ключа типа int используется процент времени
|
||||
Поле KeyFrames описывает ключевые кадры. В качестве ключа типа int используется процент времени
|
||||
прошедший с начала анимации (именно начала самой анимации, время заданное свойством "delay" исключается).
|
||||
А значание это значение свойства в данный момент времени. Например
|
||||
|
||||
|
@ -4767,9 +4767,9 @@ KeyFrames - промежуточные значения свойства (клю
|
|||
В данном примере свойство "width" 90% времени будет увеличиваться со 100px до 220px. В оставшиеся
|
||||
10% времени - будет уменьшаться с 220px до 200px.
|
||||
|
||||
Свойству "property" присваивается []AnimatedProperty, а значит можно анимаровать сразу несколько свойств.
|
||||
Свойству "property" присваивается []AnimatedProperty, а значит можно анимировать сразу несколько свойств.
|
||||
|
||||
Вы должны задать хотя бы один эдемент "property", иначе анимация будет игнорироваться.
|
||||
Вы должны задать хотя бы один элемент "property", иначе анимация будет игнорироваться.
|
||||
|
||||
#### Свойство "id"
|
||||
|
||||
|
|
|
@ -609,8 +609,7 @@ func (session *sessionData) registerAnimation(props []AnimatedProperty) string {
|
|||
|
||||
style := cssBuilder.finish()
|
||||
session.animationCSS += style
|
||||
style = strings.ReplaceAll(style, "\n", `\n`)
|
||||
session.runScript(`document.querySelector('style').textContent += "` + style + `"`)
|
||||
session.addAnimationCSS(style)
|
||||
|
||||
return name
|
||||
}
|
||||
|
|
65
appWasm.go
65
appWasm.go
|
@ -26,7 +26,7 @@ func (app *wasmApp) Finish() {
|
|||
}
|
||||
|
||||
func wasmLog(text string) {
|
||||
js.Global().Call("log", text)
|
||||
js.Global().Get("console").Call("log", text)
|
||||
}
|
||||
|
||||
func (app *wasmApp) handleMessage(this js.Value, args []js.Value) any {
|
||||
|
@ -37,60 +37,9 @@ func (app *wasmApp) handleMessage(this js.Value, args []js.Value) any {
|
|||
}
|
||||
if obj := ParseDataText(text); obj != nil {
|
||||
switch command := obj.Tag(); command {
|
||||
/*
|
||||
case "startSession":
|
||||
answer := ""
|
||||
if session, answer = app.startSession(obj, events, bridge); session != nil {
|
||||
if !bridge.writeMessage(answer) {
|
||||
return
|
||||
}
|
||||
session.onStart()
|
||||
go sessionEventHandler(session, events, bridge)
|
||||
}
|
||||
case "session-close":
|
||||
app.close <- obj
|
||||
|
||||
case "reconnect":
|
||||
if sessionText, ok := obj.PropertyValue("session"); ok {
|
||||
if sessionID, err := strconv.Atoi(sessionText); err == nil {
|
||||
if session = app.sessions[sessionID]; session != nil {
|
||||
session.setBridge(events, bridge)
|
||||
answer := allocStringBuilder()
|
||||
defer freeStringBuilder(answer)
|
||||
|
||||
session.writeInitScript(answer)
|
||||
if !bridge.writeMessage(answer.String()) {
|
||||
return
|
||||
}
|
||||
session.onReconnect()
|
||||
go sessionEventHandler(session, events, bridge)
|
||||
return
|
||||
}
|
||||
DebugLogF("Session #%d not exists", sessionID)
|
||||
} else {
|
||||
ErrorLog(`strconv.Atoi(sessionText) error: ` + err.Error())
|
||||
}
|
||||
} else {
|
||||
ErrorLog(`"session" key not found`)
|
||||
}
|
||||
|
||||
answer := ""
|
||||
if session, answer = app.startSession(obj, events, bridge); session != nil {
|
||||
if !bridge.writeMessage(answer) {
|
||||
return
|
||||
}
|
||||
session.onStart()
|
||||
go sessionEventHandler(session, events, bridge)
|
||||
}
|
||||
|
||||
case "disconnect":
|
||||
session.onDisconnect()
|
||||
return
|
||||
|
||||
case "session-close":
|
||||
session.onFinish()
|
||||
session.App().removeSession(session.ID())
|
||||
bridge.close()
|
||||
|
||||
*/
|
||||
case "answer":
|
||||
app.session.handleAnswer(obj)
|
||||
|
||||
|
@ -176,6 +125,10 @@ func (app *wasmApp) init(params AppParams) {
|
|||
style.Set("textContent", css)
|
||||
document.Call("querySelector", "head").Call("appendChild", style)
|
||||
|
||||
style = document.Call("createElement", "style")
|
||||
style.Set("id", "ruiAnimations")
|
||||
document.Call("querySelector", "head").Call("appendChild", style)
|
||||
|
||||
buffer := allocStringBuilder()
|
||||
defer freeStringBuilder(buffer)
|
||||
|
||||
|
@ -216,14 +169,14 @@ func StartApp(addr string, createContentFunc func(Session) SessionContent, param
|
|||
|
||||
app := new(wasmApp)
|
||||
app.createContentFunc = createContentFunc
|
||||
app.bridge = createWasmBridge()
|
||||
app.close = make(chan DataObject)
|
||||
app.bridge = createWasmBridge(app.close)
|
||||
|
||||
app.init(params)
|
||||
<-app.close
|
||||
}
|
||||
|
||||
func FinishApp() {
|
||||
//app.Finish()
|
||||
}
|
||||
|
||||
func OpenBrowser(url string) bool {
|
||||
|
|
|
@ -5,6 +5,8 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
var wasmMediaResources = false
|
||||
|
||||
//go:embed app_scripts.js
|
||||
var defaultScripts string
|
||||
|
||||
|
@ -66,6 +68,7 @@ func getStartPage(buffer *strings.Builder, params AppParams, addScripts string)
|
|||
<style>`)
|
||||
buffer.WriteString(appStyles)
|
||||
buffer.WriteString(`</style>
|
||||
<style id="ruiAnimations"></style>
|
||||
<script>
|
||||
`)
|
||||
buffer.WriteString(defaultScripts)
|
||||
|
|
3
image.go
3
image.go
|
@ -83,8 +83,9 @@ func (manager *imageManager) loadImage(url string, onLoaded func(Image), session
|
|||
image.loadingStatus = ImageLoading
|
||||
manager.images[url] = image
|
||||
|
||||
if runtime.GOOS == "js" {
|
||||
if runtime.GOOS == "js" && wasmMediaResources {
|
||||
if file, ok := resources.images[url]; ok && file.fs != nil {
|
||||
|
||||
dataType := map[string]string{
|
||||
".svg": "data:image/svg+xml",
|
||||
".png": "data:image/png",
|
||||
|
|
|
@ -226,7 +226,7 @@ func (imageView *imageViewData) src(src string) (string, string) {
|
|||
|
||||
if src != "" {
|
||||
srcset := imageView.srcSet(src)
|
||||
if runtime.GOOS == "js" {
|
||||
if runtime.GOOS == "js" && wasmMediaResources {
|
||||
if image, ok := resources.images[src]; ok && image.fs != nil {
|
||||
dataType := map[string]string{
|
||||
".svg": "data:image/svg+xml",
|
||||
|
|
2
path.go
2
path.go
|
@ -79,7 +79,7 @@ func NewPath() Path {
|
|||
|
||||
func (path *pathData) Reset() {
|
||||
path.elements = []pathElement{
|
||||
pathElement{funcName: "beginPath", args: []any{}},
|
||||
{funcName: "beginPath", args: []any{}},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
27
session.go
27
session.go
|
@ -18,6 +18,8 @@ type webBridge interface {
|
|||
removeProperty(htmlID, property string)
|
||||
readMessage() (string, bool)
|
||||
writeMessage(text string) bool
|
||||
addAnimationCSS(css string)
|
||||
clearAnimation()
|
||||
cavnasStart(htmlID string)
|
||||
callCanvasFunc(funcName string, args ...any)
|
||||
callCanvasVarFunc(v any, funcName string, args ...any)
|
||||
|
@ -119,9 +121,10 @@ type Session interface {
|
|||
updateCSSProperty(htmlID, property, value string)
|
||||
updateProperty(htmlID, property string, value any)
|
||||
removeProperty(htmlID, property string)
|
||||
runScript(script string)
|
||||
startUpdateScript(htmlID string) bool
|
||||
finishUpdateScript(htmlID string)
|
||||
addAnimationCSS(css string)
|
||||
clearAnimation()
|
||||
cavnasStart(htmlID string)
|
||||
callCanvasFunc(funcName string, args ...any)
|
||||
createCanvasVar(funcName string, args ...any) any
|
||||
|
@ -309,7 +312,7 @@ func (session *sessionData) reload() {
|
|||
buffer.WriteString("';\nscanElementsSize();")
|
||||
}
|
||||
|
||||
session.runScript(buffer.String())
|
||||
session.bridge.writeMessage(buffer.String())
|
||||
}
|
||||
|
||||
func (session *sessionData) ignoreViewUpdates() bool {
|
||||
|
@ -409,6 +412,18 @@ func (session *sessionData) finishUpdateScript(htmlID string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (session *sessionData) addAnimationCSS(css string) {
|
||||
if session.bridge != nil {
|
||||
session.bridge.addAnimationCSS(css)
|
||||
}
|
||||
}
|
||||
|
||||
func (session *sessionData) clearAnimation() {
|
||||
if session.bridge != nil {
|
||||
session.bridge.clearAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
func (session *sessionData) cavnasStart(htmlID string) {
|
||||
if session.bridge != nil {
|
||||
session.bridge.cavnasStart(htmlID)
|
||||
|
@ -452,14 +467,6 @@ func (session *sessionData) cavnasFinish() {
|
|||
}
|
||||
}
|
||||
|
||||
func (session *sessionData) runScript(script string) {
|
||||
if session.bridge != nil {
|
||||
session.bridge.writeMessage(script)
|
||||
} else {
|
||||
ErrorLog("No connection")
|
||||
}
|
||||
}
|
||||
|
||||
func (session *sessionData) canvasTextMetrics(htmlID, font, text string) TextMetrics {
|
||||
if session.bridge != nil {
|
||||
return session.bridge.canvasTextMetrics(htmlID, font, text)
|
||||
|
|
|
@ -329,11 +329,7 @@ func (session *sessionData) SetLanguage(lang string) {
|
|||
buffer := allocStringBuilder()
|
||||
defer freeStringBuilder(buffer)
|
||||
|
||||
//buffer.WriteString(`document.getElementById('ruiRootView').innerHTML = '`)
|
||||
viewHTML(session.rootView, buffer)
|
||||
//buffer.WriteString("';\nscanElementsSize();")
|
||||
|
||||
//session.runScript(buffer.String())
|
||||
session.bridge.updateInnerHTML("ruiRootView", buffer.String())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,25 +5,22 @@ package rui
|
|||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"sync"
|
||||
"strings"
|
||||
"syscall/js"
|
||||
)
|
||||
|
||||
type wasmBridge struct {
|
||||
queue chan string
|
||||
answer map[int]chan DataObject
|
||||
answerID int
|
||||
answerMutex sync.Mutex
|
||||
closed bool
|
||||
canvas js.Value
|
||||
answer map[int]chan DataObject
|
||||
answerID int
|
||||
canvas js.Value
|
||||
closeEvent chan DataObject
|
||||
}
|
||||
|
||||
func createWasmBridge() webBridge {
|
||||
func createWasmBridge(close chan DataObject) webBridge {
|
||||
bridge := new(wasmBridge)
|
||||
bridge.queue = make(chan string, 1000)
|
||||
bridge.answerID = 1
|
||||
bridge.answer = make(map[int]chan DataObject)
|
||||
bridge.closed = false
|
||||
bridge.closeEvent = close
|
||||
|
||||
return bridge
|
||||
}
|
||||
|
@ -57,7 +54,15 @@ func (bridge *wasmBridge) callFunc(funcName string, args ...any) bool {
|
|||
}
|
||||
|
||||
func (bridge *wasmBridge) updateInnerHTML(htmlID, html string) {
|
||||
bridge.updateProperty(htmlID, "innerHTML", html)
|
||||
if ProtocolInDebugLog {
|
||||
DebugLog(fmt.Sprintf("%s.innerHTML = '%s'", htmlID, html))
|
||||
}
|
||||
|
||||
element := js.Global().Get("document").Call("getElementById", htmlID)
|
||||
if !element.IsUndefined() && !element.IsNull() {
|
||||
element.Set("innerHTML", html)
|
||||
js.Global().Call("scanElementsSize")
|
||||
}
|
||||
}
|
||||
|
||||
func (bridge *wasmBridge) appendToInnerHTML(htmlID, html string) {
|
||||
|
@ -86,15 +91,7 @@ func (bridge *wasmBridge) updateCSSProperty(htmlID, property, value string) {
|
|||
}
|
||||
|
||||
func (bridge *wasmBridge) updateProperty(htmlID, property string, value any) {
|
||||
if ProtocolInDebugLog {
|
||||
DebugLog(fmt.Sprintf("%s.%s = '%v'", htmlID, property, value))
|
||||
}
|
||||
|
||||
element := js.Global().Get("document").Call("getElementById", htmlID)
|
||||
if !element.IsUndefined() && !element.IsNull() {
|
||||
element.Set(property, value)
|
||||
js.Global().Call("scanElementsSize")
|
||||
}
|
||||
bridge.callFunc("updateProperty", htmlID, property, value)
|
||||
}
|
||||
|
||||
func (bridge *wasmBridge) removeProperty(htmlID, property string) {
|
||||
|
@ -102,6 +99,7 @@ func (bridge *wasmBridge) removeProperty(htmlID, property string) {
|
|||
}
|
||||
|
||||
func (bridge *wasmBridge) close() {
|
||||
bridge.closeEvent <- NewDataObject("close")
|
||||
}
|
||||
|
||||
func (bridge *wasmBridge) readMessage() (string, bool) {
|
||||
|
@ -120,6 +118,23 @@ func (bridge *wasmBridge) writeMessage(script string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (bridge *wasmBridge) addAnimationCSS(css string) {
|
||||
css = strings.ReplaceAll(css, `\t`, "\t")
|
||||
css = strings.ReplaceAll(css, `\n`, "\n")
|
||||
css = strings.ReplaceAll(css, `\'`, "'")
|
||||
css = strings.ReplaceAll(css, `\"`, "\"")
|
||||
css = strings.ReplaceAll(css, `\\`, "\\")
|
||||
|
||||
styles := js.Global().Get("document").Call("getElementById", "ruiAnimations")
|
||||
content := styles.Get("textContent").String()
|
||||
styles.Set("textContent", content+"\n"+css)
|
||||
}
|
||||
|
||||
func (bridge *wasmBridge) clearAnimation() {
|
||||
styles := js.Global().Get("document").Call("getElementById", "ruiAnimations")
|
||||
styles.Set("textContent", "")
|
||||
}
|
||||
|
||||
func (bridge *wasmBridge) cavnasStart(htmlID string) {
|
||||
if ProtocolInDebugLog {
|
||||
DebugLog("const ctx = document.getElementById('" + htmlID + "'elementId').getContext('2d');\nctx.save();")
|
||||
|
|
14
webBridge.go
14
webBridge.go
|
@ -224,6 +224,20 @@ func (bridge *wsBridge) removeProperty(htmlID, property string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (bridge *wsBridge) addAnimationCSS(css string) {
|
||||
bridge.writeMessage(`var styles = document.getElementById('ruiAnimations');
|
||||
if (styles) {
|
||||
styles.textContent += '` + css + `';
|
||||
}`)
|
||||
}
|
||||
|
||||
func (bridge *wsBridge) clearAnimation() {
|
||||
bridge.writeMessage(`var styles = document.getElementById('ruiAnimations');
|
||||
if (styles) {
|
||||
styles.textContent = '';
|
||||
}`)
|
||||
}
|
||||
|
||||
func (bridge *wsBridge) cavnasStart(htmlID string) {
|
||||
bridge.canvasBuffer.Reset()
|
||||
bridge.canvasBuffer.WriteString(`const ctx = getCanvasContext('`)
|
||||
|
|
Loading…
Reference in New Issue