Canvas库 KonvaJS入门 2坐标体系总结
- 一、 准备环境
- 二、konvasJS坐标基本使用演示
- 1. 按坐标放置控件
- 2. 移动group
- 3. 父元素 scale 变化
- 4. 子元素scale变化
- 5. 旋转
一、 准备环境
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"></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});t.target.scale({x:2});printLog(t.target.index);});group.on('dragend',function(){printLog();});shapesLayer.add(group);stage.add(shapesLayer);printLog();</script></body>
</html>
总结:
- 子元素 scale 的变化 ,不会影响自身尺寸;
5. 旋转
- 旋转时,width,height不会发生变化 ;
- 父元素旋转时,子元素的{x,y}不会变化 , absolutePosition会发生变化 ;
- 旋转是以左上角为中心;
- 旋转后position和absolutePosition都不会发生变化