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都不会发生变化