深入理解 copyWithin:提升JavaScript图形处理中数组数据的复用与变换能力

引言

copyWithin 是 JavaScript 中数组对象的一个实例方法,用于在数组内部进行元素的复制和移动。从数组的指定位置拷贝元素到另一个指定位置,覆盖原数组中的相应位置。它不会改变数组的长度。

copyWithin 方法解析

语法:

arr.copyWithin(target, start[, end])

参数:

  • target(必填):整数,指定复制操作的目标起始位置(索引),复制的元素将被放置在这个位置及其之后。如果 target 为负数,将从数组尾部开始计算,即 -1 表示最后一个元素的位置。

  • start(必填):整数,指定复制操作的源起始位置(索引),复制操作将从此位置开始读取元素。如果 start 为负数,同样从数组尾部开始计算。

  • end(可选):整数,指定复制操作的源结束位置(不包含),默认为数组长度。如果 end 为负数,从数组尾部开始计算。

行为:

copyWithin 方法将从 startend 之间的源数组元素(左闭右开区间)复制到 target 位置及其之后。如果 target 位于 startend 之间,被复制的元素会被覆盖。复制操作不会改变数组的长度。

常规的应用场景

1.数组元素移动与重排:

const arr = [1, 2, 3, 4, 5];// 将数组的前两个元素移动到末尾
arr.copyWithin(2, 0, 2);
console.log(arr); // 输出:[1, 2, 3, 4, 5]// 交换数组的第一和最后一个元素
arr.copyWithin(0, arr.length - 1, arr.length);
arr.copyWithin(arr.length - 1, 0, 1);
console.log(arr); // 输出:[5, 2, 3, 4, 1]

2.数组部分区域复制:

const source = [0, 1, 2, 3, 4, 5];
const target = new Array(10).fill(null);// 将源数组的部分区域复制到目标数组的指定位置
target.copyWithin(2, 0, 4, source);
console.log(target); // 输出:[null, null, 0, 1, 2, null, null, null, null, null]

3.数组填充与初始化:

const arr = new Array(5).fill(0);// 使用数组自身的元素填充数组
arr.copyWithin(0, 2, 4);
console.log(arr); // 输出:[2, 3, 2, 3, 0]// 使用数组的某个元素初始化数组
const pattern = [1, 2, 3];
const repeatedPattern = new Array(9).fill(null).map((_, i) => pattern[i % pattern.length]);
console.log(repeatedPattern); // 输出:[1, 2, 3, 1, 2, 3, 1, 2, 3]

4.数据结构调整与转换:

const data = [1, 2, 3, 4, 5, 6];// 将数组的奇数位置元素复制到偶数位置,形成交错数组
data.copyWithin(1, 0, data.length, 2);
console.log(data); // 输出:[1, 1, 3, 2, 5, 4]

图形编程应用场景

JavaScript 中的 copyWithin 方法虽然是数组操作的一部分,但其本身并不直接与图形应用程序相关联。然而,考虑到图形应用程序通常会涉及大量的数据结构操作,特别是与像素、顶点、颜色、纹理坐标等相关的数组,copyWithin 方法可以在某些特定场景下为图形编程提供便利。以下是一些可能的应用示例:

1. 图像像素数据操作:

在处理 Canvas 或 WebGL 中的图像像素数据时,通常会使用类型化数组(如 Uint8ClampedArrayFloat32Array)表示图像的二维像素矩阵。copyWithin 方法可以帮助快速复制或移动图像的部分区域,实现图像裁剪、复制、平移等效果。

// 假设 imageData 是 CanvasRenderingContext2D.getImageData() 返回的 ImageData 对象
const pixelData = imageData.data; // 类型化数组,表示像素数据// 将图像左上角 10x10 区域复制到右下角
pixelData.copyWithin(pixelData.length - 100, 0, 100);

2. 顶点数据重用与变换:

在 WebGL 程序中,顶点数据通常存储在数组或缓冲对象中。当需要创建相似形状的几何体(如多个位置稍有不同的立方体)时,可以先定义一个基础顶点数组,然后使用 copyWithin 方法复制并稍作调整,避免重复定义相同的顶点数据。

const baseVertices = new Float32Array([// 基础立方体顶点数据...
]);function createTranslatedCube(x, y, z) {const vertices = new Float32Array(baseVertices.length);// 复制基础顶点数据并平移vertices.copyWithin(0, 0, baseVertices.length);for (let i = 0; i < vertices.length; i += 3) {vertices[i] += x;vertices[i + 1] += y;vertices[i + 2] += z;}return vertices;
}// 创建两个位置不同的立方体顶点数据
const cube1Vertices = createTranslatedCube(0, 0, 0);
const cube2Vertices = createTranslatedCube(2, 0, 0);

3. 颜色或纹理数据调整:

在处理颜色数组(如用于绘制渐变或图案)或纹理坐标数组时,copyWithin 方法可用于快速复制和调整颜色序列或纹理坐标,实现重复图案的生成、颜色序列的反转等效果。

const gradientColors = [0xFF0000, 0x00FF00, 0x0000FF]; // 红绿蓝渐变// 创建一个反向的渐变颜色数组
const reversedGradient = new Uint32Array(gradientColors.length);
reversedGradient.copyWithin(0, gradientColors.length - 1, 0, gradientColors);

copyWithin 是JavaScript数组的一个内置方法,它允许我们直接在数组内部执行高效的元素移动和复制操作。在图形数据处理中,如处理像素数组、顶点坐标、颜色值序列等,这种方法可以极大地简化代码并提升性能。以下是如何利用 copyWithin 实现图形数据的高效剪切、复制与反转的技巧:

4.高效剪切

在图形数据处理中,有时需要对数组的一部分进行裁剪(剪切),即提取出一个子数组并保留其内容。copyWithin 可以帮助实现这一操作,通过指定源起始索引、目标起始索引以及要复制的元素数量,实现在原数组内的“自我剪切”。

const sourceArray = [/* 图形数据... */];
const cutStart = /* 起始索引 */;
const cutEnd = /* 结束索引 */;
const cutLength = cutEnd - cutStart;sourceArray.copyWithin(0, cutStart, cutEnd);// 现在,sourceArray包含了从cutStart到cutEnd的子数组内容

5.快速复制

复制图形数据子集是常见需求,比如复制特定区域的像素到另一位置,或者复制某个几何形状的顶点信息以创建副本。copyWithin 允许我们直接将数组的一部分复制到自身或其他数组的指定位置。

const sourceArray = [/* 图形数据... */];
const copyStart = /* 要复制的起始索引 */;
const copyEnd = /* 复制结束索引 */;
const copyLength = copyEnd - copyStart;
const targetStart = /* 目标位置起始索引 */;sourceArray.copyWithin(targetStart, copyStart, copyEnd); // 同一数组内复制// 或者,如果要复制到另一个数组:
const targetArray = new Array(sourceArray.length);
sourceArray.copyWithin(targetStart, copyStart, copyEnd, targetArray, 0); // 注意:此语法为ES202½提案中的Array.prototype.copyWithin()// 现在,源数组的部分内容被复制到了目标位置

6.轻松反转

图形数据的反转(例如,沿某轴翻转图像或颠倒顶点顺序)可以通过 copyWithin 实现。只需将数组的一半元素复制到另一半,同时调整索引来确保正确的反转顺序。

const arrayToReverse = [/* 图形数据... */];
const midIndex = Math.floor(arrayToReverse.length / 2);for (let i = 0; i < midIndex; i++) {const mirroredIndex = arrayToReverse.length - 1 - i;arrayToReverse.copyWithin(mirroredIndex, i, i + 1);
}// 现在,arrayToReverse已按中点对称反转

7.像素数据剪切

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');// 获取整个画布的像素数据
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const pixelData = imageData.data;// 剪切左上角100x100像素区域的数据
const cutSize = 100 * 4; // 像素数据每像素占4个字节(RGBA)
pixelData.copyWithin(0, 0, cutSize);// 重新设置剪切后的图像数据
imageData.data = pixelData.slice(0, cutSize);
ctx.putImageData(imageData, 0, 0);

8.像素数据复制与平移

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');// 获取源像素数据
const srcImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const srcPixelData = srcImageData.data;// 创建目标图像数据并复制源数据
const dstImageData = new ImageData(canvas.width, canvas.height);
const dstPixelData = dstImageData.data;
dstPixelData.set(srcPixelData);// 将源图像数据的左上角100x100区域复制到目标图像右下角
const copySize = 100 * 4;
const dstStartIndex = (canvas.width - 100) * 4 + (canvas.height - 100) * canvas.width * 4;
dstPixelData.copyWithin(dstStartIndex, 0, copySize);ctx.putImageData(dstImageData, 0, 0);

9.顶点数据复制与平移

const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);// 假设vertices是包含顶点数据的Float32Array
const vertices = new Float32Array([...]); // 顶点数据// 将顶点数据的前一半复制到后一半,实现水平镜像
const halfLength = vertices.length / 2;
vertices.copyWithin(vertices.length - halfLength, 0, halfLength);// 上传调整后的顶点数据到缓冲区
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

虽然 copyWithin 方法并非图形应用程序特有,但在处理与图形相关的数组数据时,它能够简化数据复制与移动的操作,提高代码的可读性和执行效率。实际应用中,应结合具体图形编程库或API的特性,合理利用 copyWithin 方法和其他数组操作方法来满足特定图形处理需求。

写在最后

总结来说,JavaScript 中的 copyWithin 方法主要用于数组内部的元素复制和移动操作,它简化了数组元素位置调整、部分区域复制、填充与初始化等场景的代码实现,增强了数组操作的灵活性和效率。在实际应用中,copyWithin 与数组的其他方法(如 slicesplice 等)结合使用,可以实现更复杂的数组数据处理逻辑。

喜欢的话帮忙点个赞 + 关注吧,将持续更新 JavaScript 相关的文章,还可以关注我的公众号 梁三石FE ,感谢您的关注~

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

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

相关文章

【uniapp】状态存储Pinia的使用,以及它的数据持久化

1、下载安装pinia&#xff0c;引入pinia //stores->index.ts import { createPinia } from pinia import persist from pinia-plugin-persistedstate //持久化插件// 创建 pinia 实例 const pinia createPinia() // 使用持久化存储插件 pinia.use(persist)// 默认导出&…

spark实验三-spark进阶编程

1&#xff0e;Spark编程统计各地区租房人数 实验目标&#xff1a; (1) 掌握在IntelliJ IDEA 中操作spark程序开发 (2) 打包程序提交集群运行 实验说明&#xff1a; 现有一份某省份各地区租房信息文件 house.txt&#xff0c;文件中共有8个数据字段&#xff0c;字段说明…

vue 项目中添加DES加密

vue 项目中添加DES加密 由于现在项目使用http协议&#xff0c;且登录界面是明文传输&#xff0c;项目真正上线后基本的密码传输都很不安全。 决定用前端框架加密后再进行传输&#xff0c;以提高密码传输过程中的安全性。 crypto-js 是一个流行的 JavaScript 加密库&#xff0…

vxe-vxe-toolbar中vxe-button选中切换status

1.VXE-Toolbar 在VXE-Toolbar中&#xff0c;可以使用vxe-button组件实现按钮的选中切换效果&#xff0c;并且可以根据不同的选中状态显示不同的样式。你可以通过设置status属性来控制按钮的选中状态&#xff0c;并通过监听按钮的点击事件来切换选中状态。需要在vxe-toolbar中添…

服务器配置ssh免密登录

需求:备份test10.22.33.96上的文件到 test10.22.33.97的定时脚本,需要使用scp命令传输文件,两台节点没有ssh互信,需要配置服务器之间的SSH互信为了让两台或多台服务器之间能够无密码自动登录 步骤1&#xff1a;生成密钥对 在每一台需要建立互信的服务器(test10.22.33.96)上执…

每日两题1

