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

news2024/12/24 0:00:51

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/95708.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端基础_传统Web页面

传统Web页面 传统Web页面就是打开浏览器&#xff0c;整个页面都会打开的应用。例如&#xff0c;笔者的个人网站http://siwei.me就是一个典型的“传统Web应用”&#xff0c;每次单击其中任意一个链接&#xff0c;都会引起页面的整个刷新 传统的页面每次打开&#xff0c;都要把…

π120E60 双通道数字隔离器 完美代替ISO7820FDW

π120E60 双通道数字隔离器 完美代替ISO7820FDW 。具有出色的性能特征和可靠性&#xff0c;整体性能优于光耦和基于其他原理的数字隔离器产品。产品传输通道间彼此独立&#xff0c;可实现多种传输方向的配置&#xff0c;可实现5.0kV rms 隔离耐压等级和 DC 到 200Mbps信号传输。…

Seata实现分布式事务控制

目录 1. 启动Seata 1.1 下载seata 1.2 修改配置文件及初始化 2. 使用Seata实现事务控制 2.1 初始化数据表 2.2 添加配置 1. 启动Seata 1.1 下载seata 下载地址&#xff1a;https://github.com/seata/seata/releases/v1.3.0/ 1.2 修改配置文件及初始化 将下载得到的…

安全智能分析 思路方案

数据共享 定义内涵 数据共享 是指在多个用户或多个程序之间遵循一定规则共同享用数据&#xff0c;并进行各种操作、运算和分析的一种技术。数据共享包括数据发布、接口、交换等内容。 技术背景 随着数字经济成为拉动全球经济增长的新引擎&#xff0c;大数据成为经济中重要的…

[附源码]Node.js计算机毕业设计个人资金账户管理Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

【OpenCV-Python】教程:6-3 Epipolar Geometry 对极几何

OpenCV Python Epipolar Geometry 对极几何 【目标】 学习多视图几何学习极点、对极线、对极约束等等&#xff1b; 【理论】 当我们使用针孔相机拍摄图像时&#xff0c;我们会丢失一个重要的信息&#xff0c;即图像的深度。或者图像中的每个点距离摄像机有多远&#xff0c;…

下一个AI舞台,名叫煤矿

如果大海给贝壳下的定义是珍珠&#xff0c;那么时间给煤的定义就是钻石。2020年初&#xff0c;我们曾经探访过山西一家大型矿山。矿山中的工程师对我们说&#xff0c;现在矿上特别需要新技术&#xff0c;需要数字化、智能化。但现在年轻人&#xff0c;尤其是懂AI、懂云计算的人…

Stm32旧版库函数16——stm32 超声波测距

/******************** (C) COPYRIGHT 2012 ELC ******************** * File Name : main.c * Author : ELCWHUT * Version : V1.0 * Date : 2012-12-05 * Description : 超声波测距的STM32代码&#xff0c;采用HC-HR04…

Git全栈体系(一)

第一章 Git 概述 Git 是一个免费的、开源的分布式版本控制系统&#xff0c;可以快速高效地处理从小型到大型的各种项目。Git 易于学习&#xff0c;占地面积小&#xff0c;性能极快。 它具有廉价的本地库&#xff0c;方便的暂存区域和多个工作流分支等特性。其性能优于 Subvers…

ArcGIS创建地理处理包!让你制作的工具自由分享

喜欢就关注我们吧&#xff01; 0 前言 当用模型做好工具 分享到其他电脑 出现的模型不可用的情况 就如我们上期制作分享 的提取四至点的工具 有这个红叉的情况 因为他用到了子模型 所以发生路径不一致的情况 只要编辑配置就好了 那如何从根本上解决这个问题呢 答案是…

大数据Kudu(八):Kudu与Impala整合

文章目录 Kudu与Impala整合 一、​​​​​​​Kudu与Impala整合配置

乌班图(ubantu)部署.NET Core 6web项目(保姆教程)

1、新建文件夹&#xff0c;给读写权限 $ cd / #移动根目录&#xff08;方便好找&#xff09; 文件夹授权方式1&#xff1a;命令 $ sudo mkdir www #新建文件夹 $ cd /www $ sudo chmod 777 * -R #给读写权限 2、上传打包的项目文件&#xff0c;并解压 安装解压工具 $ sudo …

线性代数之N维向量

向量空间是线性代数的重要研究对象&#xff0c;具有广泛的应用。 1 n维向量运算 向量既有大小又有方向&#xff0c;如下表示&#xff1a; m*n个数aij(i1,2,...,m;j1,2,...,n)排成m行n列的矩形数表 若向量大小相当&#xff0c;方向相同则着两个向量相等 n个数a1,a2,...,an组成的…

SQL执行顺序

目录 1.执行顺序 2.SELECT查询时的两个顺序 3.关联过程 1.执行顺序 我们先执行from,join来确定表之间的连接关系&#xff0c;得到初步的数据 where对数据进行普通的初步的筛选 group by 分组 各组分别执行having中的普通筛选或者聚合函数筛选。 然后把再根据我们要的数据进…

00后女记者的一场直播挑战,触动了多少城市年轻打工人的心

一、00后的女记者&#xff0c;在浙江的一个小镇做了一场直播挑战&#xff0c;几天的体验并不轻松&#xff0c;却打开了一个新世界。又或者说&#xff0c;她发现了生活的另一面&#xff0c;人生的另一种可能。这个名叫濮院的小镇&#xff0c;位于浙江北部&#xff0c;桐乡辖下&a…

测试员求职路漫漫其修远兮,HR眼中的你,为什么无人问津

&#x1f4cc; 博客主页&#xff1a; 程序员二黑 &#x1f4cc; 专注于软件测试领域相关技术实践和思考&#xff0c;持续分享自动化软件测试开发干货知识&#xff01; &#x1f4cc; 公号同名&#xff0c;欢迎加入我的测试交流群&#xff0c;我们一起交流学习&#xff01; 许多…

GrapeCity Documents .NET Bundle 6.0.0 Crack

GrapeCity 文档 .NET 包 6.0.0 添加新的图像查看器和数据查看器以及将 HTML 呈现为 PDF 的能力。2022 年 12 月 16 日 - 15:27 新版本特征 GrapeCity Word文档 您现在可以添加反射、发光、模糊、柔化边缘和填充叠加效果。报告模板 SVG 图像现在可以用作图像模板中的数据。有条件…

SOFA Weekly|Tongsuo 8.3.2 版本发布、C 位大咖说、本周 Contributor QA

SOFA WEEKLY | 每周精选 筛选每周精华问答&#xff0c;同步开源进展欢迎留言互动&#xff5e;SOFAStack&#xff08;Scalable Open Financial Architecture Stack&#xff09;是蚂蚁集团自主研发的金融级云原生架构&#xff0c;包含了构建金融级云原生架构所需的各个组件&#…

[附源码]Python计算机毕业设计Django宁财二手物品交易网站

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

换种方式看后端参数接收、建议躺着看!!!

持续创作&#xff0c;加速成长&#xff01;这是我参与「掘金日新计划 10 月更文挑战」的第1天&#xff0c;点击查看活动详情 常用的接收参数注解RequestParam PathVariable RequestBody 先看个例子RestController public class testController { RequestMapping(value "…