【问题标题】:EaselJs: How to restrict image movement inside canvas (after scaling or rotation)?EaselJs:如何限制画布内的图像移动(缩放或旋转后)?
【发布时间】:2017-06-20 00:23:02
【问题描述】:

我正在使用 EaselJs 创建一个简单的图像裁剪工具(类似于this)。到目前为止,我已经编写了大部分代码,除了一个小问题。我希望图像在拖动时保留在容器内。换句话说,我不希望背景显示在图像下方。

请看我的代码:

var img = new Image();
var canvas, stage, bmp;

img.src = 'http://i.imgur.com/wMW4nDL.jpg?timestamp=' + Math.random();
img.crossOrigin = 'anonymous';

img.onload = function() {  
  canvas = document.getElementById('canvas');
  stage = new createjs.Stage(canvas);
  bmp = new createjs.Bitmap(img).set();

  bmp.on("pressmove", function(evt) {
    var ct = evt.currentTarget;

    ct.x = evt.stageX;
    ct.y = evt.stageY;

    stage.update();
  });

  bmp.on('mousedown', function(evt) {
    var ct = evt.currentTarget,
      local = ct.globalToLocal(evt.stageX, evt.stageY),
      nx = ct.regX - local.x,
      ny = ct.regY - local.y;
    //set the new regX/Y
    ct.regX = local.x;
    ct.regY = local.y;
    //adjust the real-position, otherwise the new regX/Y would cause a jump
    ct.x -= nx;
    ct.y -= ny;
  });
  
  bmp.regX = img.width / 2;
  bmp.regY = img.height / 2;
  bmp.x = bmp.y = 300;
  bmp.scaleX = bmp.scaleY = 0.5;
  
  bmp.rotation = 90;
  stage.addChild(bmp);  
  stage.update();
}
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>

<canvas id="canvas" width="600" height="200" style="cursor:move;border:2px solid red">Canvas is not supported</canvas>

运行代码并继续向下拖动图像。很快图像就会出现在画布之外,您将开始看到它下面的白色画布。如果图像的顶角相对于画布大于 (0, 0),我希望图像停止拖动。底部也一样,如果图像的底部被拖到画布底部后,我希望它停止拖动。

如何更新我的代码以使图像在画布外时停止拖动?(从左上角、左下角、右上角或右下角) p>

【问题讨论】:

    标签: css canvas html5-canvas createjs easeljs


    【解决方案1】:

    我最近用 createJS 做了类似的事情。基本上你想要做的是在pressmove监听器中限制图像的移动,像这样:

    if (ct.x > 0){
        ct.x = 0;
    }
    

    当然也适用于所有可能的移动场景。

    下面是我自己的代码的一部分,我用来强制执行这些确切的界限。然而,在我自己的代码中不同的是,我还必须强制执行放大图像的界限。或许对你有些用处。

        function handleMouse(me)
        {
    
            switch (me.type){
                case "mousedown":
                    _initialX = _stage.mouseX;
                    _initialY = _stage.mouseY;
                    break;
                case "pressmove":
                    if (_imageOrientation == "portrait"){
                        handlePortraitMovement();
                    } else if (_imageOrientation == "landscape"){
                        handleLandscapeMovement();
                    }
    
                    _overlayerImageCopy.x = _imagesContainer.x;
                    _overlayerImageCopy.y = _imagesContainer.y;
    
                    _initialX = _stage.mouseX;
                    _initialY = _stage.mouseY;
                    _stage.update();
                    break;
            }
    
        }
    
        function handlePortraitMovement()
        {
            var alphaOfMovement;
            if (_stage.mouseX - _initialX > 0){
                //up movement
                alphaOfMovement = -1;
            } else {
                //down movement
                alphaOfMovement = 1;
            }
            _imagesContainer.y += _stage.mouseY - _initialY;
            if (_imagesContainer.y >= _maxMovementPosition){
                _imagesContainer.y = _maxMovementPosition;
            }
            if (_imagesContainer.y < -_maxMovementPosition + _canvas.height * (1 - _imagesContainer.scaleY)){
                _imagesContainer.y = -_maxMovementPosition + _canvas.height * (1 - _imagesContainer.scaleY);
            }
            if ((alphaOfMovement == 1) && (-_imagesContainer.x + SQUARE_SIZE < SQUARE_SIZE * _imagesContainer.scaleX)){
                _imagesContainer.x += _stage.mouseX - _initialX;
                if (-_imagesContainer.x + SQUARE_SIZE > SQUARE_SIZE * _imagesContainer.scaleX) {
                    _imagesContainer.x = SQUARE_SIZE - SQUARE_SIZE * _imagesContainer.scaleX;
                }
            }
            if (alphaOfMovement == 1 && _imagesContainer.x > 0){
                _imagesContainer.x = 0;
            }
            if (alphaOfMovement == -1 && _imagesContainer.x < 0){
                _imagesContainer.x += _stage.mouseX - _initialX;
            }
        }
    
        function handleLandscapeMovement()
        {
            var alphaOfMovement;
            if (_stage.mouseY - _initialY > 0){
                //left movement
                alphaOfMovement = -1;
            } else {
                //right movement
                alphaOfMovement = 1;
            }
            _imagesContainer.x += _stage.mouseX - _initialX;
            if (_imagesContainer.x >= _maxMovementPosition){
                _imagesContainer.x = _maxMovementPosition;
            }
            if (_imagesContainer.x < -_maxMovementPosition + _canvas.width * (1 - _imagesContainer.scaleX)){
                _imagesContainer.x = -_maxMovementPosition + _canvas.width * (1 - _imagesContainer.scaleX);
            }
            if ((alphaOfMovement == 1) && (-_imagesContainer.y + SQUARE_SIZE < SQUARE_SIZE * _imagesContainer.scaleY)){
                _imagesContainer.y += _stage.mouseY - _initialY;
                if (-_imagesContainer.y + SQUARE_SIZE > SQUARE_SIZE * _imagesContainer.scaleY) {
                    _imagesContainer.y = SQUARE_SIZE - SQUARE_SIZE * _imagesContainer.scaleY;
                }
            }
            if (alphaOfMovement == 1 && _imagesContainer.y > 0){
                _imagesContainer.y = 0;
            }
            if (alphaOfMovement == -1 && _imagesContainer.y < 0){
                _imagesContainer.y += _stage.mouseY - _initialY;
            }
        }
    

    【讨论】:

    • 谢谢,这看起来很有用。我将逐行解释它。我认为包含它最难的部分是旋转图像时,因为那样 X 和 Y 值会变得非常混乱..
    • 是的,从头开始设计很痛苦。最好的办法是定义所有 4 个方向的移动规则,就像我使用 alphaOfMovement 所做的那样。
    猜你喜欢
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多