вторник, 31 мая 2011 г.

Добавляем стрелки, корпус, тени и "стекло"

Наступило лето и приходится часто бывать на даче без телефона и интернета. Поэтому, используя набеги в Питер, постепенно довел часы до такой кондиции.

Опишу только то, что добавил после предыдущей статьи.

-- рисуем стрелки. За основу взята разработка wlourf, полностью статью можно посмотреть http://u-scripts.blogspot.com/2010/01/shadowed-clock.html , правда на англиском, но с множеством видов стрелок и их данными.
    local function draw_hand(arc, arc0, arc1, length_hand, width_hand, color_border, alpha_border, color_hand, alpha_hand)
-- расчет основных точек для прорисовки стрелок
        local xx = t.x + t.radius*math.sin(arc)*length_hand
        local yy = t.y - t.radius*math.cos(arc)*length_hand
        local x0 = t.x + width_hand*math.sin(arc0)
        local y0 = t.y - width_hand*math.cos(arc0)
        local x1 = t.x + width_hand*math.sin(arc1)
        local y1 = t.y - width_hand*math.cos(arc1)

-- если необходимо нарисовать контуры стрелок тогда
        if t.border then
-- назначаем толщину линий
            cairo_set_line_width(cr, 1)
-- назначаем цвет и насыщенность линий контура стрелок
            cairo_set_source_rgba(cr, rgb_to_r_g_b(color_border, alpha_border))
-- переходим в первую точку
            cairo_move_to (cr, x0, y0)
-- рисуем кривые проходящие через три точки
            cairo_curve_to (cr, x0, y0, xx, yy, x1, y1)
-- рисуем половину окружности основания стрелки
            cairo_arc(cr, t.x, t.y, width_hand, arc1 - math.pi/2, arc0 - math.pi/2)
            cairo_stroke(cr)
        end

-- если необходимо вывести тень от стрелок, длина тени изменяется в зависимости от расположения "источника света"
        if t.shadow then
-- переходим в первую точку
            cairo_move_to (cr, x0, y0)
-- рисуем кривые через три точки со смещением зависищим от расположения "источника света"
            cairo_curve_to (cr, x0, y0, xx + t.shadow_degree, yy + t.shadow_height, x1, y1)
-- рисуем половину окружности основания тени стрелки
            cairo_arc(cr, t.x, t.y, width_hand, arc1 - math.pi/2, arc0 - math.pi/2)
-- для закрашивания тени от стрелок используем радиальную окраску
            pat = cairo_pattern_create_radial (t.x - math.sin(math.rad(t.shadow_degree))*length_hand, t.y + math.cos(math.rad(t.shadow_degree))*length_hand, 0, t.x, t.y, t.radius)
 

-- цвет тени черный поэтому на темных циферблатах тень не очень заметна
            cairo_pattern_add_color_stop_rgba (pat, 0, 0, 0, 0, t.shadow_opacity)
            cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 0, 0)
            cairo_set_source (cr, pat)
            cairo_fill (cr)
        end

-- рисуем стрелки по тому же принципу, что и тень, но без смещения
        cairo_move_to (cr, x0, y0)
        cairo_curve_to (cr, x0, y0, xx, yy, x1, y1)
        cairo_arc(cr, t.x, t.y, width_hand, arc1 - math.pi/2, arc0 - math.pi/2)
        pat = cairo_pattern_create_radial (t.x, t.y, t.radius/10, t.x, t.y, t.radius*length_hand)
        cairo_pattern_add_color_stop_rgba (pat, 0, rgb_to_r_g_b(color_hand, alpha_hand))
        cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 0, 1)
        cairo_set_source (cr, pat)
        cairo_fill (cr)
        cairo_pattern_destroy (pat)
    end

-- забираем данные из ОС
    local hours = os.date("%I")
    local mins = os.date("%M")
    local secs = os.date("%S")

-- расчет угла движения стрелок
    local gamma = math.pi/2 - math.atan(t.width_second_hand / (t.radius * t.length_second_hand))
    local secs_arc = (2*math.pi/60)*secs
    local secs_arc0 = secs_arc - gamma
    local secs_arc1 = secs_arc + gamma

    local gamma = math.pi/2 - math.atan(t.width_minute_hand/(t.radius*t.length_minute_hand))
    local mins_arc = (2*math.pi/60)*mins + secs_arc/60
    local mins_arc0 = mins_arc - gamma
    local mins_arc1 = mins_arc + gamma

    local gamma = math.pi/2 - math.atan(t.width_hour_hand/(t.radius*t.length_hour_hand))
    local hours_arc = (2*math.pi/12)*hours + mins_arc/12
    local hours_arc0 = hours_arc - gamma
    local hours_arc1 = hours_arc + gamma

-- вывод стрелок
-- задаем данные для вывода часовой стрелки
    draw_hand(hours_arc, hours_arc0, hours_arc1, t.length_hour_hand, t.width_hour_hand, t.color_border_hour, t.alpha_border_hour, t.color_hour_hand, t.alpha_hour_hand)
