Anonymous
Canvas SVG манипуляции и GLSL
Сообщение
Anonymous » 19 июл 2025, 00:04
Я пытаюсь построить 3D -приложение конфигуратора, которое вы можете выбрать шаблон или наклейку и т. Д., И оно применимо к модели. холст, но это очень медленное, неэффективное, плохое разрешение, и не все SVG работают < /p>
Есть ли способ сделать это лучше?
Спасибо < /p>
Код: Выделить всё
export const drawPatternsOnCanvas = (ctx, itemsOnTshirt, uvConditions) => {
itemsOnTshirt.forEach((item) => {
if (item.type !== "pattern" || !item.img) return;
const uv = uvConditions[item.part];
if (!uv) return;
const canvasSize = 100;
const img = new Image();
img.src = item.pattern; //item.pattern="/pattern/pattern01.svg"
img.crossOrigin = "anonymous";
img.onload = () => {
const minX = uv[0];
const maxX = uv[1];
const minY = uv[2];
const maxY = uv[3];
const regionWidth = maxX - minX;
const regionHeight = maxY - minY;
const coloredPattern = document.createElement("canvas");
coloredPattern.width = img.width;
coloredPattern.height = img.height;
const cpCtx = coloredPattern.getContext("2d");
cpCtx.drawImage(img, 0, 0);
cpCtx.globalCompositeOperation = "source-atop";
cpCtx.fillStyle = `rgb(${Math.floor(item.color[0] * 255)}, ${Math.floor(
item.color[1] * 255
)}, ${Math.floor(item.color[2] * 255)})`;
cpCtx.fillRect(0, 0, img.width, img.height);
cpCtx.globalCompositeOperation = "source-over";
const fillPattern = ctx.createPattern(coloredPattern, "repeat");
if (fillPattern.setTransform) {
const rotationDegrees = parseFloat(item.rotation) || 0;
const patternRatioX = img.width / canvasSize;
const patternRatioY = img.height / canvasSize;
const center = canvasSize * 0.5;
const matrix = new DOMMatrix()
.translateSelf(center, center)
.rotateSelf(-rotationDegrees)
.scaleSelf(item.scale / patternRatioX, -item.scale / patternRatioY)
.translateSelf(item.moveX * canvasSize, item.moveY * canvasSize)
.translateSelf(-center, -center);
fillPattern.setTransform(matrix);
}
ctx.save();
ctx.beginPath();
ctx.rect(minX, minY, regionWidth, regionHeight);
ctx.clip();
ctx.fillStyle = fillPattern;
ctx.fillRect(minX, minY, regionWidth, regionHeight);
ctx.restore();
};
});
};
< /code>
Это код, который подразумевает шаблон SVG в Canvas < /p>
export const createUnifiedCanvasTexture = (
uvConditions,
colorsForparts,
itemsOnTshirt
) => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const width = (canvas.width = 1000);
const height = (canvas.height = 1000)
//drawing colors
drawUVRegions(ctx, uvConditions, colorsForparts);
// Draw patterns
drawPatternsOnCanvas(ctx, itemsOnTshirt, uvConditions);
//inside color
ctx.fillStyle = "#ffffff";
ctx.fillRect(1, 180, 124, -179);
const texture = new THREE.CanvasTexture(canvas);
texture.flipY = false;
texture.needsUpdate = true;
return texture;
};
И это мой основной холст, который подключен к шейдерам и модели
Подробнее здесь:
https://stackoverflow.com/questions/797 ... n-and-glsl
1752872645
Anonymous
Я пытаюсь построить 3D -приложение конфигуратора, которое вы можете выбрать шаблон или наклейку и т. Д., И оно применимо к модели. холст, но это очень медленное, неэффективное, плохое разрешение, и не все SVG работают < /p> Есть ли способ сделать это лучше? Спасибо < /p> [code]export const drawPatternsOnCanvas = (ctx, itemsOnTshirt, uvConditions) => { itemsOnTshirt.forEach((item) => { if (item.type !== "pattern" || !item.img) return; const uv = uvConditions[item.part]; if (!uv) return; const canvasSize = 100; const img = new Image(); img.src = item.pattern; //item.pattern="/pattern/pattern01.svg" img.crossOrigin = "anonymous"; img.onload = () => { const minX = uv[0]; const maxX = uv[1]; const minY = uv[2]; const maxY = uv[3]; const regionWidth = maxX - minX; const regionHeight = maxY - minY; const coloredPattern = document.createElement("canvas"); coloredPattern.width = img.width; coloredPattern.height = img.height; const cpCtx = coloredPattern.getContext("2d"); cpCtx.drawImage(img, 0, 0); cpCtx.globalCompositeOperation = "source-atop"; cpCtx.fillStyle = `rgb(${Math.floor(item.color[0] * 255)}, ${Math.floor( item.color[1] * 255 )}, ${Math.floor(item.color[2] * 255)})`; cpCtx.fillRect(0, 0, img.width, img.height); cpCtx.globalCompositeOperation = "source-over"; const fillPattern = ctx.createPattern(coloredPattern, "repeat"); if (fillPattern.setTransform) { const rotationDegrees = parseFloat(item.rotation) || 0; const patternRatioX = img.width / canvasSize; const patternRatioY = img.height / canvasSize; const center = canvasSize * 0.5; const matrix = new DOMMatrix() .translateSelf(center, center) .rotateSelf(-rotationDegrees) .scaleSelf(item.scale / patternRatioX, -item.scale / patternRatioY) .translateSelf(item.moveX * canvasSize, item.moveY * canvasSize) .translateSelf(-center, -center); fillPattern.setTransform(matrix); } ctx.save(); ctx.beginPath(); ctx.rect(minX, minY, regionWidth, regionHeight); ctx.clip(); ctx.fillStyle = fillPattern; ctx.fillRect(minX, minY, regionWidth, regionHeight); ctx.restore(); }; }); }; < /code> Это код, который подразумевает шаблон SVG в Canvas < /p> export const createUnifiedCanvasTexture = ( uvConditions, colorsForparts, itemsOnTshirt ) => { const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); const width = (canvas.width = 1000); const height = (canvas.height = 1000) //drawing colors drawUVRegions(ctx, uvConditions, colorsForparts); // Draw patterns drawPatternsOnCanvas(ctx, itemsOnTshirt, uvConditions); //inside color ctx.fillStyle = "#ffffff"; ctx.fillRect(1, 180, 124, -179); const texture = new THREE.CanvasTexture(canvas); texture.flipY = false; texture.needsUpdate = true; return texture; }; [/code] И это мой основной холст, который подключен к шейдерам и модели Подробнее здесь: [url]https://stackoverflow.com/questions/79706741/canvas-svg-manipulation-and-glsl[/url]