}
package require Tk proc FerrisWheel {w xm ym r {cars 12}} { $w create oval [expr $xm-$r] [expr $ym-$r] [expr $xm+$r] [expr $ym+$r]\ -width 4 -fill {} -tag wheel $w create oval [expr $xm-8] [expr $ym-8] [expr $xm+8] [expr $ym+8]\ -fill black for {set d 0} {$d<360} {set d [expr {$d+360./$cars}]} { set rad [deg2rad $d] set x [expr {$xm+cos($rad)*$r}] set y [expr {$ym+sin($rad)*$r}] $w create line $xm $ym $x $y -tag "wheel spoke sx$d" set color [lpick {white yellow orange green purple}] $w create oval [expr $x-2] [expr $y-2] [expr $x+2] [expr $y+2] \ -fill $color -tags "wheel x$d lamp" car $w $x $y x$d } $w raise wheel set ybot [expr {$ym+$r*1.5}] $w create line [expr $xm-$r] $ybot $xm $ym [expr $xm+$r] $ybot \ -fill grey30 -width 8 -tag frame incr r -12; set yy [expr {$ym+$r*1.5}] foreach xx {25 35 45} { $w create rect [expr $xm-$xx] [expr $yy-3] [expr $xm+$xx] [expr $yy+3] \ -fill grey50 -tag stairs set yy [expr {$yy + 5.0}] } after 100 animate $w } proc car {w x y tag} { #set color red set color [lpick {red pink yellow orange green cyan blue purple}] $w create rect [expr {$x-10}] $y [expr {$x+10}] [expr {$y+20}] \ -fill $color -tag $tag $w create rect [expr {$x-8}] [expr {$y+3}] [expr {$x+8}] [expr {$y+10}] \ -fill [$w cget -bg] -tag $tag $w create rect [expr {$x-3}] [expr {$y+3}] [expr {$x+3}] [expr {$y+18}] \ -fill {} -width 2 -tag $tag } proc deg2rad deg {expr {$deg * atan(1)*8/360}} proc lpick list {lindex $list [expr {int(rand()*[llength $list])}]} proc animate {w} { if $::go { foreach {x0 - xm ym} [$w coords [$w find withtag frame]] break set r [expr {$xm-$x0}] foreach spoke [$w find withtag spoke] { foreach {x0 y0 x y} [$w coords $spoke] break set th [expr {($x? atan2($y-$ym,$x-$xm) : 0.0)+0.0075}] set x1 [expr {$xm + cos($th) * $r}] set y1 [expr {$ym + sin($th) * $r}] $w coords $spoke $x0 $y0 $x1 $y1 regexp {s([x[0-9.]+)} [$w gettags $spoke] -> id $w move $id [expr {$x1-$x}] [expr {$y1-$y}] } } set id [lpick [$w find withtag lamp]] set color [$w itemcget $id -fill] if {$color ne "black"} { $w itemconfigure $id -fill black after 250 [list $w itemconfigure $id -fill $color] } after 50 [list animate $w] } pack [canvas .c -width 200 -height 220 -bg lightblue] -fill both -expand 1 FerrisWheel .c 100 100 85 15 checkbutton .c.go -variable go -text "" set go 1 .c create window 180 212 -window .c.go bind .c <1> { .c configure -height [expr [.c cget -height] * 2] .c configure -width [expr [.c cget -width] * 2] .c scale all 0 0 2 2 } bind .c <3> { .c configure -height [expr [.c cget -height] / 2] .c configure -width [expr [.c cget -width] / 2] .c scale all 0 0 0.5 0.5 } bind . <KeyPress-q> {destroy .} wm resizable . 0 0
HJG 2005-06-29 Added random colors for the cars, and little stairs at the bottom of the wheel.
Steven A 2006-01-08 The whole widget now scales up/down with the wheel.