文章目录 使用最小花费爬楼梯91解码方法 使用最小花费爬楼梯 class Solution { public:int minCostClimbingStairs(vector<int>& cost) {if(cost.size() 2)return min(cost[0],cost[1]);vector<int> dp;dp.reserve(cost.size()1);dp[0] 0;dp[1] 0;for(int i…

【域适应】基于深度域适应MMD损失的典型四分类任务实现

关于 MMD &#xff08;maximum mean discrepancy&#xff09;是用来衡量两组数据分布之间相似度的度量。一般地&#xff0c;如果两组数据分布相似&#xff0c;那么MMD 损失就相对较小&#xff0c;说明两组数据/特征处于相似的特征空间中。基于这个想法&#xff0c;对于源域和目…

顶切,半顶切是什么意思?

齿轮加工及刀具中有一些特定名词或者叫法&#xff0c;不熟悉的小伙伴可能最开始会有一些困惑&#xff0c;这不&#xff0c;最近有小伙伴问了一个问题&#xff1a;顶切是说齿顶的倒角吗&#xff1f; 今天就给大家说说顶切和半顶切。 一、顶切 Topping 从字面上可以看到可以想到…

Swagger API 文档 | SpringCloudGateway 集成 SpringDoc

文章目录 工作原理方案 1:配置 swagger-ui.urls方案 2:通过路由定义动态配置具体案例第 1 步:导入代码第 2 步:配置 Swagger Url 列表第 3 步:启动程序第 4 步:查看注册中心第 5 步:访问网关 Swagger UI相关博文😎 本节目标: Spring Cloud Gateway 集成 SpringDoc,实…

MySQL的权限管理

MySQL的权限管理 在理解MySQL的权限管理之前&#xff0c;我们需要先了解其架构设计以及权限管理在该架构中的定位。 MySQL的架构设计 MySQL数据库系统采用了分层的架构设计&#xff0c;主要可以分为以下几个层级&#xff1a; 连接层&#xff1a;最外层&#xff0c;处理连接…

x264 8x8 水平预测汇编分析

C 语言代码 void s264_predict_8x8_h_c( pixel *src, pixel edge[36] ) { PREDICT_8x8_LOAD_LEFT #define ROW(y) MPIXEL_X4( srcy*FDEC_STRIDE0 ) \ MPIXEL_X4( srcy*FDEC_STRIDE4 ) PIXEL_SPLAT_X4( l##y ); ROW(0); ROW(1); ROW(2); ROW(3); ROW(4); ROW(5); ROW(6); ROW(7…

VUE3:自定义loading指令

一、效果描述 在一个div中使用该指令并绑定一个变量&#xff0c;通过修改变量实现Loading的显示与隐藏。 二、代码与使用方式 1.使用指令的vue组件 <template><div v-loading"showLoading"></div> </template> <script setup lang&q…

爬虫 selenium

爬虫 selenium 【一】介绍 【1】说明 Selenium是一款广泛应用于Web应用程序测试的自动化测试框架 它可以模拟用户再浏览器上的行为对Web应用进行自动化测试 主要作用&#xff1a; 浏览器控制&#xff1a;启动、切换、关闭不同浏览器元素定位于操作&#xff1a;通过CSS选择器…

vscode中运行js

vscode中运行js 目前vscode插件运行js都是基于node环境&#xff0c;vscode控制台打印有些数据不方便等缺点。 每次调试在浏览器中运行js&#xff0c;需要创建html模板、插入js。期望能够直接运行js可以打开浏览器运行js&#xff0c;在vscode插件市场找到一款插件可以做到。 插…

yolo系列(之一)

深度学习经典检测算法 two-stage (两阶段) : Faster-rcnn Mask-Rcnn系列 &#xff08;输入图像---》CNN特征---》预选框---》输出结果&#xff09; one-stage (单阶段): YOLO系列 &#xff08;输入图像---》CNN特征---》输出结果&#xff09; one-stage的特点&#xff1a;&…

深度学习学习日记4.15 (面向GPT学习)

精确学习时间&#xff08;09点35分开始&#xff09; 深度学习 torch.nntorch.utils.datanumpytorchvision中的模块有哪些os 模块PIL&#xff08;Python Imaging Library&#xff09;tqdmmatplotlibnn.ReLU inplace参数设为Truenn.relu 训练的迭代过程梯度清零loss指标计算为什…

2024 蓝桥打卡Day40

2021、2022年蓝桥杯真题练习 2021年蓝桥杯真题练习A ASCB 卡片C 查找D 货物摆放F 时间显示H 杨辉三角形 2022年蓝桥杯真题练习A 星期计算B 山C 字符统计D 最少刷题数E 求阶乘 2021年蓝桥杯真题练习 A ASC package THL_0412;public class A_2021 {public static void main(Str…

SQLite超详细的编译时选项(十六)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite数据库文件格式&#xff08;十五&#xff09; 下一篇&#xff1a;SQLite 在Android安装与定制方案&#xff08;十七&#xff09; 1. 概述 对于大多数目的&#xff0c;SQLite可以使用默认的 编译选项。但是…

WinForms 零基础进阶教程:文件操作与 CSV 处理

文章目录 文件操作数据存储与文件操作文件存取的好处文件存取的方式文本文件的写入和读取文本文件的删除、复制和移动 目录的操作文件属性操作文件路径 对话框OpenFileDialog对话框SaveFileDialog对话框对话框中CheckPathExists属性的应用 CSV 文件读写与 DataGridView 进阶Dat…

Python基于Django的微博热搜、微博舆论可视化系统

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…