LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

LeaferJS 尝鲜 及 应用数学

freeflydom
2024年8月13日 13:30 本文热度 1345

前言

Leafer.js 是最近新开源的一个 2D 图形绘制库,根据宣传文章中所言:速度很快,性能极高,资源占用极低。

正好,本来也要记录一篇开发中在绘图时应用数学的笔记,同时尝试一下 leafer.js。

LeaferJS宣传文章:点击跳转

LeaferJS官网:点击跳转

官方基于 LeaferJS 实现的半成品:点击跳转 wodisign

Leafer 尝鲜

本篇只是尝鲜文章,初衷是记录一篇开发中遇到数学问题的笔记,所以不对过多用法进行讲解,如果感兴趣的人多,我再另出一篇。

安装 leafer-ui

Leafer UI 是基于 Leafer 开发的一套 UI 绘图框架,可结合 AI 绘图、生成界面,提供了常用的 UI 绘图组件,后面全部以 leafer 简称。

npm install leafer-ui

基本环境

为了方便测试,我直接通过 vue-cli 创建了一个项目

初始化一个 DOM 容器,并设置高度为 100%,  后续所有方法 我们默认放到 nextTick 中执行。

<script setup>

import { nextTick } from 'vue'

nextTick(()=> {})

</script>


<template>

  <main id="main"></main>

</template>


<style scoped>

#main {

  height: 100%;

}

</style>


创建一个应用

这里的创建一个应用,其实就是创建一个实例,或者说是画布,创建好画布之后,可以在画布上进行绘制元素。

创建画布时可以传入 widthheight 规定大小,如果不传则会自动计算容器的大小。

  const leafer = new Leafer({

// 挂载的元素,支持:window 、div、canvas 标签对象, 可使用id字符串

    view: 'main',

    // 默认是黑色画布,我们初始化成白色

    fill: '#fff',

    // 默认是 true, 设置为 false 后需要手动执行 start() 才能渲染

    // 当图形数量很多,异步创建完后,通过手动 start(),可以加快创建速度。

    start: false

  })


创建一个图形

Leafer 支持矩形、圆形、多边形、多角星形、直线

通过这些基础图形类型可以延伸出:圆角矩形、椭圆形、三角形、五角星等等...

当实际开发中,可以基于这些图形组合出各类各样的复合图形。

下面我们创建一个简单的圆形,将创建好的圆形实例添加到画布中即可

  const masterNode = new Ellipse({

    // x, y 的位置

    x: 100, 

    y: 100,

    // 背景色

    fill: '#32cd79',

    // 图形的宽、高

    width: 300,

    height: 300,

  });

  // 将图形添加到画布中

  leafer.add(masterNode);

  leafer.start();


实现效果

完成以上代码后,此时屏幕左上角会出现一个渲染好的圆形

设置样式

可以直接通过 masterNode.x=300 的方式进行修改,也可以通过 masterNode.set() 传入一个对象进行修改

下面这个示例我们将屏幕上的图形移动到屏幕的正中心

// 获取当前屏幕的大小

const width = window.innerWidth;

const height = window.innerHeight;


// 我们直接通过 set 方法修改图形

masterNode.set({

    x: width / 2 - masterNode.width / 2,

    y: height / 2 - masterNode.height / 2,

    // 背景色

    fill: "#91caff",

    // 边框颜色

    stroke: "#4096ff",

    // 边框的宽度

    strokeWidth: 2,

})


实现效果

节点平均分布

这是项目上的一个绘图问题,需求时 多个节点 围绕着 中心圆 在边缘进行平均分布。

需求类似于下图,是多个子节点围绕着圆心平均分布的网路图

刚一接到这个需求,就一个头两个大,由于节点是动态渲染,个数及内容不定,所以当时我就知道需要通过某种数学公式进行计算点位,然而本来就孱弱的数学,更是早就还给了老师。

实现思路

实际计算圆边任意点坐标是一个初中数学题,可以使用极坐标转换和三角函数来计算。

假设圆的圆心坐标为 (x0, y0),半径为 r,要求的点的角度为 θ(以弧度表示)

  1. 将极坐标转换为直角坐标系中的坐标,使用以下公式计算圆边上点的直角坐标:

x = x0 + r * cos(θ) 

y = y0 + r * sin(θ)


这可以计算出相对于圆心的偏移量,cos(θ)sin(θ) 分别代表给定角度 θ 的余弦和正弦值。

  1. 那么通过以上公式,我们只要知道 θ 就可以求出  x , y 的坐标了

我们需要先给定圆心坐标和角度,首先需要将角度转换为弧度,因为三角函数要求传入的是弧度。

通过以下公式计算出弧度 θ 的值

弧度 = 角度 * (π / 180)


具体实现

有了上面的实现思路,我们只要提供角度 与 圆心的坐标,即可计算出对应的点位。

同时因为我们需要平均分布,所以每个节点角度是 360 / 节点个数

const createChildNode = (leafer, masterNode, count) => {

  const baseNodeConf = {

    width: 40,

    height: 40,

    fill: "#b5f5ec",

    stroke: "#5cdbd3",

    strokeWidth: 2,

  }

  // 平均角度

  const baseAngle = 360 / count;

  // 计算圆心半径

  const rx = masterNode.width / 2;

  const ry = masterNode.height / 2;

  // 由于 Leafer 坐标是从左顶点开始,所以要加上半径才是圆心坐标

  const cx = masterNode.x + rx - (baseNodeConf.width / 2);

  const cy = masterNode.y + ry - (baseNodeConf.height / 2);

  for (let i = 0; i < count; i++) {

    // 每个节点的角度

    const angle = baseAngle * i;

    // 将角度转换为弧度:θ

    const radian = angle * (Math.PI / 180);

    // 将极坐标转换为直角坐标系中的坐标

    baseNodeConf.x = cx + rx * Math.cos(radian);

    baseNodeConf.y = cy + ry * Math.sin(radian);

    const circle = new Ellipse(baseNodeConf)

    leafer.add(circle)

  }

}


createChildNode(leafer, masterNode, 6)


实现效果

其他示例

对于这套公式,可以任意修改圆的大小及形状,节点都会平均分布, 例如椭圆形

同时,我还组合出了一个有趣的图形

完整代码

App.vue

<script setup>

import { nextTick } from 'vue'

import { createGraph } from './graph';

nextTick(()=> createGraph("main"))

</script>


<template>

  <main id="main"></main>

</template>


<style scoped>

#main {

  height: 100%;

}

</style>


graph.js

import { Ellipse, Leafer } from 'leafer-ui';


const createChildNode = (leafer, masterNode, count) => {

  const baseNodeConf = {

    width: 100,

    height: 100,

    fill: "#b5f5ec",

    stroke: "#5cdbd3",

    strokeWidth: 2,

  }

  // 设置基础角度

  const baseAngle = 360 / count;

  // 圆的半径

  const rx = masterNode.width / 2;

  const ry = masterNode.height / 2;

  // 圆心坐标

  const cx = masterNode.x + rx - baseNodeConf.width / 2;

  const cy = masterNode.y + ry - baseNodeConf.height / 2;

  for (let i = 0; i < count; i++) {

    // 当前角度

    const angle = baseAngle * i;

    // 将角度转换为弧度:θ

    const radian = angle * (Math.PI / 180);

    baseNodeConf.x = cx + rx * Math.cos(radian);

    baseNodeConf.y = cy + ry * Math.sin(radian);

    const circle = new Ellipse(baseNodeConf)

    leafer.add(circle)

  }

}


const createGraph = (view) => {

  // 实例应用

  const width = window.innerWidth;

  const height = window.innerHeight - 10;

  // 画布实例

  const leafer = new Leafer({

    view,

    width,

    height,

    fill: '#fff',

    wheel: { zoomMode: true },

    move: { dragEmpty: true },

    start: false

  })

  // 中心主节点

  const masterNode = new Ellipse({

    width: 200,

    height: 200,

    fill: "#91caff",

    stroke: "#4096ff",

    strokeWidth: 2,

  })

  // 这里单独设置是为了方便动态计算

  masterNode.set({

    x: width / 2 - masterNode.width / 2,

    y: height / 2 - masterNode.height / 2

  })

  // 添加主节点

  leafer.add(masterNode)

  // 添加环绕子节点

  createChildNode(leafer, masterNode, 20)

  // 启动应用

  leafer.start()

}


export { createGraph };


作者:子洋
链接:https://juejin.cn/post/7252251628090507301
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。



该文章在 2024/8/14 9:58:47 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved