Часы без JavaScript

Часы без JavaScript

Сделал крошечные аналоговые часы, которые работают без JavaScript. Кто первый догадается как они работают, тот молодец.

Правда я их ускорил в 60 раз (а то очень уж скучно смотреть), поэтому это скорее секундомер, но стартуют они с текущего времени.

36 комментариев

Часы без JavaScript: фильм о фильме

Как уже догадались все, кому это было хоть каплю интересно, часы без JavaScript сделаны анимированным GIF. Сделал я всё очень просто: скачал найденный где-то на FTP шрифт «clock.ttf», внутри которого вместо букв нарисованы стрелки в разных положениях и сгенерировал с его помощью 720 картинок.

Шрифт clock (27.08КиБ)

Оказалось, что проще всего сгенерировать картинки при помощи Go. В Пайтоне на «Маке» у меня нет PIL и я его плохо знаю, во встроенном PHP нет поддержки TTF, так что Go:

package main

import "gd"
import "os"
import "fmt"

func main() {
    im := gd.CreateTrueColor(21, 21)
    white := im.ColorAllocate(255, 255, 255)
    black := im.ColorAllocate(0, 0, 0)
    
    // стрелки: 64 → 123 (m) и 192 → 251 (h)

    defer im.Destroy()
        
    for i := 0; i < 720; i++ {
        im.FilledRectangle(0, 0, 20, 20, white)
        
        min  := i % 60
        hour := (i / 60) * 5 + min / 12
        
        im.StringFT(black, "./clock.ttf", 10, 0, 0, 16, "1")
        im.StringFT(black, "./clock.ttf", 10, 0, 0, 16, string(hour + 192))
        im.StringFT(black, "./clock.ttf", 10, 0, 0, 16, string(min + 64))

        name := fmt.Sprintf("gifs/%02d%02d.gif", i/60, i%60)
        im.Gif(name)
        
    }
    
}

После запуска получилось 720 картинок с ноль часов ноль минут до 11:59 (я не зря выбрал часы со стрелками, это позволило сократить размер анимированных часов вдвое).

Когда на сервер приходит запрос, я проверяю сколько сейчас времени и, если файл с часами для текущей минуты уже существует, то делаю редирект на существующую картинку. Если нет, то генерирую из 720 картинок новый «мультик», кладу его на диск и делаю редирект на него (остальные картинки удаляю):

<?
    include "clock.inc.php";
    
    list($h, $m) = explode(':', date('H:i'));
    if ($h > 12) $h -= 12;
    $name = sprintf("%02d%02d.gif", $h, $m);
    
    if (!file_exists($name)) {	
        @array_map('unlink', glob('*.gif'));
    
        $frames_tail = $frames = $framed = array();
        $frames_name = 'frames_tail';
    
        for ($H = 0; $H<12; $H++) {
            for ($M = 0; $M<60; $M++) {
                if ($h == $H && $m == $M) {
                    $frames_name = 'frames';
                }
            
                ${$frames_name}[] = sprintf("gifs/%02d%02d.gif", $H, $M);
                $framed[] = 100;
            }
        }
    
        $frames = array_merge($frames, $frames_tail);
    
        $gif = new GIFAnimator($frames, $framed, 0, 2, -1, -1, -1, 'url');
    
        fwrite(fopen($name, 'wb'), $gif->GetAnimation());
    }
    
    header("Location: $name");

Для генерации анимированных GIF применяется какой-то первый попавшийся в интернете класс, предназначенный для этого. Работает шустро.

8 комментариев

Re: Господи, неужели это произошло с моим мальчиком?

Помните статью «Господи, неужели это произошло с моим мальчиком?» в которой одна жижистка обвиняет сотрудников и медицинскую службу «Шереметьева» в бездействии, когда руку её ребёнка сломала дверь лифта?

История, конечно ужасная, но не всё так просто. В «Шереметьеве» начали расследование этого случая и уже есть результаты, есть видеозапись с камеры наблюдения и полная хронология событий. Почитайте, посмотрите видео.

9 комментариев