Заполните белую часть изображения за пределами границ — обрежьте изображение с помощью CSS-преобразованийCSS

Разбираемся в CSS
Ответить Пред. темаСлед. тема
Anonymous
 Заполните белую часть изображения за пределами границ — обрежьте изображение с помощью CSS-преобразований

Сообщение Anonymous »

У меня есть DIV-контейнер и изображение внутри него.
Изображение имеет CSS-преобразования, такие как: перемещение, поворот, масштабирование.
Изображение может перетаскиваться пользователем. (и масштабирован, повернут) в родительском div. Иногда части изображения могут находиться за пределами родительского элемента div.
Я хочу создать новое изображение, идентичное по размеру исходному изображению (без применения поворота и масштабирования). ), но часть изображения (повернутая/масштабируемая) из элемента div, которая не видна, в конечном изображении должна быть полностью белой.
Позвольте мне показать, что я хочу получить с помощью изображения:
Изображение

I пробовал разные методы, но мне не удалось получить желаемый результат.
Вот код, который я придумал (также с помощью ChatGPT)

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




Dynamic Image Transformation and Cropping

body {
font-family: Arial, sans-serif;
margin: 20px;
}
.container {
width: 300px; /* You can change this to any size */
height: 300px; /* You can change this to any size */
border: 2px solid #000;
position: relative;
overflow: hidden;
margin-bottom: 20px;
}
.container img {
width: 150px; /* You can change this to any size */
height: 150px; /* You can change this to any size */
/* Apply CSS transformations */
transform: translate(-30px, -30px) rotate(45deg) scale(1.2);
transform-origin: center center;
position: absolute;
top: 0;
left: 0;
}
#buttons {
margin-bottom: 20px;
}
#tempCanvases {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
#tempCanvases canvas {
border: 1px solid #ccc;
}



Dynamic Image Transformation and Cropping

[img]https://sodevrom.net/your-image.jpg[/img]

Process
Download

Temporary Canvases (For Debugging)


