Создание отражения рисунка с помощью JavaScript

HTML 5 приходит на помощь

Постановка задачи: из исходного изображения получить отраженное изображение: Дополнительное условие: генерировать изображение на стороне клиента (то есть без использования GD, ImageMagick и иже с ними). В черновике стандарта HTML 5 пристутствует такой замечательный элемент как <canvas>. Если вкратце, то данный элемент предназначен для создания изображений при помощи JavaScript. Впервые элемент <canvas> был представлен компанией Apple и [...]

← Вернуться к полной версии записи «Создание отражения рисунка с помощью JavaScript»…

Вложения:

Автор: ; опубликовано в: JavaScript; метки: canvas, HTML, JavaScript, эффекты
17
Ноя
2008

RSS Комментарии к статье «Создание отражения рисунка с помощью JavaScript» (9)  »

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

    В 90% на заданы. Я не тестил пример, но если критично указание явных размеров, но решение спросом пользоваться не будет :(

  2. Всё равно всё просто :-) Я сэкономил на нескольких строчках в JS, чтобы не вносить путаницу.

    Для вертикального отражения: ширина контейнера — это ширина рисунка, а высота — две высоты рисунка.
    Для горизонтального отражения: ширина контейнера — это две ширины рисунка, а высота — высота рисунка.

    Написал на коленке:

    [-]
    View Code Javascript
        /**
         * @param image document.getElementById('image')
         * @param h_coef Коэффициент растягивания отражения
         * @param opacity_start Начальное значение непрозрачности
         * @param opacity_end Конечное значение непрозрачности
         * @param mode 0 = вертикальное отражение, 1 = горизонтальное
         */

        function add_reflection(image, h_coef, opacity_start, opacity_end, mode)
        {
            var container  = document.createElement('div');
            var ref_height, ref_width, div_height, div_width;
           
            if (0 == mode) {
                ref_height = Math.floor(image.height * h_coef);
                ref_width  = image.width;
                div_height = Math.floor(image.height * (1 + h_coef));
                div_width  = ref_width;
            }
            else {
                ref_width  = Math.floor(image.width * h_coef);
                ref_height = image.height;
                div_height = ref_height
                div_width  = Math.floor(image.width * (1 + h_coef));
            }
           
            var reflection;
           
            if (!window.opera && document.all) {
                reflection = document.createElement('img');
                reflection.src = image.src;
                reflection.style.width = image.width + 'px';
               
                if (0 == mode) {
                    reflection.style.filter = 'flipv progid:DXImageTransform.Microsoft.Alpha(opacity='+(opacity_start*100)+', style=1, finishOpacity='+(opacity_end*100)+', startx=0, starty=0, finishx=0, finishy='+(h_coef*100)+')';
                }
                else {
                    reflection.style.filter = 'fliph progid:DXImageTransform.Microsoft.Alpha(opacity='+(opacity_start*100)+', style=1, finishOpacity='+(opacity_end*100)+', startx=0, starty=0, finishx='+(h_coef*100)+', finishy=0)';
                }

                container.style.width  = div_width + 'px';
                container.style.height = div_height + 'px';
                image.parentNode.replaceChild(container, image);
                container.appendChild(image);
                container.appendChild(reflection);
            }
            else {
                reflection  = document.createElement('canvas');
                var context = reflection.getContext('2d');
                reflection.style.height = ref_height + 'px';
                reflection.style.width  = ref_width + 'px';
                reflection.height       = ref_height;
                reflection.width        = ref_width;
               
                container.style.width  = div_width + 'px';
                container.style.height = div_height + 'px';
                image.parentNode.replaceChild(container, image);
                container.appendChild(image);
                container.appendChild(reflection);
               
                context.save();
                var gradient;
               
                if (0 == mode) {
                    context.translate(0, image.height);
                    context.scale(1, -1);
                    gradient = context.createLinearGradient(0, 0, 0, ref_height);
                }
                else {
                    context.translate(image.width, 0);
                    context.scale(-1, 1);
                    gradient = context.createLinearGradient(0, 0, ref_width, 0);
                }
               
                context.drawImage(image, 0, 0, image.width, image.height);
                context.restore();
               
                context.globalCompositeOperation = "destination-out";
                gradient.addColorStop(1, "rgba(255, 255, 255, " + (1 - opacity_end) + ")");
                gradient.addColorStop(0, "rgba(255, 255, 255, " + (1 - opacity_start) + ")");
                context.fillStyle = gradient;
                if (-1 != navigator.appVersion.indexOf('WebKit')) {
                    context.fill();
                }
                else {
                    context.fillRect(0, 0, image.width, 2*ref_height);
                }
            }
        }

    Как пользоваться: HTML:

    [-]
    View Code HTML
    <img id="image" src="image.png" alt=""/>

    JavaScript:

    [-]
    View Code Javascript
    add_reflection(document.getElementById('image'), 1, 1, 0.1, 0);

    В результате скрипт обернет image в div и задаст ему требуемую высоту и ширину.

  3. Да тоже думал когда попробывать реализовать… тока уровня знаний не хватило. А теперь нужда отпала, потому что готово. Спасибо.

    Вопрос не втему, но я думаю по адресу, чем отличается clientHeight от offsetHeight

    PS на маленьком разрешении (800х600) боковая колонка падает… нехватватет страничке min-width:

  4. есть стати лекарство которое лечит IE от незнания canavas
    http://sourceforge.net/project/showfiles.php?group_id=163391

  5. Бодя

    Привет. Я поработал с твоим кодом, думаю у тебя мелкая ошибка, вместо 2*ref_height должно быть image.height.

  6. Бодя

    не атачится

    [-]
    View Code Javascript
        document.myGetElementsByClassName = function(className) {
            var children = document.getElementsByTagName('img');
            var elements = [];
         
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                if(child.getAttribute('alt')=='reflect')
                        elements.push(child);
            }
            return elements;
        }

    function addReflections(){
        var rimages = document.myGetElementsByClassName('reflect');
        for (i=0;i<rimages.length;i++) {
            reflect_image(rimages[i])
        }
    }


    function reflect_image(image)
    {
            if(!image.complete)
                return;

        var k       = 3;  // aka ratio
            var opacity_start = 0.31;
            var opacity_end   = 0.001;
            var mode          = 1;  //0 = vertical, 1 = horizontal  

            var container  = image.parentNode, replace;
            if(replace = container.childNodes.length!=1){
                container  = document.createElement('div');
            }
            container.style.display='inline-block';
             
            var
                ref_height = image.offsetHeight,
                ref_width  = image.offsetWidth;

           
            var reflection;
           
             if (!window.opera && document.all){
                reflection = document.createElement('img');
            }else{
                reflection  = document.createElement('canvas');
                var context = reflection.getContext('2d');
            }
           
           /* reflection.height       = ref_height;
            reflection.width        = ref_width;*/


            if(0 == mode){
                reflection.style.display = 'block';
                reflection.style.marginTop  = '1px';
                reflection.style.height = ref_height/k + 'px';
                reflection.style.width  = ref_width + 'px';
            }else{
                reflection.style.cssFloat  = 'left';
                reflection.style.marginRight  = '1px';
                reflection.style.height = ref_height + 'px';
                reflection.style.width  = ref_width/k + 'px';
            }

            /*container.style.width  = div_width + 'px';
            container.style.height = div_height + 'px';*/

               
            if (!window.opera && document.all) {
                reflection.src = image.src;
               
                if (0 == mode) {
                    reflection.style.filter = 'flipv progid:DXImageTransform.Microsoft.Alpha(opacity='+(opacity_start*100)+', style=1, finishOpacity='+(opacity_end*100)+', startx=0, starty=0, finishx=0, finishy='+(100)+')';
                }
                else {
                    reflection.style.filter = 'fliph progid:DXImageTransform.Microsoft.Alpha(opacity='+(opacity_end*100)+', style=1, finishOpacity='+(opacity_start*100)+', startx=0, starty=0, finishx='+(100)+', finishy=0)';
                }
            }
            else
            {
                context.save();
                var gradient;
                reflection.src = image.src;//только для того чтоб знать размеры…
                var z1=reflection.width, z2=reflection.height;
               
                if (0 == mode) {
                    context.translate(0, z2);
                    context.scale(1, -1);
                    gradient = context.createLinearGradient(0, 0, 0, ref_width);
                }
                else {
                    context.translate(z1, 0);
                    context.scale(-1, 1);
                    gradient = context.createLinearGradient(0, 0, ref_height, 0);
                }
               
                context.drawImage(image, 0, 0, z1, z2);
                context.restore();
               
                context.globalCompositeOperation = "destination-out";
                gradient.addColorStop(1, "rgba(255, 255, 255, " + (1 - opacity_start) + ")");
                gradient.addColorStop(0, "rgba(255, 255, 255, " + (1 - opacity_end) + ")");
                context.fillStyle = gradient;
                if (-1 != navigator.appVersion.indexOf('WebKit')) {
                    context.fill();
                }
                else {
                    context.fillRect(0, 0, z1, z2);
                }
            }

           
            if(replace){
                image.parentNode.replaceChild(container, image);
                container.appendChild(image);
            }
            container.appendChild(reflection);
    }
  7. ОХ ТЫ.. СПАСИБО ИСКАЛ НЕЧТО ПОХОЖИЕ…
    Хорошая статья.

Пожалуйста, не используйте эту форму для комментирования! Данная форма предназначена исключительно для ботов.

Оставить комментарий к записи «Создание отражения рисунка с помощью JavaScript»

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя

गते गते पारगते पारसंगते बोधि स्वाहा