图形系统开发实战课程:进阶篇(上)——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,     // 执行一次 callback
        start,     // 开始循环执行 callback
        stop       // 停止动画
    };
}(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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MAUI 需要先部署项目,然后才能进行调试。请在配置服务器中启动部署。

刚刚创建完MAUI项目&#xff0c;选中windows&#xff0c;运行的时候提示这个 解决方案 选择菜单【项目】-> 【概述】 打开界面如下 然后点击【发布】&#xff0c;再点击【添加发布配置文件】&#xff0c;再点【下一步】 然后就可以运行了

rabbitmq知识梳理

一.WorkQueues模型 Work queues&#xff0c;任务模型。简单来说就是让多个消费者绑定到一个队列&#xff0c;共同消费队列中的消息。 当消息处理比较耗时的时候&#xff0c;可能生产消息的速度会远远大于消息的消费速度。长此以往&#xff0c;消息就会堆积越来越多&#xff0c…

个人健康|个人健康管理小程序|基于微信小程序的个人健康管理系统设计与实现(源码+数据库+文档)

个人健康管理小程序目录 目录 基于微信小程序的个人健康管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、微信小程序前台 2、管理员后台 &#xff08;1&#xff09;用户信息管理 &#xff08;2&#xff09;运动教程管理 &#xff08;3&#xff09;公告…

10.vue学习笔记(组件数据传递-props回调函数子传父+透传Attributes+插槽slot)

文章目录 1.组件数据传递2.透传Attributes&#xff08;了解&#xff09;禁用Attributes继承 3.插槽slot3.1.插槽作用域3.2.默认内容3.3.具名插槽3.4.插槽中的数据传递3.5.具名插槽传递数据 1.组件数据传递 我们之前讲解过了组件之间的数据传递&#xff0c;props 和 自定义事件…

排序(9.17)

1.排序的概念及其运用 1.1排序的概念 排序 &#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性 &#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记…

【HarmonyOS】鸿蒙开发之Stage模型-应用配置文件——第4.2章

Stage模型-应用配置文件 AppScope -> app.json5&#xff1a;应用的全局配置信息entry&#xff1a;OpenHarmony工程模块&#xff0c;编译构建生成一个HAP包 build&#xff1a;用于存放OpenHarmony编译生成的hap包src -> main -> ets&#xff1a;用于存放ArkTS源码src …

linux卸载mysql8重装5

目录 背景操作卸载重装配置启动 背景 在linux&#xff08;阿里云ECS&#xff09;安装部署Hive时初始化Hive元数据库&#xff0c;遇到报错前一天两三小时没解决&#xff0c;问题定位为mysql&#xff0c;次日打算重装 操作 卸载 停止 MySQL 服务 systemctl stop mysql yum卸载…

外包干了三个月,技术退步明显。。。

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 先说一下自己的情况&#xff0c;普通本科&#xff0c;毕业后进入深圳某软件公司&#xff08;其实…

websocket入门及应用

websocket When to use a HTTP call instead of a WebSocket (or HTTP 2.0) WebSocket 是基于TCP/IP协议&#xff0c;独立于HTTP协议的通信协议。WebSocket 是双向通讯&#xff0c;有状态&#xff0c;客户端一&#xff08;多&#xff09;个与服务端一&#xff08;多&#xff09…

成都爱尔蔡裕主任讲解飞蚊症严重吗?不然自测看看

先来看看你有没有以下症状&#xff1a; 眼前有一会有一会没有的小阴影&#xff1b; 会跟随看的方向飘动&#xff1b; 有些清楚有些模糊&#xff1b; 有时大&#xff0c;有些小&#xff1b; 有时突然变大变明显&#xff1b; 有时聚在一起&#xff1b; 有时如雨点般还伴随…

Windows计划任务执行日志和文件输出路径修改

在日常工作中&#xff0c;针对需重复执行的操作&#xff0c;通常都会使用系统的任务计划程序功能&#xff1b; 1、大家可以运行中&#xff0c;执行taskschd.msc来调用任务计划程序对话窗口&#xff0c;也可以在服务器管理的-工具菜单中-选择任务计划程序来调用对话窗口。 2、…

Rust-windows安装环境

文章目录 前言一、Using rustup (Recommended)二、配置vscode解决办法&#xff1a;在终端依次运行如下两条指令&#xff1a; 总结 前言 Rust学习系列&#xff0c;之前介绍了macOS环境下的rust安装方式macOS rust安装。这篇学习windows的rust安装方式。 提示&#xff1a;以下是…

win11家庭版安装Docker启动一直Starting the Docker Engine...

越多越多的应用通过Docker方式来运行&#xff0c;确实Docker方式运行也很方便&#xff0c;都是一个独立的运行环境&#xff0c;部署也很方便。于是决定安装下Docker试试&#xff0c;之前用Docker的时候还是win10&#xff0c;现在win11了。 安装倒是可以安装上&#xff0c;但是…

OpenCV开发笔记(七十五):相机标定矫正中使用remap重映射进行畸变矫正

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://blog.csdn.net/qq21497936/article/details/136293833 各位读者&#xff0c;知识无穷而人力有穷&#xff0c;要么改需求&#xff0c;要么找专业人士&#xff0c;要么自己研究 红胖子(红模仿…

【C语言基础】:操作符详解(二)

文章目录 操作符详解一、上期扩展二、单目操作符三、逗号表达式四、下标访问[]、 函数调用()五、结构成员访问操作符六、操作符的属性&#xff1a;优先级、结合性1. 优先级2. 结合性 操作符详解 上期回顾&#xff1a;【C语言基础】&#xff1a;操作符详解(一) 一、上期扩展 …

YOLO学习中的琐碎知识点

目录 一、导入的库 二、名词介绍 &#xff08;1&#xff09;pytorch张量 &#xff08;2&#xff09;边界框&#xff08;bounding box&#xff09; 三、pycharm操作 &#xff08;1&#xff09;参数设置 四、文件认识 五、YOLO如何训练自己的模型 一、导入的库 import to…

五.AV Foundation 视频播放 - 标题和字幕

引言 本篇博客主要介绍使用AV Foundation加载视频资源的时候&#xff0c;如何获取视频标题&#xff0c;获取字幕并让其显示到播放界面。 设置标题 资源标题的元数据内容&#xff0c;我们需要从资源的commonMetadata中获取&#xff0c;在加载AVPlayerItem的时候我们已经指定了…

vue2实现无感刷新token

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 &#x1f4d8; 引言&#xff1a; &#x1f4…

大概了解一下G1收集器

在上一篇文章中&#xff08;链接&#xff1a;大概了解一下CMS收集器&#xff09;我们提到&#xff0c;CMS是一种主要针对旧生代对象进行回收的收集器。与CMS不同&#xff0c;G1号称“全功能的垃圾收集器”&#xff0c;对初生代内存和旧生代内存均进行管理。鉴于此&#xff0c;这…

如何多环境切换?如何在微服务配置多环境?

问题本质: nacos配置中心的配置是如何被项目读取到的&#xff1f;(nacos的配置中心和项目是如何联系的&#xff1f;) 注意&#xff1a;nacos有配置管理和服务管理&#xff0c;别弄混。自动注册的是服务管理&#xff01;&#xff01;&#xff01; 1. 如何注册到nacos服务管理中心…