Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

torrvic, возможно, Вам нужно добавить -lGLU
Извините за тупой вопрос. У меня при сборке Вашего примера выходит ошибка: "undefined reference to gluLookAt". Не могу найти в какой библиотеке находится эта функция. У меня задано: -lGL -lglut ... Искал в /usr/lib таким образом: nm lib*so* | grep...
Здравствуйте. Спасибо за проект. У меня вопрос, по какой причине определение принадлежности точки многоугольнику работает некорректно, если координаты из больших чисел состоят, например: int[] vertex = new int[] {...
Сейчас проверила нашла причину не запускания // Создание контекста воспроизведения OpenGL и привязка его к панели на форме OpenGLControl1:=TOpenGLControl.Create(Self); with OpenGLControl1 do begin Name:='OpenGLControl1'; //вот тут...
Ну..кажется что то пошло не так http://pp.usera...

Счетчики и рейтинг

Рейтинг@Mail.ru
Среда программирования: 
HTML 5 + JavaScript

В этот части мы разберем анимацию, поработаем с цветом и научимся обрабатывать события.
Предварительно необходимо ознакомиться с первым уроком рисования в HTML 5.

В качестве подопытного, возьму свою птичку из прошлого урока.

Она собрана в объект angrybird из множества элементарных фигур.

var angrybird = new fabric.Group([
                                   tails, 
                                   light_all_topknot, 
                                   shadow_body,
                                   all_topknot,
                                   body,
                                   light_body,
                                   shadow_all_topknot,
                                   belly,
                                   all_eye,
                                   shadow_group_beak,
                                   group_beak
                                  ], { });

Анимация

Каждый объект в Fabric имеет метод animate (наследуя от fabric.Object) который… анимирует этот объект. Давайте поднимем птичку вверх!

Пример:

angrybird.animate({ 'top': 170 },{
                    onChange: example.renderAll.bind(example)
                });

Первый аргумент это атрибут который хотим менять. Второй аргумент — финальное значение этого атрибута. Например, если объект находится на высоте 200, и мы указываем «100», то расстояние от верха постепенно изменится с 200 до 100. Последний аргумент — опциональный объект для более детальных настроек (длительность, вызовы, easing, и т.д.) animate имеет очень полезную функциональность — поддержку относительных значений. Например, если нужно подвинуть объект на 100px вправо, то сделать это очень просто:

angrybird.animate('left', '+=100', { 
                  onChange: example.renderAll.bind(example)
                 });

3-й аргумент не опциональный, это перерисовка экрана нужна для того чтобы увидеть анимацию.

Опции для анимации:
from: Позволяет менять начальное значение атрибута для анимации (если не хотим использовать текущее).
duration: Длительность анимации. По умолчанию 500 (ms).
onComplete: Функция для вызова в конце анимации.
easing: Функция easing (смягчение).

По умолчанию, animate используют линейную функцию для смягчения анимации. Если такой вариант не подходит, в Fabric имеется большой набор популярных easing функций (доступных через объект fabric.util.ease). Например, вот так можно подвинуть объект направо, при этом отпружинивая в конце:

angrybird.animate('left', 350, {
  onChange: example.renderAll.bind(example),
  duration: 1000,
  easing: fabric.util.ease.easeOutBounce
});

Есть и другие популярные функцииeaseInCubic, easeOutCubic, easeInElastic, easeOutElastic, easeInBounce, easeOutExpo, и т.д.

Цвета

Независимо от того, с чем вам удобней работать — hex, RGB, или RGBA форматами цвета — Fabric упрощает утомительные операции и переводы из одного формата в другой. Давайте посмотрим на несколько способов определить цвет в Fabric:

new fabric.Color('#f55');
new fabric.Color('#123123');
new fabric.Color('356735');
new fabric.Color('rgb(100,0,100)');
new fabric.Color('rgba(10, 20, 30, 0.5)');

Перевод формата происходит очень просто. toHex() переводит цвет в hex. toRgb() — в RGB, а toRgba() — в RGB с альфа каналом (прозрачностью).

new fabric.Color('#f55').toRgb(); // "rgb(255,85,85)"
new fabric.Color('rgb(100,100,100)').toHex(); // "646464"
new fabric.Color('fff').toHex(); // "FFFFFF"

Можно «накладывать» цвета один на другой, или делать из них чёрно-белый вариант.

var redish = new fabric.Color('#f55');
var greenish = new fabric.Color('#5f5');
 
redish.overlayWith(greenish).toHex(); // "AAAA55"
redish.toGrayscale().toHex(); // "A1A1A1"

Градиенты

Ещё более экспрессивный способ работы с цветами — используя градиенты. Градиенты позволяет плавно смешать один цвет с другим, открывая возможность довольно изумительным эффектам.

Fabric поддерживает их с помощью метода setGradientFill, который присутствует на всех объектах. Вызывание setGradientFill это почти как выставление значения «fill» у объекта, только вместо цвета используется градиент.
Поэкспериментируем с птичкой, зальем каждый ее элемент градиентом:

angrybird.setGradientFill({
                x1: 0,
                y1: 0,
                x2: 0,
                y2: angrybird.height,
                colorStops: {
                    0: '#000',
                    1: '#fff'
                }
            });

результат:

также можем сделать птичку Боба Марли залив 3-х шаговым градиентом, с цветами занимающими по 33% всей длины:

angrybird.setGradientFill({
                x1: 0,
                y1: angrybird.height / 2,
                x2: angrybird.width,
                y2: angrybird.height / 2,
                colorStops: {
                    0: "green",
                    0.33: "yellow",
                    1: "red"
                }
            });

результат:

События

События — незаменимый инструмент для создания сложных приложений. Для удобства пользования, и более детальной настройки, Fabric имеет обширную систему событий; начиная от низкоуровневых событий мыши, и вплоть до высокоуровневых событий объектов.

События позволяют нам «поймать» различные моменты когда что-то происходит на холсте. когда была нажата мышка — cледим за событием «mouse:down». Объект был добавлен на холст — «object:added». Перерисовка холста — «after:render».

API событий очень прост, и похож на то к чему вы скорее всего привыкли в jQuery, Underscore.js, или других популярных JS библиотеках. Есть метод on для инициализации слушателя событий, и есть метод off для его удаления.

var canvas = new fabric.Canvas('...');
canvas.on('mouse:down', function(options) {
  alert(options.e.clientX + ' ' + options.e.clientY);
});

Мы добавили слушатель события «mouse:down» на canvas объекте, и указали обработчика, который будет записывать координаты где произошло это событие. Таким образом, мы можем видеть где именно произошёл клик на холсте. Обработчик событий получает options объект, с двумя параметрами: e — оригинальное событие, и target — Fabric объект на холсте, если он найден. Первый параметр присутствует всегда, а вот target только если клик произошёл на объекте. Ну и конечно же, target передаётся только разработчикам тех событий, где это имеет смысл. Например, для «mouse:down» но не для «after:render» (так как это событие не «имеет» никаких объектов, а просто обозначает что холст был перерисован).

canvas.on('mouse:down', function(options) {
  if (options.target) {
    alert('Вы нажали на ' + options.target.type);
  }
});

Этот пример выведет «Вы нажали на (тип объекта)!» если мы нажмём на объект.

События доступны в Fabric. На уровне мышки "mouse:down", "mouse:move", и "mouse:up". Из общих "after:render". Есть события выбора объектов: "before:selection:cleared", "selection:created", "selection:cleared". События объектов: "object:modified", "object:selected", "object:moving", "object:scaling", "object:rotating", и "object:added".

Для удобства, Fabric позволяет добавлять слушатели прямо на Fabric объекты

angrybird.on('selected', function() {
                    alert('Чик-чирик');
            });

Пример рисования в canvas при помощи Fabric.js, создание объекта, его анимация и обработка событий.

<html>
    <head>
        <title>Angry bird</title>
        <meta charset="utf-8"/>
        <script src="min.js"></script>
    </head>
    <body>
        <div style='color:red; margin:auto; width:400px; text-align:center; top:50%;'>
            <h1>Angry bird</h1>
            <canvas id="example" width="500" height="500">
                Ваш браузер не поддерживает канвас!
            </canvas>
        </div>
        <script>
            var example = new fabric.Canvas('example');
 
            //хвост
            var first_tail  = new fabric.Triangle({ 
                width: 40, 
                height: 60, 
                fill: '#000', 
                angle: 100, 
                left: 0,  
                top: 0
            });
            var second_tail = new fabric.Triangle({ 
                width: 30, 
                height: 60, 
                fill: '#000', 
                angle: 140, 
                left: 10, 
                top: -14 
            });
            var third_tail  = new fabric.Triangle({ 
 
                width: 30, 
 
 
                height: 60, 
                fill: '#000', 
                angle: 60,  
                left: 10, 
                top: 18 
            });
            var tails = new fabric.Group([ first_tail, 
                                           second_tail, 
                                           third_tail ], {
                    left: 40,
                    top: 200
                });
 
            //тело
            var shadow_body = new fabric.Circle({ 
                radius: 156,
                 fill: '#000',
                  left: 201,
                   top: 203 
               });
            var body        = new fabric.Circle({ 
                radius: 150,
                 fill: '#FF0050',
                  left: 200,
                   top: 200 
               });
            var light_body  = new fabric.Circle({ 
                radius: 146,
                 fill: '#D5002C',
                  left: 198,
                   top: 204 
               });
 
            //обводка глаз
            var shadow_lft_eye = new fabric.Circle({ 
                radius: 35, 
                fill: '#000' 
            });
            var shadow_rgt_eye = new fabric.Circle({ 
                radius: 29, 
                fill: '#000',
                left: 60 
            });
            var shadow_group_eye = new fabric.Group([ shadow_lft_eye, 
                                                      shadow_rgt_eye ], {
                    top: 1
                });
                //глаза
                var lft_eye   = new fabric.Circle({ 
                    radius: 30, 
                    fill: '#fff'
                });
                var rgt_eye   = new fabric.Circle({ 
                    radius: 24, 
                    fill: '#fff',
                     left: 58 
                 });
                var group_eye = new fabric.Group([ lft_eye, 
                                                   rgt_eye ], { });
                    //зрачки
                    var lft_pupil = new fabric.Circle({ 
                        radius: 10, 
                        fill: '#000' });
                    var rgt_pupil = new fabric.Circle({ 
                        radius: 7,  
                        fill: '#000', 
                        left: 40 
                    });
                    var group_pupil = new fabric.Group([ lft_pupil, 
                                                         rgt_pupil ], {
                            left: 22,
                            top: 1,
                        });
                        //брови
                        var lft_eyebrow = new fabric.Rect({ 
                            width: 26, 
                            height: 86, 
                            fill: '#000', 
                            angle: 114
                        });
                        var rgt_eyebrow = new fabric.Rect({ 
                            width: 26, 
                            height: 86, 
                            fill: '#000', 
                            left: 68, 
                            angle: -114 
                        });
                        var eyebrows = new fabric.Group([ lft_eyebrow, 
                                                          rgt_eyebrow ], {
                                left: 28,
                                top: -36
                            });
            var all_eye = new fabric.Group([ shadow_group_eye, 
                                             group_eye, 
                                             group_pupil, 
                                             eyebrows ], {
                  left: 250,
                  top: 190,
                });
 
            //обводка клюва
            var shadow_top_beak = new fabric.Triangle({ 
                width: 70,
                 height: 110,
                  fill: '#000',
                   top: -2,
                    angle: 114
                });
            var shadow_bottom_beak  = new fabric.Rect({ 
                width: 62,
                 height: 60,
                  fill: '#000',
                   left: -21,
                    top: 8, 
                     angle: 45 
                });
            var shadow_group_beak = new fabric.Group([ shadow_top_beak, 
                                                       shadow_bottom_beak ], {
                  left: 288,
                  top: 260
                });
                //клюв
                var top_beak = new fabric.Triangle({ 
                    width: 60, 
                    height: 100, 
                    fill: '#FBBA1E',
                    angle: 114 
                });
                var bottom_beak  = new fabric.Rect({ 
                    width: 52, 
                    height: 50,  
                    fill: '#FBBA1E', 
                    left: -20, top: 8, 
                    angle: 45 
                });
                var tt_beak =  new fabric.Triangle({ 
                    width: 8,  
                    height: 106, 
                    top: 12, left: -7, 
                    fill: '#000', 
                    angle: 100 
                });
                var group_beak = new fabric.Group([ bottom_beak, 
                                                    top_beak, 
                                                    tt_beak ], {
                      left: 286,
                      top: 260,
                });
                //пузо
                var belly = new fabric.Circle({ 
                    radius: 100, 
                    fill: '#E2C4A8', 
                    scaleY: 0.5, 
                    left: 200, 
                    top: 300 });
                //хохолок
                var topknot         = new fabric.Circle({ 
                    radius: 60, 
                    fill: '#FF0050', 
                    scaleY: 0.5, 
                    angle: 30 
                });
                var shadow_topknot  = new fabric.Circle({ 
                    radius: 52, 
                    fill: '#D5002C', 
                    scaleY: 0.5, 
                    angle: 30 
                });
                var topknot2        = new fabric.Circle({ 
                    radius: 40, 
                    fill: '#FF0050', 
                    scaleY: 0.5, 
                    left: -60, 
                    angle: 20 
                });
                var shadow_topknot2 = new fabric.Circle({ 
                    radius: 32, 
                    fill: '#D5002C', 
                    scaleY: 0.5, 
                    left: -60, 
                    angle: 20 
                });
                var all_topknot = new fabric.Group([ topknot, topknot2 ], {
                        left: 180,
                        top: 54
                    });
                    var shadow_all_topknot = new fabric.Group([ shadow_topknot, 
                                                                shadow_topknot2 ], {
                            left: 172,
                            top: 54
                        });
 
                var light_topknot  = new fabric.Circle({ 
                    radius: 64, 
                    fill: '#000', 
                    scaleY: 0.5, 
                    angle: 30 
                });
                var light_topknot2 = new fabric.Circle({ 
                    radius: 44, 
                    fill: '#000', 
                    scaleY: 0.5, 
                    left: -60,
                    angle: 20 
                });
                var light_all_topknot = new fabric.Group([ light_topknot, 
                                                           light_topknot2 ], {
                        left: 180,
                        top: 54
                    });
 
                var angrybird = new fabric.Group([
                                                    tails, 
                                                    light_all_topknot, 
                                                    shadow_body,
                                                    all_topknot,
                                                    body,
                                                    light_body,
                                                    shadow_all_topknot,
                                                    belly,
                                                    all_eye,
                                                    shadow_group_beak,
                                                    group_beak
                                                ], { direction: 1, left: 210 });
 
 
            var s_ellips = new fabric.Circle({ 
                radius: 100, 
                fill: '#B9BBAD', 
                scaleY: 0.2, 
                left: 230, 
                top: 410 
            });
            example.add( s_ellips, angrybird );
            var minScale = 1, maxScale = 1.07;
 
            function animate(dir) {
                angrybird.animate({
                    scaleX: dir ? maxScale : minScale,
                    scaleY: dir ? maxScale : minScale
                },{
                    duration: 1000,
                    onChange: example.renderAll.bind(example)
                });
 
                angrybird.animate({ 'top': angrybird.getTop() === 200 ? '170' : '200'},{
                    duration: 1000,
                    onChange: example.renderAll.bind(example)
                });
 
                s_ellips.animate('radius', s_ellips.getRadiusX() === 130 ? '100' : '130',{
                    duration: 1000,
                    onChange: example.renderAll.bind(example),
                    onComplete: function() {
                        angrybird.direction = !angrybird.direction;
                        animate(angrybird.direction);
                    }
                });
            }
            animate(angrybird.direction);
 
            angrybird.on('selected', function() {
                    alert('Чик-чирик');
            });
        </script>
    </body>
</html>

Прикрепленный файлРазмер
Исходная птичка с анимацией38.01 кб