当前位置: 首页 > news >正文

CocosCreator3.8研究笔记(二十一)CocosCreator Tween系统理解


在 Cocos Creator 3.x 版本中, Tween系统代替了原来的Action系统。很多朋友不明白Tween到底是什么,Tween原理是什么?怎么使用Tween?


今天就来详细了解一下,希望能帮助到大家加深对Tween的了解,并快速掌握Tween的使用方法。


一、Tween到底是什么?


Tween 又称为缓动系统,可以用于变换位置、旋转、缩放和颜色等常规动画信息,也支持延迟,队列,并行等动作行为。


首先我们来看一段案例代码:

tween(this.node)//to,在第1秒的时候放大为2倍,位置为(50,50),角度变化到90
.to(1,{scale:2,position:cc.v2(50,50),rotation:90})//by,在第2秒时,缩放变化了2倍(现在是原始大小的4倍),位置变化了(50,50),现在位置为(100,100)
.by(1,{scale:2, position:cc.v2(100,100)})//在第3秒时缩放为原始大小,位置设置为(0,0),然后加了一个缓动效果 backOut
.to(1,{scale:1,position:cc.v2(0,0)},{easing:"backOut"}).start();

通过上面演示的代码,我们可以知道,Tween可以同时设置多个属性, 在调用 start 时会将之前生成的 action 队列重新组合生成一个 cc.sequence 队列,依次执行。


Tween的特点

  • 支持以链式结构的方式创建一个动画序列

  • 不局限于节点上的属性


Tween有2种设置方式

  • to 改变到某个值(绝对值)

  • by 变化值(相对值)


二、Tween 缓动系统原理

为了加深理解,来看一张UML图:


