Créer une horloge analogique


24

Créer une horloge analogique

Objectif: créer une horloge analogique fonctionnelle en utilisant n'importe quel langage de programmation.

Exigences:

  • Votre horloge doit comporter au moins les pointeurs des heures et des minutes.
  • L'horloge produite peut prendre la forme d'une image, d'une animation ou d'un art ASCII.
  • Il est prévu que l'horloge indique l'heure locale.

Optionnel:

  • Vous pouvez faire en sorte que votre horloge affiche le pointeur des secondes en plus des pointeurs des minutes et des heures.
  • Vous pouvez également rendre le fuseau horaire configurable si vous le souhaitez.
  • Vous êtes libre de choisir si vous pouvez négliger ou gérer les problèmes de secondes intercalaires.
  • Vous pourriez penser à ce qui arrive à votre programme si l'utilisateur ajuste l'horloge système ou si un changement de lumière du jour se produit.

Comme il s'agit d'un , soyez créatif et dessinez de belles et belles horloges pour mériter les votes positifs. La réponse la plus votée l'emporte , à l'exception que je n'accepterai pas ma propre réponse.

Enfin, il est recommandé (mais pas obligatoire) de publier au moins une capture d'écran (ou une sortie de texte en cas d'art ASCII) de votre horloge dans votre réponse. De cette façon, les gens n'auront pas besoin de le compiler et de l'exécuter pour voir de quoi il s'agit.


Cette question est destinée à être une reprise d'une question supprimée.

Notez qu'il ne s'agit pas d'un doublon de cette autre question . Cette question était un demandant de l'art ASCII. Celui-ci n'est pas limité à l'art ASCII et est plutôt un , donc les réponses devraient être très différentes.


Ma solution shell: xclock. Nécessite xclock pour être installé.
juniorRubyist

Réponses:


31

SVG + Javascript

Capture d'écran de l'horloge analogique SVG

▶▶▶ Démonstration en direct ici ◀◀◀

Cela utilise les fonctions d'animation intégrées de SVG pour tourner les mains, avec un peu de Javascript supplémentaire pour récupérer l'heure locale et définir les positions initiales des mains. Il fonctionne bien dans Chrome et Safari, et devrait être compatible avec la plupart des navigateurs modernes car il n'utilise aucun effet de filtre.

<?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>

Hou la la! Tout ce qui manque pour avoir l'air super-skeuomorphique, ce sont des ombres sous les mains!

Il semble bon avec des ombres portées, mais l'animation peut devenir un peu glitch dans Chrome.
squeamish ossifrage

1
Cool. Je n'avais aucune idée que les SVG pouvaient faire de telles choses.
Sebastian Negraszus

17

Java 8

J'ai fait une horloge qui change ses couleurs en fonction de l'heure du jour, indiquant l'heure locale. Au fil du temps, il changera lentement de couleurs, en utilisant des couleurs plus lumineuses le jour et des couleurs plus sombres la nuit.

La fenêtre est redimensionnable et l'horloge se redimensionne automatiquement à la taille que vous choisissez.

De plus, si l'utilisateur ajuste l'horloge du système ou si un changement d'heure d'été se produit, l'horloge le reflétera automatiquement.

Il existe deux formes pour l'exécuter:

  1. Exécution du ClockDemofichier, c.-à-d java clock.ClockDemo. Cela ouvrira une fenêtre et vous y verrez l'horloge.

  2. Exécution du ClockSavefichier, c.-à-d java clock.ClockSave filename width height [HH:mm:ss]. Cela enregistrera simplement l'horloge dans un fichier PNG avec le nom de fichier, la largeur et la hauteur donnés. L'horloge sera tirée avec l'heure donnée ou, si elle est omise, avec l'heure actuelle. Par exemple, si vous l'exécutez car java clock.ClockSave clock.png 600 500 12:38:24cela enregistrera l'horloge dans une image 600x500 dans un clock.pngfichier et l'horloge affichera 00h38:24. Utilisez les heures dans l'intervalle 00-23.


Captures d'écran

Voici quelques captures d'écran et fichiers générés:

00:36:50:

00:36:50 AM

02:38:51:

02:39:51 AM

06:42:13 AM:

06:42:13 AM

11:15:28:

11:15:28 AM

17h02: 37:

05:02:37 PM

19h11h30:

07:11:30 PM

21h29: 34:

21:29:34


Code source

J'ai séparé la source dans cinq fichiers différents dans un package appelé clock.

Également disponible sur GitHub .

ClockDemo.java

package clock;

import java.awt.EventQueue;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;

public class ClockDemo {
    public static void main(String[] args) {
        EventQueue.invokeLater(ClockDemo::runIt);
    }

    private static void runIt() {
        final JFrame j = new JFrame();
        j.setTitle("JClock");
        final JClock clock = new JClock(new CoolPaint());

        j.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                clock.stop();
                j.dispose();
            }
        });

        j.add(clock);
        j.setBounds(20, 20, 600, 500);
        j.setVisible(true);
        clock.start();
    }
}

ClockSave.java

package clock;

import java.io.IOException;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

public class ClockSave {
    public static void main(String[] args) {

        // Too much arguments.
        if (args.length < 3 || args.length > 4) {
            System.out.println("Bad usage: Should be java clock.ClockSave filename width height [HH:mm:ss]");
            return;
        }

        // Parse the image size.
        int h, w;
        try {
            w = Integer.parseInt(args[1]);
            h = Integer.parseInt(args[2]);
        } catch (NumberFormatException e) {
            System.out.println("Bad usage: Should be java clock.ClockSave filename width height [HH:mm:ss]");
            return;
        }

        // Parse the intended time.
        LocalTime time;
        if (args.length == 4) {
            try {
                DateTimeFormatter df = DateTimeFormatter.ofPattern("HH:mm:ss");
                time = LocalTime.parse(args[3], df);
            } catch (DateTimeParseException e) {
                System.out.println("Bad usage: Should be java clock.ClockSave filename width height [HH:mm:ss]");
                return;
            }
        } else {
            time = LocalTime.now();
        }

        // Save to an image.
        try {
            new CoolPaint().saveClock(w, h, time, args[0]);
        } catch (IOException e) {
            System.out.println("Error on image output: " + e.getMessage());
        }
    }
}

JClock.java

package clock;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.time.LocalTime;
import java.time.temporal.ChronoField;
import javax.swing.JComponent;

public class JClock extends JComponent {
    private static final long serialVersionUID = 1L;

    private final CoolPaint paint;
    private final Object lock;
    private Thread updater;

    public JClock(CoolPaint paint) {
        this.paint = paint;
        this.lock = new Object();
    }

    private void runClock() {
        int lastTime = -1;
        try {
            while (isRunning()) {
                Thread.sleep(10);
                int t = time();
                if (t != lastTime) {
                    lastTime = t;
                    repaint();
                }
            }
        } catch (InterruptedException e) {
            // Do nothing, the thread will die naturally.
        }
    }

    private int time() {
        return LocalTime.now().get(ChronoField.SECOND_OF_DAY);
    }

    private boolean isRunning() {
        synchronized (lock) {
            return updater == Thread.currentThread();
        }
    }

    public void start() {
        synchronized (lock) {
            if (updater != null) return;
            updater = new Thread(this::runClock);
            updater.start();
        }
    }

    public void stop() {
        synchronized (lock) {
            updater = null;
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        paint.paintClock(getWidth(), getHeight(), time(), (Graphics2D) g);
    }
}

ClockPaint.java

package clock;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.time.LocalTime;
import java.time.temporal.ChronoField;
import javax.imageio.ImageIO;

public interface ClockPaint {

    public void paintClock(int width, int height, int seconds, Graphics2D g2);

    public default void paintClock(int width, int height, LocalTime time, Graphics2D g2) {
        paintClock(width, height, time.get(ChronoField.SECOND_OF_DAY), g2);
    }

    public default void paintClock(int width, int height, Graphics2D g2) {
        paintClock(width, height, LocalTime.now(), g2);
    }

    public default void saveClock(int width, int height, String fileName) throws IOException {
        saveClock(width, height, LocalTime.now(), fileName);
    }

    public default void saveClock(int width, int height, LocalTime time, String fileName) throws IOException {
        saveClock(width, height, time.get(ChronoField.SECOND_OF_DAY), fileName);
    }

    public default void saveClock(int width, int height, int seconds, String fileName) throws IOException {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        paintClock(width, height, seconds, (Graphics2D) image.getGraphics());
        String f = fileName.endsWith(".png") ? fileName : fileName + ".png";
        ImageIO.write(image, "png", new File(f));
    }
}

CoolPaint.java

package clock;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.RadialGradientPaint;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;

public class CoolPaint implements ClockPaint {

    private static final int SECONDS_IN_MINUTE = 60;
    private static final int SECONDS_IN_HALF_HOUR = 30 * SECONDS_IN_MINUTE;
    private static final int SECONDS_IN_HOUR = 60 * SECONDS_IN_MINUTE;
    private static final int SECONDS_IN_12_HOURS = 12 * SECONDS_IN_HOUR;

    private static final int AM_0_00 = 0;
    private static final int AM_3_00 = 3 * SECONDS_IN_HOUR;
    private static final int AM_4_30 = 4 * SECONDS_IN_HOUR + SECONDS_IN_HALF_HOUR;
    private static final int AM_7_30 = 7 * SECONDS_IN_HOUR + SECONDS_IN_HALF_HOUR;
    private static final int AM_12_00 = 12 * SECONDS_IN_HOUR;
    private static final int PM_4_30 = 16 * SECONDS_IN_HOUR + SECONDS_IN_HALF_HOUR;
    private static final int PM_7_30 = 19 * SECONDS_IN_HOUR + SECONDS_IN_HALF_HOUR;
    private static final int PM_9_00 = 21 * SECONDS_IN_HOUR;
    private static final int PM_12_00 = 24 * SECONDS_IN_HOUR;

    private static final Color BLACK = new Color(0, 0, 0);
    private static final Color DARK_GRAY = new Color(32, 32, 32);
    private static final Color DARK_BLUE = new Color(0, 0, 128);
    private static final Color PURPLE = new Color(128, 0, 128);
    private static final Color CYAN = new Color(0, 255, 255);
    private static final Color YELLOW = new Color(225, 225, 0);
    private static final Color PALE_YELLOW = new Color(224, 224, 64);
    private static final Color RED = new Color(255, 0, 0);
    private static final Color GREEN = new Color(0, 255, 0);
    private static final Color LIGHT_BLUE = new Color(128, 128, 255);
    private static final Color SKY_CYAN = new Color(48, 224, 224);

    private static final Color[] COLOR_CYCLE = {
        DARK_GRAY, LIGHT_BLUE, RED, PALE_YELLOW, GREEN, SKY_CYAN, LIGHT_BLUE, DARK_GRAY
    };

    private static final int RADIAL_PERIOD_LENGTH = PM_12_00 / COLOR_CYCLE.length;
    private static final String[] ROMAN = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII"};

    private static class Painter {
        private final int width;
        private final int height;
        private final int seconds;
        private final int radius;
        private final Graphics2D g2;
        private final int cx;
        private final int cy;
        private final int secondColorIndex;
        private final int secondsInPeriod;
        private final Color pointersAndNumbersColor;

        public Painter(int width, int height, int seconds, Graphics2D g2) {
            this.width = width;
            this.height = height;
            this.seconds = seconds;
            this.radius = Math.min(width / 2, height / 2);
            this.cx = width / 2;
            this.cy = height / 2;
            this.g2 = g2;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            this.secondColorIndex = seconds / RADIAL_PERIOD_LENGTH;
            this.secondsInPeriod = seconds % RADIAL_PERIOD_LENGTH;

            int startIndex = (secondColorIndex + COLOR_CYCLE.length + 5) % COLOR_CYCLE.length;
            int endIndex = (secondColorIndex + COLOR_CYCLE.length + 6) % COLOR_CYCLE.length;
            Color color1 = COLOR_CYCLE[startIndex];
            Color color2 = COLOR_CYCLE[endIndex];
            this.pointersAndNumbersColor = mixColors(color1, color2, 0, RADIAL_PERIOD_LENGTH, secondsInPeriod);
        }

        private int mixColorComponent(int startComponent, int endComponent, double position) {
            int difference = endComponent - startComponent;
            return startComponent + (int) (difference * position);
        }

        private Color mixColors(Color startColor, Color endColor, int startTime, int endTime, int currentTime) {
            double normalized = (currentTime - startTime) / (double) (endTime - startTime);
            return new Color(
                    mixColorComponent(startColor.getRed(), endColor.getRed(), normalized),
                    mixColorComponent(startColor.getGreen(), endColor.getGreen(), normalized),
                    mixColorComponent(startColor.getBlue(), endColor.getBlue(), normalized));
        }

        private Color upperBackgroundColor() {
            if (seconds < 0) throw new IllegalArgumentException();
            if (seconds <= AM_3_00) return BLACK;
            if (seconds <= AM_4_30) return mixColors(BLACK, DARK_BLUE, AM_3_00, AM_4_30, seconds);
            if (seconds <= AM_7_30) return mixColors(DARK_BLUE, CYAN, AM_4_30, AM_7_30, seconds);
            if (seconds <= AM_12_00) return CYAN;
            if (seconds <= PM_4_30) return CYAN;
            if (seconds <= PM_7_30) return mixColors(CYAN, DARK_BLUE, PM_4_30, PM_7_30, seconds);
            if (seconds <= PM_9_00) return mixColors(DARK_BLUE, BLACK, PM_7_30, PM_9_00, seconds);
            if (seconds <= PM_12_00) return BLACK;
            throw new IllegalArgumentException();
        }

        private Color lowerBackgroundColor() {
            if (seconds < 0) throw new IllegalArgumentException();
            if (seconds <= AM_3_00) return mixColors(BLACK, DARK_BLUE, AM_0_00, AM_3_00, seconds);
            if (seconds <= AM_4_30) return mixColors(DARK_BLUE, PURPLE, AM_3_00, AM_4_30, seconds);
            if (seconds <= AM_7_30) return mixColors(PURPLE, YELLOW, AM_4_30, AM_7_30, seconds);
            if (seconds <= AM_12_00) return mixColors(YELLOW, CYAN, AM_7_30, AM_12_00, seconds);
            if (seconds <= PM_4_30) return mixColors(CYAN, YELLOW, AM_12_00, PM_4_30, seconds);
            if (seconds <= PM_7_30) return mixColors(YELLOW, PURPLE, PM_4_30, PM_7_30, seconds);
            if (seconds <= PM_9_00) return mixColors(PURPLE, DARK_BLUE, PM_7_30, PM_9_00, seconds);
            if (seconds <= PM_12_00) return mixColors(DARK_BLUE, BLACK, PM_9_00, PM_12_00, seconds);
            throw new IllegalArgumentException();
        }

        private void paintBackground() {
            Point2D p1 = new Point2D.Double(width / 2, 0);
            Point2D p2 = new Point2D.Double(width / 2, height);
            g2.setPaint(new GradientPaint(p1, upperBackgroundColor(), p2, lowerBackgroundColor()));
            g2.fillRect(0, 0, width, height);
        }

        private RadialGradientPaint colorOnCycle(Point2D center, float radius) {
            Color baseColor1 = COLOR_CYCLE[(secondColorIndex + COLOR_CYCLE.length - 1) % COLOR_CYCLE.length];
            Color baseColor2 = COLOR_CYCLE[secondColorIndex];
            Color baseColor3 = COLOR_CYCLE[(secondColorIndex + COLOR_CYCLE.length + 1) % COLOR_CYCLE.length];
            Color baseColor4 = COLOR_CYCLE[(secondColorIndex + COLOR_CYCLE.length + 2) % COLOR_CYCLE.length];

            Color start = mixColors(baseColor1, baseColor2, 0, RADIAL_PERIOD_LENGTH, secondsInPeriod);
            Color end = mixColors(baseColor3, baseColor4, 0, RADIAL_PERIOD_LENGTH, secondsInPeriod);
            float index2 = (RADIAL_PERIOD_LENGTH - secondsInPeriod) / (float) RADIAL_PERIOD_LENGTH / 2;
            float index3 = 0.5f + index2;
            float[] positions = index3 == 1.0 ? new float[] {0.0f, index2, 1.0f}
                    : new float[] {0.0f, index2, index3, 1.0f};
            Color[] colors = index3 == 1.0 ? new Color[] {start, baseColor2, end}
                    : new Color[] {start, baseColor2, baseColor3, end};

            return new RadialGradientPaint(center, radius, positions, colors);
        }

        private void paintClockArea() {
            Point2D center = new Point2D.Double(width / 2, height / 2);
            g2.setPaint(colorOnCycle(center, radius));
            g2.fillOval(width / 2 - radius, height / 2 - radius, radius * 2, radius * 2);
        }

        private double pointerRevolutionsToRadians(double angle) {
            return Math.toRadians((450 + angle * -360) % 360.0);
        }

        private void paintPointers() {
            double hAngle = pointerRevolutionsToRadians(seconds % SECONDS_IN_12_HOURS / (double) SECONDS_IN_12_HOURS);
            double mAngle = pointerRevolutionsToRadians(seconds % SECONDS_IN_HOUR / (double) SECONDS_IN_HOUR);
            double sAngle = pointerRevolutionsToRadians(seconds % SECONDS_IN_MINUTE / (double) SECONDS_IN_MINUTE);

            g2.setStroke(new BasicStroke(4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g2.drawLine(cx, cy, (int) (cx + Math.cos(hAngle) * radius * 0.55), (int) (cy - Math.sin(hAngle) * radius * 0.55));
            g2.drawLine(cx, cy, (int) (cx + Math.cos(mAngle) * radius * 0.85), (int) (cy - Math.sin(mAngle) * radius * 0.85));
            g2.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g2.drawLine(cx, cy, (int) (cx + Math.cos(sAngle) * radius * 0.85), (int) (cy - Math.sin(sAngle) * radius * 0.85));
        }

        private void paintNumbers() {
            Font originalFont = g2.getFont();
            double amplification = (int) Math.max(radius * 0.08, originalFont.getSize()) / (double) originalFont.getSize();
            AffineTransform at0 = AffineTransform.getScaleInstance(amplification, amplification);
            Font amplifiedFont = originalFont.deriveFont(at0);
            g2.setFont(amplifiedFont);
            FontMetrics fm = g2.getFontMetrics();

            for (int i = 1; i <= 12; i++) {
                double angle = pointerRevolutionsToRadians(i / 12.0);
                double textInclination = Math.toRadians(30 * i);
                AffineTransform at = AffineTransform.getRotateInstance(textInclination);
                at.scale(amplification, amplification);
                Font derivedFont = originalFont.deriveFont(at);
                g2.setFont(derivedFont);
                int pixelsOffset = fm.stringWidth(ROMAN[i]) / 2;
                int xPlot = (int) (cx + Math.cos(angle) * radius * 0.9 - pixelsOffset * Math.cos(textInclination));
                int yPlot = (int) (cy - Math.sin(angle) * radius * 0.9 - pixelsOffset * Math.sin(textInclination));
                g2.drawString(ROMAN[i], xPlot, yPlot);
            }
            g2.setFont(originalFont);
        }

        private void paintDots() {
            for (int i = 1; i < 60; i++) {
                if (i % 5 == 0) continue;
                double angle = pointerRevolutionsToRadians(i / 60.0);
                g2.fillRect((int) (cx + Math.cos(angle) * radius * 0.9) - 1, (int) (cy - Math.sin(angle) * radius * 0.9) - 1, 3, 3);
            }
        }

        public void paintClock() {
            paintBackground();
            paintClockArea();

            g2.setColor(pointersAndNumbersColor);
            g2.setPaint(pointersAndNumbersColor);
            paintNumbers();
            paintDots();
            paintPointers();
        }
    }

    @Override
    public void paintClock(int width, int height, int seconds, Graphics2D g2) {
        new Painter(width, height, seconds, g2).paintClock();
    }
}

Je suis devenu frustré par diverses horloges de bureau (j'en ai besoin :)), j'ai donc décidé d'utiliser votre code comme base pour une horloge simple. Avez-vous par hasard un repo Github pour ce code?
ipolevoy

@ipolevoy Comme vous le souhaitiez, je l'ai ajouté à GitHub .
Victor Stafusa

appréciez l'effort!
ipolevoy

16

Freepascal

Cette horloge affiche l'heure, la date et la phase de la lune. Cependant contrairement aux horloges mécaniques qui ont une petite fenêtre pour afficher la phase de la lune, dans mon horloge tout le visage est utilisé pour l'afficher. Aujourd'hui, le 14 février est une pleine lune. Vous pouvez voir la sortie attendue au cours des prochains jours ci-dessous.

uses graph,sysutils;

const hemisphere=-1; {-1=north,1=south}
MonthStr : array[1..12] of string [3] =
('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep ','Oct','Nov','Dec');

var yy,dd,mm,hh,mn,ss,ms: word;
var s: string; d2fullmoon,hour,min:real; sec:word;

var gd, gm, n : integer;
var right, left, centre: word;

begin

  gd := D4bit;
  gm := m640x480;
  initgraph(gd,gm,'');
  setbkcolor(blue);cleardevice; setbkcolor(black);
  setlinestyle(0,0,3);
  settextjustify(centertext,centertext);
  settextstyle(defaultfont,horizdir,2);

  while true do begin

    {output to console}

    DecodeDate(Date,YY,MM,DD);
    Writeln (Format ('Today is %d/%d/%d',[dd,mm,yy]));

    DecodeTime(Time,HH,Mn,SS,MS);
    Writeln (format('The time is %d:%d:%d.%d',[hh,mm,ss,ms]));

    d2fullmoon:=yy*(365*3+366)/4+mm*365/12+dd-2014*(365*3+366)/4-2*365/12-14;
    writeln ('days since full moon 14 feb 2014 ',d2fullmoon);

    if ss mod 15=0 then begin {Refresh display every 15 sec. Only the second hand is refreshed every sec.}

      {Draw circle and 180deg pie in yellow/black. Draw yellow or black ellipse on top. Add boxes for date}

      if sin(d2fullmoon/29.530588853*2*pi)*hemisphere>0 then right:=yellow else right:=black;
      left:=yellow-right;

      setcolor(right);setfillstyle(solidfill,right);
      fillellipse(320,240,200,200);

      setfillstyle(solidfill,left);setcolor(left);
      pieslice(320,240,90,270,200);

      if cos(d2fullmoon/29.530588853*2*pi)>0 then centre:=yellow else centre:=black;
      setcolor(centre); setfillstyle(solidfill,centre);
      fillellipse(320,240,abs(trunc(200*cos(d2fullmoon/29.530588853*2*pi))),200);

      setcolor (blue); setfillstyle(solidfill,blue);
      bar (270,135,370,165); bar (270,345,370,315);

      {fill in numbers}

      for n:=1 to 12 do begin
        setcolor(blue); setfillstyle(solidfill,blue);
        fillellipse(319+trunc(170*sin(n*pi/6)),240-trunc(170*cos(n*pi/6)),15,15);
        fillellipse(320+trunc(170*sin(n*pi/6)),240-trunc(170*cos(n*pi/6)),15,15);

        moveto(322+trunc(170*sin(n*pi/6)),240-trunc(170*cos(n*pi/6)));
        setcolor(white);
        str(n,s);outtext(s);
      end;

      {fill in date}

      str(yy,s);
      moveto(320,330);outtext(s);
      str(dd,s);
      moveto(320,150);outtext(s+monthstr[mm]);

      {draw hour and minute hands}

      hour:=hh+mn/60; min:=mn+ss/60;
      setcolor(cyan) ;setfillstyle(solidfill,cyan);
      moveto(320,240);
      linerel(trunc(140*sin(min*pi/30)),trunc(-140*cos(min*pi/30)));
      fillellipse(320+trunc(140*sin(min*pi/30)),240+trunc(-140*cos(min*pi/30)),7,7);
      moveto(320,240);
      linerel(trunc(100*sin(hour*pi/6)),trunc(-100*cos(hour*pi/6)));
      fillellipse(320+trunc(100*sin(hour*pi/6)),240+trunc(-100*cos(hour*pi/6)),7,7);
      fillellipse(320,240,10,10);

    end;

    {draw second hand in XOR mode, sleep for a second, then repeat to undraw}

    sec:=ss;
    setwritemode(xorput); setcolor(white);
    moveto(320+trunc(12*sin(sec*pi/30)),240+trunc(-12*cos(sec*pi/30)));
    linerel(trunc(150*sin(sec*pi/30)),trunc(-150*cos(sec*pi/30)));

    Sleep(1000);

    moveto(320+trunc(12*sin(sec*pi/30)),240+trunc(-12*cos(sec*pi/30)));
    linerel(trunc(150*sin(sec*pi/30)),trunc(-150*cos(sec*pi/30)));
    setwritemode(copyput);

  end;
  closegraph;
end.

entrez la description de l'image ici entrez la description de l'image ici entrez la description de l'image ici entrez la description de l'image ici


Merveilleux, j'ai vraiment aimé celui-ci.
Victor Stafusa

12

Un simple que mon ami a écrit dans TI 84 BASIC:

StoreGDB 0
CoordOff
GridOff
AxesOff
LabelOff
ExprOff
ClrDraw
62->Ymax
0->Ymin
94->Xmax
0->Xmin
Func
FnOff 0,1,2,3,4,5,6,7,8,9
PlotsOff 1,2,3
Full
Xmax/2->Xmax
Ymax/2->Ymax
~Xmax->Xmin
~Ymax->Ymin
Degree

15->H
18->M
20->S

Circle(36,~22,7)
Circle(0,0,30)
For(X,1,12)
Text(28-int(cos(X*30)*25),46+int(sin(30*X)*25),X)
End

{0,0,0}->|LANG

While getKey=0
getTime->|LTIME
getDate->|LDATE

Text(0,0,"12 HR")
Text(50,0,"24 HR")
If |LTIME(1)>12:Then
Text(6,7,(|LTIME(1)-12))
Else
Text(6,7,|LTIME(1))
End

If |LTIME(1)<=9
Then
Text(56,4,"O")
Text(56,8,|LTIME(1))
Else
Text(56,4,|LTIME(1))
End

Text(29,4,|LTIME(2))


If |LDATE(2)=1
Text(0,70,"JAN")

If |LDATE(2)=2
Text(0,70,"FEB")

If |LDATE(2)=3
Text(0,70,"MAR")

If |LDATE(2)=4
Text(0,70,"APR")

If |LDATE(2)=5
Text(0,70,"MAY")

If |LDATE(2)=6
Text(0,70,"JUN")

If |LDATE(2)=7
Text(0,70,"JUL")

If |LDATE(2)=8
Text(0,70,"AUG")

If |LDATE(2)=9
Text(0,70,"SEP")

If |LDATE(2)=10
Text(0,70,"OCT")

If |LDATE(2)=11
Text(0,70,"NOV")

If |LDATE(2)=12
Text(0,70,"DEC"
Text(2,81,",")
Text(0,85,|LDATE(3))
Text(8,75,|LDATE(1))


If |LTIME(1)>=12
Then
Text(50,80,"PM")
Else
Text(50,80,"AM")
End

If |LTIME(3)!=|LANG(3)/6
Line(0,0,sin(|LANG(3))*S,cos(|LANG(3))*S,0)

If |LTIME(2)!=|LANG(2)/6
Then
Line(0,0,sin(|LANG(2))*M,cos(|LANG(2))*M,0)
Line(0,0,sin(|LANG(1))*H,cos(|LANG(1))*H,0)
End

|LTIME(1)*30+|LTIME(2)/2->|LANG(1)
|LTIME(2)*6->|LANG(2)
|LTIME(3)*6->|LANG(3)

Line(0,0,sin(|LANG(1))*H,cos(|LANG(1))*H
Line(0,0,sin(|LANG(2))*M,cos(|LANG(2))*M
Line(0,0,sin(|LANG(3))*S,cos(|LANG(3))*S
End

entrez la description de l'image ici


Je donnerais ce +100 si je pouvais :)
Timtech

Pouvez-vous publier une capture d'écran?
Victor Stafusa

non, ma TI-84 est cassée et je ne trouve pas un bon émulateur pour elle
TheDoctor

2
@Victor - j'ai mis la main sur une TI, mise à jour avec capture d'écran
TheDoctor

@TheDoctor Nice. :)
Victor Stafusa

9

Mathematica

Une horloge simple et fonctionnelle qui affiche l'heure locale:

Dynamic@Refresh[ClockGauge@AbsoluteTime[], UpdateInterval -> 1]

l'horloge


Options standard

les options


Jauge d'horloge dessinée à la main

Il existe des alternatives à la jauge d'horloge intégrée. En voici un.

Un balayage continu a été mis en place pour les aiguilles des heures et des minutes. Ils se mettent à jour avec la seconde main.

u[i_, k_] := {Sin[2 \[Pi] i/k], Cos[2 \[Pi] i/k]};
Dynamic[{f = Date[], Clock[{1, 1}, 1]}]
Graphics[Dynamic@{Circle[{0, 0}, 1.175], Circle[{0, 0}, 1.2],

   (* tick marks at minutes *)
   Table[Text[".", u[i, 60]], {i, 60}],  

   (* hour labels *)
   Table[Text[i, u[i, 12]], {i, 12}],  

   (* hour hand *)
   {Darker@Red, Arrowheads[.12], Thickness[.0175], Arrow[{{0, 0}, .6 u[f[[4]]+f[[5]]/60, 12]}]},

   (*minute hand *)
   {Blue, Arrowheads[.08], Thickness[.0085], Arrow[{{0, 0}, .85 u[f[[5]]+f[[6]]/60, 60]}]},

   (*second hand *)
   {Thickness[.005], Arrow[{{0, 0}, .9 u[f[[6]], 60]}]}}, 
   BaseStyle -> 25]

horloge 4


Vous avez rendu orpheline une ligne de code en haut de votre bloc de code de jauge dessiné à la main. Je l'éditerais, mais le système n'autorisera pas les modifications à un caractère et tout ce dont il a besoin est d'une nouvelle ligne.
Jonathan Van Matre

8

Postscript - écrit à l'origine pour aider mes enfants à apprendre à lire l'heure. La page 1 montre l'heure actuelle, les pages 2 à 4 sont des pages pour les apprenants. Les pages pour les apprenants utilisent randpour créer des moments aléatoires, ils sont donc différents à chaque fois que vous le traitez. Utilisez Ghostscript pour créer une version PDF si vous souhaitez afficher l'heure actuelle. Format papier A4.

%!PS-Adobe-3.0
%%Creator: Toby Thurston
%%Title: (Pages of pedagogical clocks)
%%CreationDate: (2014-02-14)
%%BoundingBox: 12 12 583 828 
%%Pages: 1
%%EndComments
<< /PageSize [595 842] >> setpagedevice
%%BeginSetup
/clock {
  /mins exch def
  /hour exch def
  /r exch def % radius
  /cr r 100 div def
  % draw the minute marks
  12 { .5 setlinewidth 4 { 6 rotate r 0 moveto r 20 div 0 rlineto stroke } repeat
        2 setlinewidth     6 rotate r 0 moveto r 20 div 0 rlineto stroke } repeat  
  % numbers           
  /fontsize r 0.14 mul def
  /Helvetica findfont fontsize scalefont setfont
  /s 2 string def 
  /rr r 0.9 mul def
  1 1 12 { /n exch def /theta 90 30 n mul sub def
  /st n s cvs def st stringwidth pop /dx exch 2 div neg def
  rr theta cos mul rr theta sin mul moveto dx fontsize 3 div neg rmoveto st show
  } for

  % draw hands (unless hour is negative)
  -1 hour lt {
      gsave % hour hand first
      90 60 hour mul mins add 2 div sub rotate
      newpath
      0 2 moveto
      15 cr mul  3 cr mul 33 cr mul   0 cr mul 50 cr mul  3 cr mul curveto 
      55 cr mul 15 cr mul 60 cr mul   0 cr mul 76 cr mul  0 cr mul curveto
      60 cr mul  0 cr mul 55 cr mul -15 cr mul 50 cr mul -3 cr mul curveto 
      33 cr mul  0 cr mul 15 cr mul  -3 cr mul  0 cr mul -2 cr mul curveto
      closepath 0 0 .677 setrgbcolor fill
      grestore
      gsave % minute hand on top
      90 6 mins mul sub rotate
      newpath
      0 2 moveto
      15 cr mul 3 cr mul 33 cr mul 0         50 cr mul  1 cr mul curveto 
      65 cr mul 3 cr mul 83 cr mul 0         97 cr mul  0        curveto
      83 cr mul 0        65 cr mul -3 cr mul 50 cr mul -1 cr mul curveto 
      33 cr mul 0        15 cr mul -3 cr mul 0         -2 cr mul curveto
      closepath .635 0 0 setrgbcolor fill
      grestore
  } if 

  % finally do central dot (to cover starts of hands) and outer band      
  .5 setlinewidth
  0 0 moveto 0 0 r 20 div   0 360 arc fill
             0 0 r 1.07 mul 0 360 arc stroke

} def
%%EndSetup
%%Page: 1 1 
%%BeginPageSetup
/pgsave save def
%%EndPageSetup
  297 480 translate
  120 

  (%Calendar%) /IODevice resourcestatus {
   pop pop (%Calendar%) currentdevparams
   dup /Running get { dup /Hour get exch /Minute get }{ 0 0 } ifelse } { -1 -1 } ifelse

  clock
pgsave restore
showpage
%%Page: 2 2
%%BeginPageSetup
/pgsave save def
%%EndPageSetup
  75 -55 translate
  4 {
     5 { 0 165 translate % a page of clocks for learners
         50 rand 12 mod rand 60 mod clock 
         % line underneath           
         gsave [1 3] 0 setdash 50 neg dup 1.8 mul moveto 50 2 mul 0 rlineto stroke grestore
     } repeat
     146 5 165 mul neg translate
  } repeat
pgsave restore
showpage
%%Page: 3 3
%%BeginPageSetup
/pgsave save def
%%EndPageSetup
  75 -55 translate
  4 {
     5 { 0 165 translate    % whole multiple of five minutes only
         50 rand 12 mod rand 12 mod 5 mul clock 
         gsave [1 3] 0 setdash 50 neg dup 1.8 mul moveto 50 2 mul 0 rlineto stroke grestore
     } repeat
     146 5 165 mul neg translate
  } repeat
pgsave restore
showpage
%%Page: 4 4
%%BeginPageSetup
/pgsave save def
%%EndPageSetup
  75 -55 translate
  4 {
     5 { 0 165 translate    % quarter hours only
         50 rand 12 mod rand 4 mod 15 mul clock 
         gsave [1 3] 0 setdash 50 neg dup 1.8 mul moveto 50 2 mul 0 rlineto stroke grestore
     } repeat
     146 5 165 mul neg translate
  } repeat
pgsave restore
showpage
%%EOF

entrez la description de l'image ici entrez la description de l'image ici


4
+1 pour avoir écrit Postscript pour enseigner à vos enfants. Vous êtes un parent génial.
Jonathan Van Matre

Ne randvous donnera pas les mêmes résultats à chaque fois? À moins que vous ne l'ensemenciez d'une manière ou d'une autre, peut-être (/dev/rand)(r)file read pop srand.
luser droog

@luserdroog ... err no. Vous n'avez besoin que srandsi vous voulez fixer votre position dans la séquence PS de nombres pseudo-aléatoires. Pour citer le PSLRM: "L'exécution srandavec une valeur particulière provoque des invocations ultérieures de randpour générer une séquence reproductible de résultats."
Thruston

C'est vrai, mais l'interpréteur initialise lui-même avec 1 srandavant d'exécuter des programmes utilisateur. Vous devez donc introduire votre propre entropie pour obtenir une séquence non reproductible. N'ont pas été testés avec Distiller, mais c'est ce que fait Ghostscript. gsnd -q -dBATCH -c 'rand ='me donne toujours 16807.
luser droog

4

Démo: http://jsfiddle.net/kelunik/Vuuq8/7/embedded/result/

HTML

<div id="clock">
    <div id="h"></div>
    <div id="m"></div>
    <div id="s"></div>
</div>

CSS

html, body {
    margin: 0;
    padding: 0;
    text-align: center;
}
#clock {
    width: 100vmin;
    height: 100vmin;
    border-radius: 50%;
    border: 1vmin solid #333;
    position: relative;
    box-shadow: 0 0 5vmin rgba(0, 0, 0, .3);
    box-sizing: border-box;
    margin: 0 auto;
    transform: scale(.8);
}
#h, #m, #s {
    top: 50vmin;
    left: 50vmin;
    position: absolute;
}
#h:before, #m:before, #s:before {
    content:"";
    position: absolute;
    left: 100%;
    height: 0;
    box-shadow: 0 0 2vmin rgba(0,0,0,.2);
    border-radius: 50%;
}
#h:before {
    width: 25vmin;
}
#m:before {
    width: 35vmin;
}
#s:before {
    width: 45vmin;
}
#h:before {
    background: black;
    height: 4vmin;
    transform: translateY(-2vmin);
}
#m:before {
    background: black;
    height: 2vmin;
    transform: translateY(-1vmin);
}
#s:before {
    background: red;
    height: 2vmin;
    transform: translateY(-1vmin);
}

