图形系统开发实战课程:进阶篇(上)——7.图形交互操作: 视点控制与动画

本文主要是介绍图形系统开发实战课程:进阶篇(上)——7.图形交互操作: 视点控制与动画,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


[

图形开发学院|GraphAnyWhere

  • 课程名称:图形系统开发实战课程:进阶篇(上)
  • 课程章节:“图形交互操作: 视点控制与动画”
  • 原文地址:https://www.graphanywhere.com/graph/advanced/2-7.html

第七章 图形交互操作: 视点控制与动画

\quad 视点控制是指在图形系统中,通过调整视点的位置和角度,来改变用户观察图形的范围。本章我们讲述如何在图形初始化时控制图形视点,以及通过API控制图形视点。

1. 视图对象

\quad 在第二章 图形管理类(Graph)中讲述过图形管理对象相关的类包括:Graph类、Layer类、View类、GraphRenderer类,其中Graph类是这几个类的核心,负责构建另外几个类,并提供外部访问api接口;GraphRenderer类是负责图形的渲染过程、Layer类负责图层属性、图层数据和图层的渲染、View类负责图形的视点控制。

\quad 本节我们来讲述视图控制类 View,这几个类的关系如下图所示:

Graph
name:String
layers:Array
addLayer(layer)
removeLayer(layer)
render()
setView(view)
getCoordinateFromPixel(pixel)
getPixelFromCoordinate(coordinate)
GraphRenderer
mainCanvas:Canvas
getSize()
prepareFrame()
composeBuffer(frameState)
renderFrame()
filter()
View
center: [float,float]
resolutions:float
zoom: int
fill()
calculateCenterZoom()
getState()
Layer
source: Source
renderer: LayerRenderer
setStyle(style)
getVisible()
visibleAtResolution()
setOffset(x, y)

\quad 视图对象主要用于控制图形的显示范围。下图显示的是某个图形的全图,而红色框内的是当前屏幕中显示的内容,称之为当前视点范围或图形显示范围。

在这里插入图片描述

\quad 在第五章 图形交互操作:平移和缩放中,我们讲述过,实现图形的缩放与平移其核心思路是改变图形的显示范围,而不是改变图形中各图形对象的坐标值。图形显示范围(Extent) 是指图形在屏幕或窗口中的可视区域,是一个由显示的图形中最小坐标值(min)和最大坐标值(max)确定的矩形区域,图形显示范围采用图形坐标来表达,可记录为[minX, minY, maxX, maxY]

\quad 在SVG图形中,当前图形视点范围称之为 ViewBox,在SVG文件中由根节点的 viewBox 属性指定,例如 viewBox='40 20 300 200' ;此外还有一个 ViewPort 属性,指的是当前图形在浏览器中显示的宽度和高度,在SVG文件中由根节点的 widthheight 属性指定。

\quad anyGraph 中,也存在上述两个概念,图形显示范围 对应的就是 viewBox ,而 Canvas 画布大小对应的就是 viewPort。而 视图对象 除了包含图形显示范围这些属性之外,还提供了 视图约束 方面的属性。

1.1 属性

名称说明
center当前的中心点坐标
resolution当前的分辨率
viewPortSizeviewPort大小
resolutions图形分辨率数组
minResolution最小分辨率
maxResolution最大分辨率
extentConstrain允许显示的最大图形范围

说明:

  • center 和 resolution 这两个属性是View类中最常用的两个属性,表达的是当前图形显示范围的中心点坐标和分辨率;
  • viewPortSize viewPort大小,本质上就是Canvas尺寸;
  • resolutions 分辨率数组,常用于分级缩放的图形系统中,表达的是每一个缩放级别的分辨率;
  • minResolution 最小分辨率,是指在图形缩放时所允许的最小分辨率;
  • maxResolution 最大分辨率,是指在图形缩放时所允许的最大分辨率;
  • extentConstrain 属性用于约束图形移动的范围;

1.2 方法

名称说明
setCenter(center)设置中心点坐标
setResolution(resolution)设置当前分辨率
calculateCenterZoom(resolution, anchor)根据锚点和分辨率计算中心点
fill(extent, size)改变视图位置,根据四角坐标和窗口像素宽高
getExtent()获取图形显示范围
getCenter()获取中心点坐标
getResolution()返回当前的分辨率
getZoom()返还当前的zoom level

说明:

  • setCenter(center) 设置中心点坐标,该坐标将限制在 extentConstrain 范围内;
  • setResolution(resolution) 设置当前分辨率,分辨率也将限制在 minResolution 和 maxResolution的范围内;

2. 图形初始化时控制视点

\quad anyGraph 通过 视图对象(View) 控制图形的显示。在初始化 Graph 对象的时候如果指定了 view 属性,则按照 view 属性指定的信息显示图形。如果没有指定 view 属性,则默认按照图形坐标与 Canvas坐标 1:1 的方式显示图形,此外还提供了 fullView 属性,设置为 true 时可在初始化的时候显示全图。

\quad 下面我们通过几个示例来熟悉视图控制方面的功能。

2.1 显示默认图形

\quad 在初始化Graph对象时,如果没有指定任何显示相关的属性,图形初始化之后将按照图形坐标与Canvas坐标1:1的方式(即 resolution=1 )显示图形。如果图形的内容较多,这种方式只会显示图形的一部分。

\quad 下面这段代码在初始化时没有指定任何显示相关的属性,源代码如下:

<script type="module">import { Graph, VectorSource, Layer, debug } from "../../../src/index.js";// 初始化graph对象let graph = new Graph({"target": "graphWrapper","layers": [new Layer({source: new VectorSource({"fileUrl": "../../../data/geom.json"}),zIndex: 10010,name: "数据层"})]});// 显示辅助网格debug.generateGrid(Object.assign({ "interval": 10, "graph": graph }, graph.getSize()));// 图形渲染graph.render();
</script>

\quad 运行效果如下图所示:

在这里插入图片描述

2.2 显示全图

\quad 下面这个示例,在初始化 Graph 对象时,通过 fullView=true 属性,指定图形初始化之后显示全图,如果图形内容较少,则会放大图形充满整个Canvas画布,如果图形内容较多,则会缩小图形至Canvas画布中。

<script type="module">import { Graph, VectorSource, Layer, debug } from "../../../src/index.js";// 初始化graph对象let graph = new Graph({"target": "graphWrapper","fullView": true,"layers": [new Layer({source: new VectorSource({"fileUrl": "../../../data/geom.json"}),zIndex: 10010,name: "数据层"})]});// 显示辅助网格debug.generateGrid(Object.assign({ "interval": 10, "graph": graph }, graph.getSize()));// 图形渲染graph.render();
</script>

\quad 运行效果如下图所示:

在这里插入图片描述

2.3 显示指定位置

\quad 下面这个示例,在初始化Graph对象时,设置 view 属性,在该属性中指定了初始视图的中心点坐标 center 和分辨率 resolutionGraph 对象初始完成之后将按照这两个信息显示图形位置。

<script type="module">import { Graph, View, VectorSource, Layer, debug } from "../../../src/index.js";// 初始化graph对象let graph = new Graph({"target": "graphWrapper","fullView": true,"layers": [new Layer({source: new VectorSource({"fileUrl": "../../../data/geom.json"}),zIndex: 10010,name: "数据层"})],"view": new View({center: [220, 240],   // 初始中心点resolution: 0.5       // 初始分辨率})});// 显示辅助网格debug.generateGrid(Object.assign({ "interval": 10, "graph": graph }, graph.getSize()));// 图形渲染graph.render();
</script>

\quad 运行效果如下图所示:

在这里插入图片描述

3. 使用API控制视点

\quad Graph 类中包含了对 视图对象的实例,可通过 setView()getView() 方法设置和获取 视图对象,同时还提供了以下几个方法通过修改视图对象属性而控制图形的当前视点。

名称说明
showExtent(extent)设置图形显示范围,并重绘图形
setView(view)设置中心点和密度,并重绘图形
getFullExtent()根据各图层的数据计算当前图形的最大范围

3.1 显示全图

\quad 下面这段代码,可将当前图形的显示范围改变为显示全图。

let maxExtent = graph.getFullExtent();
graph.showExtent(maxExtent);

3.2 显示指定坐标

\quad 下面这段代码,可将当前图形的显示范围改变为显示指定坐标位置,并按指定分辨率控制图形大小。

let center = [280, 200];
let resolution = 0.25;
if (graph.getView().setResolution(resolution)) {graph.getView().setCenter(center);
}
graph.render();

3.3 显示指定范围

\quad 下面这段代码,可将当前图形的显示范围改变为显示指定的图形范围。

let extent = [200, 120, 400, 220];
graph.showExtent(extent);

4. 动画

\quad 在图形系统中,动画是由一系列叫做“帧(frame)”的图形组成的,通过一系列连续的画面来展示物体或场景的运动和变化。它们以一定的帧率(即每秒显示的帧数)进行播放,从而在视觉上呈现出连续的运动效果。

\quad 一帧即对应了一幅图形,在1秒内如果能够重复绘制15帧以上,图形看起来就不卡了,通常所说的60帧是指每秒重绘60次,这已经超过了人眼的极限,可以达到非常流畅的效果。

\quad 在图形系统开发实战课程-第八章动画 中讲述了在浏览器中实现动画功能的几种方法,分别是setInterval()setTimeout()requestAnimationFrame() 。从对动画的精确控制和节省计算机资源等角度,推荐在浏览器中使用requestAnimationFrame() 实现动画。

\quad 图形系统中通常按以下几个步骤实现动画:

  1. 清空Canvas
  2. 绘制当前帧图形
  3. 计算下一帧图形数据
  4. 循环,重复上述过程

\quad 直接使用 requestAnimationFrame() 实现动画时,需要在每一帧绘制完成后再次调用 requestAnimationFrame() 且需要自己编程实现帧率的控制,或是自己编码实现动画持续的时间等功能。anyGraph 中提供了一个 Animation 工具类,封装了这几个功能。

4.1 Animation 工具类

Animation 工具类提供了以下几个方法:

名称说明
start(callback, duration, frameRate)开始动画
stop(animationId)停止动画
frame(callback)显示一帧动画
start()

下表为该方法的参数:

名称说明
callback回调函数
duration持续时间
frameRate帧率

\quad 该方法用于开始一段动画,callback 参数用于指定回调函数,对于图形系统而言,我们在该回调方法中重绘图形。 duration 用于指定动画持续的时间,如果没有指定该参数,则动画一直重复下去,直至通过 stop 方法来停止该动画。 frameRate 用于指定帧率,即每秒执行的次数,对于某些不需要在1秒内频繁刷新的动画(例如时钟),我们可通过该参数来降低系统运行资源。

\quad 由于采用了 window.requestAnimationFrame(frame) 动画技术,该方式为根据屏幕刷新率控制帧率,因此屏幕刷新率即为最大帧率。

stop()

\quad 在执行 star() 方法开始一段动画时,star() 方法会返回一个整数类型的 “动画ID”,调用stop()方法时通过该 “动画ID” 结束该动画。

Animation源代码

\quad 以下为Animation的源代码:

/*** 动画工具类*/
const Animation = (function (window) {// 缺省帧率60帧/秒let TIME = Math.floor(1000 / 60);let stop, frame;let frames = {};let lastFrameTime = 0;let counter = 0;let loops = {};if (typeof window.requestAnimationFrame === 'function' && typeof window.cancelAnimationFrame === 'function') {frame = function (callback) {let id = Math.random();frames[id] = requestAnimationFrame(function onFrame(time) {if (lastFrameTime === time || lastFrameTime + TIME - 1 < time) {lastFrameTime = time;delete frames[id];callback();} else {frames[id] = requestAnimationFrame(onFrame);}});return id;};stop = function (id) {if (frames[id]) {cancelAnimationFrame(frames[id]);}delete loops[id];};} else {frame = function (callback) {return setTimeout(callback, TIME);};stop = function (timer) {delete loops[timer];return clearTimeout(timer);};}/*** 开始动画* @param {*} callback 绘制帧函数* @param {*} duration 持续时间(动画执行时长(秒))* @param {*} frameRate 帧率(每秒执行多少次)* @returns */function start(callback, duration=0, frameRate=0) {duration = duration > 0 ? duration : Number.POSITIVE_INFINITY;if(frameRate > 0) {TIME = Math.floor(1000 / frameRate);}let id = ++counter;let start = Date.now();loops[id] = function () {if (loops[id] && Date.now() - start <= duration) {callback();if (loops[id]) {frame(loops[id]);}} else {delete loops[id];}};frame(loops[id]);return id;}return { frame,     // 执行一次 callbackstart,     // 开始循环执行 callbackstop       // 停止动画};
}(window));

4.2 缓动功能

\quad 现实生活中,物体并不是突然启动或者停止, 当然也不可能一直保持匀速移动。就像我们 打开抽屉的过程那样,刚开始拉的那一下动作很快, 但是当抽屉被拉出来之后我们会不自觉的放慢动作。 或是掉落在地板上的物体,一开始下降的速度很快, 接着就会在地板上来回反弹直到停止。

\quad 缓动动画,指带有一定缓冲的动画,物体在一定时间内渐进加速或者减速,从而使动画更加的真实和自然。我们先感受一下使用缓动动画实现小球平移功能的示例。

在这里插入图片描述

\quad 在这个示例中,easeIn的小球刚开始启动很缓慢,然后逐渐加速,最终与其他小球同时到达终点;而 linear 行的小球则始终保持匀速移动。easeOut小球刚开始启动很快,然后逐渐减速,也是同时到达终点。

\quad 上述小球运动的缓动动画包括以下几个要点:

  1. 确定起点位置和终点位置,由于小球做的是水平运动,因此小球在运动前的X坐标均为50,结束时的坐标是800,Y坐标保持不变;
  2. 确定运动的时间或次数;在该示例中,小球在两秒内移动了10次到达了终点;
  3. 通过缓动函数计算每一次移动的距离;
  4. 绘制帧图形;

\quad 下面代码为一个水平运动的小球,源码如下:

<script type="module">import { Graph, Circle, debug, Animation, Easing } from "../../../src/index.js";// 初始化graph对象let graph = new Graph({"target": "graphWrapper"});// 增加数据层let layer = graph.addLayer({ "name": "数据层" });let ball = layer.getSource().add(new Circle({"x": 50,"y": 100,"radius": 20,"style": { "color": "none", "fillStyle": 1, "fillColor": "#FF0000" }}))// 动画相关变量let minX = 50, maxX = 800;let totalTimes = 10;let times = 0;let rafId = -1;// 绘制帧图形function frame() {// 计算小球移动的距离let dx = (maxX - minX) * Easing.easeIn(times / totalTimes);ball.moveTo(minX + dx, 100);// 图形渲染graph.render();// 动画停止条件if (times < totalTimes) {times++;} else {times = 0;Animation.stop(rafId);}}$("#btnStart").on("click", function () {times = 0;rafId = Animation.start(frame, 0, 5);});$("#btnStop").on("click", function () {Animation.stop(rafId);})
</script>

\quad anyGraph 将缓动函数封装到了工具类 Easing 中,Easing.easeIn()为缓入动画函数,该函数开始启动很缓慢然后逐渐加速,将该函数换成其他缓动函数就可以实现不同的动画效果。

\quad 缓动函数的实现比较多,有关这部分的内容请参见:缓动函数速查表。下面介绍几个最常见的缓动效果。

缓慢加速 easeIn

在这里插入图片描述

/*** 启动缓慢,后期加速快(加速曲线)* @param {number} t 输入参数(0至1之间). (0.1,   0.2,   0.3,   0.4,   0.5,   0.6,   0.7,   0.8,   0.9,   1.0)* @return {number}  返回参数(0至1之间). (0.001, 0.008, 0.026, 0.064, 0.125, 0.215, 0.343, 0.512, 0.729, 1.0)*/
function easeIn(t) {return Math.pow(t, 3);
}
缓慢减速 easeOut

在这里插入图片描述

/*** 启动加速快,结束缓慢(减速曲线)* @param {number} t 输入参数(0至1之间). (0.1,   0.2,   0.3,   0.4,   0.5,   0.6,   0.7,   0.8,   0.9,   1.0)* @return {number}  返回参数(0至1之间). (0.270, 0.488, 0.657, 0.784, 0.875, 0.936, 0.973, 0.992, 0.999, 1.0)*/
function easeOut(t) {return 1 - easeIn(1 - t);
}
匀速 linear

在这里插入图片描述

/*** 随着时间的推移保持恒定的速度(匀速)* @param {number} t 输入参数(0至1之间). (0.1,   0.2,   0.3,   0.4,   0.5,   0.6,   0.7,   0.8,   0.9,   1.0)* @return {number}  返回参数(0至1之间). (0.1,   0.2,   0.3,   0.4,   0.5,   0.6,   0.7,   0.8,   0.9,   1.0)*/
function linear(t) {return t;
}
先缓慢加速后缓慢减速 inAndOut

在这里插入图片描述

/*** 先缓慢加速后缓慢减速(加速减速曲线)* @param {number} t 输入参数(0至1之间). (0.1,   0.2,   0.3,   0.4,   0.5,   0.6,   0.7,   0.8,   0.9,   1.0)* @return {number}  返回参数(0至1之间). (0.028, 0.104, 0.215, 0.352, 0.5,   0.648, 0.784, 0.896, 0.972, 1.0)*/
function inAndOut(t) {return 3 * t * t - 2 * t * t * t;
}
来回运动 upAndDown

在这里插入图片描述

/*** 来回运动* @param {number} t 输入参数(0至1之间). (0.1,   0.2,   0.3,   0.4,   0.5,   0.6,   0.7,   0.8,   0.9,   1.0)* @return {number}  返回参数(0至1之间). (0.104, 0.352, 0.648, 0.896, 1.0,   0.896, 0.648, 0.352, 0.104, 0.0)*/
function upAndDown(t) {if (t < 0.5) {return inAndOut(2 * t);} else {return 1 - inAndOut(2 * (t - 0.5));}
}

5. 视图动画

\quad 在本章第三节中讲述了通过访问API控制视点,Graph类还提供了两个api用于进行视点控制,这两个方法在执行的时候应用了缓动的动画效果,使得在进行图形缩放和平移时可以产生更好的视觉效果。

名称说明
animailMove(center, resolution, duration)具有动画效果的图形移动
animailZoom(scale, anchor, duration)具有动画效果的图形缩放

5.1 平移动画

\quad animailMove() 方法中,通过使用 Animation 类和 Easing.easeOut() 减速缓动功能,实现了动画效果的图形移动,其源码如下:

/*** 具有动画效果的图形移动* @param {Coord} center 中心点坐标* @param {Number} resolution 新的分辨率,如果为空则不改变分辨率 * @param {int} duration 延时时间*/
animailMove(center, resolution, duration = 500) {let start = Date.now();let that = this;let originalCenter = this.getView().getCenter();let originalRes = this.getView().getResolution();// 开始动画Animation.start(function () {let drawTime = Date.now() - 1;let delta = Easing.easeOut((drawTime - start) / duration);let centerX = originalCenter[0] + delta * (center[0] - originalCenter[0]);let centerY = originalCenter[1] + delta * (center[1] - originalCenter[1]);that.getView().setCenter([centerX, centerY]);if (resolution != null && resolution > 0) {let res = originalRes + delta * (resolution - originalRes);that.getView().setResolution(res);}that.renderSync();}, duration);
}

\quad 在这个方法中,我们先记录当前的中心点坐标和分辨率,根据缓动方法计算当前中心点和目标点坐标之间的线性差值,计算当前分辨率和目标分辨率之间的线性差值,逐帧进行图形重绘,从而实现移动的动画效果。缺省动画时间为500毫秒,如果按照每秒60帧计算,这个过程共绘制了30次图形。

\quad 其调用示例如下:

let center = [280, 200];
let resolution = 0.25;
graph.animailMove(center, resolution, 600);

\quad 运行效果如下:

在这里插入图片描述

5.2 缩放动画

\quad animailZoom() 方法中,通过使用 Animation 类和 Easing.easeOut() 减速缓动功能,实现了动画效果的图形缩放,其源码如下:

/*** 具有动画效果的图形缩放* @param {Number} scale 缩放倍率 * @param {Coord} anchor 锚点坐标 */
animailZoom(scale = 1.5, anchor, duration = 500) {let originalRes = this.getView().getResolution();let targetRes = this.getView().getResolution() * scale;let start = Date.now();let that = this;// 缺省锚点为中心点if(anchor == null) {anchor = Extent.getCenter(this.getExtent());}// 开始动画Animation.start(function () {let drawTime = Date.now() - 1;let delta = Easing.easeOut((drawTime - start) / duration);let res = originalRes + delta * (targetRes - originalRes);let center = that.getView().calculateCenterZoom(res, anchor);that.getView().setCenter(center);that.getView().setResolution(res);that.renderSync();}, duration);
}

\quad 在这个方法中,我们先获取当前分辨率和计算目标分辨率,根据缓动方法计算当前分辨率和目标分辨率之间的线性差值,逐帧进行图形重绘,从而实现图形缩放的动画效果。缺省动画时间为500毫秒,如果按照每秒60帧计算,这个过程共绘制了30次图形。

\quad 其调用示例如下:

let scale = 1.5;  // 放大
// let scale = 0.67;  // 缩小
graph.animailZoom(scale);

\quad 运行效果如下:

在这里插入图片描述


\quad “图形系统实战开发-进阶篇 第七章 图形交互操作:视点控制与动画” 的内容讲解到这里就结束了,如果觉得对你有帮助有收获,可以关注我们的官方账号,持续关注更多精彩内容。

相关资料

▶ 系列教程及代码资料:https://GraphAnyWhere.com
▶ 图形系统开发实战课程:进阶篇(上)——前言
▶ 图形系统开发实战课程:进阶篇(上)——1.基础知识
▶ 图形系统开发实战课程:进阶篇(上)——2.图形管理类(Graph)
▶ 图形系统开发实战课程:进阶篇(上)——3.图层类(Layer)
▶ 图形系统开发实战课程:进阶篇(上)——4.图形基本形状
▶ 图形系统开发实战课程:进阶篇(上)——5.图形交互操作:平移和缩放
▶ 图形系统开发实战课程:进阶篇(上)——6.图形交互操作:拾取


作者信息

作者 : 图形开发学院
CSDN: https://blog.csdn.net/2301_81340430?type=blog
官网:https://graphanywhere.com

这篇关于图形系统开发实战课程:进阶篇(上)——7.图形交互操作: 视点控制与动画的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/750206

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount