Эффект лупы на ActionScript 3.0

Я, конечно, знаю, что готовых реализаций эффекта лупы для ActionScript существует довольно много, но реализация данного эффекта от Barbara Kaskosz мне показалась довольно интересной. Не идеальной, но интересной. Естественно, вам, почти наверняка, придётся внести некоторые изменения в код, но всё же основа эффекта уже готова и работает.

Итак, код. К счастью или к сожалению, код процедурный. Но зато он снабжён комментариями автора и понять его не составит большого труда.

Код ActionScript 3.0:

/* ActionScript 3 Effect by Barbara Kaskosz. www.flashandmath.com Last modified: September 30, 2008. */ /* Below, we comment the portion of the code whcih you can change to easily customize the applet. */ //'board' its the main conatiner in which the image resides. The position //of 'board' will detrmine the position of your picture within the main movie. var board:Sprite=new Sprite(); this.addChild(board); board.x = 0; board.y = 0; var loader:Loader; //The text field that displays loading information. To customize its //apearance, got to setUpLoadBox function at the end of the script. var infoBox:TextField; var image:Bitmap; var imageData:BitmapData; var glass:Sprite=new Sprite(); //The size of the magnifying glass. You can change the values as you wish. var glassWidth:int = 150; var glassHeight:int = 150; var doDrag:Boolean = false; var picWidth:Number; var picHeight:Number; var dataWidth:Number; var dataHeight:Number; /* 'shrinkFactor' is the factor by which your original (high resolution) image will be scaled down for display. The reciprocal of shrinkFactor is the magnifying factor. 'shrinkFactor has to be less than 1 for the mangnifying effect to occur. */ var shrinkFactor:Number = 1 / 4; var magFactor:Number = 1 / shrinkFactor; setUpLoadBox(); startApp(); function startApp():void { loader=new Loader(); //Replace Kazanie_Skargi by the name of your image or the address of your image. loader.load(new URLRequest("magnifyingeffect.jpg")); //Replace 187 by the size of your high resolution image. Although it //will show only for a second or so. In progress display, the total size will //be determined automatically. infoBox.text = "Loading: 0 KB of 187 KB"; loader.contentLoaderInfo.addEventListener(Event.COMPLETE,initPic); loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,updateInfo); } function updateInfo(e:ProgressEvent):void { infoBox.text = "Loading: " + String(Math.floor(e.bytesLoaded / 1024)) + " KB of " + String(Math.floor(e.bytesTotal / 1024)) + " KB."; } function initPic(e:Event):void { image = Bitmap(loader.content); imageData = image.bitmapData; dataWidth = image.width; dataHeight = image.height; image.scaleX = shrinkFactor; image.scaleY = shrinkFactor; picWidth = image.width; picHeight = image.height; board.addChild(image); loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,initPic); loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS,updateInfo); loader = null; infoBox.text = ""; infoBox.visible = false; board.addChild(glass); glass.filters=[ new DropShadowFilter() ]; board.filters=[ new DropShadowFilter() ]; setUpListeners(); } function drawInGlass(a:Number,b:Number):void { var curBd:BitmapData; var curBmp:Bitmap; var xbeg:Number = a - glassWidth / 2; var ybeg:Number = b - glassHeight / 2; if (xbeg<0) { xbeg = 0; } if (ybeg<0) { ybeg = 0; } if (xbeg>dataWidth-glassWidth) { xbeg = dataWidth - glassWidth; } if (ybeg>dataHeight-glassHeight) { ybeg = dataHeight - glassHeight; } curBmp = new Bitmap(new BitmapData(glassWidth,glassHeight)); curBmp.bitmapData.copyPixels(imageData,new Rectangle(xbeg,ybeg,glassWidth,glassHeight),new Point(0,0)); curBd = curBmp.bitmapData; glass.graphics.clear(); glass.graphics.lineStyle(); glass.graphics.beginBitmapFill(curBd); glass.graphics.drawRect(0,0,glassWidth,glassHeight); glass.graphics.endFill(); } function glassClear():void { glass.graphics.clear(); } function setUpListeners():void { board.addEventListener(MouseEvent.ROLL_OUT,boardOut); board.addEventListener(MouseEvent.MOUSE_MOVE,boardMove); board.addEventListener(MouseEvent.MOUSE_DOWN,boardDown); board.addEventListener(MouseEvent.MOUSE_UP,boardUp); } function boardOut(e:MouseEvent):void { doDrag = false; glassClear(); Mouse.show(); } function boardDown(e:MouseEvent):void { var locX:Number = board.mouseX; var locY:Number = board.mouseY; glass.x = locX - glassWidth / 2; glass.y = locY - glassHeight / 2; drawInGlass(magFactor*locX,magFactor*locY); doDrag = true; Mouse.hide(); } function boardUp(e:MouseEvent):void { doDrag = false; glassClear(); Mouse.show(); } function boardMove(e:MouseEvent):void { var locX:Number = board.mouseX; var locY:Number = board.mouseY; var goodCoords:Point = getGoodCoords(locX,locY); if (doDrag) { glass.x = goodCoords.x - glassWidth / 2; glass.y = goodCoords.y - glassHeight / 2; locX = goodCoords.x; locY = goodCoords.y; drawInGlass(magFactor*locX,magFactor*locY); e.updateAfterEvent(); } } function getGoodCoords(a:Number,b:Number):Point { var goodCoords=new Point(); goodCoords.x = a; goodCoords.y = b; if (a < glassWidth/(2*magFactor)) { goodCoords.x = glassWidth / (2 * magFactor); } if (a > picWidth-glassWidth/(2*magFactor)) { goodCoords.x = picWidth - glassWidth / (2 * magFactor); } if (b < glassHeight/(2*magFactor)) { goodCoords.y = glassHeight / (2 * magFactor); } if (b > picHeight-glassHeight/(2*magFactor)) { goodCoords.y = picHeight - glassHeight / (2 * magFactor); } return goodCoords; } function setUpLoadBox():void { var infoFormat:TextFormat=new TextFormat(); infoBox=new TextField(); board.addChild(infoBox); infoBox.x = 0; infoBox.y = 0; infoBox.type = TextFieldType.DYNAMIC; infoBox.autoSize = TextFieldAutoSize.LEFT; infoBox.wordWrap = false; infoBox.border = false; infoBox.background = false; infoBox.mouseEnabled = false; infoFormat.color = 0xCC0000; infoFormat.size = 14; infoFormat.font = "Arial"; infoBox.defaultTextFormat = infoFormat; }

Что делает код? Данный код загружает внешнее изображение (magnifyingeffect.jpg) и помещает его на сцену флеш-ролика. Затем мы может зажать левую клавишу мышки над любым участком загруженного изображения и появится лупа, которая увеличит данный участок изображения. Попробуйте сами:

Загрузить Adobe Flash Player

Но есть одно важное условие. Дело в том, что само изображение должно быть изначально достаточно большим и качественным, иначе эффект достигнут не будет. То есть код загружает изображение с высоким разрешением, масштабирует (уменьшает) его до тех пор, пока оно не влезет на сцену флеш-ролика. А с помощью лупы мы фактически получаем фрагмент картинки, взятый от исходного высококачественного изображения. Надеюсь, сумел донести смысл:-)

Размеры лупы можно настраивать. За это в коде отвечают две переменные:

- glassWidth - ширина лупы;

- glassHeight - высота лупы.

Изменять можно и форму лупы. Для этого надо просто изменить форму спрайта glass. Для примера сделаем лупу круглой.

Код ActionScript 3.0:

/* ActionScript 3 Effect by Barbara Kaskosz. www.flashandmath.com Last modified: September 30, 2008. */ /* Below, we comment the portion of the code whcih you can change to easily customize the applet. */ //'board' its the main conatiner in which the image resides. The position //of 'board' will detrmine the position of your picture within the main movie. var board:Sprite=new Sprite(); this.addChild(board); board.x = 0; board.y = 0; var loader:Loader; //The text field that displays loading information. To customize its //apearance, got to setUpLoadBox function at the end of the script. var infoBox:TextField; var image:Bitmap; var imageData:BitmapData; var glass:Sprite=new Sprite(); //The size of the magnifying glass. You can change the values as you wish. var glassWidth:int = 150; var glassHeight:int = 150; var doDrag:Boolean = false; var picWidth:Number; var picHeight:Number; var dataWidth:Number; var dataHeight:Number; /* 'shrinkFactor' is the factor by which your original (high resolution) image will be scaled down for display. The reciprocal of shrinkFactor is the magnifying factor. 'shrinkFactor has to be less than 1 for the mangnifying effect to occur. */ var shrinkFactor:Number = 1 / 4; var magFactor:Number = 1 / shrinkFactor; setUpLoadBox(); startApp(); function startApp():void { loader=new Loader(); //Replace Kazanie_Skargi by the name of your image or the address of your image. loader.load(new URLRequest("magnifyingeffect.jpg")); //Replace 187 by the size of your high resolution image. Although it //will show only for a second or so. In progress display, the total size will //be determined automatically. infoBox.text = "Loading: 0 KB of 187 KB"; loader.contentLoaderInfo.addEventListener(Event.COMPLETE,initPic); loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,updateInfo); } function updateInfo(e:ProgressEvent):void { infoBox.text = "Loading: " + String(Math.floor(e.bytesLoaded / 1024)) + " KB of " + String(Math.floor(e.bytesTotal / 1024)) + " KB."; } function initPic(e:Event):void { image = Bitmap(loader.content); imageData = image.bitmapData; dataWidth = image.width; dataHeight = image.height; image.scaleX = shrinkFactor; image.scaleY = shrinkFactor; picWidth = image.width; picHeight = image.height; board.addChild(image); loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,initPic); loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS,updateInfo); loader = null; infoBox.text = ""; infoBox.visible = false; board.addChild(glass); glass.filters=[ new DropShadowFilter() ]; board.filters=[ new DropShadowFilter() ]; setUpListeners(); } function drawInGlass(a:Number,b:Number):void { var curBd:BitmapData; var curBmp:Bitmap; var xbeg:Number = a - glassWidth / 2; var ybeg:Number = b - glassHeight / 2; if (xbeg<0) { xbeg = 0; } if (ybeg<0) { ybeg = 0; } if (xbeg>dataWidth-glassWidth) { xbeg = dataWidth - glassWidth; } if (ybeg>dataHeight-glassHeight) { ybeg = dataHeight - glassHeight; } curBmp = new Bitmap(new BitmapData(glassWidth,glassHeight)); curBmp.bitmapData.copyPixels(imageData,new Rectangle(xbeg,ybeg,glassWidth,glassHeight),new Point(0,0)); curBd = curBmp.bitmapData; glass.graphics.clear(); glass.graphics.lineStyle(); glass.graphics.beginBitmapFill(curBd); glass.graphics.drawCircle(glassWidth/2,glassWidth/2,glassWidth/2); glass.graphics.endFill(); } function glassClear():void { glass.graphics.clear(); } function setUpListeners():void { board.addEventListener(MouseEvent.ROLL_OUT,boardOut); board.addEventListener(MouseEvent.MOUSE_MOVE,boardMove); board.addEventListener(MouseEvent.MOUSE_DOWN,boardDown); board.addEventListener(MouseEvent.MOUSE_UP,boardUp); } function boardOut(e:MouseEvent):void { doDrag = false; glassClear(); Mouse.show(); } function boardDown(e:MouseEvent):void { var locX:Number = board.mouseX; var locY:Number = board.mouseY; glass.x = locX - glassWidth / 2; glass.y = locY - glassHeight / 2; drawInGlass(magFactor*locX,magFactor*locY); doDrag = true; Mouse.hide(); } function boardUp(e:MouseEvent):void { doDrag = false; glassClear(); Mouse.show(); } function boardMove(e:MouseEvent):void { var locX:Number = board.mouseX; var locY:Number = board.mouseY; var goodCoords:Point = getGoodCoords(locX,locY); if (doDrag) { glass.x = goodCoords.x - glassWidth / 2; glass.y = goodCoords.y - glassHeight / 2; locX = goodCoords.x; locY = goodCoords.y; drawInGlass(magFactor*locX,magFactor*locY); e.updateAfterEvent(); } } function getGoodCoords(a:Number,b:Number):Point { var goodCoords=new Point(); goodCoords.x = a; goodCoords.y = b; if (a < glassWidth/(2*magFactor)) { goodCoords.x = glassWidth / (2 * magFactor); } if (a > picWidth-glassWidth/(2*magFactor)) { goodCoords.x = picWidth - glassWidth / (2 * magFactor); } if (b < glassHeight/(2*magFactor)) { goodCoords.y = glassHeight / (2 * magFactor); } if (b > picHeight-glassHeight/(2*magFactor)) { goodCoords.y = picHeight - glassHeight / (2 * magFactor); } return goodCoords; } function setUpLoadBox():void { var infoFormat:TextFormat=new TextFormat(); infoBox=new TextField(); board.addChild(infoBox); infoBox.x = 0; infoBox.y = 0; infoBox.type = TextFieldType.DYNAMIC; infoBox.autoSize = TextFieldAutoSize.LEFT; infoBox.wordWrap = false; infoBox.border = false; infoBox.background = false; infoBox.mouseEnabled = false; infoFormat.color = 0xCC0000; infoFormat.size = 14; infoFormat.font = "Arial"; infoBox.defaultTextFormat = infoFormat; }

Проверим, изменилась ли форма нашей лупы:

Загрузить Adobe Flash Player

Ну, не знаю как у вас, а у меня всё работает правильно:-)

Исходник к данному уроку под Adobe Flash CS5.5 скачать можно здесь.

Автор: admin

Дата добавления: 2011-12-15

Просмотров: 3137

Рейтинг поста: +5-

Правила перепечатки

Социальные закладки:
Комментарии:
К данной заметке комментариев пока нет. Ваш комментарий может стать первым.
Добавить комментарий:







[ + ] помощь по форматирование текста

Идиот-тест

Если все обязательные поля (отмечены * ) заполнены необходимой информацией, то нажимаем кнопку Добавить комментарий.

Меню
Подписка
Рубрики
Метки
Последние комментарии
Рейтинг постов
Реклама
Друзья
География гостей
Статистика
Яндекс.Метрика