Canvas库 KonvaJS入门 2坐标体系总结

Posted 编程圈子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Canvas库 KonvaJS入门 2坐标体系总结相关的知识,希望对你有一定的参考价值。

Canvas库 KonvaJS入门 2坐标体系总结

一、 准备环境

KonvaJS的几个属性值与坐标都有关系,有时候不容易分清坐标如何计算,本文作个简单总结。
为调试方便,本文直接html引用 konvasjs库。

二、konvasJS坐标基本使用演示

1. 按坐标放置控件



<!DOCTYPE html>
<html>
  <head>
    <script src="https://unpkg.com/konva@8.3.14/konva.min.js"></script>
    <meta charset="utf-8" />
    <title>Konva Drag and Drop a Group Demo</title>
    <style>
      body 
        margin: 0;
        padding: 0;
        overflow: hidden;
        background-color: #f0f0f0;
      
    </style>
  </head>
  <body>
    <div id="container"></div>
    <script>
      var width = window.innerWidth;
      var height = window.innerHeight;

      var stage = new Konva.Stage(
        container: 'container',
        width: width,
        height: height,
      );

      var shapesLayer = new Konva.Layer();
      var group = new Konva.Group(
        draggable: true,
      );
      var colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'];

      for (var i = 0; i < 6; i++) 
        var box = new Konva.Rect(
          x: i * 30 + 10,
          y: i * 18 + 20,
          width: 100,
          height: 50,
          name: colors[i],
          fill: colors[i],
          stroke: 'black',
          strokeWidth: 0,
        );
        group.add(box);
      

      function printLog()
        const children = group.getChildren();
        console.info('group position', group.position());
        console.info('group absolutePosition', group.absolutePosition());
        console.info('group width', group.width());
        console.info('group height', group.height());
        console.info('group clipX', group.clipX());
        console.info('group getAbsoluteScale', group.getAbsoluteScale());
        console.info('group getClientRect', group.getClientRect());
      
      shapesLayer.add(group);
      stage.add(shapesLayer);
      printLog();
    </script>
  </body>
</html>


注意这时打印的坐标值:

group position x: 0, y: 0
group absolutePosition x: 0, y: 0
group width 0
group height 0
group clipX undefined
group getAbsoluteScale x: 1, y: 1
group getClientRect x: 10, y: 20, width: 250, height: 140
child0 position x: 10, y: 20
child0 absolutePosition x: 10, y: 20
child0 scale x: 1, y: 1
child0 width 100
child0 height 50

可以看到:

  • group的初始坐标全是0,因为group的坐标是相对于stage计算的;
  • group的width、height获取不到尺寸信息;
  • group可以通过getClientRect获取尺寸信息;

2. 移动group

给group添加事件:


<!DOCTYPE html>
<html>
  <head>
    <script src="https://unpkg.com/konva@8.3.14/konva.min.js"></script>
    <meta charset="utf-8" />
    <title>Konva Drag and Drop a Group Demo</title>
    <style>
      body 
        margin: 0;
        padding: 0;
        overflow: hidden;
        background-color: #f0f0f0;
      
    </style>
  </head>
  <body>
    <div id="container"></div>
    <script>
      var width = window.innerWidth;
      var height = window.innerHeight;

      var stage = new Konva.Stage(
        container: 'container',
        width: width,
        height: height,
      );

      var shapesLayer = new Konva.Layer();
      var group = new Konva.Group(
        draggable: true,
      );
      var colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'];

      for (var i = 0; i < 6; i++) 
        var box = new Konva.Rect(
          x: i * 30 + 10,
          y: i * 18 + 20,
          width: 100,
          height: 50,
          name: colors[i],
          fill: colors[i],
          stroke: 'black',
          strokeWidth: 0,
        );
        group.add(box);
      

      function printLog()
        const children = group.getChildren();
        console.info('group position', group.position());
        console.info('group absolutePosition', group.absolutePosition());
        console.info('child0 position', children[0].position());
        console.info('child0 absolutePosition', children[0].absolutePosition());
      

      group.on('mouseover', function () 
        document.body.style.cursor = 'pointer';
      );
      group.on('mouseout', function () 
        document.body.style.cursor = 'default';
      );
      group.on('dragend',function()
        printLog();
      );

      shapesLayer.add(group);
      
      stage.add(shapesLayer);
      printLog();
    </script>
  </body>
</html>

