首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Konvajs:创建一个可拖的区域,其中一个孩子有一些约束。

Konvajs:创建一个可拖的区域,其中一个孩子有一些约束。
EN

Stack Overflow用户
提问于 2020-01-23 19:11:58
回答 4查看 2.3K关注 0票数 4

我正在用Konva创建一个时间线,整个时间线(舞台)可以拖到所有方向,但是我有一个轴,它有所有的时间线(Konva组),我想限制它的移动,使它只能水平移动。

我不能使用dragBoundFunc,因为它将限制时间线上所有节点的移动。

我试图使用dragmove事件更改元素的位置:

代码语言:javascript
复制
stage.on("dragmove", function(evt) {
  xaxis.y(0);
});

但是,X轴在拖曳舞台的同时,仍然向各个方向移动。

我也可以使用不同的拖放层作为轴和时间线本身,但当我拖动轴,它不会移动时间线和相同的,如果我移动时间线。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-01-24 15:14:42

作为最简单的解决方案,您只需确保您的时间差组的绝对位置相同:

代码语言:javascript
复制
stage.on("dragmove", function(evt) {
  // read absolute position
  const oldAbs = xaxis.absolutePosition();

  // set new absolute position, but make sure x = 0
  xaxis.absolutePosition({
   x: oldAbs.x,
   y: 0
  });
});
票数 3
EN

Stack Overflow用户

发布于 2020-01-24 11:19:40

这是一个稍微更有能力的版本,它允许事件层的垂直拖动,同时保持时间线轴可见以供参考。这使用两个层-一个作为包含时间线和网格的背景,而第二个层显示事件。

这里的关键技术是使用可拖事件层上的dragMove事件侦听器水平而不是垂直同步地移动背景层。同时,事件层还受到一个dragBound函数的约束,以阻止愚蠢的UX。

一个改进是在事件层中添加剪裁,这样当它向下拖动时,就不会模糊时间线。

代码语言:javascript
复制
var stageWidth = 800,
  stageHeight = 300,
  timeFrom = 1960,
  timeTo = 2060,
  timeRange = timeTo - timeFrom,
  timeLineWidth = 1000,
  timeSteps = 20, // over 100 yrs = 5 year intervals
  timeInt = timeRange / timeSteps,
  timeLineStep = timeLineWidth / timeSteps,
  yearWidth = timeLineWidth / timeRange,
  plotHeight = 500,
  events = [{
      date: 1964,
      desc: 'Born',
      dist: 10
    },
    {
      date: 1966,
      desc: 'England win world cup - still celebrating !',
      dist: 20
    },    
    {
      date: 1968,
      desc: 'Infant school',
      dist: 30
    },
    {
      date: 1975,
      desc: 'Secondary school',
      dist: 50
    },
    {
      date: 1981,
      desc: 'Sixth form',
      dist: 7
    },
    {
      date: 1983,
      desc: 'University',
      dist: 30
    },
    {
      date: 1986,
      desc: 'Degree, entered IT career',
      dist: 50
    },
    {
      date: 1990,
      desc: 'Marriage #1',
      dist: 0
    },
    {
      date: 1996,
      desc: 'Divorce #1',
      dist: 0
    },
    {
      date: 1998,
      desc: 'Marriage #2 & Son born',
      dist: 90
    },
    {
      date: 2000,
      desc: 'World did not end',
      dist: 20
    },    
    {
      date: 2025,
      desc: 'Retired ?',
      dist: 0
    },
    {
      date: 2044,
      desc: 'Enters Duncodin - retirement home for IT workers',
      dist: 0
    },
    {
      date: 2054,
      desc: 'Star dust',
      dist: 0
    }
  ]


function setup() {

  // Set up a stage and a shape
  stage = new Konva.Stage({
    container: 'konva-stage',
    width: stageWidth,
    height: stageHeight
  });

  // bgLayer is the background with the grid, timeline and date text.
  var bgLayer = new Konva.Layer({
    draggable: false
  })

  stage.add(bgLayer);

  for (var i = 0, max = timeSteps; i < max; i = i + 1) {
    bgLayer.add(new Konva.Line({
      points: [(i * timeLineStep) + 0.5, 0, (i * timeLineStep) + .5, plotHeight],
      stroke: 'cyan',
      strokeWidth: 1
    }))

    bgLayer.add(new Konva.Text({
      x: (i * timeLineStep) + 4,
      y: 260,
      text: timeFrom + (timeInt * i),
      fontSize: 12,
      fontFamily: 'Calibri',
      fill: 'magenta',
      rotation: 90,
      listening: false
    }));

  }

  for (var i = 0, max = plotHeight; i < max; i = i + timeLineStep) {
    bgLayer.add(new Konva.Line({
      points: [0, i + 0.5, timeLineWidth, i + .5],
      stroke: 'cyan',
      strokeWidth: 1
    }))
  }

  // add timeline
  var timeLine = new Konva.Rect({
    x: 0,
    y: 245,
    height: 1,
    width: timeLineWidth,
    fill: 'magenta',
    listening: false
  });
  bgLayer.add(timeLine)

  // eventLayer contains only the event link line and text.
  var eventLayer = new Konva.Layer({
    draggable: true,

    // the dragBoundFunc returns an object as {x: val, y: val} in which the x is constricted to stop
    // the user dragging out of sight, and the y is not allowed to change.
    // ! position of bgLayer is moved in x axis in sync with eventLayer via dragMove event 
    dragBoundFunc: function(pos) {
      return {

        x: function() {
          var retX = pos.x;
          if (retX > 20) { // if the left exceeds 20px from left edge of stage
            retX = 20;
          } else if (retX < (stageWidth - (timeLineWidth + 50))) { // if the right exceeds 50 px from right edge of stage
            retX = stageWidth - (timeLineWidth + 50);
          }
          return retX;
        }(),

        y: function() {
          var retY = pos.y;
          if (retY < 0) {
            retY = 0;
          } else if (retY > 200) {
            retY = 200;
          }
          return retY;
        }()

      };
    }
  });
  stage.add(eventLayer);

  // ! position of bgLayer is moved in x axis in sync with eventLayer via dragMove event of eventLayer.
  eventLayer.on('dragmove', function() {
    var pos = eventLayer.position();
    var bgPos = bgLayer.position();
    bgLayer.position({
      x: pos.x,
      y: bgPos.y
    }); // <--- move the bgLayer in sync with the event eventLayer.
    stage.draw()
  });

  for (var i = 0, max = events.length; i < max; i = i + 1) {
    var event = events[i];
    var link = new Konva.Rect({
      x: yearWidth * (event.date - timeFrom),
      y: 200 - event.dist,
      width: 1,
      height: 55 + event.dist,
      fill: 'magenta',
      listening: false
    });
    eventLayer.add(link)

    var eventLabel = new Konva.Text({
      x: yearWidth * (event.date - timeFrom) - 5,
      y: 190 - event.dist,
      text: event.date + ' - ' + event.desc,
      fontSize: 16,
      fontFamily: 'Calibri',
      fill: 'magenta',
      rotation: -90,
      listening: false
    });
    eventLayer.add(eventLabel);

    var dragRect = new Konva.Rect({
      x: 0,
      y: 0,
      width: timeLineWidth,
      height: 500,
      opacity: 0,
      fill: 'cyan',
      listening: true
    });
    eventLayer.add(dragRect);

    dragRect.moveToTop()
  }

  stage.draw()

}

var stage, eventLayer;

setup()
代码语言:javascript
复制
.konva-stage {
  width: 100%;
  height: 100%;
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/4.0.13/konva.js"></script>
<p>Drag the timeline left & right AND up & down...</p>
<div id="konva-stage"></div>

票数 2
EN

Stack Overflow用户

发布于 2020-01-27 11:08:34

只是为了好玩,我的答案的简化版本显示了ondrag()函数,而没有所有的时间线细节。

代码语言:javascript
复制
var stage;

function setup() {

  // Set up a stage and a shape
  stage = new Konva.Stage({
    container: 'konva-stage',
    width: 600,
    height: 300
  });

  // layer1.
  var layer1 = new Konva.Layer({
    draggable: false
  })

  stage.add(layer1);

  var ln1 = new Konva.Line({
    points: [10, 0, 10, 20, 10, 10, 0, 10, 20, 10],
    stroke: 'cyan',
    strokeWidth: 4
  });
  layer1.add(ln1);



  var layer2 = new Konva.Layer({
    draggable: true,
  });
  stage.add(layer2);


  var ln2 = new Konva.Line({
    points: [10, 0, 10, 20, 10, 10, 0, 10, 20, 10],
    stroke: 'magenta',
    strokeWidth: 4
  });
  layer2.add(ln2);

  // position the crosses on the canvas
  ln1.position({
    x: 100,
    y: 80
  });
  ln2.position({
    x: 100,
    y: 40
  });

  // ! position of layer1 is moved in x axis in sync with layer2 via dragMove event of layer2.
  layer2.on('dragmove', function() {
    var pos = layer2.position();
    var bgPos = layer1.position();
    layer1.position({
      x: pos.x,
      y: bgPos.y
    }); // <--- move  layer1 in sync with layer2.
    stage.draw()
  });

  stage.draw()
}


setup()
代码语言:javascript
复制
  .konva-stage {
  width: 100%;
  height: 100%;
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/4.0.13/konva.js"></script>
<p>Drag the upper cross - only one moves vertically whilst the other is contrained in the y-axis. Both move in sync on the x-axis</p>
<div id="konva-stage"></div>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59885608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档