![在这里插入图片描述](https://img-blog.csdnimg.cn/022bc559bbcb40ba83d6e47e8a80600c.png#pic_center)

此UML图中,Node(目标节点)、Action(动作) 、ActionManager(动作管理) 类, 相信大家都比较熟悉了,这里就不作介绍。

这里还涉及到一些比较新的内容:Tween 、TweenAction、props 、ITweenOption下面分别介绍。


1、Tween类是干嘛的?

通过上面UML 图的接口,我们可以清晰地看到,Tween其实有两个主要功能:

  • Action创建器,负责Action的创建

​ 在使用的时候,可以添加一个或者多个Action到内部缓冲,也可添加多个Action组合的串行Action或者并行Action。

  • 内部维护一个最终Action,可控制这个Action的启动与停止

Tween类重要成员属性:

  • _target: 目标对象,比如节点。
  • _actions: 类型为Action[],创建过程中的一组Action缓冲。
  • _finalAction: 创建完成之后的最终使用的Action。

Tween类重要接口:

  • target: 设置目标对象

  • delay: 添加一个DelayAction

  • to: 添加一个TweenAction来指定每个属性变换到多少-目标值

  • by: 添加一个TweenAction来指定每个属性变换多少-变化值

  • union: 将缓冲中的多个Action变成一个串行Action

  • sequence: 将指定的多个Action或者Tween变成一个串行Action后添加到缓冲中

  • parallel: 将指定的多个Action或者Tween变成一个并行Action后添加到缓冲中

  • start: 开始运行,此时会创建最终的Action,并且启动此Action

  • stop: 停止Action的运行


2、TweenAction是做什么的?

TweenAction类从ActionInterval派生,UML图中简化成从Action派生,能够针对目标对象的多个任意属性,以指定缓动方式进行变换。

只要目标对象的属性能够直接赋值和取值,这个TweenAction就能够胜任。

前面的Tween类by接口和to接口就是用TweenAction实现。

它的灵活和强大之处在于,不用像以前那样,每个属性都要实现重复代码的Action类。


3、props是什么?

props是TweenAction需要进行变换的属性。

props 本质就是一个键值对数据结构,键为对象的属性名称,值为进行变换的值。

例如:

{ angle: 90, position: v3(200, 200, 0)}

4、ITweenOption接口

ITweenOption接口,其实就是进行变换的缓动方式以及变换过程中的回调,从UML 图中我们也可以看到,

可以指定如下属性:

  • easing: 缓动方式

  • progress: 插值函数,用来自定义缓动方式

  • onStart: 缓动动作启动时的回调函数

  • onUpdate: 缓动动作更新时的回调函数

  • onComplete: 缓动动作完成时的回调函数


三、Tween 的使用


明白了Tween 的原理和重要的接口后,使用就比较简单了。


使用步骤可以简单分为三步:

Step1:创建一个针对目标的Tween对象

let tween = new Tween(this.node);

Step2:添加执行过程

tween.to(1.0, {angle:90,position:v3(100,100,0) });

Step3:开始执行tween对象

tween.start();

四、Tween的源码实现


如果想深入了解Tween的朋友,这里我贴了官方tween.ts和tween-action.ts 源码,建议花点时间完整的看一下,这样用起来会更加得心应手。


官方tween.ts源码:

/*Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.https://www.cocos.com/Permission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rights touse, copy, modify, merge, publish, distribute, sublicense, and/or sell copiesof the Software, and to permit persons to whom the Software is furnished to do so,subject to the following conditions:The above copyright notice and this permission notice shall be included inall copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS INTHE SOFTWARE.
*/import { warn } from '@base/debug';
import { cclegacy } from '@base/global';
import { TweenSystem } from './tween-system';
import { ActionInterval, sequence, repeat, repeatForever, reverseTime, delayTime, spawn } from './actions/action-interval';
import { removeSelf, show, hide, callFunc } from './actions/action-instant';
import { Action, FiniteTimeAction } from './actions/action';
import { ITweenOption } from './export-api';
import { TweenAction } from './tween-action';
import { SetAction } from './set-action';// https://medium.com/dailyjs/typescript-create-a-condition-based-subset-types-9d902cea5b8c
type FlagExcludedType<Base, Type> = { [Key in keyof Base]: Base[Key] extends Type ? never : Key };
type AllowedNames<Base, Type> = FlagExcludedType<Base, Type>[keyof Base];
type KeyPartial<T, K extends keyof T> = { [P in K]?: T[P] };
type OmitType<Base, Type> = KeyPartial<Base, AllowedNames<Base, Type>>;
// eslint-disable-next-line @typescript-eslint/ban-types
type ConstructorType<T> = OmitType<T, Function>;/*** @en* Tween provide a simple and flexible way to action, It's transplanted from cocos creator。* @zh* Tween 提供了一个简单灵活的方法来缓动目标,从 creator 移植而来。* @class Tween* @param [target]* @example* tween(this.node)*   .to(1, {scale: new Vec3(2, 2, 2), position: new Vec3(5, 5, 5)})*   .call(() => { log('This is a callback'); })*   .by(1, {scale: new Vec3(-1, -1, -1), position: new Vec3(-5, -5, -5)}, {easing: 'sineOutIn'})*   .start()*/
export class Tween<T> {private _actions: Action[] = [];private _finalAction: Action | null = null;private _target: T | null = null;private _tag = Action.TAG_INVALID;constructor (target?: T | null) {this._target = target === undefined ? null : target;}/*** @en Sets tween tag* @zh 设置缓动的标签* @method tag* @param tag @en The tag set for this tween @zh 为当前缓动设置的标签*/tag (tag: number): Tween<T> {this._tag = tag;return this;}/*** @en* Insert an action or tween to this sequence.* @zh* 插入一个 tween 到队列中。* @method then* @param other @en The rear tween of this tween @zh 当前缓动的后置缓动*/then (other: Tween<T>): Tween<T> {if (other instanceof Action) {this._actions.push(other.clone());} else {this._actions.push(other._union());}return this;}/*** @en* Sets tween target.* @zh* 设置 tween 的 target。* @method target* @param target @en The target of this tween @zh 当前缓动的目标对象*/target (target: T): Tween<T | undefined> {this._target = target;return this;}/*** @en* Start this tween.* @zh* 运行当前 tween。*/start (): Tween<T> {if (!this._target) {warn('Please set target to tween first');return this;}if (this._finalAction) {TweenSystem.instance.ActionManager.removeAction(this._finalAction);}this._finalAction = this._union();this._finalAction.setTag(this._tag);TweenSystem.instance.ActionManager.addAction(this._finalAction, this._target as any, false);return this;}/*** @en* Stop this tween.* @zh* 停止当前 tween。*/stop (): Tween<T> {if (this._finalAction) {TweenSystem.instance.ActionManager.removeAction(this._finalAction);}return this;}/*** @en* Clone a tween.* @zh* 克隆当前 tween。* @method clone* @param target @en The target of clone tween @zh 克隆缓动的目标对象*/clone (target: T): Tween<T> {const action = this._union();return tween(target).then(action.clone() as any);}/*** @en* Integrate all previous actions to an action.* @zh* 将之前所有的 action 整合为一个 action。*/union (): Tween<T> {const action = this._union();this._actions.length = 0;this._actions.push(action);return this;}/*** @en* Add an action which calculates with absolute value.* @zh* 添加一个对属性进行绝对值计算的 action。* @method to* @param duration @en Tween time, in seconds @zh 缓动时间,单位为秒* @param props @en List of properties of tween @zh 缓动的属性列表* @param opts @en Optional functions of tween @zh 可选的缓动功能* @param opts.progress @en Interpolation function @zh 缓动的速度插值函数* @param opts.easing @en Tween function or a lambda @zh 缓动的曲线函数或lambda表达式*/to (duration: number, props: ConstructorType<T>, opts?: ITweenOption): Tween<T> {opts = opts || Object.create(null);(opts as any).relative = false;const action = new TweenAction(duration, props, opts);this._actions.push(action);return this;}/*** @en* Add an action which calculates with relative value.* @zh* 添加一个对属性进行相对值计算的 action。* @method by* @param duration @en Tween time, in seconds @zh 缓动时间,单位为秒* @param props @en List of properties of tween @zh 缓动的属性列表* @param opts @en Optional functions of tween @zh 可选的缓动功能* @param [opts.progress]* @param [opts.easing]* @return {Tween}*/by (duration: number, props: ConstructorType<T>, opts?: ITweenOption): Tween<T> {opts = opts || Object.create(null);(opts as any).relative = true;const action = new TweenAction(duration, props, opts);this._actions.push(action);return this;}/*** @en* Directly set target properties.* @zh* 直接设置 target 的属性。* @method set* @param props @en List of properties of tween @zh 缓动的属性列表* @return {Tween}*/set (props: ConstructorType<T>): Tween<T> {const action = new SetAction(props);this._actions.push(action);return this;}/*** @en* Add a delay action.* @zh* 添加一个延时 action。* @method delay* @param duration @en Delay time of this tween @zh 当前缓动的延迟时间* @return {Tween}*/delay (duration: number): Tween<T> {const action = delayTime(duration);this._actions.push(action);return this;}/*** @en* Add a callback action.* @zh* 添加一个回调 action。* @method call* @param callback @en Callback function at the end of this tween @zh 当前缓动结束时的回调函数* @return {Tween}*/// eslint-disable-next-line @typescript-eslint/ban-typescall (callback: Function): Tween<T> {const action = callFunc(callback);this._actions.push(action);return this;}/*** @en* Add a sequence action.* @zh* 添加一个队列 action。* @method sequence* @param args @en All tween that make up the sequence @zh 组成队列的所有缓动*/sequence (...args: Tween<T>[]): Tween<T> {const action = Tween._wrappedSequence(...args);this._actions.push(action);return this;}/*** @en* Add a parallel action.* @zh* 添加一个并行 action。* @method parallel* @param args @en The tween parallel to this tween @zh 与当前缓动并行的缓动*/parallel (...args: Tween<T>[]): Tween<T> {const action = Tween._wrappedParallel(...args);this._actions.push(action);return this;}/*** @en* Add a repeat action.* This action will integrate before actions to a sequence action as their parameters.* @zh* 添加一个重复 action,这个 action 会将前一个动作作为他的参数。* @param repeatTimes @en The repeat times of this tween @zh 重复次数* @param embedTween @en Optional, embedded tween of this tween @zh 可选,嵌入缓动*/repeat (repeatTimes: number, embedTween?: Tween<T>): Tween<T> {/** adapter */if (repeatTimes === Infinity) {return this.repeatForever(embedTween);}const actions = this._actions;let action: any;if (embedTween instanceof Tween) {action = embedTween._union();} else {action = actions.pop();}actions.push(repeat(action, repeatTimes));return this;}/*** @en* Add a repeat forever action.* This action will integrate before actions to a sequence action as their parameters.* @zh* 添加一个永久重复 action,这个 action 会将前一个动作作为他的参数。* @method repeatForever* @param embedTween @en Optional, embedded tween of this tween @zh 可选,嵌入缓动*/repeatForever (embedTween?: Tween<T>): Tween<T> {const actions = this._actions;let action: any;if (embedTween instanceof Tween) {action = embedTween._union();} else {action = actions.pop();}actions.push(repeatForever(action as ActionInterval));return this;}/*** @en* Add a reverse time action.* This action will integrate before actions to a sequence action as their parameters.* @zh* 添加一个倒置时间 action,这个 action 会将前一个动作作为他的参数。* @method reverseTime* @param embedTween @en Optional, embedded tween of this tween @zh 可选,嵌入缓动*/reverseTime (embedTween?: Tween<T>): Tween<T> {const actions = this._actions;let action: any;if (embedTween instanceof Tween) {action = embedTween._union();} else {action = actions.pop();}actions.push(reverseTime(action as ActionInterval));return this;}/*** @en* Add a hide action, only for node target.* @zh* 添加一个隐藏 action,只适用于 target 是节点类型的。*/hide (): Tween<T> {const action = hide();this._actions.push(action);return this;}/*** @en* Add a show action, only for node target.* @zh* 添加一个显示 action,只适用于 target 是节点类型的。*/show (): Tween<T> {const action = show();this._actions.push(action);return this;}/*** @en* Add a removeSelf action, only for node target.* @zh* 添加一个移除自己 action,只适用于 target 是节点类型的。*/removeSelf (): Tween<T> {const action = removeSelf(false);this._actions.push(action);return this;}/*** @en* Add a destroySelf action, only for node target.* @zh* 添加一个移除并销毁自己 action,只适用于 target 是节点类型的。*/destroySelf (): Tween<T> {const action = removeSelf(true);this._actions.push(action);return this;}/*** @en* Stop all tweens* @zh* 停止所有缓动*/static stopAll (): void {TweenSystem.instance.ActionManager.removeAllActions();}/*** @en* Stop all tweens by tag* @zh* 停止所有指定标签的缓动*/// eslint-disable-next-line @typescript-eslint/ban-typesstatic stopAllByTag (tag: number, target?: object): void {TweenSystem.instance.ActionManager.removeAllActionsByTag(tag, target as any);}/*** @en* Stop all tweens by target* @zh* 停止所有指定对象的缓动*/// eslint-disable-next-line @typescript-eslint/ban-typesstatic stopAllByTarget (target?: object): void {TweenSystem.instance.ActionManager.removeAllActionsFromTarget(target as any);}private _union (): Action {const actions = this._actions;let action: Action;if (actions.length === 1) {action = actions[0];} else {action = sequence(actions);}return action;}private _destroy (): void {this.stop();}private static readonly _tmp_args: Tween<any>[] | Action[] = [];private static _wrappedSequence (...args: Action[] | Tween<any>[]): ActionInterval {const tmp_args = Tween._tmp_args;tmp_args.length = 0;for (let l = args.length, i = 0; i < l; i++) {const arg = tmp_args[i] = args[i];if (arg instanceof Tween) {tmp_args[i] = arg._union();}}return sequence.apply(sequence, tmp_args as any);}private static _wrappedParallel (...args: Action[] | Tween<any>[]): FiniteTimeAction {const tmp_args = Tween._tmp_args;tmp_args.length = 0;for (let l = args.length, i = 0; i < l; i++) {const arg = tmp_args[i] = args[i];if (arg instanceof Tween) {tmp_args[i] = arg._union();}}return spawn.apply(spawn, tmp_args as any);}
}
cclegacy.Tween = Tween;/*** @en* tween is a utility function that helps instantiate Tween instances.* @zh* tween 是一个工具函数,帮助实例化 Tween 实例。* @param target @en The target of the result tween @zh 缓动的目标* @returns Tween 实例* @example* tween(this.node)*   .to(1, {scale: new Vec3(2, 2, 2), position: new Vec3(5, 5, 5)})*   .call(() => { log('This is a callback'); })*   .by(1, {scale: new Vec3(-1, -1, -1)}, {easing: 'sineOutIn'})*   .start()*/
export function tween<T> (target?: T): Tween<T> {return new Tween<T>(target);
}
cclegacy.tween = tween;/*** @en* tweenUtil is a utility function that helps instantiate Tween instances.* @zh* tweenUtil 是一个工具函数,帮助实例化 Tween 实例。* @deprecated please use `tween` instead.*/
export function tweenUtil<T> (target?: T): Tween<T> {warn('tweenUtil\' is deprecated, please use \'tween\' instead ');return new Tween<T>(target);
}
cclegacy.tweenUtil = tweenUtil;

官方tween-action.ts源码:

/*Copyright (c) 2020-2023 Xiamen Yaji Software Co., Ltd.https://www.cocos.com/Permission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rights touse, copy, modify, merge, publish, distribute, sublicense, and/or sell copiesof the Software, and to permit persons to whom the Software is furnished to do so,subject to the following conditions:The above copyright notice and this permission notice shall be included inall copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS INTHE SOFTWARE.
*/import { warnID, warn } from '@base/debug';
import { VERSION } from '@base/global';
import { easing } from '../core';
import { ActionInterval } from './actions/action-interval';
import { ITweenOption } from './export-api';/** adapter */
function TweenEasingAdapter (easingName: string): string {const initialChar = easingName.charAt(0);if (/[A-Z]/.test(initialChar)) {easingName = easingName.replace(initialChar, initialChar.toLowerCase());const arr = easingName.split('-');if (arr.length === 2) {const str0 = arr[0];if (str0 === 'linear') {easingName = 'linear';} else {const str1 = arr[1];switch (str0) {case 'quadratic':easingName = `quad${str1}`;break;case 'quartic':easingName = `quart${str1}`;break;case 'quintic':easingName = `quint${str1}`;break;case 'sinusoidal':easingName = `sine${str1}`;break;case 'exponential':easingName = `expo${str1}`;break;case 'circular':easingName = `circ${str1}`;break;default:easingName = str0 + str1;break;}}}}return easingName;
}/** checker */
function TweenOptionChecker (opts: ITweenOption): void {const header = ' [Tween:] ';const message = ` option is not support in v + ${VERSION}`;const _opts = opts as unknown as any;if (_opts.delay) {warn(`${header}delay${message}`);}if (_opts.repeat) {warn(`${header}repeat${message}`);}if (_opts.repeatDelay) {warn(`${header}repeatDelay${message}`);}if (_opts.interpolation) {warn(`${header}interpolation${message}`);}if (_opts.onStop) {warn(`${header}onStop${message}`);}
}export class TweenAction extends ActionInterval {private _opts: any;private _props: any;private _originProps: any;constructor (duration: number, props: any, opts?: ITweenOption) {super();if (opts == null) {opts = Object.create(null);} else {/** checker */TweenOptionChecker(opts);/** adapter */if (opts.easing && typeof opts.easing === 'string') {opts.easing = TweenEasingAdapter(opts.easing) as any;}// global easing or progress used for this actionif (!opts.progress) {opts.progress = this.progress;}if (opts.easing && typeof opts.easing === 'string') {const easingName = opts.easing as string;opts.easing = easing[easingName];if (!opts.easing) { warnID(1031, easingName); }}}this._opts = opts;this._props = Object.create(null);for (const name in props) {// filtering if// - it was not own property// - types was function / string// - it was undefined / null// eslint-disable-next-line no-prototype-builtinsif (!props.hasOwnProperty(name)) continue;let value = props[name];if (typeof value === 'function') {value = value();}if (value == null || typeof value === 'string') continue;// property may have custom easing or progress functionlet customEasing: any; let progress: any;if (value.value !== undefined && (value.easing || value.progress)) {if (typeof value.easing === 'string') {customEasing = easing[value.easing];if (!customEasing) warnID(1031, value.easing);} else {customEasing = value.easing;}progress = value.progress;value = value.value;}const prop = Object.create(null);prop.value = value;prop.easing = customEasing;prop.progress = progress;this._props[name] = prop;}this._originProps = props;this.initWithDuration(duration);}clone (): TweenAction {const action = new TweenAction(this._duration, this._originProps, this._opts);this._cloneDecoration(action);return action;}startWithTarget (target: Record<string, unknown>): void {ActionInterval.prototype.startWithTarget.call(this, target);const relative = !!this._opts.relative;const props = this._props;for (const property in props) {const _t: any = target[property];if (_t === undefined) { continue; }const prop: any = props[property];const value = prop.value;if (typeof _t === 'number') {prop.start = _t;prop.current = _t;// eslint-disable-next-line @typescript-eslint/restrict-plus-operandsprop.end = relative ? _t + value : value;} else if (typeof _t === 'object') {if (prop.start == null) {prop.start = {}; prop.current = {}; prop.end = {};}for (const k in value) {// filtering if it not a number// eslint-disable-next-line no-restricted-globalsif (isNaN(_t[k])) continue;prop.start[k] = _t[k];prop.current[k] = _t[k];// eslint-disable-next-line @typescript-eslint/restrict-plus-operandsprop.end[k] = relative ? _t[k] + value[k] : value[k];}}}if (this._opts.onStart) { this._opts.onStart(this.target); }}update (t: number): void {const target = this.target;if (!target) return;const props = this._props;const opts = this._opts;let easingTime = t;if (opts.easing) easingTime = opts.easing(t);const progress = opts.progress;for (const name in props) {const prop = props[name];const time = prop.easing ? prop.easing(t) : easingTime;const interpolation = prop.progress ? prop.progress : progress;const start = prop.start;const end = prop.end;if (typeof start === 'number') {prop.current = interpolation(start, end, prop.current, time);} else if (typeof start === 'object') {// const value = prop.value;for (const k in start) {// if (value[k].easing) {//     time = value[k].easing(t);// }// if (value[k].progress) {//     interpolation = value[k].easing(t);// }prop.current[k] = interpolation(start[k], end[k], prop.current[k], time);}}target[name] = prop.current;}if (opts.onUpdate) { opts.onUpdate(this.target, t); }if (t === 1 && opts.onComplete) { opts.onComplete(this.target); }}progress (start: number, end: number, current: number, t: number): number {return current = start + (end - start) * t;}
}

相关文章:

CocosCreator3.8研究笔记(二十一)CocosCreator Tween系统理解

在 Cocos Creator 3.x 版本中&#xff0c; Tween系统代替了原来的Action系统。很多朋友不明白Tween到底是什么&#xff0c;Tween原理是什么&#xff1f;怎么使用Tween&#xff1f; 今天就来详细了解一下&#xff0c;希望能帮助到大家加深对Tween的了解&#xff0c;并快速掌握Tw…...

大数据学习-目录

学习内容持续更新ing 1.大数据学习1.0-Centos8虚拟机安装 大数据学习1.0-Centos8虚拟机安装_汉卿HanQ的博客-CSDN博客 2.大数据学习1.1-Centos8网络配置 大数据学习1.1-Centos8网络配置_汉卿HanQ的博客-CSDN博客 3.大数据学习1.2-yum配置 大数据学习1.2-yum配置_汉卿HanQ的…...

《动手学深度学习 Pytorch版》 7.5 批量规范化

7.5.1 训练深层网络 训练神经网络的实际问题&#xff1a; 数据预处理的方式会对最终结果产生巨大影响。 训练时&#xff0c;多层感知机的中间层变量可能具有更广的变化范围。 更深层的网络很复杂容易过拟合。 批量规范化对小批量的大小有要求&#xff0c;只有批量大小足够…...

Toaster - Android 吐司框架,专治 Toast 各种疑难杂症

官网 https://github.com/getActivity/Toaster 这可能是性能优、使用简单&#xff0c;支持自定义&#xff0c;不需要通知栏权限的吐司 想了解实现原理的可以点击此链接查看&#xff1a;Toaster 源码 集成步骤 如果你的项目 Gradle 配置是在 7.0 以下&#xff0c;需要在 bui…...

2023年9月26日,历史上的今天大事件早读

1620年9月26日大明皇帝朱常洛驾崩 1815年9月26日俄、普、奥三国在巴黎发表缔结“神圣同盟” 1841年9月26日清代思想家、诗人龚自珍逝世 1849年9月26日“生理学之父”巴甫洛夫诞生 1909年9月26日云南陆军讲武堂创办 1953年9月26日画家徐悲鸿逝世 1980年9月26日国际宇航联合…...

CListCtrl控件为只显示一列,持滚动显示其他,不用SetScrollFlags

CListCtrl控件为只显示一列,持滚动显示其他,不用SetScrollFlags 2023/9/5 下午4:52:58 如果您不希望使用 SetScrollFlags 函数来设置滚动条样式,可以使用以下代码将 CListCtrl 控件设置为只显示一列,并支持滚动显示其他内容: cpp // 设置控件样式和属性 m_listCtrl.Se…...

spring博客实现分页查询

1、首先创建dto下的分页类PageBean package com.zzz.blog.dto;import java.util.List;public class PageBean {private Integer pageSize; //页面大小private Integer currentPage; //当前页private Integer totalCount; //总条数private Integer totalPage; //总页数private …...

代码阅读分析神器-Scitools Understand

这里写目录标题 前言概要功能介绍1.代码统计2.图形化分析3.代码检查 使用方法下载及使用 前言 作为一名程序员&#xff0c;阅读代码是一个必须要拥有的能力&#xff0c;但无奈很多代码逻辑嵌套非常多&#xff0c;看起来非常吃力&#xff0c;看了那段逻辑就忘记了刚才的逻辑&am…...

学霸吐血整理‼《2023 年 IC 验证岗面试真题解析》宝藏干货!

Q1.定宽数组、动态数组、关联数组、队列各自的特点和使用方式。 Q2.fork…join/fork…join_any/fork…join_none 之间的异同 Q3.mailbox、event、semaphore 之间的异同 Q4.(event_handle)和 wait(event_handle.triggered)区别 Q5.task 和 function 异同区别 Q6.使用 clocking b…...

稳定性、可靠性、可用性、灵活性、解耦性

稳定性 平衡的能力 Linux系统的OOM机制、tcp的拥塞控制 可靠性 确定的能力 tcp的ACK、HA机制、加密 可用性 复原的能力 负债均衡、tcp的重传、冗余机制、故障域 灵活性 界限的能力 用户态、restful api、IP地址掩码 解耦性 不依赖的能力 分布式、SDN、容器、操作…...

docker搭建Redis三主三从

docker搭建Redis三主三从 首先启动6个redis进入容器构建主从关系连接进入6381作为切入点&#xff0c;查看集群状态 首先启动6个redis [rootdocker redis-node-1]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 …...

亚马逊要求的UL报告的产品标准是什么?如何区分

亚马逊为什么要求电子产品有UL检测报告&#xff1f; 首先&#xff0c;美国是一个对安全要求非常严格的国家&#xff0c;美国本土的所有电子产品生产企业早在很多年前就要求有相关安规检测。 其次&#xff0c;随着亚马逊在全球商业的战略地位不断提高&#xff0c;境外的电子设…...

如何在linux定时备份opengauss数据库(linux核心至少在GLIBC_2.34及以上)

前提环境&#xff0c;linux的核心至少在GLIBC_2.34及以上才能使用。 查看linux的glibc版本的命令如下 strings /lib64/libc.so.6 | grep GLIBC 如下图 或者用ldd --version 如下图 在官网下载对应的依赖包&#xff0c; 只需要这个lib文件即可&#xff0c;将这个包放在lin…...

SkyWalking快速上手(七)——Skywalking UI 界面简介

文章目录 前言1. 仪表盘1.1 指标展示1.2 自定义仪表盘 2. 拓扑图2.1 节点展示2.2 连接展示 3. 追踪3.1 请求链路3.2 请求详情 4. 性能剖析4.1 方法级别性能分析4.2 代码级别性能分析 5. 告警5.1 告警规则设置5.2 告警通知 6. 日志记录6.1 日志展示6.2日志分析6.3代码示例 总结 …...

python+vue驾校驾驶理论考试模拟系统

管理员的主要功能有&#xff1a; 1.管理员输入账户登陆后台 2.个人中心&#xff1a;管理员修改密码和账户信息 3.用户管理&#xff1a;管理员可以对用户信息进行添加&#xff0c;修改&#xff0c;删除&#xff0c;查询 4.添加选择题&#xff1a;管理员可以添加选择题目&#xf…...

go-redis 框架基本使用

文章目录 redis使用场景下载框架和连接redis1. 安装go-redis2. 连接redis 字符串操作有序集合操作流水线事务1. 普通事务2. Watch redis使用场景 缓存系统&#xff0c;减轻主数据库&#xff08;MySQL&#xff09;的压力。计数场景&#xff0c;比如微博、抖音中的关注数和粉丝数…...

java内嵌浏览器CEF-JAVA、jcef、java chrome

java内嵌浏览器CEF-JAVA、jcef、java chrome jcef是老牌cef的chrome内嵌方案&#xff0c;可以进行java-chrome-h5-桌面开发&#xff0c;下面为最新版本&#xff08;2023年9月22日10:33:07&#xff09; JCEF&#xff08;Java Chromium Embedded Framework&#xff09;是一个基于…...

string类模拟实现——C++

一、构造与析构 1.构造函数 构造函数需要尽可能将成员在初始化列表中初始化&#xff0c;string类的成员这里自定义的和顺序表相似&#xff0c;有_str , _size , _capacity , 以及一个静态成员 npos &#xff0c;构造函数这里实现两种&#xff0c;一种是传参为常量字符串的&am…...

在 SQL Server 中,可以使用加号运算符(+)来拼接字符串。但是,如果需要拼接多个字符串或表中的字段,就需要使用内置的拼接函数了

以下是 SQL Server 中的一些内置拼接函数&#xff1a; 1. CONCAT&#xff1a;将两个或多个字符串拼接在一起。语法为&#xff1a; CONCAT (string1, string2, ...)示例&#xff1a; SELECT CONCAT(Hello, , World) as combined_string;输出结果为&#xff1a;Hello World&a…...

蓝桥杯每日一题2023.9.25

4406. 积木画 - AcWing题库 题目描述 分析 在完成此问题前可以先引入一个新的问题 291. 蒙德里安的梦想 - AcWing题库 我们发现16的二进制是 10000 15的二进制是1111 故刚好我们可以从0枚举到1 << n(相当于二的n次方的二进制表示&#xff09; 注&#xff1a;奇数个0…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...