mirror of https://github.com/anoshenko/rui.git
Added Start, Stop, Pause, and Resume methods to Animation interface
This commit is contained in:
parent
2f3de8fce3
commit
5e3d37a6a0
|
@ -1,6 +1,7 @@
|
||||||
# v0.17.0
|
# v0.17.0
|
||||||
* Added "mod", "rem", "round", "round-up", "round-down", and "round-to-zero" SizeFunc functions
|
* Added "mod", "rem", "round", "round-up", "round-down", and "round-to-zero" SizeFunc functions
|
||||||
* Added ModSize, RemSize, RoundSize, RoundUpSize, RoundDownSize, and RoundToZeroSize functions
|
* Added ModSize, RemSize, RoundSize, RoundUpSize, RoundDownSize, and RoundToZeroSize functions
|
||||||
|
* Added Start, Stop, Pause, and Resume methods to Animation 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
|
||||||
|
|
53
animation.go
53
animation.go
|
@ -121,6 +121,10 @@ type animationData struct {
|
||||||
propertyList
|
propertyList
|
||||||
keyFramesName string
|
keyFramesName string
|
||||||
usageCounter int
|
usageCounter int
|
||||||
|
view View
|
||||||
|
listener func(view View, animation Animation, event string)
|
||||||
|
oldListeners map[string][]func(View, string)
|
||||||
|
oldAnimation []Animation
|
||||||
}
|
}
|
||||||
|
|
||||||
// Animation interface is used to set animation parameters. Used properties:
|
// Animation interface is used to set animation parameters. Used properties:
|
||||||
|
@ -128,6 +132,17 @@ type animationData struct {
|
||||||
type Animation interface {
|
type Animation interface {
|
||||||
Properties
|
Properties
|
||||||
fmt.Stringer
|
fmt.Stringer
|
||||||
|
|
||||||
|
// Start starts the animation for the view specified by the first argument.
|
||||||
|
// The second argument specifies the animation event listener (can be nil)
|
||||||
|
Start(view View, listener func(view View, animation Animation, event string)) bool
|
||||||
|
// Stop stops the animation
|
||||||
|
Stop()
|
||||||
|
// Pause pauses the animation
|
||||||
|
Pause()
|
||||||
|
// Resume resumes an animation that was stopped using the Pause method
|
||||||
|
Resume()
|
||||||
|
|
||||||
writeTransitionString(tag string, buffer *strings.Builder)
|
writeTransitionString(tag string, buffer *strings.Builder)
|
||||||
animationCSS(session Session) string
|
animationCSS(session Session) string
|
||||||
transitionCSS(buffer *strings.Builder, session Session)
|
transitionCSS(buffer *strings.Builder, session Session)
|
||||||
|
@ -163,19 +178,29 @@ func NewAnimation(params Params) Animation {
|
||||||
return animation
|
return animation
|
||||||
}
|
}
|
||||||
|
|
||||||
func (animation *animationData) hasAnimatedProperty() bool {
|
func (animation *animationData) animatedProperties() []AnimatedProperty {
|
||||||
props := animation.getRaw(PropertyTag)
|
value := animation.getRaw(PropertyTag)
|
||||||
if props == nil {
|
if value == nil {
|
||||||
ErrorLog("There are no animated properties.")
|
ErrorLog("There are no animated properties.")
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := props.([]AnimatedProperty); !ok {
|
props, ok := value.([]AnimatedProperty)
|
||||||
|
if !ok {
|
||||||
ErrorLog("Invalid animated properties.")
|
ErrorLog("Invalid animated properties.")
|
||||||
return false
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
if len(props) == 0 {
|
||||||
|
ErrorLog("There are no animated properties.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return props
|
||||||
|
}
|
||||||
|
|
||||||
|
func (animation *animationData) hasAnimatedProperty() bool {
|
||||||
|
return animation.animatedProperties() != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (animation *animationData) animationName() string {
|
func (animation *animationData) animationName() string {
|
||||||
|
@ -394,19 +419,11 @@ func (animation *animationData) String() string {
|
||||||
|
|
||||||
func (animation *animationData) animationCSS(session Session) string {
|
func (animation *animationData) animationCSS(session Session) string {
|
||||||
if animation.keyFramesName == "" {
|
if animation.keyFramesName == "" {
|
||||||
props := animation.getRaw(PropertyTag)
|
if props := animation.animatedProperties(); props != nil {
|
||||||
if props == nil {
|
animation.keyFramesName = session.registerAnimation(props)
|
||||||
ErrorLog("There are no animated properties.")
|
} else {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
animatedProps, ok := props.([]AnimatedProperty)
|
|
||||||
if !ok || len(animatedProps) == 0 {
|
|
||||||
ErrorLog("Invalid animated properties.")
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
animation.keyFramesName = session.registerAnimation(animatedProps)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer := allocStringBuilder()
|
buffer := allocStringBuilder()
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
package rui
|
||||||
|
|
||||||
|
func (animation *animationData) Start(view View, listener func(view View, animation Animation, event string)) bool {
|
||||||
|
if view == nil {
|
||||||
|
ErrorLog("nil View in animation.Start() function")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !animation.hasAnimatedProperty() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
animation.view = view
|
||||||
|
animation.listener = listener
|
||||||
|
|
||||||
|
animation.oldAnimation = nil
|
||||||
|
if value := view.Get(AnimationTag); value != nil {
|
||||||
|
if oldAnimation, ok := value.([]Animation); ok && len(oldAnimation) > 0 {
|
||||||
|
animation.oldAnimation = oldAnimation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
animation.oldListeners = map[string][]func(View, string){}
|
||||||
|
|
||||||
|
setListeners := func(event string, listener func(View, string)) {
|
||||||
|
var listeners []func(View, string) = nil
|
||||||
|
if value := view.Get(event); value != nil {
|
||||||
|
if oldListeners, ok := value.([]func(View, string)); ok && len(oldListeners) > 0 {
|
||||||
|
listeners = oldListeners
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if listeners == nil {
|
||||||
|
view.Set(event, listener)
|
||||||
|
} else {
|
||||||
|
animation.oldListeners[event] = listeners
|
||||||
|
view.Set(event, append(listeners, listener))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setListeners(AnimationStartEvent, animation.onAnimationStart)
|
||||||
|
setListeners(AnimationEndEvent, animation.onAnimationEnd)
|
||||||
|
setListeners(AnimationCancelEvent, animation.onAnimationCancel)
|
||||||
|
setListeners(AnimationIterationEvent, animation.onAnimationIteration)
|
||||||
|
|
||||||
|
view.Set(AnimationTag, animation)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (animation *animationData) finish() {
|
||||||
|
if animation.view != nil {
|
||||||
|
for _, event := range []string{AnimationStartEvent, AnimationEndEvent, AnimationCancelEvent, AnimationIterationEvent} {
|
||||||
|
if listeners, ok := animation.oldListeners[event]; ok {
|
||||||
|
animation.view.Set(event, listeners)
|
||||||
|
} else {
|
||||||
|
animation.view.Remove(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
animation.view.Set(AnimationTag, animation.oldAnimation)
|
||||||
|
|
||||||
|
animation.oldListeners = map[string][]func(View, string){}
|
||||||
|
animation.oldAnimation = nil
|
||||||
|
animation.view = nil
|
||||||
|
animation.listener = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (animation *animationData) Stop() {
|
||||||
|
animation.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (animation *animationData) Pause() {
|
||||||
|
if animation.view != nil {
|
||||||
|
animation.view.Set(AnimationPaused, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (animation *animationData) Resume() {
|
||||||
|
if animation.view != nil {
|
||||||
|
animation.view.Remove(AnimationPaused)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (animation *animationData) onAnimationStart(view View, _ string) {
|
||||||
|
if animation.view != nil && animation.listener != nil {
|
||||||
|
animation.listener(animation.view, animation, AnimationStartEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (animation *animationData) onAnimationEnd(view View, _ string) {
|
||||||
|
if animation.view != nil {
|
||||||
|
if animation.listener != nil {
|
||||||
|
animation.listener(animation.view, animation, AnimationEndEvent)
|
||||||
|
}
|
||||||
|
animation.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (animation *animationData) onAnimationIteration(view View, _ string) {
|
||||||
|
if animation.view != nil && animation.listener != nil {
|
||||||
|
animation.listener(animation.view, animation, AnimationIterationEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (animation *animationData) onAnimationCancel(view View, _ string) {
|
||||||
|
if animation.view != nil && animation.listener != nil {
|
||||||
|
animation.listener(animation.view, animation, AnimationCancelEvent)
|
||||||
|
}
|
||||||
|
}
|
|
@ -299,10 +299,13 @@ type canvasData struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCanvas(view CanvasView) Canvas {
|
func newCanvas(view CanvasView) Canvas {
|
||||||
|
session := view.Session()
|
||||||
|
if !session.canvasStart(view.htmlID()) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
canvas := new(canvasData)
|
canvas := new(canvasData)
|
||||||
canvas.view = view
|
canvas.view = view
|
||||||
canvas.session = view.Session()
|
canvas.session = session
|
||||||
canvas.session.canvasStart(view.htmlID())
|
|
||||||
return canvas
|
return canvas
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
41
session.go
41
session.go
|
@ -144,7 +144,9 @@ type Session interface {
|
||||||
sendResponse()
|
sendResponse()
|
||||||
addAnimationCSS(css string)
|
addAnimationCSS(css string)
|
||||||
removeAnimation(keyframe string)
|
removeAnimation(keyframe string)
|
||||||
canvasStart(htmlID string)
|
htmlPropertyValue(htmlID, name string) string
|
||||||
|
|
||||||
|
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
|
||||||
callCanvasVarFunc(v any, funcName string, args ...any)
|
callCanvasVarFunc(v any, funcName string, args ...any)
|
||||||
|
@ -152,7 +154,7 @@ type Session interface {
|
||||||
updateCanvasProperty(property string, value any)
|
updateCanvasProperty(property string, value any)
|
||||||
canvasFinish()
|
canvasFinish()
|
||||||
canvasTextMetrics(htmlID, font, text string) TextMetrics
|
canvasTextMetrics(htmlID, font, text string) TextMetrics
|
||||||
htmlPropertyValue(htmlID, name string) string
|
|
||||||
addToEventsQueue(data DataObject)
|
addToEventsQueue(data DataObject)
|
||||||
handleAnswer(command string, data DataObject) bool
|
handleAnswer(command string, data DataObject) bool
|
||||||
handleRootSize(data DataObject)
|
handleRootSize(data DataObject)
|
||||||
|
@ -427,20 +429,32 @@ func (session *sessionData) appendToInnerHTML(htmlID, html string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *sessionData) updateCSSProperty(htmlID, property, value string) {
|
func (session *sessionData) updateCSSProperty(htmlID, property, value string) {
|
||||||
if !session.ignoreViewUpdates() && session.bridge != nil {
|
if !session.ignoreViewUpdates() {
|
||||||
|
if session.bridge != nil {
|
||||||
session.bridge.updateCSSProperty(htmlID, property, value)
|
session.bridge.updateCSSProperty(htmlID, property, value)
|
||||||
|
} else {
|
||||||
|
ErrorLog("No connection")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *sessionData) updateProperty(htmlID, property string, value any) {
|
func (session *sessionData) updateProperty(htmlID, property string, value any) {
|
||||||
if !session.ignoreViewUpdates() && session.bridge != nil {
|
if !session.ignoreViewUpdates() {
|
||||||
|
if session.bridge != nil {
|
||||||
session.bridge.updateProperty(htmlID, property, value)
|
session.bridge.updateProperty(htmlID, property, value)
|
||||||
|
} else {
|
||||||
|
ErrorLog("No connection")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *sessionData) removeProperty(htmlID, property string) {
|
func (session *sessionData) removeProperty(htmlID, property string) {
|
||||||
if !session.ignoreViewUpdates() && session.bridge != nil {
|
if !session.ignoreViewUpdates() {
|
||||||
|
if session.bridge != nil {
|
||||||
session.bridge.removeProperty(htmlID, property)
|
session.bridge.removeProperty(htmlID, property)
|
||||||
|
} else {
|
||||||
|
ErrorLog("No connection")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,18 +462,23 @@ func (session *sessionData) startUpdateScript(htmlID string) bool {
|
||||||
if session.bridge != nil {
|
if session.bridge != nil {
|
||||||
return session.bridge.startUpdateScript(htmlID)
|
return session.bridge.startUpdateScript(htmlID)
|
||||||
}
|
}
|
||||||
|
ErrorLog("No connection")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *sessionData) finishUpdateScript(htmlID string) {
|
func (session *sessionData) finishUpdateScript(htmlID string) {
|
||||||
if session.bridge != nil {
|
if session.bridge != nil {
|
||||||
session.bridge.finishUpdateScript(htmlID)
|
session.bridge.finishUpdateScript(htmlID)
|
||||||
|
} else {
|
||||||
|
ErrorLog("No connection")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *sessionData) sendResponse() {
|
func (session *sessionData) sendResponse() {
|
||||||
if session.bridge != nil {
|
if session.bridge != nil {
|
||||||
session.bridge.sendResponse()
|
session.bridge.sendResponse()
|
||||||
|
} else {
|
||||||
|
ErrorLog("No connection")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,6 +486,8 @@ func (session *sessionData) addAnimationCSS(css string) {
|
||||||
session.animationCSS += css
|
session.animationCSS += css
|
||||||
if session.bridge != nil {
|
if session.bridge != nil {
|
||||||
session.bridge.appendAnimationCSS(css)
|
session.bridge.appendAnimationCSS(css)
|
||||||
|
} else {
|
||||||
|
ErrorLog("No connection")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,14 +524,20 @@ func (session *sessionData) removeAnimation(keyframe string) {
|
||||||
session.animationCSS = css[:index] + css[end:]
|
session.animationCSS = css[:index] + css[end:]
|
||||||
if session.bridge != nil {
|
if session.bridge != nil {
|
||||||
session.bridge.setAnimationCSS(session.animationCSS)
|
session.bridge.setAnimationCSS(session.animationCSS)
|
||||||
|
} else {
|
||||||
|
ErrorLog("No connection")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *sessionData) canvasStart(htmlID string) {
|
func (session *sessionData) canvasStart(htmlID string) bool {
|
||||||
if session.bridge != nil {
|
if session.bridge != nil {
|
||||||
session.bridge.canvasStart(htmlID)
|
session.bridge.canvasStart(htmlID)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorLog("No connection")
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *sessionData) callCanvasFunc(funcName string, args ...any) {
|
func (session *sessionData) callCanvasFunc(funcName string, args ...any) {
|
||||||
|
@ -587,6 +614,8 @@ func (session *sessionData) handleAnswer(command string, data DataObject) bool {
|
||||||
|
|
||||||
if session.bridge != nil {
|
if session.bridge != nil {
|
||||||
session.bridge.sendResponse()
|
session.bridge.sendResponse()
|
||||||
|
} else {
|
||||||
|
ErrorLog("No connection")
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue