1

I figured out how to load an external image and zoom and pan that. (main image)

I would like to implement information icons at certain places on the main image, but because the image can be zoomed and panned, I need these icons to remain at the position where it used to be.

See the image below for a better understanding. Wherever the icons are is a product, and if an icon is clicked, an external .SWF loads with the product information. In a perfect world, the icon wouldn't zoom, only pan.

My base understanding is that each of the icons would have to be a separate movieclip. Each with its own set of listeners. I just can't figure out how to make the icons stay on the relevant product when the main image is panned and zoomed.

Any help or advise would be greatly appreciated.

(http://www.marketingfanatics.co.za/images/example.jpg)

package  {

import flash.display.MovieClip;
import fl.motion.MatrixTransformer;
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.Bitmap;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.ProgressEvent;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.DropShadowFilter;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.events.KeyboardEvent;
import flash.ui.Mouse;

public class Main extends MovieClip {


    public function Main() {

        mcIn.visible = false;
        mcOut.visible = false;
        infoBox.wordWrap = true;
        infoBox.mouseEnabled = false;

        var board:Sprite = new Sprite();
        addChild(board);

        var boardWidth:int = 690;
        var boardHeight:int = 489;

        board.x = 0.0;
        board.y = 0.0;


        board.graphics.beginFill(0xDDDDDD);
        board.graphics.drawRect(0, 0, boardWidth, boardHeight);
        board.graphics.endFill();

        var spImage:Sprite = new Sprite();
        board.addChild(spImage);

        var boardMask:Shape = new Shape();
        boardMask.graphics.beginFill(0xDDDDDD);
        boardMask.graphics.drawRect(0, 0, boardWidth, boardHeight);
        boardMask.graphics.endFill();
        board.addChild(boardMask);
        spImage.mask = boardMask;

        var scaleFactor:Number = 0.8;
        var minScale:Number = 0.25;
        var maxScale:Number = 2.0;
        var image:Bitmap;

        var loader:Loader = new Loader();
        loader.load(new URLRequest("source_material/Irrigation_1195X847.jpg"));
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, initPic);
        loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, updateInfo);
        infoBox.text = "Loading the Image";

        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 {
            infoBox.text = "";
            infoBox.visible = false;
            image = Bitmap(loader.content);
            minScale = boardWidth/image.width;
            image.scaleX = minScale;
            image.scaleY = minScale;

            spImage.addChild(image);
            spImage.addChild(mcIn);
            spImage.addChild(mcOut);

            spImage.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
            stage.addEventListener(MouseEvent.MOUSE_UP, stopDragging);

            loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, initPic);
            loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, updateInfo);
            loader = null;

            board.filters = [ new DropShadowFilter() ];
            spImage.addEventListener(MouseEvent.CLICK, zoom);
        }

        function startDragging(mev:MouseEvent):void {
            spImage.startDrag();
        }

        function stopDragging(mev:MouseEvent):void {
            spImage.stopDrag();
        }

        function zoom(mev:MouseEvent):void {
            if ((!mev.shiftKey) && (!mev.ctrlKey)) {
                return;
            }

            if ((mev.shiftKey) && (mev.ctrlKey)) {
                return;
            }

            var mat:Matrix;

            var externalCenter:Point = new Point(spImage.mouseX, spImage.mouseY);
            var internalCenter:Point = new Point(image.mouseX, image.mouseY);

            if (mev.shiftKey) {
                image.scaleX = Math.max(scaleFactor * image.scaleX, minScale);
                image.scaleY = Math.max(scaleFactor * image.scaleY, minScale);

            }

            if (mev.ctrlKey) {
                image.scaleX = Math.min(1 / scaleFactor * image.scaleX, maxScale);
                image.scaleY = Math.min(1 / scaleFactor * image.scaleY, maxScale);

            }

            mat = image.transform.matrix.clone();

            MatrixTransformer.matchInternalPointWithExternal(mat, internalCenter, externalCenter);

            image.transform.matrix = mat;
        }

        stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandler);
        stage.addEventListener(KeyboardEvent.KEY_UP, keyHandler);

        function keyHandler(ke:KeyboardEvent):void {
            mcIn.x = spImage.mouseX;
            mcIn.y = spImage.mouseY;

            mcOut.x = spImage.mouseX;
            mcOut.y = spImage.mouseY;

            mcIn.visible = ke.ctrlKey;
            mcOut.visible = ke.shiftKey;

            if (ke.ctrlKey || ke.shiftKey) {
                Mouse.hide(); } else {
                    Mouse.show();
            }
        }
    }
}

}

Deon
  • 109
  • 2
  • 13

2 Answers2

0

Add the descriptions on top of the main image in lets say Sprite object. After your main image is added to stage do: setChildIndex(descriptionObject,numChildren-1); This will ensure desription being on top of everything.

SzRaPnEL
  • 171
  • 3
  • 17
  • The problem I'm having is not displaying something on top of the externally loaded image, but rather to have a movieclip stick to a point on this image. For instance, when a user pans the image, the movieclip has to pan with the image at that point. The movieclip shouldn't be statically displayed over the image. It has to move WITH the image, but it has to be a click-able moveclip to load an external .SWF to display relevant info about that part of the image. Almost like Google Maps. The map markers remain at the same point regardless of the zoom or pan. That's what I'm trying to achieve. – Deon Apr 17 '13 at 11:47
  • put all objects inside one container object and zoom+pan that container – SzRaPnEL Apr 17 '13 at 12:43
  • How would I go about that? The image is 3000 pixels wide but my board/stage is set at 690 pixels to accommodate the zoom. Based on the code above, how could I rather zoom and pan a movieclip? Would I have to remove the loader information and somehow change that the movieclip? – Deon Apr 17 '13 at 12:51
0

your question: Is it possible to zoom and pan more than one image/movieclip in Actionscript 3?

You can pan an image that size, or zoom ...you will loose frames because of the size of the image so i suggest using green sock BlitMask, does exactly what you need. it has examples on how to use it:

    http://www.greensock.com/blitmask/

Also if you want multiple images to scroll put the images into a container, hence movieClip then scroll the movieclip or change scale ,change depth Z position or what have you.

joshua
  • 676
  • 1
  • 5
  • 19