【问题标题】:Scaling to a fixed point in KineticJS在 KineticJS 中缩放到固定点
【发布时间】:2012-09-04 13:07:10
【问题描述】:

我在将容器缩放到固定点时遇到了一些问题。
就我而言,我正在尝试将舞台缩放(缩放)到鼠标光标。

这是一种使用纯画布的方法: http://phrogz.net/tmp/canvas_zoom_to_cursor.html(在Zoom Canvas to Mouse Cursor 讨论过)

我只是不知道如何在使用 KineticJS API 时应用相同的逻辑。

示例代码:

var position = this.stage.getUserPosition();
var scale = Math.max(this.stage.getScale().x + (0.05 * (scaleUp ? 1 : -1)), 0);
this.stage.setScale(scale);
// Adjust scale to position...?
this.stage.draw();

【问题讨论】:

    标签: javascript html canvas scaling kineticjs


    【解决方案1】:

    您需要偏移舞台,使其中心点位于固定点。这是一个例子,因为舞台的中心点默认在画布的左上角。假设您的舞台宽 600 像素,高 400 像素,并且您希望舞台从中心缩放。你需要这样做:

    var stage = new Kinetic.Stage({
       container: 'container',
       width: 600,
       height: 400,
       offset: [300, 200]
    };
    

    【讨论】:

      【解决方案2】:

      经过大量的挣扎、搜索和尝试,使用@Eric Rowell 提供的提示和 SO 问题Zoom in on a point (using scale and translate) 中发布的代码,我终于使用KineticJS 放大和缩小了一个固定点。

      这是一个有效的DEMO

      这是代码:

      var ui = {
          stage: null,
          scale: 1,
          zoomFactor: 1.1,
          origin: {
              x: 0,
              y: 0
          },
          zoom: function(event) {
              event.preventDefault();
              var evt = event.originalEvent,
                  mx = evt.clientX /* - canvas.offsetLeft */,
                  my = evt.clientY /* - canvas.offsetTop */,
                  wheel = evt.wheelDelta / 120;
              var zoom = (ui.zoomFactor - (evt.wheelDelta < 0 ? 0.2 : 0));
              var newscale = ui.scale * zoom;
              ui.origin.x = mx / ui.scale + ui.origin.x - mx / newscale;
              ui.origin.y = my / ui.scale + ui.origin.y - my / newscale;
      
              ui.stage.setOffset(ui.origin.x, ui.origin.y);
              ui.stage.setScale(newscale);
              ui.stage.draw();
      
              ui.scale *= zoom;
          }
      };
      
      $(function() {
          var width = $(document).width() - 2,
              height = $(document).height() - 5;
          var stage = ui.stage = new Kinetic.Stage({
              container: 'container',
              width: width,
              height: height
          });
          var layer = new Kinetic.Layer({
              draggable: true
          });
          var rectX = stage.getWidth() / 2 - 50;
          var rectY = stage.getHeight() / 2 - 25;
      
          var box = new Kinetic.Circle({
              x: 100,
              y: 100,
              radius: 50,
              fill: '#00D200',
              stroke: 'black',
              strokeWidth: 2,
          });
      
          // add cursor styling
          box.on('mouseover', function() {
              document.body.style.cursor = 'pointer';
          });
          box.on('mouseout', function() {
              document.body.style.cursor = 'default';
          });
      
          layer.add(box);
          stage.add(layer);
      
          $(stage.content).on('mousewheel', ui.zoom);
      });​
      

      【讨论】:

      • 嘿,谢谢,这工作正常,但我有很多层,所以我不能将层设置为“可拖动”。因此我设置了可拖动的舞台。当我通过拖动移动舞台时,我无法缩放到所需的缩放点。我必须重新计算一些东西来计算阶段 x 和 y,但我无法实现。你能帮我吗?
      • @user1645941 请分享一些您正在处理的问题的工作示例(可能是fiddle),我会尽我所能提供帮助。
      • @juan.facorro 但它在 Firefox 中不起作用。你能解决它吗?
      • @trungkien 在 Chrome 中也不能正常工作,所以我将 KineticJS 版本更新到 4.4.3,现在一切似乎都正常了。
      【解决方案3】:

      更新了@juan.facorro 的演示以缩放形状而不是舞台

      jsFiddle

      var ui = {
          stage: null,
          box: null,
          scale: 1,
          zoomFactor: 1.1,
          zoom: function(event) {
              event.preventDefault();
              var evt = event.originalEvent,
                  mx = evt.offsetX,
                  my = evt.offsetY,
                  wheel = evt.wheelDelta / 120; //n or -n
              var zoom = (ui.zoomFactor - (evt.wheelDelta < 0 ? 0.2 : 0));
              var newscale = ui.scale * zoom;
      
              var origin = ui.box.getPosition();
              origin.x = mx - (mx - origin.x) * zoom;
              origin.y = my - (my - origin.y) * zoom;
      
              ui.box.setPosition(origin.x, origin.y);
              ui.box.setScale(newscale);
              ui.stage.draw();
      
              ui.scale *= zoom;
          }
      };
      
      $(function() {
          var width = $(document).width() - 2,
              height = $(document).height() - 5;
          var stage = ui.stage = new Kinetic.Stage({
              container: 'container',
              width: width,
              height: height
          });
          var layer = new Kinetic.Layer();
          var rectX = stage.getWidth() / 2 - 50;
          var rectY = stage.getHeight() / 2 - 25;
      
          var box = ui.box = new Kinetic.Circle({
              x: 100,
              y: 100,
              radius: 50,
              fill: '#00D200',
              stroke: 'black',
              strokeWidth: 2,
              draggable: true
          });
      
          // add cursor styling
          box.on('mouseover', function() {
              document.body.style.cursor = 'pointer';
          });
          box.on('mouseout', function() {
              document.body.style.cursor = 'default';
          });
      
          layer.add(box);
          stage.add(layer);
      
          $(stage.content).on('mousewheel', ui.zoom);
      });
      

      【讨论】:

        【解决方案4】:

        上面的演示只有在舞台的 x 和 y 坐标为 0 时才有效。例如舞台是可拖动的,它会在拖动时更改这些坐标,因此它们需要包含在偏移计算中。这可以通过从画布偏移中减去它们来实现:

        jsfiddle

        zoom: function(event) {
            event.preventDefault();
            var evt = event.originalEvent,
                mx = evt.offsetX - ui.scale.getX(),
                my = evt.offsetY - ui.scale.getY(),
            var zoom = (ui.zoomFactor - (evt.wheelDelta < 0 ? 0.2 : 0));
            var newscale = ui.scale * zoom;
        
            var origin = ui.box.getPosition();
            origin.x = mx - (mx - origin.x) * zoom;
            origin.y = my - (my - origin.y) * zoom;
        
            ui.box.setPosition(origin.x, origin.y);
            ui.box.setScale(newscale);
            ui.stage.draw();
        
            ui.scale *= zoom;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-03-29
          • 2012-09-17
          • 2013-01-19
          • 2012-09-28
          • 1970-01-01
          • 1970-01-01
          • 2013-07-02
          • 2013-05-31
          相关资源
          最近更新 更多