Javascript

var h = document.getElementById('h');
var m = document.getElementById('m');
var s = document.getElementById('s');

setInterval(function () {
    refreshClock();
}, 1000);

function refreshClock() {
    var time = new Date;

    deg = time.getSeconds() * 6 - 90;
    s.style.webkitTransform = s.style.MozTransform = s.style.msTransform = s.style.transform = "rotate(" + deg + "deg)";

    deg = time.getMinutes() * 6 - 90;
    m.style.webkitTransform = m.style.MozTransform = m.style.msTransform = m.style.transform = "rotate(" + deg + "deg)";

    deg = time.getHours() % 12 * 30 - 90;
    h.style.webkitTransform = h.style.MozTransform = h.style.msTransform = h.style.transform = "rotate(" + deg + "deg)";
}

window.onload = function () {
    refreshClock();
};

J'ai une horloge, mais les aiguilles des heures et des minutes (et des secondes?) Pointent directement vers la droite. Rien ne bouge.
Justin

Quel navigateur utilisez-vous?
kelunik

Google Chrome ..
Justin

Votre réponse semble prometteuse et intéressante, mais elle échoue maintenant. Il y a quelque chose qui ne va pas avec la propriété CSS de transformation dans la fonction refreshClock (mais je ne sais pas exactement quoi). Je l'ai essayé dans IE, Chrome et Firefox, ne fonctionnait chez personne.
Victor Stafusa