-- задаем данные для минутной стрелки
    draw_hand(mins_arc, mins_arc0, mins_arc1, t.length_minute_hand, t.width_minute_hand, t.color_border_minute, t.alpha_border_minute, t.color_minute_hand, t.alpha_minute_hand)
-- если необходима секундная стрелка, то задаем данные
    if t.show_seconds then
        draw_hand(secs_arc, secs_arc0, secs_arc1, t.length_second_hand, t.width_second_hand, t.color_border_second, t.alpha_border_second, t.color_second_hand, t.alpha_second_hand)
    end


-- рисуем ось стрелок
-- расчитываем радиус оси стрелок
    local radius = math.min(t.width_hour_hand, t.width_minute_hand, t.width_second_hand)*0.75
-- если радиус меньше 1, то устанавливаем радиус равный 1
    if radius < 1 then radius = 1 end
-- рисуем ось
    cairo_arc(cr, t.x, t.y, radius, 0, 2*math.pi)
    cairo_set_source_rgba(cr, 0, 0, 0, 1)
    cairo_fill (cr)

-- рисуем тень на стеклк часов
    pat_glass = cairo_pattern_create_radial (t.x + t.radius*math.sin(math.rad(t.shadow_degree)), t.y + t.radius*math.sin(math.rad(t.shadow_height)), 0, t.x, t.y, t.radius*1.2)
    cairo_pattern_add_color_stop_rgba (pat_glass, 0, 1,1,1,0)
    cairo_pattern_add_color_stop_rgba (pat_glass, 1, 0,0,0, 0.3)
    cairo_set_source (cr, pat_glass)
    cairo_arc (cr, t.x, t.y, t.radius+t.width_housing_hours/2, 0, 2*math.pi)
    cairo_fill (cr)
    cairo_pattern_destroy (pat_glass)
end


Полностью скрипт можно взять  здесь

 Все данные часов задаем в начале скрипта

    clock_settings = {

    {
-- корпус часов
width_housing_hours = 15,               -- толщина корпуса часов
color_housing_hours = 0x5b5b5b,    -- цвет корпуса часов
alpha_housing_hours = 1,    -- насыщенность цвета
-- циферблат
    x = 150,            -- координаты часов по горизонтали
    y = 150,            -- координаты часов по вертикали
    radius = 100,            -- радиус часов
    color_dial = 0xffffff,        -- цвет циферблата
    alpha_dial = 1,            -- насыщенность цвета
-- цифры
    font_size = 16,            -- размер шрифта цифр
    bold = true,
    color_font = 0x000000,        -- цвет цифр
    alpha_font = 1,            -- насыщенность цвета
-- стрелки
    border = true,        -- контур стрелок Да - true, Нет - false.
    width_hour_hand = 2.5,        -- ширина часовой стрелки
    length_hour_hand = 1.4,     -- длина часовой стрелки
    color_hour_hand = 0xeeeeee,    -- цвет часовой стрелки
    alpha_hour_hand = 1,        -- насыщенность цвета
    color_border_hour = 0x000000,    -- цвет контура часовой стрелки
    alpha_border_hour = 0.8,    -- насыщенность цвета
    width_minute_hand = 2,        -- ширина минутной стрелки
    length_minute_hand = 1.9,    -- длина минутной стрелки
    color_minute_hand = 0xffffff,    -- цвет минутной стрелки
    alpha_minute_hand = 0.8,    -- насыщенность цвета
    color_border_minute = 0x000000,    -- цвет контура минутной стрелки
    alpha_border_minute = 0.8,    -- насыщенность цвета
-- Выводить секундную стрелку, Да - true, Нет - false.
-- При выводе секундной стрелки update_interval в .conkyrc должен быть менее 1 сек.
    show_seconds = true,        -- вывод секундной стрелки
    width_second_hand = 1,        -- ширина секундной стрелки
    length_second_hand = 1.9,    -- длина секундной стрелки
    color_second_hand = 0xff0000,    -- цвет секундной стрелки
    alpha_second_hand = 1,        -- насыщенность цвета
    color_border_second = 0xff0000,    -- цвет контура секундной стрелки
    alpha_border_second = 1,    -- насыщенность цвета
-- тень от стрелок Да - true, Нет - false.
    shadow = true,            -- вывод тени
-- координаты источника света относительно центра часов, 0 - источник света над центром часов
    shadow_degree = -90,    -- координаты источника света по горизонтали от -90 до 90
    shadow_height = 25,    -- координаты источника света по вертикали от -90 до 90
    shadow_opacity = 0.5,    -- прозрачность тени, значения от 0 до 1
    }
    }
С часами кажется закончил, теперь "на отдыхе" подумаю, о чем писать дальше. Если есть пожелания, то пишите или здесь, или на e-mail.

2 комментария:

  1. Доброго времени суток.
    Прочитал ваши статьи и они мне очень понравились.
    Можете скинуть маны по функциям связки cairo+lua
    pitrovich@list.ru
    Заранее спасибо.

    ОтветитьУдалить
  2. Hi olgmen.
    Where can I unload this your LUA?
    Thanks......Deegan
    http://www.imagehost.it/di-O83U.png

    ОтветитьУдалить