Raphael.js拖动比例导致奇怪的跳跃行为

问题描述:

我正在尝试使用Raphael.js内置的拖动方法调整图像大小/缩放图像,但我得到了一些奇怪的行为。

I'm trying to resize/scale an image using Raphael.js's built in drag method, but I'm getting some weird behavior.

以下是jsfiddle: http:// jsfiddle.net/charleshimmer/5pdyy/1/

Here is the jsfiddle: http://jsfiddle.net/charleshimmer/5pdyy/1/

使用右下角或右下角调整图像大小。你会看到一些奇怪的行为,它使用scale方法跳跃和跳过。任何人都知道为什么?

Use the right or bottom right corner to resize the image. You will see some weird behavior with it jumping and skipping using the scale method. Anybody have any idea why?

我可以通过更新图像的宽度和高度来调整平滑度,但随后宽高比关闭。使用 image.scale ,保持宽高比,但随后它会跳到各处。

I can get it to resize smoothing by updating the image's width and height, but then the aspect ratio is off. Using image.scale, the aspect ratio is maintained, but then it jumps all over the place.

HTML

<html>
 <head>
    <title>Photo Test</title>
 </head>
 <body>
    <div id="editor"></div>
    <img id="image" 
         src="http://www.pyrblu.com/assets/launchpad_resources/demo.jpg"
         style="display:none"
    >
 </body>
</html>

CSS

svg 
  {
  border: 1px solid red;
  background:#fff;
  border-radius: 45px;
  }

JavaScript

JavaScript

var Editor = {},
ctFactor = 7;

// create Raphael canvas
Editor.paper = Raphael('editor', 582, 514.8);

// wait for image to load
$("#image").load(function(){

    Editor.image = Editor.paper.image("http://www.pyrblu.com/assets/launchpad_resources/demo.jpg", 25, 25, 282, 465.2);

    Editor.image.drag(Editor.dragging, Editor.dragStart, Editor.dragEnd);
    Editor.image.ready = true;
    Editor.image.mousemove(function (e) {
        // only do this if the user isn't currently moving / resizing image
        if( ! this.ready){
            return;
        }
        var side = Editor.sideDection(e, this);
        // if the user's mouse is along the edge we want resize
        if(side){
            Editor.image.state = 'resizable';
        }
        // else it's towards the middle and we want to move
        else{
            Editor.image.state = 'movable';
        }
        var cursor = (side) ? side + '-resize' : 'move';
        this.attr('cursor', cursor);
    });

});

Editor.sideDection = function(event, ct){
    // check north side
    var directions = {
        n: Math.abs(event.offsetY - ct.attr('y')) <= ctFactor,
        s: Math.abs(event.offsetY - (ct.attr('height') + ct.attr('y'))) <= ctFactor,
        e: Math.abs(event.offsetX - (ct.attr('width') + ct.attr('x'))) <= ctFactor,
        w: Math.abs(event.offsetX - ct.attr('x')) <= ctFactor
    },
    side = '';

    // loop through all 4 sides and concate the ones that are true
    for(var key in directions) {
        if(directions.hasOwnProperty(key)){
            if(directions[key]){
                side = side + key;
            }    
        }
    }

    return side;
};

Editor.dragStart = function () {
    console.log('at start');
    // grab original x, y coords        
    this.ox = this.attr("x");
    this.oy = this.attr("y");

    // toggle user is doing something
    // so other actions are blocked
    this.ready = false;

    this.animate({opacity: .65}, 500, ">");
};

Editor.dragging = function (dx, dy, x, y, e) {
    console.log('at dragging');
    if(this.state === 'movable'){
        // this does the actual moving of the object
        this.attr({x: this.ox + dx, y: this.oy + dy});    
    }
    // we are resizing then
    else{

        var diff = (x - this.ox) - this.attr('width'),
            xratio = 1 + diff / this.attr('width'),
            yratio = 1 + diff / this.attr('height');

        console.log('diff: ', diff, 'xratio: ', xratio, 'yratio: ', yratio);           
        //resize image, update both height and width to keep aspect ratio
        // this.attr({
        //     'width': this.attr('width') * xratio,
        //     'height': this.attr('height') * yratio
        // });
        this.scale(xratio, xratio, 0, 0);

        //console.log('h: ', this.attr('height'), 'w: ', this.attr('width'), 'r', this.attr('width') / this.attr('height'));
    }
};

Editor.dragEnd = function () {
    this.ready = true;
    this.animate({opacity: 1}, 500, ">");
};