Создание шаблона с помощью jQuery и повторение его на холстеJquery

Программирование на jquery
Ответить
Anonymous
 Создание шаблона с помощью jQuery и повторение его на холсте

Сообщение Anonymous »

Я работаю над алгоритмом размещения узоров для SVG на холсте, и это будет плагин WordPress. Я могу разместить SVG на холсте и вычислить значения ширины и высоты, однако, поскольку SVG имеет углубления и выступы, неправильно учитывать только ограничивающую рамку, поскольку этот метод создает промежутки между шаблонами. Я пытался разместить следующий узор правильно, учитывая реальные границы узора и занимаемую им площадь, но и с этим мне не удалось добиться желаемого результата. Фиксированное значение в любом случае не решает ситуацию, потому что у меня есть шаблоны с очень разными углублениями и выступами.
Вот изображение, которое я получил с помощью написанного мной кода:
Изображение

Это это изображение, которое я пытаюсь получить:
Изображение

Я какое-то время застрял на этом этапе проекта и больше не могу найти решение. Где я ошибаюсь? Я думаю, что мне нужна совершенно другая перспектива, потому что я не могу получить желаемый результат с помощью расчета площади, ширины и высоты. Может ли кто-нибудь мне помочь с этим?
Вот мои коды:

Код: Выделить всё

jQuery(document).ready(function($) {
const mainCanvas = $('#cmc-canvas')[0];
const mainCtx = mainCanvas.getContext('2d');
const svgElements = $('.cmc-svg-item');

if (svgElements.length === 0) {
return;
}

function loadAndDrawPattern() {
const tempCanvas = document.createElement('canvas');
const tempCtx = tempCanvas.getContext('2d');
let loadedSVGs = 0;

svgElements.each(function(index, imgElem) {
const svgSrc = $(imgElem).attr('src');
$.get(svgSrc, function(data) {
const svgElement = $(data).find('svg')[0];
if (svgElement) {
const svgData = new XMLSerializer().serializeToString(svgElement);
const svgBlob = new Blob([svgData], { type: 'image/svg+xml;charset=utf-8' });
const url = URL.createObjectURL(svgBlob);

const img = new Image();
img.onload = function() {
tempCtx.drawImage(img, 0, 0);
loadedSVGs++;
URL.revokeObjectURL(url);

if (loadedSVGs === svgElements.length) {
calculateRealDimensions(tempCanvas);
}
};

img.onerror = function() {
URL.revokeObjectURL(url);
};

img.src = url;
}
}).fail(function() {});
});
}

function calculateRealDimensions(tempCanvas) {
const imageData = tempCanvas.getContext('2d').getImageData(0, 0, tempCanvas.width, tempCanvas.height);
let minX = tempCanvas.width, minY = tempCanvas.height;
let maxX = 0, maxY = 0;

for (let y = 0; y < imageData.height; y++) {
for (let x = 0; x < imageData.width; x++) {
const alpha = imageData.data[(y * imageData.width + x) * 4 + 3];
if (alpha > 0) {
minX = Math.min(minX, x);
minY = Math.min(minY, y);
maxX = Math.max(maxX, x);
maxY = Math.max(maxY, y);
}
}
}

const realWidth = maxX - minX;
const realHeight = maxY - minY;

const patternCanvas = document.createElement('canvas');
patternCanvas.width = realWidth;
patternCanvas.height = realHeight;
const patternCtx = patternCanvas.getContext('2d');
patternCtx.drawImage(tempCanvas, minX, minY, realWidth, realHeight, 0, 0, realWidth, realHeight);

const patternArea = calculatePatternArea(patternCanvas);
fillCanvasWithDynamicPlacement(patternCanvas, patternArea);
}

function calculatePatternArea(tempCanvas) {
const ctx = tempCanvas.getContext('2d');
const imageData = ctx.getImageData(0, 0, tempCanvas.width, tempCanvas.height);
let pixelCount = 0;

for (let i = 0; i < imageData.data.length; i += 4) {
const alpha = imageData.data[i + 3];
if (alpha > 0) {
pixelCount++;
}
}

return pixelCount;
}

function fillCanvasWithDynamicPlacement(patternCanvas, patternArea) {
const patternWidth = patternCanvas.width;
const patternHeight = patternCanvas.height;
const mainCanvasWidth = mainCanvas.width;
const mainCanvasHeight = mainCanvas.height;

let currentX = 0;
let currentY = 0;

while (currentY < mainCanvasHeight) {
while (currentX < mainCanvasWidth) {
mainCtx.drawImage(patternCanvas, currentX, currentY, patternWidth, patternHeight);
currentX += patternWidth;
}
currentX = 0;
currentY += patternHeight;
}
}

loadAndDrawPattern();
});

Код, который я упростил и который работает в JSFiddle:

Код: Выделить всё

document.addEventListener('DOMContentLoaded', () =>  {
const mainCanvas = document.getElementById('cmc-canvas');
const mainCtx = mainCanvas.getContext('2d');
const svgString = `









































































`;

function loadSVGData(svgString, callback) {
const svgBlob = new Blob([svgString], { type: 'image/svg+xml' });
const url = URL.createObjectURL(svgBlob);
const img = new Image();
img.onload = function() {
callback(img);
URL.revokeObjectURL(url);
};
img.onerror = function() {
console.error('SVG yüklenemedi.');
URL.revokeObjectURL(url);
};
img.src = url;
}

function drawSVGOnCanvasRepeated() {
loadSVGData(svgString, (img) => {
const patternWidth = 100; // Desired width of each SVG pattern
const patternHeight = 100; // Desired height of each SVG pattern

let currentX = 0;
let currentY = 0;

while (currentY < mainCanvas.height) {
while (currentX <  mainCanvas.width) {
mainCtx.drawImage(img, currentX, currentY, patternWidth, patternHeight);
currentX += patternWidth;
}
currentX = 0;
currentY += patternHeight;
}
});
}

drawSVGOnCanvasRepeated();
});



Подробнее здесь: https://stackoverflow.com/questions/791 ... nto-canvas
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Jquery»