初始位置:

移动整个组:

可以看出分组坐标的变化:

  • group在这里的position,absolutePosition值是相同的;
  • 初始group的position,absolutePosition都是0,0;
  • 当移动分组时,分组的坐标是相对于起点在发生变化;

可以理解为:

  • 添加的新group,它的坐标起点都在左上角0,0处;
  • 移动group时,它的position,absolutePosition都是相对于上一层画布来计算的;这里的画面基础坐标是不会变的,所以两个属性值保持相等;
  • 子元素相对于group放置,它的x,y属性值一直相对于group起点来计算;
  • 子元素的absolutePosition是相对画布的真实坐标。

3. 父元素 scale 变化

测试代码:


<!DOCTYPE html>
<html>
  <head>
    <script src="https://unpkg.com/konva@8.3.14/konva.min.js"></script>
    <meta charset="utf-8" />
    <title>Konva Drag and Drop a Group Demo</title>
    <style>
      body 
        margin: 0;
        padding: 0;
        overflow: hidden;
        background-color: #f0f0f0;
      
    </style>
  </head>
  <body>
    <div id="container"></div>
    <script>
      var width = window.innerWidth;
      var height = window.innerHeight;

      var stage = new Konva.Stage(
        container: 'container',
        width: width,
        height: height,
      );

      var shapesLayer = new Konva.Layer();
      var group = new Konva.Group(
        draggable: true,
      );
      var colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'];

      for (var i = 0; i < 6; i++) 
        var box = new Konva.Rect(
          x: i * 30 + 10,
          y: i * 18 + 20,
          width: 100,
          height: 50,
          name: colors[i],
          fill: colors[i],
          stroke: 'black',
          strokeWidth: 0,
        );
        group.add(box);
      

      function printLog(index)
        const children = group.getChildren();
        console.info('group position', group.position());
        console.info('group absolutePosition', group.absolutePosition());
        console.info('group width', group.width());
        console.info('group height', group.height());
        console.info('group clipX', group.clipX());
        console.info('group getAbsoluteScale', group.getAbsoluteScale());
        console.info('group getClientRect', group.getClientRect());
        if(!index)index=0;
        console.info(`child$index position`, children[index].position());
        console.info(`child$index absolutePosition`, children[index].absolutePosition());
        console.info(`child$index scale`, children[index].scale());
        console.info(`child$index getAbsoluteScale`, children[index].getAbsoluteScale());
        console.info(`child$index width`, children[index].width());
        console.info(`child$index height`, children[index].height());
      

      group.on('mouseover', function () 
        document.body.style.cursor = 'pointer';
      );
      group.on('mouseout', function () 
        document.body.style.cursor = 'default';
      );
      group.on('click tap', function(t)
        console.info('click target', t.target);
        group.scale(x:2);
        printLog(t.target.index);
      );
      group.on('dragend',function()
        printLog();
      );

      shapesLayer.add(group);
      
      stage.add(shapesLayer);
      printLog();
    </script>
  </body>
</html>


总结:

  • 父层group的scale变化,不会影响子元素 position 的值;
  • 父层group的scale变化,会影响子元素absolutePosition的值;
  • 父层group的scale变化,不会影响子元素scale的值;
  • 父层group的scale变化,不会影响子元素尺寸值;
  • 父层group的scale变化,会影响父元素getClientRect尺寸值;
  • 父层group的scale变化,会影响子元素absoluteScale值。

4. 子元素scale变化


<!DOCTYPE html>
<html>
  <head>
    <script src="https://unpkg.com/konva@8.3.14/konva.min.js"></script>
    <meta charset="utf-8" />
    <title>Konva Drag and Drop a Group Demo</title>
    <style>
      body 
        margin: 0;
        padding: 0;
        overflow: hidden;
        background-color: #f0f0f0;
      
    </style>
  </head>
  <body>
    <div id="container"以上是关于Canvas库 KonvaJS入门 2坐标体系总结的主要内容,如果未能解决你的问题,请参考以下文章

Vue2-Canvas库 KonvaJS入门 1 安装与引用

Three.js 学习笔记--坐标体系和旋转

将 HTML Canvas 坐标系转换为笛卡尔坐标系

KonvaJS / HTML5 Canvas 无限滚动循环项目 - 无法克隆舞台并附加到顶部

canvas坐标体系+canvas画直线矩形圆

Flutter——Canvas自定义曲线图