zoukankan      html  css  js  c++  java
  • Flex 学习笔记------ 自定义拖放控件ObjectHandler

    Flex 学习笔记------ 自定义拖放控件ObjectHandler

    Flex里面写动画效果甚是简单,而且没有兼容性问题,这一点比js好太多了。也是最近学习Flex以来感到令人欣慰的地方。

    废话不多说,进入正题。

    现在的需求是给定一张图片(或其他控件也可以,暂时我就按自己做的项目上的来举例吧),要求拖动四个角的时候,图片可以按比例缩放。这么一个常见的需求,不用多想,网上肯定已经有现成的控件了不是。google一下,果然,ObjectHandles,这个类库还能支持旋转。功能看那上去很强大,但是,跟我的需求还是有些冲突,我的要求是拖动四个角的时候图片大小按比率缩放,不能拉伸。没关系,没有的东西就自己动手吧,本来也觉得这个功能有点挑战性,正和我意。

    那么写之前,简单理一下思路:1),选中一张图片后,四个角上出现可拖动的标志;2)拖动一个角,此时其斜对角为不动点,图片缩放。嗯,看上去主要也就是这么两步。先上效果图吧:

    P1P2P3P4围成的是原始图片,拖动P4时,原始图片不动,跟着鼠标缩放的是另一张半透明的图片,当然这张图片是拷贝自原始图片的。

    然后,鼠标松开后,图片自动缩放至拖放后的大小。半透明图消失。

    首先第一步,选中图片,绘制四个角的操作按钮。

    其实就是绘制四个小矩形而已,方法很简单:

     // 创建句柄,用来拖动和拉伸对象
     private static function createRect():Image {
            var img:Image = new Image();
            var size:int = 10;
            img.graphics.beginFill(0xcf67b9, 0.5);
            img.graphics.drawRect(-size / 2, -size / 2, size, size);
            img.graphics.endFill();
            img.graphics.lineStyle(1, 0);
            img.graphics.drawRect(-size / 2, -size / 2, size, size);
            return img;
    }

    有了这个方法之后,只要在图片上加上点击事件,第一步就算完成了。直接看效果图:

    点击前:               点击后:

    第二步:拖动四个角,图片缩放。

    方法其实也不难,但需要注意到的是,当拖动一个角的时候,以其对角的点作为当前不动点。比如,在最上面的第一幅图中,拖动P4时,P1为不动点,拖动P2时,P3为不动点,...以此类推。

    不就是变换一下不动点嘛,easy,立马就会想到,Flex里面,图片在缩放时是可以设置变换中心的(也就是设置不动点,默认是图片的左上角)。so,开始动手啦:核心功能代码如下

        // 在句柄上按下鼠标左键
        private function rect_mouse_down(e:MouseEvent):void {
            trace("evt_rect_mouse_down");
            currRect = e.currentTarget as Sprite;
            if (!currRect) {
                return;
            }
            container.addEventListener(MouseEvent.MOUSE_MOVE, mouse_move);
    
            startX = e.stageX;
            startY = e.stageY;
    
            // 跟随鼠标缩放的操作对象
            displayEl = cloneImage(widget as Image, widget.width, widget.height);
            displayEl.alpha = 0.5;
            displayEl.width = widget.width * widget.scaleX;
            displayEl.height = widget.height * widget.scaleY;
            displayEl.x = rects[0].x;
            displayEl.y = rects[0].y;
    
            container.addChild(displayEl);
    
            var index:int = rects.indexOf(currRect);
    
         // 设置变换不动点 setTransformCenter(displayEl, index); }
    // 拖动矩形句柄,鼠标移动 private function mouse_move(e:MouseEvent):void { if (!currRect) { return; } trace("evt_mouse_move"); var moveX:int = e.stageX - startX; var moveY:int = e.stageY - startY; var ind:int = rects.indexOf(currRect); // 正代表放大,负代表缩小 if (ind == 0) { moveX = -moveX; moveY = -moveY; } else if (ind == 1) { moveY = -moveY; } else if (ind == 2) { moveX = -moveX; } deltaScale = Math.max( moveY / widget.height, moveX / widget.width ); displayEl.scaleX = deltaScale / widget.scaleX + 1; displayEl.scaleY = deltaScale / widget.scaleY + 1; } // 在句柄上松开鼠标左键 private function rect_mouse_up(e:MouseEvent):void { trace("rect_mouse_up"); if(!currRect) return; currRect = null; container.removeEventListener(MouseEvent.MOUSE_MOVE, mouse_move); container.removeChild(displayEl); widget.scaleX += deltaScale || 0; widget.scaleY += deltaScale || 0;
         // 重新计算四个角上句柄的位置 setRects(); }

    测试之后,出问题了,嗯,忘记设置原图的变换中心了嘛!这样导致拖动任意一个角后,松开鼠标,原图的左上角都不动。不知道各位看官看明白没有,还是截个图说明下吧:

    上图中,鼠标拖动P3,不动点是P2,松开鼠标后,应该是P2不动,但实际结果还是P1没动。这样当然不行了,事先还是少考虑了一层啊!。

    第三步:鼠标松开后,更新原图的位置。

    考虑到以后的重用及可扩展性,这里觉得一次性解决这个问题比较好,而不是每次都要改变图片的变换中心,变来变去,自己都不知道最后的中心在哪了。现在固定变换的中心就是左上角,

    指定最后图片显示的位置,让图片正确显示就好。

      private function fixPosition():void{
            var index:int = rects.indexOf(currRect);
            var scale: Number = widget.scaleX + (deltaScale || 0);
    
            var w:Number = widget.width * scale;
            var h:Number = widget.height * scale;
    
            var left:Number, top:Number;
            switch (index){
                case 0: // 左上角
                    left = rects[3].x - w;
                    top = rects[3].y - h;
                    break;
                case 1: // 右上角
                    left = rects[2].x;
                    top = rects[2].y - h;
                    break;
                case 2: //  左下角
                    left = rects[1].x - w;
                    top = rects[1].y;
                    break;
                case 3: // 右下角
                    left = rects[0].x;
                    top = rects[0].y;
                    break;
            }
            widget.x = left;
            widget.y = top;
        }

    测试一下,嗯,没什么问题!到这里,基本功能就算完成了。当然,这里只是提供一个了基本的思路,这也只是一个最简单的版本,很多项目中的功能还没实现,比如,图片旋转操作,边框不应被放大,图片的平移等。

    后面有时间再来补充一下。

    测试源码: 这里下载

    -----------------------------一花开五叶 结果自然成-------------------------------------------------
  • 相关阅读:
    蓝桥题库基础练习1-10
    HTML5(八)Web Workers
    对自动化测试工具的实战运用
    对自动化测试工具的简要认识
    HTML5(七)Web 存储
    蓝桥杯javaB组入坑
    Google Play内购测试
    【python】python中的json、字典dict
    【python】python之tuple元组
    性能测试基础知识
  • 原文地址:https://www.cnblogs.com/zyc-undefined/p/3302186.html
Copyright © 2011-2022 走看看