@Victor semble fonctionner uniquement dans Firefox en ce moment, mais là, cela fonctionne.
kelunik

4

En voici une en cours de traitement:

int ax,ay,bx,by,cx,cy,dx,dy,last;
int q = 1;
float c = 0;
float h = 0;
float m = 0;

void setup() {
  size(displayWidth, displayHeight);
  background(0);
}

boolean sketchFullScreen() {
  return true;
}

void draw() {
  colorMode(HSB);
  fill(c,255,255,4);
  noStroke();
  rect(0,0,width,height);

  c+=0.4;
  if (c > 255) c = 0;

  colorMode(RGB);

  ax = int(random(displayWidth));
  ay = int(random(displayHeight));
  bx = ax + int(random(-50,50));
  by = ay + int(random(0,50));

  strokeWeight(1);

  if (random(0,1)>0.5) {
    fill(random(255),random(255),random(255));
    stroke(random(255),random(255),random(255));
  }
  else {
    noFill();
    stroke(random(255),random(255),random(255));
  }

  switch(int(random(6))) {
    case 0: // line
    line(ax,ay,bx,by);

    break;
    case 1: // bezier (arc)
    cx = int(random(ax-20,bx+20));
    cy = int(random(ay-20,by+20));
    dx = int(random(ax-20,bx+20));
    dy = int(random(ay-20,by+20));
    bezier(ax,ay,cx,cy,dx,dy,bx,by);

    break;
    case 2: // box
    quad(ax,ay,ax,by,bx,by,bx,ay);

    break;
    case 3: // ellipse
    ellipse(ax,ay,random(15,50),random(15,50));

    break;
    case 4: // triangle
    cx = int(random(ax-20,bx+20));
    cy = int(random(ay-20,by+20));
    dx = int(random(ax-20,bx+20));
    dy = int(random(ay-20,by+20));
    triangle(cx,cy,bx,by,dx,dy);

    break;
    case 5: // arc
    arc(ax,ay,random(15,50),random(15,50),random(2)*PI,random(2)*PI);

    break;  
  }

  float s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI;
  float m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI; 
  float h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI;

  cx = width/2;
  cy = height/2;

  // Draw the hands of the clock
  stroke(255);
  strokeWeight(1);
  line(cx, cy, cx + cos(s) * 500, cy + sin(s) * 500);
  strokeWeight(2);
  line(cx, cy, cx + cos(m) * 400, cy + sin(m) * 400);
  strokeWeight(4);
  line(cx, cy, cx + cos(h) * 300, cy + sin(h) * 300);

}

void mouseMoved() {
  exit();
}
void keyPressed() {
  background(0);
}

c'est plein écran


C'est si beau!
danmcardle

Il dit que je ne peux pas remplacer la méthode de PApplet?
Kritixi Lithos

@danmcardle: C'est tellement moche!
sergiol


3

GNUPLOT

unset clip points
set clip one
unset clip two
set bar 1.000000
unset border
set xdata
set ydata
set zdata
set x2data
set y2data
set timefmt x "%d/%m/%y,%H:%M"
set timefmt y "%d/%m/%y,%H:%M"
set timefmt z "%d/%m/%y,%H:%M"
set timefmt x2 "%d/%m/%y,%H:%M"
set timefmt y2 "%d/%m/%y,%H:%M"
set timefmt cb "%d/%m/%y,%H:%M"
set boxwidth
set style fill  empty border
set dummy t,y
set format x "% g"
set format y "% g"
set format x2 "% g"
set format y2 "% g"
set format z "% g"
set format cb "% g"
set angles radians
unset grid
set key title ""
unset key
unset label
unset arrow
unset style line
unset style arrow
set style histogram clustered gap 2 title  offset 0, 0, 0
unset logscale
set offsets 0, 0, 0, 0
set pointsize 1
set encoding default
unset polar
set parametric
unset decimalsign
set view 60, 30, 1, 1
set samples 100, 100
set isosamples 10, 10
set surface
unset contour
set clabel '%8.3g'
set mapping cartesian
set datafile separator whitespace
unset hidden3d
set cntrparam order 4
set cntrparam linear
set cntrparam levels auto 5
set cntrparam points 5
set size ratio 0 1,1
set origin 0,0
set style data points
set style function lines
set xzeroaxis linetype -2 linewidth 1.000
set yzeroaxis linetype -2 linewidth 1.000
set zzeroaxis linetype -2 linewidth 1.000
set x2zeroaxis linetype -2 linewidth 1.000
set y2zeroaxis linetype -2 linewidth 1.000
set ticslevel 0.5
set mxtics default
set mytics default
set mztics default
set mx2tics default
set my2tics default
set mcbtics default
set noxtics
set noytics
set noztics
set nox2tics
set noy2tics
set nocbtics
set title ""  offset character 0, 0, 0 font "" norotate
set timestamp bottom 
set timestamp ""  offset character 0, 0, 0 font "" norotate
set rrange [ * : * ] noreverse nowriteback  # (currently [0.000000:10.0000] )
set trange [ * : * ] noreverse nowriteback  # (currently [-5.00000:5.00000] )
set urange [ * : * ] noreverse nowriteback  # (currently [-5.00000:5.00000] )
set vrange [ * : * ] noreverse nowriteback  # (currently [-5.00000:5.00000] )
set xlabel ""  offset character 0, 0, 0 font "" textcolor lt -1 norotate
set x2label ""  offset character 0, 0, 0 font "" textcolor lt -1 norotate
set xrange [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set x2range [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set ylabel ""  offset character 0, 0, 0 font "" textcolor lt -1 rotate by 90
set y2label ""  offset character 0, 0, 0 font "" textcolor lt -1 rotate by 90
set yrange [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set y2range [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set zlabel ""  offset character 0, 0, 0 font "" textcolor lt -1 norotate
set zrange [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set cblabel ""  offset character 0, 0, 0 font "" textcolor lt -1 norotate
set cbrange [ * : * ] noreverse nowriteback  # (currently [-10.0000:10.0000] )
set zero 1e-008
set lmargin -1
set bmargin -1
set rmargin -1
set tmargin -1
set locale "C"
set pm3d explicit at s
set pm3d scansautomatic
set pm3d interpolate 1,1 flush begin noftriangles nohidden3d corners2color mean
set palette positive nops_allcF maxcolors 0 gamma 1.5 color model RGB 
set palette rgbformulae 7, 5, 15
set colorbox default
set colorbox vertical origin screen 0.9, 0.2, 0 size screen 0.05, 0.6, 0 bdefault
set loadpath 
set fontpath 
set fit noerrorvariables
set arrow from 0,0 to sin(`date +%M`*3.1416/30),cos(`date +%M`*3.1416/30) 
set arrow from 0,0 to sin((`date +%H`%12)*3.1416/6)/2,cos((`date +%H`%12)*3.1416/6)/2
plot sin(t),cos(t)
reread

dans linux centos 6.5


+1 Cela fonctionne même dans une fenêtre Tektronix. xterm -t -e "gnuplot -e 'set term tek40xx' clock.plot"(avec des clignotements ennuyeux)
luser droog

1
Pour éviter les clignotements, vous pouvez ajouter une "pause 60" juste avant de relire
delfosse

3

Code MATLAB simple, écrit principalement pour apprécier le cadran de 24 heures au travail.

Exemple de montre MATLAB avec cadrans 24 et 12 heures tandis que 1 runWatch () pause (0,6); fin

% 20160829 :: grapesh@gmail.com
function runWatch()
cla;

dialHours  = 24;   % You can set it to 12 but why?
midnightUp = true; % defines position of midnight

col.hr = 'k'; 
col.mn = 'b'; 
col.sc = 'r'; 

logoStr = ['Perpetuum'];

xo = 0; yo = 0; 
RH  = 0.7;   RM  = 0.95; Rb = 0.5*(RH+RM);
RarrH = RH; RarrM = Rb; RarrS = RM;

fig_handle = findobj(allchild(0), 'flat', 'type', 'figure');

if isempty(fig_handle), set(gcf,'Position',[100 100 500 500]); end
hoursPhase = 3*pi/2; if midnightUp == true, hoursPhase = pi/2; end

hold on;
circle(xo, yo, RH,col.hr); 
circle(xo, yo, RM,col.mn);% ,'b');
circle(xo, yo, (RH+RM)/2,col.mn); %0.5*[1 1 1]);

text (xo - 2.5*RH/8+0.003, yo - RH/2-0.003, logoStr,'Color',0.5*[1 1 1],'FontAngle','italic');
text (xo - 2.5*RH/8,       yo - RH/2,       logoStr, 'FontAngle','italic')
axis equal; axis off;

% Hour dial
dh = pi/dialHours; h = 0:-dh:-pi+dh;
xH = RH*cos(2*h+hoursPhase); yH = RH*sin(2*h+hoursPhase);
xHb= Rb*cos(2*h+hoursPhase); yHb= Rb*sin(2*h+hoursPhase);
for n=1:length(xH)
    plot([xH(n),xHb(n)],[yH(n),yHb(n)],col.hr);
end
% Minute dial
dm = pi/60; m = 0:-dm:-pi+dm;
xM = RM*cos(2*m+pi/2); yM = RM*sin(2*m+pi/2);
xMb= Rb*cos(2*m+pi/2); yMb= Rb*sin(2*m+pi/2);
for n=1:length(xM)
    plot([xM(n),xMb(n)],[yM(n),yMb(n)],'Color',col.mn);
end

% Labels Hour
dhl = pi/dialHours; hl = 0:-dhl:-pi+dhl;  ratioH = -dialHours/180;
xHl= 0.5*(Rb+RH)*cos(2*hl+hoursPhase); 
yHl= 0.5*(Rb+RH)*sin(2*hl+hoursPhase);
for n=1:length(xHl)
    octagon (xHl(n), yHl(n), 0.3*(RH-Rb), 'w');
    text (xHl(n),yHl(n), num2str( rad2deg(hl(n)*ratioH) ),...
        'HorizontalAlignment','center','Rotation',rad2deg(2*hl(n)+hoursPhase-pi/2),...
        'FontWeight','b','FontSize',13,'Color',col.hr);    

end

% Labels Minute
dml = pi/12; ml=0:-dml:-pi+dml;  ratioM = -60/180; 
xMl= 0.5*(Rb+RM)*cos(2*ml+pi/2); yMl= 0.5*(Rb+RM)*sin(2*ml+pi/2);
for n=1:length(xMl)    
    octagon (xMl(n), yMl(n), 0.3*(RM-Rb), 'w');
    text (xMl(n),yMl(n), num2str( rad2deg(ml(n)*ratioM) ),...
        'HorizontalAlignment','center','Rotation',rad2deg(2*ml(n)), ...
        'FontWeight','b','Color',col.mn);
end

octagon (xo, yo-0.5*(RH+Rb), 0.04, col.hr);
octagon (xo, yo-0.5*(RH+Rb), 0.03, col.mn);

[now_year, now_month, now_day, ...
    now_hour, now_minute, now_second] = datevec(now);

% Arrows
K = -2*pi/dialHours; D = hoursPhase;
now_hour = now_hour + now_minute/60;
xarrowh = RarrH*cos(K*now_hour+D);
yarrowh = RarrH*sin(K*now_hour+D);
plot([0,xarrowh],[0,yarrowh],'Color',col.hr,'LineWidth',6); 
plot([0,xarrowh],[0,yarrowh],'Color',0.5*[1 1 1],'LineWidth',3); 
arrowhead (xarrowh,yarrowh,0.02,atan2(yarrowh,xarrowh),col.hr);

K = -2*pi/60; D = pi/2;
now_minute = now_minute + now_second/60;
xarrowm  = RarrH*cos(K*now_minute+D);
yarrowm  = RarrH*sin(K*now_minute+D);
xarrowml = RarrM*cos(K*now_minute+D);
yarrowml = RarrM*sin(K*now_minute+D);
plot([0,xarrowml],[0,yarrowml],'Color','k', 'LineWidth',4);
plot([0,xarrowml],[0,yarrowml],'Color',col.mn, 'LineWidth',2);
arrowhead (xarrowml,yarrowml,0.02,atan2(yarrowml,xarrowml),col.mn);

K = -2*pi/60; D = pi/2;
now_second = round(now_second);
xarrows = RarrH*cos(K*now_second+D);
yarrows = RarrH*sin(K*now_second+D);
xarrowsl = RarrS*cos(K*now_second+D);
yarrowsl = RarrS*sin(K*now_second+D);
plot([0,xarrowsl],[0,yarrowsl],'Color',col.sc,'LineWidth',1);
arrowhead (xarrowsl,yarrowsl,0.02,atan2(yarrows,xarrows)-pi,col.sc);

text(0.7,1,...
    [pad_with(floor(now_hour),2,'0'), ':', pad_with(floor(now_minute),2,'0'), ':', pad_with(now_second,2,'0')],...
    'FontSize',8,'FontWeight','n','BackgroundColor','w');

% Dial center
plot(xo, yo, 'ko','MarkerSize',10,'MarkerFaceColor','k');
plot(xo, yo, 'ko','MarkerSize',8,'MarkerFaceColor',0.5*[0 1 1]);

end

function [XX,YY] = circle(varargin)
%x and y are the coordinates of the center of the circle
%r is the radius of the circle
%0.01 is the angle step, bigger values will draw the circle faster but
%you might notice imperfections (not very smooth)

col = 'k';
x = varargin{1};
y = varargin{2};
r = varargin{3};
if length(varargin) > 3
    col = varargin{4};
end

ang=0:0.01:2*pi; 
xp=r*cos(ang);
yp=r*sin(ang);
XX = x+xp; YY = y+yp;
plot(XX,YY,'Color',col);
end

function octagon (xo, yo, R, col)

t = (1/16:1/8:1)'*2*pi;
x = R*cos(t);
y = R*sin(t);
fill(xo+x, yo+y,col,'EdgeColor','none')
end

% 20151001 :: grapesh@gmail.com
% Use :: str = pad_with (num, L, pad)
% function creates a string of L length
% padded with leading 'pad' symbol
% e.g., num=23,    L=4, pad='.' --> '..23';
% e.g., num='23W', L=4, pad=' ' --> ' 23W';
% 
function str = pad_with (num, L, pad)

if ~ischar(num)
    num = num2str(num);
end
strL = length(num);
if L<strL, L = strL; end;
for n=1:L-strL, str(n) = pad; end;
c = 0;
for n=L-strL+1:L
    c = c+1; str(n) = num(c);
end
end

function [x, y] = arrowhead (xo, yo, height, alpha, col)

x(1) = xo + height*sin(alpha);
y(1) = yo - height*cos(alpha);

x(2) = xo - height*sin(alpha);
y(2) = yo + height*cos(alpha);

x(3) = xo + 2*height*cos(alpha);
y(3) = yo + 2*height*sin(alpha);

fill(x, y,col,'EdgeColor','none')
end

1
Bienvenue chez PPCG! Belle première réponse.
FantaC

2

Python (avec matplotlib)

Voici une horloge très basique qui s'exécute sur le bureau. Changez intervaldans la 2ème à la dernière ligne 1pour un mouvement continu au lieu d'une tique par seconde.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import datetime

plt.rcParams['toolbar'] = 'None' 
fig = plt.figure(figsize=(4,4),facecolor='w')
ax = plt.subplot(111, polar=True)
plt.axes().get_yaxis().set_visible(False)

#12 labels, clockwise
marks = np.linspace(360./12,360,12, endpoint=True)
ax.set_thetagrids(marks,map(lambda m: int(m/30),marks),frac=.85,size='x-large')
ax.set_theta_direction(-1)
ax.set_theta_offset(np.pi/2)
ax.grid(None)

#hands
wids  = [.2,.03,.01]
lens  = [.75,.9,1]
clrs = plt.cm.winter(np.linspace(0, 1, 3))
factor = [12,60,60,1]

#convert time to radians
def timedata():
    x =  str(datetime.datetime.now().time())
    fig.canvas.set_window_title(x[:8])
    data = map(lambda n: float(n), x.split(':'))+[0]
    for i in range(3):
        data[i]=2*np.pi*(data[i]/factor[i]+data[i+1]/factor[i+1]/factor[i])
        data[i]-=(wids[i]/2)
    return data[:3]

#create hands
bars = ax.bar(timedata(), lens, width=wids, bottom=0.0, color=clrs, linewidth=0)
map(lambda b: b.set_alpha(0.5), bars)

#tick
def animate(i):
    map(lambda bt: bt[0].set_x(bt[1]), zip(bars,timedata()))
    return bars

ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), interval=1000)
plt.show()

pyclock


2

Mathematica

En utilisant plus de code de démonstration du navigateur d'aide de Mathematica que je ne le devrais probablement, j'obtiens

l'horloge

avec

Voltmeter3[v_, label_] := 
  Graphics[{{(*case*){EdgeForm[{Thickness[.007], GrayLevel[0]}], 
      GrayLevel[.2], 
      Rectangle[{-1.2, -1.1}, {1.2, 1.3}, 
       RoundingRadius -> .2]},(*case holes*){White, 
      Disk[{-1, -.9}, .05], Disk[{1, -.9}, .05], Disk[{1, 1.1}, .05], 
      Disk[{-1, 1.1}, .05]},(*case outer rim*){Black, 
      Disk[{0, .1}, 1.15], GrayLevel[.5], Disk[{-.02, .12}, 1.13], 
      GrayLevel[.2], Disk[{0, .1}, 1.11]},(*face highlight*)
     EdgeForm[{CapForm["Round"], Thickness[.02], Hue[.125, .7, .6]}], 
     Hue[.125, 1, 1], 
     Disk[{.02, .1}, 
      1, {1.1 Pi, -.1 Pi}],(*face shadow*){EdgeForm[{CapForm["Round"],
         Thickness[.01], Hue[.125, 1, 1]}], Hue[.125, 1, 1], 
      Disk[{-.02, .12}, 1, {1.1 Pi, -.1 Pi}]},(*face*){EdgeForm[], 
      Hue[.125, .5, 1], 
      Rotate[Polygon[({.1, -.04} + # &) /@ 
         Flatten[{{{0, 0}, {0, 1}}, 
           Array[{Sin[2 Pi*(#/50)], Cos[2 Pi*(#/50)]} &, 30]}, 1], 
        VertexColors -> 
         Flatten[{Hue[.125, 0, 1], 
           Array[Hue[.125, .5, 1] &, 50 + 1]}]], 
       30/50 Pi, {0, 
        0}]},(*case mid line highlight*){Hue[.125, .7, .6], 
      Thickness[.025], CapForm["Round"], 
      Line[{{-.95, -.2}, {0, .1}, {.95, -.2}}]},(*case mid disk \
highlight*){Hue[.125, .7, .6], Disk[{0, 0}, .25, {.95 Pi, .05 Pi}]}},
    Inset[
     AngularGauge[v, {0, 100}, GaugeFaceStyle -> None, 
      GaugeFrameStyle -> None, 
      GaugeMarkers -> 
       Graphics[{Hue[0, 1, .7], 
         Polygon[{{.1, .03}, {.1, -.03}, {.95, -.03}, {1, 
            0}, {.95, .03}}]}], 
      GaugeLabels -> {Placed[
         Style[label, FontFamily -> "Helvetica", Bold, 
          FontSize -> Scaled[.08], White], {.5, .35}]}, 
      LabelStyle -> 
       Directive[FontFamily -> "Helvetica", FontSize -> Scaled[.06]], 
      ScaleOrigin -> {{.85 Pi, .15 Pi}, .9}, 
      ScaleDivisions -> {2, 10}, 
      ScaleRanges -> {{Scaled[.75], Scaled[1]}}, 
      ScaleRangeStyle -> Hue[0, 1, .7, .7], AxesStyle -> Opacity[0], 
      TicksStyle -> {Thickness[.01], Thickness[.005]}, 
      ImageSize -> Automatic, ImagePadding -> None], {0, 0}, {0, 
      0}, {1.75, Automatic}], {(*case mid disk*)GrayLevel[.2], 
     Disk[{0, 0}, .2], GrayLevel[0], Disk[{0, 0}, .075], 
     Disk[{-.85, -.4}, .05], Disk[{.85, -.4}, .05]}}, 
   PlotRangeClipping -> True];

Dynamic@Refresh[
  GraphicsRow[{Voltmeter3[DateList[][[4]], "Hour"], 
    Voltmeter3[DateList[][[5]], "Minute"], 
    Voltmeter3[DateList[][[6]], "Second"]}], UpdateInterval -> 1]

1

C + Le Caire + xcb

Essentiellement arraché la solution postscript et traduit au Caire. :)

Quelques pièges en faisant cela: ps utilise des degrés, Le Caire utilise des radians; ps oriente la fenêtre avec + y vers le haut , xcb l'oriente avec + y vers le bas .

//xclock.c
//cc $(pkg-config --cflags --libs cairo xcb xcb-icccm) -o xclock xclock.c -lcairo -lxcb -lxcb-icccm
#include <math.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <cairo.h>
#include <cairo-xcb.h>
#include <xcb/xcb.h>
#include <xcb/xcb_image.h>
#include <xcb/xcb_aux.h>
#include <xcb/xcb_icccm.h>

double deg_rad (double rad){
    return rad * (180.0/M_PI);
}

double rad_deg (double deg){
    return deg * (M_PI/180.0);
}

typedef struct {
    int width, height;
    int scrno;
    xcb_screen_t *scr;
    xcb_connection_t *connection;
    xcb_drawable_t win;
    unsigned int white;
    xcb_visualtype_t *visual_type;

    cairo_surface_t *surface;
    cairo_t *cr;
} Window;
Window window;

int makewindow()
{
    xcb_screen_iterator_t iter;
    xcb_depth_iterator_t depth_iter;
    uint32_t mask=0;
    uint32_t values[2];

    window.connection = xcb_connect(NULL,&window.scrno);
    iter = xcb_setup_roots_iterator(xcb_get_setup(window.connection));
    for (; iter.rem; --window.scrno, xcb_screen_next(&iter))
        if (window.scrno == 0)
        {
            window.scr = iter.data;
            break;
        }
    window.win = xcb_generate_id(window.connection);
    window.white = window.scr->white_pixel;
    mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
    values[0] = window.white;
    values[1] = XCB_EVENT_MASK_EXPOSURE;
    xcb_create_window(window.connection, XCB_COPY_FROM_PARENT,
            window.win, window.scr->root,
            0, 0,
            window.width, window.height,
            5,
            XCB_WINDOW_CLASS_INPUT_OUTPUT,
            window.scr->root_visual,
            mask,
            values);
    xcb_icccm_set_wm_name(window.connection, window.win, XCB_ATOM_STRING, 8, strlen("xcr"), "xcr");
    xcb_map_window(window.connection, window.win);
    xcb_flush(window.connection);

    depth_iter = xcb_screen_allowed_depths_iterator(window.scr);
    for (; depth_iter.rem; xcb_depth_next(&depth_iter)) {
        xcb_visualtype_iterator_t visual_iter;

        visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
        for (; visual_iter.rem; xcb_visualtype_next(&visual_iter)) {
            if (window.scr->root_visual == visual_iter.data->visual_id) {
                window.visual_type = visual_iter.data;
                goto visual_found;
            }
        }
    }
visual_found: ;

    {
        window.surface = cairo_xcb_surface_create (window.connection,
                window.win, window.visual_type, window.width, window.height);
        window.cr = cairo_create (window.surface);

        //cairo_select_font_face (window.cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
        //cairo_set_font_size (window.cr, 32.0);
        cairo_set_source_rgb (window.cr, 0.0, 0.0, 0.0);
        cairo_translate(window.cr, window.width / 2, window.width / 2);
        cairo_scale(window.cr, 1, -1);
        //cairo_move_to (window.cr, 10.0, 50.0);
        //cairo_show_text (window.cr, "Hello, world");

        //cairo_surface_flush(window.surface);
        //xcb_flush(window.connection);
    }
    return 0;
}

int destroywindow() {
    cairo_destroy (window.cr);
    cairo_surface_destroy (window.surface);
    xcb_disconnect(window.connection);
    return 0;
}

int gettime(int *hour, int *min, int *sec) {
    time_t t;
    struct tm *tm;
    time(&t);
    tm = localtime(&t);
    *hour = tm->tm_hour;
    *min = tm->tm_min;
    *sec = tm->tm_sec;
    return 0;
}

void drawclock(int x) {
    int hour, min, sec;
    double radius, centradius;
    int i, j;

    (void)x;
    signal(SIGALRM, drawclock);
    //hour = 0; min = 30; sec = 30;
    gettime(&hour, &min, &sec);
    hour %= 12;
    //printf("%02d:%02d:%02d\n", hour, min, sec);
    radius = (double)window.width / 2.0;
    radius -= 10.0;
    centradius = radius / 100.0;

    // Erase
    cairo_set_source_rgb(window.cr, 1.0, 1.0, 1.0);
    cairo_paint(window.cr);
    cairo_set_source_rgb(window.cr, 0.0, 0.0, 0.0);

    // Ticks
    for (i = 0; i < 12; i++){
        cairo_set_line_width(window.cr, 1);
        for (j = 0; j < 4; j++){
            cairo_rotate(window.cr, rad_deg(6));
            cairo_move_to(window.cr, radius, 0);
            cairo_rel_line_to(window.cr, (double)radius / 20.0, 0);
            cairo_stroke(window.cr);
        }
        cairo_set_line_width(window.cr, 3);
        cairo_rotate(window.cr, rad_deg(6));
        cairo_move_to(window.cr, radius, 0);
        cairo_rel_line_to(window.cr, (double)radius / 20.0, 0);
        cairo_stroke(window.cr);
    }

    // Hour hand
    cairo_save(window.cr);
        cairo_rotate(window.cr, rad_deg(90.0 - (60.0 * (double)hour + (double)min)/2));
        cairo_new_path(window.cr);
        cairo_move_to(window.cr, 0, 2);
        cairo_curve_to(window.cr, 15.0 * centradius, 3.0 * centradius,
                                  33.0 * centradius, 0,
                                  50.0 * centradius, 3.0 * centradius);
        cairo_curve_to(window.cr, 55.0 * centradius, 15.0 * centradius,
                                  60.0 * centradius, 0,
                                  76.0 * centradius, 0);
        cairo_curve_to(window.cr, 60.0 * centradius, 0,
                                  55.0 * centradius, -15.0 * centradius,
                                  50.0 * centradius, -3.0 * centradius);
        cairo_curve_to(window.cr, 33.0 * centradius, 0,
                                  15.0 * centradius, -3.0 * centradius,
                                  0, -2.0 * centradius);
        cairo_close_path(window.cr);
        cairo_set_source_rgb (window.cr, 0.0, 0.0, 0.677);
        cairo_fill(window.cr);
    cairo_restore(window.cr);

    // Minute hand
    cairo_save(window.cr);
        cairo_rotate(window.cr, rad_deg(90.0 - 6.0 * (double)min));
        cairo_new_path(window.cr);
        cairo_move_to(window.cr, 0, 2);
        cairo_curve_to(window.cr, 15.0 * centradius, 3.0 * centradius,
                                  33.0 * centradius, 0,
                                  50.0 * centradius, centradius);
        cairo_curve_to(window.cr, 65.0 * centradius, 3.0 * centradius,
                                  83.0 * centradius, 0,
                                  97.0 * centradius, 0);
        cairo_curve_to(window.cr, 83.0 * centradius, 0,
                                  65.0 * centradius, -3.0 * centradius,
                                  50.0 * centradius, -1.0 * centradius);
        cairo_curve_to(window.cr, 33.0 * centradius, 0,
                                  15.0 * centradius, -3.0 * centradius,
                                  0, -2.0 * centradius);
        cairo_close_path(window.cr);
        cairo_set_source_rgb (window.cr, 0.635, 0.0, 0.0);
        cairo_fill(window.cr);
    cairo_restore(window.cr);

    cairo_surface_flush(window.surface);
    xcb_flush(window.connection);

    //printf("alarm in %d\n", 60 - sec);
    alarm(60 - sec);
}

int main(int argc, char **argv)
{
    xcb_generic_event_t *e;
    window.width = window.height = 200;
    signal(SIGALRM, drawclock);

    makewindow();
    while (e = xcb_wait_for_event(window.connection)){
        switch(e->response_type & ~0x80){
        case XCB_EXPOSE:
            drawclock(0);
        }
        free(e);
        //sleep(1);
    }
    destroywindow();

    return 0;
}

fenêtre xclock


Vous êtes en retard à la fête, mais c'est une bonne réponse. +1
Victor Stafusa

Merci. C'est une question amusante. J'ai dû apprendre un tas de xcb pour ce faire. J'ai écrit la fenêtre Hello World comme un tremplin vers cela.
luser droog

1

Cliquez sur exécuter. Il s'affiche uniquement par incréments de 30 minutes car l'horloge est un seul emoji.

function updateTick(){let e=new Date,t=e.getSeconds()+60*e.getMinutes()+e.getHours()%12*60*60,n=parseInt(t/3600*2)+1;document.documentElement.style.setProperty("--tick",n)}let d=new Date;setTimeout(()=>{setInterval(updateTick,18e5)},1e3*(d.getMinutes()+d.getSeconds())%30),updateTick();
@counter-style item{system:cyclic;symbols:"🕛" "🕧" "🕐" "🕜" "🕑" "🕝" "🕒" "🕞" "🕓" "🕟" "🕔" "🕠" "🕕" "🕡" "🕖" "🕢" "🕗" "🕣" "🕘" "🕤" "🕙" "🕥" "🕚" "🕦"}span.tik-terk-clerk::before{content:counters(item, "", item);counter-reset:item calc(var(--tick,1))}span.tik-terk-clerk::before{font-size:72pt}
<span class="tik-terk-clerk"></span>


0

La création d'horloges analogiques a une sorte d'attrait pour les gens qui apprennent la programmation. En fait, j'enseigne une classe JavaScript cette année et mes élèves se sont bien amusés lorsque nous avons implémenté une horloge analogique utilisant p5.js ...

Horloge analogique réalisée à l'aide de p5.js

Le code source de l'horloge analogique est disponible sur https://github.com/mveteanu/JSCourse


1
Bienvenue chez PPCG! Au lieu de publier uniquement un lien vers le code, vous devez inclure le code dans la réponse.
Steadybox

1
Bonjour et bienvenue sur le site. Cela ressemble à une bonne réponse, mais nous préférons généralement si le code a été mis dans la réponse plutôt qu'un lien.
Wheat Wizard
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.