bad animation ...
[1/8] from: arngar::gmail::com at: 4-Jun-2007 11:37
Hi list !
first post ;-)
I try to create a simple animation and the result is very slow and
not smooth ....
Click on the white square and the other square move to the border of
the window ....
So why is it so slow ? (it is certainly the bad way to do ;-)
thanks for help
Arnaud
------------
rebol [
title: Inteface-test
version: 1
author: Arnaud
]
; --- there is certainly a better way ;-), but I need this function
blk-pair: function [b] [] [
to-pair reduce b
]
; ---- Window init
width: 800
height: 600
delta: 58
; --- menu cursor
cursor-moving: false
cur-menu-pos: 150x0 ; Cursor Menu position
cursor-img-menu: make image! [ 72x58 168.168.168 0 ] ; this cursor
will move
destination-image: make image! [ 72x58 255.255.255 0 ] ; click on
this image to launch the animation
; ---- Menu Anim
move-cursor-menu-to: function [ item-menu ] [] [
clear menu-bar/effect/draw
either cur-menu-pos/x > 0 [
cur-menu-pos/x: cur-menu-pos/x - 10
] [
cursor-moving: false
]
append menu-bar/effect/draw [ 'image cur-menu-pos cursor-img-
menu ]
show menu-bar
]
view layout/size [
backdrop black
origin 0x0
; ---- cursor menu
menu-bar: box blk-pair [ width delta ] effect [ gradient 0x1
68.68.68 0.0.0
draw [
image cur-menu-pos cursor-img-menu
]
]
at blk-pair [ 0 delta ]
box blk-pair [ width height - delta ]
; ---- Destination box, click on it ! to begin the animation
at 10x2
register-menu: box rate 0:0:0.1 feel [
detect: func [face event] [
if event/type = 'down [
cursor-moving: true
]
]
engage: func [f a e] [
if all [ (a = 'time)
cursor-moving ] [
move-cursor-menu-to register-menu ]
]
] effect [
draw [
image destination-image
]
]
] blk-pair [width height]
[2/8] from: nick1:musiclessonz at: 4-Jun-2007 5:42
Hi Arnaud,
The line following line sets the rate to 1/10th of a second:
register-menu: box rate 0:0:0.1 feel [
Changing that to 1/100th of a second, or even 0, will speed up the animation.
Quoting Arnaud Garcia <arngar-gmail.com>:
[3/8] from: james:mustard at: 5-Jun-2007 1:11
Also if you intend to use the detect event - make sure you have event as
the last entry in the function
eg:
detect: func [f e][
stuff..
event
]
your down detection can actually be done in the engage however - with:
engage: func [f a e][
if a = 'down []
]
Nick Antonaccio wrote:
[4/8] from: arngar::gmail::com at: 4-Jun-2007 15:18
Hi Nick and thanks,
yes, I can change the rate and increase the steps of: cur-menu-pos/x: =20
cur-menu-pos/x - 10
=> As it is my first program, can you tell me if it is the good way =20
to create this kind of animation ... (I going to create more fun
stuff based on that program)
Arnaud
Le 4 juin 07 =E0 14:42, Nick Antonaccio a =E9crit :
[5/8] from: moliad::gmail::com at: 4-Jun-2007 16:55
also remember that VIEW is a cpu-based rendering engine.
so graphics card have little effect on the general feel of REBOL (they have
some effect, but at some point, the cpu is usually slower than the gfx card,
so most recent graphics card just wait after the rendering.)
I admit not having taken the time to look at the code, but here are some
general guidelines on improving animation within rebol:
-If your animation are simple and can be implemented using faces only, then
do so (don't use draw if you don't have to). Faces are generally much
faster. Things like scaling images, moving pictures around, and sliding
guis, are usually faster when only using faces.
-restrict your animations to smaller panes, when it makes sense to do so.
large areas, really kill any pretence of speed in rebol (release 2.x).
-do not mix face and draw animations within the same face. IIRC It seems to
slow down the refresh a lot (possibly two blittings instead of one)
-do not call show based on mouse events. use a timer and call show on that
event only (using engage), even if you are reacting to mouse draging and
stuff.
-clear ALL detect and redraw feels of ALL faces which are animated. if some
faces depend on this (buttons or other widgets) well, try to put them within
another pane which will not have to be refreshed (show is not called on it).
-SOME people have reported that the event handling when coupled with
refreshing, seems to be unable to go above 20-30 frames per second, even if
the refresh takes much less time to perform. (a loop able to refresh at 100
fps, if coupled to a scroller instead will generally only refresh 30 fps.
it might feel smoother, but its a perception thing)
AND THE BIGGEST SPEED IMPROVEMENT (keeping the best for last ;-):
-use the changes facet within the face, I give an example at the end of my
mail which shows the difference.
This will give you almost real-time scrolling (even on larger faces) since
they do not render, but really only blit damaged regions around! for scroll
bars and dragging around faces, for example, the difference is staggering!
(note that if you have Draw commands in the face being scrolled... there is
a bug, it seems, where view will waste a little bit of time handling it
anyways... but its still MUCH faster (it feels like its at least 10 times
faster :-)
-MAx
rebol [
title: "FAST scrolling trick"
license: 'MIT
]
; just open console
print ""
glbpane: none
gblface: none
steps: 50
; a large-ish gui
gui-size: 900x600
interrupt: false
;--------------------
;- stop-anim()
;--------------------
stop-anim: func [
""
][
iface/size: 0x0
show iface
interrupt: true
]
;--------------------
;- start-anim()
;--------------------
start-anim: func [
""
][
iface/size: 125x30
show iface
interrupt: false
]
;--------------------
;- anim-fast()
;--------------------
anim-fast: func [
""
/local i
][
start-anim
repeat i steps [
if interrupt [
break
]
print i
gblface/changes: 'offset
gblface/offset: (i * 200 * 1x0 / steps)
wait 0
show gblface
]
]
;--------------------
;- anim-slow()
;--------------------
anim-slow: func [
""
/local i
][
start-anim
repeat i steps [
if interrupt [
break
]
print i
gblface/offset: (i * 200 * 1x0 / steps)
wait 0
show gblface
]
]
view/new layout [
across
gblpane: box gui-size
return
button "slow" [anim-slow]
button "fast" [anim-fast]
iface: button "STOP!" [stop-anim] 0x0 red
]
gblface: make face [
size: 500x500
effect: [draw [
pen none
fill-pen diamond 863x9 0 216 225 8 8 142.128.110.213
250.240.230.179 0.48.0.128 250.240.230.128 255.228.196.160 128.128.0.192
255.255.0.189 0.255.255.191 0.128.128.203 128.0.128.193 175.155.120.202
100.136.116.163 72.0.90.199 38.58.108.192 160.180.160.131 255.0.255.179
255.228.196.184 139.69.19.135
box 0x0 gui-size
pen none
fill-pen conic 127x863 0 300 116 9 7 192.192.192.160
255.0.255.171 240.240.240.157 40.100.130.137 255.164.200.133 255.255.255.154
0.128.128.163 0.0.128.166 255.228.196.145 255.0.255.168
box 0x0 gui-size
pen none
fill-pen cubic 375x810 0 89 72 1 8 222.184.135.137 160.82.45.166
38.58.108.157 255.205.40.131 255.150.10.129 240.240.240.139 0.48.0.171
179.179.126.150 0.255.0.131 72.0.90.159
box 0x0 gui-size
pen none
fill-pen radial -117x-266 0 65 158 3 2 255.255.255.143
72.0.90.181 40.100.130.146 100.120.100.130 178.34.34.185 128.0.128.169
72.0.90.160 139.69.19.190 100.120.100.165 178.34.34.148 222.184.135.164
0.0.255.141 160.82.45.143
box 0x0 gui-size
pen none
fill-pen cubic 826x989 0 171 233 2 2 160.82.45.134
192.192.192.167 38.58.108.191 100.136.116.158 175.155.120.187
245.222.129.140 80.108.142.189 255.150.10.158 40.100.130.197 164.200.255.187
179.179.126.169 255.150.10.168 164.200.255.197 220.20.60.170 255.0.0.147
76.26.0.175
box 0x0 gui-size
]
]
]
gblpane/pane: gblface
show gblpane
do-events
;-------------------------------------------------
here is an old example I gave on this list, for using faces instead of draw
to resize images, might inspire you in a different direction than you where
thinking, you can change the map-size to see how image size affects the
rendering... can easily give you a good measure of the limits on which you
can base your software:
rebol [
title: "anim face resizing"
license: 'MIT
]
map-size: 200x200
steps: 50
sub-face-size-start: 50x50
sub-face-size-end: map-size * 5
; create image map
print "generating map buffer"
map: make image! reduce [map-size white]
fx: [
pen none
fill-pen diamond 863x9 0 216 225 8 8 142.128.110.213 250.240.230.179
0.48.0.128 250.240.230.128 255.228.196.160 128.128.0.192 255.255.0.189
0.255.255.191 0.128.128.203 128.0.128.193 175.155.120.202 100.136.116.163
72.0.90.199 38.58.108.192 160.180.160.131 255.0.255.179 255.228.196.184
139.69.19.135
box 0x0 map-size
pen none
fill-pen conic 127x863 0 300 116 9 7 192.192.192.160 255.0.255.171
240.240.240.157 40.100.130.137 255.164.200.133 255.255.255.154 0.128.128.163
0.0.128.166 255.228.196.145 255.0.255.168
box 0x0 map-size
pen none
fill-pen cubic 375x810 0 89 72 1 8 222.184.135.137 160.82.45.166
38.58.108.157 255.205.40.131 255.150.10.129 240.240.240.139 0.48.0.171
179.179.126.150 0.255.0.131 72.0.90.159
box 0x0 map-size
pen none
fill-pen radial -117x-266 0 65 158 3 2 255.255.255.143 72.0.90.181
40.100.130.146 100.120.100.130 178.34.34.185 128.0.128.169 72.0.90.160
139.69.19.190 100.120.100.165 178.34.34.148 222.184.135.164 0.0.255.141
160.82.45.143
box 0x0 map-size
pen none
fill-pen cubic 826x989 0 171 233 2 2 160.82.45.134 192.192.192.167
38.58.108.191 100.136.116.158 175.155.120.187 245.222.129.140 80.108.142.189
255.150.10.158 40.100.130.197 164.200.255.187 179.179.126.169 255.150.10.168
164.200.255.197 220.20.60.170 255.0.0.147 76.26.0.175
box 0x0 map-size
]
; render a pretty pic
print ["rendering pretty pic at " map-size]
draw map fx
do-size: func [
scale
][
sub/offset: (-200x-200 * scale)
sub/size: ((sub-face-size-end - sub-face-size-start) * (scale)) +
sub-face-size-start
show sub
]
; anim simulation:
do-anim: does [
s: now/precise
repeat i steps [
do-size i / steps
;sub/offset: (-200x-200 * (i / steps))
;sub/size: ((sub-face-size-end - sub-face-size-start) * (i / steps))
+ sub-face-size-start
;show sub
;print i
]
print ["map res: " map/size]
print ["steps: " steps]
print ["time: " difference now/precise s ]
print ["frame rate: " steps / (to-decimal difference now/precise s) "
f/sec"]
]
; open gui
l: layout [
sub: box map 200x200 effect [fit]
]
view layout [
canvas: box 500x500
button "animate" [do-anim]
scroller 500x15 [do-size value]
do [
canvas/pane: sub
show canvas
]
]
[6/8] from: arngar::gmail::com at: 5-Jun-2007 15:59
Many thanks for this answer !
I work on your code and try to adapt it for my program ... (there
are two squares, click on the black and the red moves ;-), just a
simple animation test ...
=> Now, the speed is not a problem , thanks !
=> but there are still some gui problems during the animation
(pictures below) ... Do I need to clean something ? (I double check
your code ..., you did nothing more )
-- Attached file included as plaintext by Ecartis --
Content-Transfer-Encoding: base64
Content-Type: application/applefile;
name=Image 1.png
Content-Disposition: inline;
filename="Image 1.png"
AAUWBwACAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAJAAAAMgAAAAoAAAADAAAAPAAAAAsAAAAAAAAA
ABAASW1hZ2UgMS5wbmc
-- Binary/unsupported file stripped by Ecartis --
-- Type: image/png
-- File: Image 1.png
-- Attached file included as plaintext by Ecartis --
-- Attached file included as plaintext by Ecartis --
Content-Transfer-Encoding: base64
Content-Type: application/applefile;
name=Image 2.png
Content-Disposition: inline;
filename="Image 2.png"
AAUWBwACAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAJAAAAMgAAAAoAAAADAAAAPAAAAAsAAAAAAAAA
ABAASW1hZ2UgMi5wbmc
-- Binary/unsupported file stripped by Ecartis --
-- Type: image/png
-- File: Image 2.png
-- Attached file included as plaintext by Ecartis --
(left picture: On windows there are sometimes verticals lines, in all
cases the first vertical line do not disappear ...
right picture: On mac os x (sdk beta 2.7.5) => it never works
correctly, I always have some verticals lines and the whole red block
disappears during the animation ! ;-((
)
here the code if you want to try:
;-------------------------
rebol [ ]
cursor-moving: false
cur-menu-pos: 150x0
move-cursor-menu-to: function [ item-menu ] [ delta steps nb-mov ] [
steps: 1
delta: cur-face/offset/x - item-menu/offset/x
nb-mov: delta / steps
loop nb-mov [
cur-face/changes: 'offset
cur-face/offset/x: cur-face/offset/x - steps
wait 0.01
show cur-face
]
cursor-moving: false
]
view/new layout/size [
origin 0x0
menu-bar: box 800x58
at 200x200 text "click on the black box ..."
at 10x0
register-menu: box 72x58 black [
if [ curson-moving = false ] [
cursor-moving: true
move-cursor-menu-to register-menu
]
]
] 800x600
cur-face: make face [
offset: cur-menu-pos
size: 72x58
color: red
edge: none
]
menu-bar/pane: cur-face
show menu-bar
do-events
;-----------------------------
Le 4 juin 07 à 22:55, Maxim Olivier-Adlhoch a écrit :
[7/8] from: moliad:g:mail at: 8-Jun-2007 19:28
hi,
in the code you sent me (sliding red box), don't ask why I figured it out,
but if you put the wait AFTER the show in your anim loop.... the problem
goes away.
now I have no clue why this fixed the rendering, but it did.
-MAx
[8/8] from: arngar:gma:il at: 9-Jun-2007 8:49
Yes ! thanks Max !
Arnaud
Le 9 juin 07 =E0 01:28, Maxim Olivier-Adlhoch a =E9crit :