// Wait for the DOM to load
document.addEventListener('DOMContentLoaded', () => {
const processButton = document.getElementById('processButton');
const downloadButton = document.getElementById('downloadButton');
const tempCanvasesDiv = document.getElementById('tempCanvases');
const sourceImage = document.getElementById('sourceImage');
let finalCanvas = null; // To store the final processed canvas

processButton.addEventListener('click', () =>  {
// Clear previous temporary canvases
tempCanvasesDiv.innerHTML = '';
finalCanvas = null;
downloadButton.disabled = true;

// Step 1: Get container and image dimensions
const container = sourceImage.parentElement;
const containerWidth = container.clientWidth;
const containerHeight = container.clientHeight;

const imageNaturalWidth = sourceImage.naturalWidth;
const imageNaturalHeight = sourceImage.naturalHeight;

const imageRenderedWidth = sourceImage.width;
const imageRenderedHeight = sourceImage.height;

console.log('Container Dimensions:', containerWidth, containerHeight);
console.log('Image Natural Dimensions:', imageNaturalWidth, imageNaturalHeight);
console.log('Image Rendered Dimensions:', imageRenderedWidth, imageRenderedHeight);

// Step 2: Get computed styles of the image
const style = window.getComputedStyle(sourceImage);
const transform = style.transform;

// If no transform is applied, set it to identity matrix
const matrix = transform === 'none' ? new DOMMatrix() : new DOMMatrix(transform);

// Extract transformation components
const scaleX = matrix.a;
const scaleY = matrix.d;
const rotateRadians = Math.atan2(matrix.b, matrix.a);
const rotateDegrees = rotateRadians * (180 / Math.PI);
const translateX = matrix.e;
const translateY = matrix.f;

console.log('Extracted Transformations:');
console.log('ScaleX:', scaleX);
console.log('ScaleY:', scaleY);
console.log('Rotate (degrees):', rotateDegrees);
console.log('TranslateX:', translateX);
console.log('TranslateY:', translateY);

// Step 3: Create the first temporary canvas (container size) with transformations applied
const tempCanvas1 = document.createElement('canvas');
tempCanvas1.width = containerWidth;
tempCanvas1.height = containerHeight;
const ctx1 = tempCanvas1.getContext('2d');

// Fill with white
ctx1.fillStyle = '#FFFFFF';
ctx1.fillRect(0, 0, tempCanvas1.width, tempCanvas1.height);

// Calculate the center of the image
const centerX = imageRenderedWidth / 2;
const centerY = imageRenderedHeight / 2;

// Apply transformations: translate, rotate, scale around the center
ctx1.translate(translateX + centerX, translateY + centerY); // Move to the center
ctx1.rotate(rotateRadians); // Apply rotation
ctx1.scale(scaleX, scaleY); // Apply scaling
ctx1.translate(-centerX, -centerY); // Move back

// Draw the image
ctx1.drawImage(sourceImage, 0, 0, imageRenderedWidth, imageRenderedHeight);

// Append the first temporary canvas for debugging
appendCanvas(tempCanvas1, 'Transformed Image');

// Step 4: Create the second temporary canvas to revert transformations and crop
const tempCanvas2 = document.createElement('canvas');
tempCanvas2.width = containerWidth;
tempCanvas2.height = containerHeight;
const ctx2 = tempCanvas2.getContext('2d');

// Fill with white
ctx2.fillStyle = '#FFFFFF';
ctx2.fillRect(0, 0, tempCanvas2.width, tempCanvas2.height);

// To revert transformations, apply inverse transformations
// Inverse scaling
const invScaleX = 1 / scaleX;
const invScaleY = 1 / scaleY;
// Inverse rotation
const invRotateRadians = -rotateRadians;

ctx2.translate(-translateX - centerX, -translateY - centerY); // Reverse translation
ctx2.translate(centerX, centerY); // Move to center
ctx2.rotate(invRotateRadians); // Apply inverse rotation
ctx2.scale(invScaleX, invScaleY); // Apply inverse scaling
ctx2.translate(-centerX, -centerY);  // Move back

// Draw the image
ctx2.drawImage(sourceImage, 0, 0, imageRenderedWidth, imageRenderedHeight);

// Append the second temporary canvas for debugging
appendCanvas(tempCanvas2, 'Reverted Transformations');

// Step 5: Crop the image back to original size (natural image size)
// Create final canvas based on the image's natural size
finalCanvas = document.createElement('canvas');
finalCanvas.width = imageNaturalWidth;
finalCanvas.height = imageNaturalHeight;
const ctxFinal = finalCanvas.getContext('2d');

// Fill with white
ctxFinal.fillStyle = '#FFFFFF';
ctxFinal.fillRect(0, 0, finalCanvas.width, finalCanvas.height);

// Calculate the scaling factor between rendered and natural size
const scaleFactorX = imageNaturalWidth / imageRenderedWidth;
const scaleFactorY = imageNaturalHeight / imageRenderedHeight;

// Draw the reverted image onto the final canvas
ctxFinal.drawImage(
tempCanvas2,
0, 0, containerWidth, containerHeight, // Source rectangle
0, 0, finalCanvas.width, finalCanvas.height // Destination rectangle
);

// Append the final canvas for debugging
appendCanvas(finalCanvas, 'Final Cropped Image');

// Enable the download button
downloadButton.disabled = false;
});

downloadButton.addEventListener('click', () => {
if (!finalCanvas) return;

// Convert the final canvas to a data URL
const dataURL = finalCanvas.toDataURL('image/png');

// Create a temporary link to trigger download
const link = document.createElement('a');
link.href = dataURL;
link.download = 'processed_image.png';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
});

/**
* Utility function to append a canvas with a label for debugging
* @param {HTMLCanvasElement} canvas
* @param {string} label
*/
function appendCanvas(canvas, label) {
const wrapper = document.createElement('div');
const caption = document.createElement('p');
caption.textContent = label;
wrapper.appendChild(caption);
wrapper.appendChild(canvas);
tempCanvasesDiv.appendChild(wrapper);
}
});





Подробнее здесь: https://stackoverflow.com/questions/790 ... nsformatio
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

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