Keith Vetter 2024-02-05 - An animation of the bouncing DVD Video logo.
package require Tk
set S(src) ::img::dvd_logo
set S(x) [expr {int(rand() * 300)}]
set S(y) [expr {int(rand() * 300)}]
set S(dx) 1
set S(dy) 1
set S(delay) 10
set S(state) animate
set S(aid) ""
proc DoDisplay {} {
# Don't like aqua theme's background around a button
::ttk::style theme use default
wm title . "DVD Logo Screensaver"
wm minsize . [expr {2 * $::S(image,width)}] [expr {2 * $::S(image,height)}]
canvas .c -bd 0 -highlightthickness 0 -width 500 -height 500 -bg black
pack .c -side top -fill both -expand 1
::ttk::button .stop -text Stop -command StopStart
place .stop -in .c -relx .5 -rely 1 -y -.2i -anchor s
.c create image $::S(x) $::S(y) -tag logo -anchor nw -image ::img::logo
bind .c <Configure> {Resize %h %w}
}
proc Resize {h w} {
# Called when window gets resized--check if logo is outside the window
set wwidth [winfo width .]
set wheight [winfo height .]
if {$::S(x) + $::S(image,width) < $wwidth
&& $::S(y) + $::S(image,height) < $wheight} {
return
}
set ::S(x) 10
set ::S(y) 10
.c coords logo $::S(x) $::S(y)
}
proc MoveLogo {} {
set wwidth [winfo width .]
set wheight [winfo height .]
if {$::S(x) == 0 || $::S(x) + $::S(image,width) == $wwidth} {
set ::S(dx) [expr {-$::S(dx)}]
PickNewColor
}
if {$::S(y) == 0 || $::S(y) + $::S(image,height) == $wheight} {
set ::S(dy) [expr {-$::S(dy)}]
PickNewColor
}
incr ::S(x) $::S(dx)
incr ::S(y) $::S(dy)
.c move logo $::S(dx) $::S(dy)
}
proc StopStart {} {
if {$::S(state) eq "animate"} {
set ::S(state) "stop"
.stop config -text Start
} else {
set ::S(state) "animate"
.stop config -text Stop
after cancel $::S(aid)
Animate
}
}
proc Animate {} {
if {$::S(state) ne "animate"} return
MoveLogo
set ::S(aid) [after $::S(delay) Animate]
}
image create photo ::img::dvd_logo -data {
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}
proc RandomColor {} {
set color [format "#%06x" [expr {int(rand() * 0xFFFFFF)}]]
return $color
}
proc MakeColoredLogos {colors} {
# Makes a bunch of copies of ::img::dvd_logo in various colors
set ::S(logos) {}
for {set i 0} {$i < [llength $colors]} {incr i} {
set img ::img::logo_$i
lappend ::S(logos) [image create photo $img -width $::S(image,width) -height $::S(image,height)]
}
for {set row 0} {$row < $::S(image,height)} {incr row} {
set state "TRANSPARENT"
for {set col 0} {$col <= $::S(image,width)} {incr col} {
set transparent 1 ;# Sentinel
if {$col < $::S(image,width)} {
set transparent [$::S(src) transparency get $col $row]
}
if {$state eq "COLORING" && ! $transparent} continue
if {$state eq "TRANSPARENT" && $transparent} continue
if {$state eq "COLORING" && $transparent} {
set state "TRANSPARENT"
foreach img $::S(logos) color $colors {
$img put $color -to $first $row $col [expr {$row + 1}]
}
}
if {$state eq "TRANSPARENT" && ! $transparent} {
set state "COLORING"
set first $col
}
}
}
}
proc PickNewColor {} {
set n [expr {int(rand() * [llength $::S(logos)])}]
::img::logo blank
::img::logo copy [lindex $::S(logos) $n]
}
proc Main {} {
set ::S(image,width) [image width ::img::dvd_logo]
set ::S(image,height) [image height ::img::dvd_logo]
set preset_colors {white purple red orange magenta yellow green blue cyan}
for {set i 0} {$i < 20} {incr i} {
lappend preset_colors [RandomColor]
}
MakeColoredLogos $preset_colors
image create photo ::img::logo
::img::logo copy [lindex $::S(logos) 0]
DoDisplay
}
Main
Animate
Jeff Smith 2024-02-13 : Below is an online demo using CloudTk. This demo runs "DVD Logo Screensaver" in an Alpine Linux Docker Container. It is a 27.4MB image which is made up of Alpine Linux + tclkit + DVD-Logo-Screensaver.kit + libx11 + libxft + fontconfig + ttf-linux-libertine. It is run under a user account in the Container. The Container is restrictive with permissions for "Other" removed for "execute" and "read" for certain directories.
Please Note : This demo has a run time of 2 minutes.
See also Bouncing DVD Logo