It's time to roll out 2021 and ring in 2022, so here's an animated New Year's Eve 7-segment countdown timer that's inspired by basketball shot clocks. The x/y coordinates for the segments came from SVG polygon definitions found in Manuel Schulz's clever CodePen project ("Digital SVG clock to be set via css and attributes"), the 11:59 analog clock image is from Wikimedia user Micthev, and the champagne bottle is a low-res version of Adrien Coquet's "Champagne Party" icon at The Noun Project. Happy New Year, all!
* Fun W/SAS ODS Graphics: New Year's Eve 7-Segment "Shot Clock" Countdown Timer
Digital clock SVG x/y coordinates courtesy of Manuel Schulz (codepen.io/tornography/pen/qaBOLJ)
Clock image courtesy of Micthev (commons.wikimedia.org/wiki/File:Clock_11-59.svg)
Champagne icon courtesy of Adrien Coquet (thenounproject.com/icon/champagne-party-970849/);
data polygons(keep=digit polygon p x y color); * Create table of polygons for digits 0-9;
length x y 3;
input digits $10. points $60.; * Read SVG x/y coordinates for segments for digits 0-9;
do digit=0 to 9;
i=1;
polygon+1;
color=ifn(index(digits,put(digit,1.))>0,1,0); * Is segment lit for this digit?;
do while(scan(points,i,' ')^=''); * Loop thru x/y point pairs;
p+1; x=scan(points,i,', '); y=scan(points,i+1,', '); i+2; output;
end;
end;
if _n_=1; digit=8; polygon+1; p+1; color=0; x=0; y=0; output; * Need a non-displayable "off" polygon for 8;
datalines;
12347890 48 38 44 42 40 38 40 10 44 6 48 10 48 382
23567890 38 0 42 4 38 8 10 8 6 4 10 0 38 0
456890 8 38 4 42 0 38 0 10 4 6 8 10 8 38
2345689 38 40 42 44 38 48 10 48 6 44 10 40 38 40
2356890 38 80 42 84 38 88 10 88 6 84 10 80 38 80
2680 8 78 4 82 0 78 0 50 4 46 8 50 8 78
134567890 48 78 44 82 40 78 40 50 44 46 48 50 48 78
;
data countdown; * Generate digits of countdown numbers 10->0;
length digit 3.;
do count=10 to 0 by -1;
place=1; digit=substr(put(count,z2.),1,1); output; * Digit for tens place;
place=2; digit=substr(put(count,z2.),2,1); output; * Digit for ones place;
end;
proc sql; * Merge countdown digits with polygons;
create table countdownpolygons as
select c.count, c.place, p.*
from countdown c join polygons p on p.digit=c.digit
order by count desc, place, polygon, p;
* Generate NYE countdown "shot clock" GIF (2-across panel of polygon plots);
options papersize=('6 in', '5.17 in') printerpath=gif animation=start
nodate nonumber animloop=YES animduration=2 NOANIMOVERLAY nobyline;
ods printer file='~/HappyNewYear2021.gif'; * Build GIF from multiple images;
ods graphics / reset antialias border=no height=5.17in width=6in imagefmt=gif border=off;
data opening; x=0; y=0; * Generate 2021 opening title frame;
proc sgplot data=opening noborder nowall noautolegend pad=0; styleattrs backcolor=black;
symbolimage name=midnight image='/home/ted.conway/1159.png'; * Clock image 11:59;
scatter x=x y=y / markerattrs=(symbol=midnight size=324pt);
xaxis display=none values=(-1 to 1 by 2) offsetmin=0 offsetmax=0; yaxis display=none values=(-1 to 1 by 2) offsetmin=0 offsetmax=0;
run;
options animduration=1; * Generate countdown frames (10->0);
proc sgpanel data=countdownpolygons noautolegend subpixel pad=0;
by descending count;
panelby place / sort=data noborder noheader novarname nowall columns=2 onepanel; * One cell per digit;
styleattrs backcolor=black;
polygon x=x y=y id=polygon / fill colorresponse=color colormodel=(cx171717 white); * Draw On (White) & Off ("Matte Black") segments;
colaxis display=none values=(-5 to 53 by 58) offsetmin=0 offsetmax=0;
rowaxis display=none reverse values=(-5 to 93 by 98) offsetmin=0 offsetmax=0;
run;
%macro closing(text=2022,inset=HAPPY NEW YEAR!, icon=Y); * Macro used to enerate closing title frames;
data closing; x=0; y=0; text="&text"; yImg=-.75;
proc sgplot data=title noborder nowall noautolegend pad=0; styleattrs backcolor=black;
inset "&inset" / noborder position=top textattrs=(weight=bold size=36pt color=white);
text x=x y=y text=text / position=center contributeoffsets=none strip textattrs=(color=white size=144pt weight=bold);;
symbolimage name=champagne image='/home/ted.conway/champagne.png'; * Show champagne icon?;
%if &icon=Y %then scatter x=x y=yImg / markerattrs=(symbol=champagne size=72pt);;
xaxis display=none values=(-1 to 1 by 2) offsetmin=0 offsetmax=0;
yaxis display=none values=(-1 to 1 by 2) offsetmin=0 offsetmax=0;
run;
%mend;
options animduration=1; %title; options animduration=.5; * Generate 2022 closing title frames;
%title(inset=); %title; %title(inset=); %title; %title(inset=);* Make inset (Happy New Year!) blink several times for a half-second;
options animduration=1; %title; %title(text=,inset=,icon=N); * Display blank frame before recycling GIF;
options printerpath=gif animation=stop; * Wrap-up animated GIF creation;
run;
ods printer close;
OK ... I didn't want to like this ... but you got me. 🙂
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.