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

Вход на сайт

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

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

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

Всем у кого не работает. файл wizard.script Ещё одно упоминание Glut32 в строке "if (!VerifyLibFile(dir_nomacro_lib, _T("glut32"), _T("GLUT's"))) return false;" меняем на "if (!VerifyLibFile(dir_nomacro_lib, _T("freeglut"), _T("GLUT's"))) return...
Не получается, емаё
огромное спасибо за подробное объяснение про 3д графику на питоне, в интернете очень мало подобной информации
dobryj den, popytalas otkryt prikreplionnyj fail ctoby posmotret kak rabotaet, no mne ego ne pokazyvaet vydajet osibku. Pochemu?
Очень интересно! ии сайт крутой жалко что умирает(

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

Рейтинг@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 кб