Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"rollup": "^3",
"rollup-plugin-binary2base64": "1.0.3",
"rollup-plugin-glslify": "^1.3.1",
"rollup-plugin-swc3": "^0.8.0",
"rollup-plugin-swc3": "^0.11.0",
"ts-node": "^10",
"typescript": "^4.8.3"
},
Expand Down
3 changes: 2 additions & 1 deletion packages/atlas-browser/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ export async function pack(images: PackingItem[], option?: PackingOption): Promi
const outPut: PackingOutput = {
code: ErrorCode.Success,
msg: "打包成功!",
info: {}
format: 1,
atlasItems: []
};
const context = { option, images, outPut };
for (let i = 0; i < packingPipe.length; i++) {
Expand Down
4 changes: 0 additions & 4 deletions packages/atlas-browser/src/interface/PackingContext.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { Rect } from "@galacean/tools-atlas-algorithm";
import { PackingOption } from "../interface/PackingOption";
import { PackingItem } from "./PackingItem";
import { PackingOutput } from "./PackingOutput";

export interface PackingContext {
images: PackingItem[];
option: PackingOption;
rects?: Rect[];
exportWidth?: number;
exportHeight?: number;
outPut?: PackingOutput;
}
17 changes: 10 additions & 7 deletions packages/atlas-browser/src/interface/PackingOutput.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { Rect } from "@galacean/tools-atlas-algorithm";

/**
* 打包的阶段产物
*/
export interface PackingOutput {
msg?: string;
code?: number;
usage?: number;
width?: number;
height?: number;
packedItem?: any[];
info?: {
imageFiles?: Array<ArrayBuffer>;
atlasFile?: string;
};
format?: number;
atlasItems?: {
img: string;
rects: Rect[];
blob: Blob;
width: number;
height: number;
}[];
}
151 changes: 47 additions & 104 deletions packages/atlas-browser/src/opt/OptDrawing.ts
Original file line number Diff line number Diff line change
@@ -1,109 +1,65 @@
import { ErrorCode } from "../enum/ErrorCode";
import { PackingContext } from "../interface/PackingContext";
import { PackingItem } from "../interface/PackingItem";
import { ErrorCode } from "../enum/ErrorCode";
import { OptHandler } from "./OptHandler";

export class OptDrawing extends OptHandler {
private canvas: OffscreenCanvas | HTMLCanvasElement;
private context2D:
| CanvasRenderingContext2D
| OffscreenCanvasRenderingContext2D;

parse(context: PackingContext): ErrorCode | Promise<ErrorCode> {
this.initCanvas(context.exportWidth, context.exportHeight);
const { context2D } = this;
// .atlas 对象
const atlasObj = { atlasItems: <any>[], format: 1 };
const item = {
img: `./temp.png`,
sprites: <any>[],
};
atlasObj.atlasItems.push(item);
const { rects, images } = context;
const { sprites } = item;
const { padding } = context.option;
for (let i = 0, l = rects.length; i < l; ++i) {
const rect = rects[i];
sprites.push({
name: rect.name,
atlasRotated: rect.isRotated,
atlasRegion: {
x: rect.x,
y: rect.y,
w: rect.width,
h: rect.height,
},
originalSize: {
w: rect.width,
h: rect.height,
},
});
private context2D: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;

const name = rect.name;
const image = this.getImage(images, name);
if (image) {
const { width: imgW, height: imgH } = image;
const { x: sX, y: sY } = rect;
context2D.drawImage(image, 0, 0, imgW, imgH, sX, sY, imgW, imgH);
async parse(context: PackingContext): Promise<ErrorCode> {
const { atlasItems } = context.outPut;
// 生成多张图集
for (let i = 0; i < atlasItems.length; i++) {
const atlasItem = atlasItems[i];
this.initCanvas(atlasItem.width, atlasItem.height);
const { context2D } = this;
const { images } = context;
const { padding } = context.option;
const { rects } = atlasItem;
for (let i = 0, l = rects.length; i < l; ++i) {
const rect = rects[i];
const name = rect.name;
const image = this.getImage(images, name);
if (image) {
const { width: imgW, height: imgH } = image;
const { x: sX, y: sY } = rect;
context2D.drawImage(image, 0, 0, imgW, imgH, sX, sY, imgW, imgH);

// Handle padding pixels.
if (padding > 0) {
try {
for (let i = 1; i <= padding; ++i) {
// Set top and bottom.
const topY = sY - i;
const bottomY = sY + imgH + i - 1;
context2D.drawImage(image, 0, 0, imgW, 1, sX, topY, imgW, 1);
context2D.drawImage(
image,
0,
imgH - 1,
imgW,
1,
sX,
bottomY,
imgW,
1
);
// Handle padding pixels.
if (padding > 0) {
try {
for (let i = 1; i <= padding; ++i) {
// Set top and bottom.
const topY = sY - i;
const bottomY = sY + imgH + i - 1;
context2D.drawImage(image, 0, 0, imgW, 1, sX, topY, imgW, 1);
context2D.drawImage(image, 0, imgH - 1, imgW, 1, sX, bottomY, imgW, 1);

// Set left and right.
const leftX = sX - i;
const rightX = sX + imgW + i - 1;
context2D.drawImage(image, 0, 0, 1, imgH, leftX, sY, 1, imgH);
context2D.drawImage(
image,
imgW - 1,
0,
1,
imgH,
rightX,
sY,
1,
imgH
);
// Set left and right.
const leftX = sX - i;
const rightX = sX + imgW + i - 1;
context2D.drawImage(image, 0, 0, 1, imgH, leftX, sY, 1, imgH);
context2D.drawImage(image, imgW - 1, 0, 1, imgH, rightX, sY, 1, imgH);
}
} catch (error) {
console.error(JSON.stringify(error));
}
} catch (error) {
console.error(JSON.stringify(error));
}
}
}

atlasItem.blob = await this.canvasToBlob();
}
return ErrorCode.Success;
}

return new Promise<ErrorCode>((resolve, reject) => {
canvasToBlob(): Promise<Blob> {
return new Promise((resolve, reject) => {
if (this.canvas instanceof HTMLCanvasElement) {
this.canvas.toBlob(
(blob) => {
blob
.arrayBuffer()
.then((value: ArrayBuffer) => {
context.outPut.info.imageFiles = [value];
context.outPut.info.atlasFile = JSON.stringify(atlasObj);
resolve(ErrorCode.Success);
})
.catch((reason: any) => {
console.error(JSON.stringify(reason));
reject(ErrorCode.CanvasBlobError);
});
resolve(blob);
},
"image/png",
1
Expand All @@ -112,17 +68,7 @@ export class OptDrawing extends OptHandler {
this.canvas
.convertToBlob({ type: "image/png", quality: 1 })
.then((blob) => {
blob
.arrayBuffer()
.then((value: ArrayBuffer) => {
context.outPut.info.imageFiles = [value];
context.outPut.info.atlasFile = JSON.stringify(atlasObj);
resolve(ErrorCode.Success);
})
.catch((reason: any) => {
console.error(JSON.stringify(reason));
reject(ErrorCode.OffscreenBlobError);
});
resolve(blob);
})
.catch((reason: any) => {
console.error(JSON.stringify(reason));
Expand Down Expand Up @@ -151,14 +97,11 @@ export class OptDrawing extends OptHandler {
this.canvas.width = exportWidth;
this.canvas.height = exportHeight;
}
this.context2D = this.canvas.getContext("2d") as
this.context2D = this.canvas.getContext("2d", { willReadFrequently: true }) as
| CanvasRenderingContext2D
| OffscreenCanvasRenderingContext2D;
} else {
if (
this.canvas.width !== exportWidth ||
this.canvas.height !== exportHeight
) {
if (this.canvas.width !== exportWidth || this.canvas.height !== exportHeight) {
this.canvas.width = exportWidth;
this.canvas.height = exportHeight;
} else {
Expand Down
26 changes: 10 additions & 16 deletions packages/atlas-browser/src/opt/OptLoadImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,11 @@ export class OptLoadImage extends OptHandler {
reject(new Error("Failed to load image buffer"));
};
img.onload = function () {
// Call requestAnimationFrame to avoid iOS's bug.
requestAnimationFrame(() => {
img.onload = null;
img.onerror = null;
img.onabort = null;
item.image = img;
resolve(img);
});
img.onload = null;
img.onerror = null;
img.onabort = null;
item.image = img;
resolve(img);
};
img.crossOrigin = "anonymous";
img.src = URL.createObjectURL(blob);
Expand All @@ -68,14 +65,11 @@ export class OptLoadImage extends OptHandler {
reject(new Error("Failed to load image buffer"));
};
img.onload = function () {
// Call requestAnimationFrame to avoid iOS's bug.
requestAnimationFrame(() => {
img.onload = null;
img.onerror = null;
img.onabort = null;
item.image = img;
resolve(img);
});
img.onload = null;
img.onerror = null;
img.onabort = null;
item.image = img;
resolve(img);
};
img.crossOrigin = "anonymous";
img.src = item.src as string;
Expand Down
Loading