BASIC User Group > Code Challenges

Simple GUI program displaying analog clock

(1/2) > >>

jalih:
To compare how easy it is to write simple GUI programs with different tools, I propose a little coding challenge to write a simple program displaying resizable analog clock.

Here is my old analog clock included in 8th samples:


--- Code: ---\ Draws a clock on the screen.  Original code by jalih:
\   https://8th-dev.com/forum/index.php/topic,1573.msg8661.html
\
\ Adapted and refactored a bit.

needs math/trigd

true app:isgui !

var ycenter
var xcenter
var radius

["3","2","1","12","11","10","9","8","7","6","5","4"] constant hours

: circleptx  \ x r deg
  n:cosd n:* n:+ ;

: circlepty \ y r deg
  n:sind n:* n:- ;

: onsize
  2dup
  2 n:/ ycenter !
  2 n:/ xcenter !
  n:min 2 n:/ 8 n:- radius ! ;

: xc-rad \ n -- m
  xcenter @ radius @ rot n:* ;

: yc-rad \ n -- m
  ycenter @ radius @ rot n:* ;

: xcyc \ -- x y
  xcenter @ ycenter @ ;

: draw-indicator \ gui width size --
  -rot g:line-width
  xcyc g:moveto
  over xc-rad r@ circleptx
  rot yc-rad r> circlepty
  g:lineto g:stroke ;

: draw-clock
  \ get current time (just HH MM SS):
  d:new d:/ 3 3 a:slice a:open
  -rot swap over

  \ hour: (hour min)
  >r 90 swap 5 n:* r> 10 n:/ n:+ 6 n:* n:- >r

  \ minutes:
  90 swap 6 n:* n:- >r

  \ seconds:
  90 swap 6 n:* n:- >r

  xcyc radius @ 0 360 g:arc
  "black" g:scolor 2 g:line-width
  g:stroke

  "black" g:fcolor
  (
    >r
    0.95 xc-rad r@ 360 60 n:*/ circleptx
    0.95 yc-rad r> 360 60 n:*/ circlepty
    2 0 360 g:arc
  ) 0 59 loop

  "20" g:setfont
  g:c-text
  (
    >r
    0.95 xc-rad r@ 360 12 n:*/ circleptx
    0.95 yc-rad r@ 360 12 n:*/ circlepty
    4 0 360 g:arc

    0.80 xc-rad r@ 360 12 n:*/ circleptx
    0.80 yc-rad r@ 360 12 n:*/ circlepty
    hours r> caseof g:draw-text-at
  ) 0 11 loop
  g:fill

  2 0.90 draw-indicator
  6 0.85 draw-indicator
  10 0.65 draw-indicator

  xcyc 10 0 360 g:arc
  g:fill ;

{
  kind: "win",
  title: "Simple Analog Clock",
  wide: 300,
  high: 300,
  min-wide: 300,
  min-high: 300,
  max-wide: 500,
  max-high: 500,
  center: true,
  bg: "white",
  resize-corner: 20,
  font: "Arial 10",
  draw: "draw-clock",
  timer: ' g:invalidate  ,
  size: "onsize",
  timer-period: 1000
} var, gui-desc

: app:main
  gui-desc @ g:new ;

--- End code ---

John:
Analog (with integrated digital) clock  (Read 24762 times)

John:
Jalih,

I suggest the following  change,

From:

["03","02","01","12","11","10","09","08","07","06","05","04"]

To:

[" 3"," 2"," 1","12","11","10"," 9"," 8"," 7"," 6"," 5"," 4"]

jalih:

--- Quote from: John on December 12, 2019, 11:26:01 pm ---Jalih,

I suggest the following  change,

From:

["03","02","01","12","11","10","09","08","07","06","05","04"]

To:

[" 3"," 2"," 1","12","11","10"," 9"," 8"," 7"," 6"," 5"," 4"]

--- End quote ---

You are right, it does look better! Source modified...

AIR:
I didn't code this, but I thought it was an interesting approach.


--- Code: XML ---<?xml version="1.0"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400" width="400" height="400" version="1.0">  <defs>    <linearGradient id="a" x1="0%" y1="100%" x2="0%" y2="0%">      <stop offset="0%" style="stop-color:#777799"/>      <stop offset="100%" style="stop-color:#ffffff"/>    </linearGradient>    <linearGradient id="b" x1="0%" y1="100%" x2="0%" y2="0%">      <stop offset="0%" style="stop-color:#ffffff"/>      <stop offset="25%" style="stop-color:#b6b6cc"/>      <stop offset="40%" style="stop-color:#515177"/>      <stop offset="48%" style="stop-color:#ffffff"/>      <stop offset="56%" style="stop-color:#ffffff"/>      <stop offset="75%" style="stop-color:#8b8baa"/>      <stop offset="98%" style="stop-color:#efeff4"/>      <stop offset="100%" style="stop-color:#fbfbfc"/>    </linearGradient>    <linearGradient id="c" x1="0%" y1="100%" x2="0%" y2="0%">      <stop offset="0%" style="stop-color:#ffffff"/>      <stop offset="100%" style="stop-color:#777799"/>    </linearGradient>    <radialGradient id="d" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">      <stop offset="0%" style="stop-color:#ffffff"/>      <stop offset="40%" style="stop-color:#ffffff"/>      <stop offset="70%" style="stop-color:#e6e6ee"/>      <stop offset="92%" style="stop-color:#b6b6cc"/>      <stop offset="100%" style="stop-color:#636388"/>    </radialGradient>    <radialGradient id="e" cx="50%" cy="150%" r="200%" fx="50%" fy="150%">      <stop offset="0%" style="stop-color:#ffffff;stop-opacity:0"/>      <stop offset="59%" style="stop-color:#ffffff;stop-opacity:0"/>      <stop offset="60%" style="stop-color:#ffffff;stop-opacity:0.6"/>      <stop offset="70%" style="stop-color:#ffffff;stop-opacity:0.3"/>      <stop offset="100%" style="stop-color:#ffffff;stop-opacity:0.0"/>    </radialGradient>  </defs>  <g transform="translate(200 200)">    <circle cx="0" cy="0" r="200" fill="#cecedd"/>    <circle cx="0" cy="0" r="196" stroke="url(#a)" stroke-width="5" fill="url(#b)"/>    <circle cx="0" cy="0" r="170" stroke="url(#c)" stroke-width="4" fill="url(#d)"/>    <circle cx="0" cy="0" r="172" stroke="#ffffff" stroke-width="0.5" fill="none"/>    <circle cx="0" cy="0" r="193.5" stroke="#ffffff" stroke-width="0.5" fill="none"/>    <g id="O">      <polygon points="4,155 4,130 -4,130 -4,155" style="fill:#777799;stroke:#313155;stroke-width:1"/>      <polygon points="4,-155 4,-130 -4,-130 -4,-155" style="fill:#777799;stroke:#313155;stroke-width:1"/>    </g>    <g transform="rotate(30)"><use xlink:href="#O"/></g>    <g transform="rotate(60)"><use xlink:href="#O"/></g>    <g transform="rotate(90)"><use xlink:href="#O"/></g>    <g transform="rotate(120)"><use xlink:href="#O"/></g>    <g transform="rotate(150)"><use xlink:href="#O"/></g>    <polygon id="h" points="6,-80 6,18 -6,18 -6,-80" style="fill:#232344">      <animateTransform id="ht" attributeType="xml" attributeName="transform" type="rotate" from="000" to="000" begin="0" dur="86400s" repeatCount="indefinite"/>    </polygon>    <polygon id="m" points="3.5,-140 3.5,23 -3.5,23 -3.5,-140" style="fill:#232344">      <animateTransform id="mt" attributeType="xml" attributeName="transform" type="rotate" from="000" to="000" begin="0" dur="3600s" repeatCount="indefinite"/>    </polygon>    <polygon id="s" points="2,-143 2,25 -2,25 -2,-143" style="fill:#232344">      <animateTransform id="st" attributeType="xml" attributeName="transform" type="rotate" from="000" to="000" begin="0" dur="60s" repeatCount="indefinite"/>    </polygon>    <circle cx="0" cy="0" r="163" fill="url(#e)"/>  </g>  <script type="text/javascript"><![CDATA[    var d = new Date();    var s = d.getSeconds();    var m = d.getMinutes() + s/60;    var h = (d.getHours() % 12) + m/60 + s/3600;    document.getElementById('st').setAttribute('from',s*6);    document.getElementById('mt').setAttribute('from',m*6);    document.getElementById('ht').setAttribute('from',h*30);    document.getElementById('st').setAttribute('to',360+s*6);    document.getElementById('mt').setAttribute('to',360+m*6);    document.getElementById('ht').setAttribute('to',360+h*30);  ]]></script></svg>  

Save that to a file called "clock.svg" and open in your browser....


AIR.

Navigation

[0] Message Index

[#] Next page

Go to full version