У меня есть сценарий samll, который позволяет вам добавлять слой «тени» к любому загруженному изображению, а затем сохранять его. В настоящее время вы можете добавить только один стиль оттенков. Мне нужна помощь, чтобы понять, как добавить в сценарий различные варианты оттенков. Предполагается, что это сработает, когда пользователь щелкает нужные оттенки. Еще хотелось бы иметь возможность переворачивать шторы.
у меня это частично получилось, продублировав скрипт для каждого оттенка. у меня 4-5 разных оттенков.
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<link rel = "stylesheet" href = "src/style.css">
<script src = "https://code.jquery.com/jquery-3.7.0.js"></script>
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<h1>Choose your FOMO Shades</h1>
<script src = "https://unpkg.com/[email protected]/konva.min.js"></script>
<script src = "https://code.jquery.com/jquery-3.6.4.min.js"></script>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<title>FOMO Shades</title>
<style>
.russo-one-regular {
font-family: "saira", sans-serif;
font-weight: 400;
font-style: normal;
}
body {
margin: 0;
padding: 0;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column; /* NEW ADD */
background-color: #2F2E2E;
min-height: 80vh;
font-family: "helvetica", sans-serif; /* Use your custom font here */
}
/* #container-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
} */
#container-wrapper {
position: relative;
}
#canvas-container {
position: relative;
background-color: transparent;
/* margin: auto; */ /* NEW ADD */
}
#uploadButton,
#saveButton {
letter-spacing: 2px;
font-family: "helvetica", sans-serif; /* Use your custom font here */
margin: 10px;
cursor: pointer;
color: #ffff;
background-color: #ff9100;
font-size: 18px;
border: 2px solid #fff;
padding: 10px;
border-radius: 0;
transition: background-color 0.3s ease-in-out;
font-weight: 600px;
}
#flipButton {
letter-spacing: 2px;
font-family: "helvetica", sans-serif; /* Use your custom font here */
margin: 10px;
cursor: pointer;
color: #ffff;
background-color: #ff9100;
font-size: 10px;
border: 2px solid #fff;
padding: 5px;
border-radius: 0;
transition: background-color 0.3s ease-in-out;
font-weight: 600px;
}
#flipButton:hover {
background-color: #d17700;
color: white;
}
#uploadButton:hover,
#saveButton:hover {
background-color: #d17700;
color: white;
}
#saveButton {
display: none; /* Initially hide the save button */
}
#closeButton {
/* NEW ADD */
opacity: 0.5;
cursor: pointer;
font-size: 18px;
border: 2px solid #fff;
border-radius: 50%;
transition: background-color 0.3s ease-in-out,
color 0.3s ease-in-out;
position: absolute;
top: 10px;
right: 10px;
color: #ffff;
background-color: #333;
width: 40px; /* Set width and height to make it circular */
height: 40px;
text-align: center;
}
#closeButton:hover {
/* NEW ADD */
background-color: #ff9100;
opacity: 1;
color: white;
}
@media screen and (max-width: 768px) {
#container-wrapper {
width: 100%; /* Full width of its parent */
}
#canvas-container {
width: 100%; /* Take full width to utilize the space */
max-width: 300px; /* But don't grow beyond 300px */
max-height: 300px; /* Same for height */
margin: auto; /* Center horizontally */
overflow: hidden; /* Hide overflow */
display: flex; /* Use flexbox to center content */
justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */
}
.konvajs-content {
width: 100%; /* Let it fill the container */
max-width: 250px; /* But don't exceed 250px */
height: auto; /* Adjust height automatically */
position: relative;
user-select: none;
}
.konvajs-content canvas {
width: 100% !important; /* Override inline styles for responsiveness */
height: auto !important; /* Maintain aspect ratio */
max-width: 250px; /* Respect the max-width of .konvajs-content */
position: absolute;
top: 0;
left: 0;
}
}
#fomo-title {
font-size: 50px;
margin: 0;
}
#fomo-subheading {
font-size: 15px;
margin: 0;
margin-bottom: 20px;
font-family: helvetica;
font-weight: 200;
}
#fomo-header {
color: #fff;
}
#button1{
border: none;
cursor: pointer;
appearance: none;
background-color: inherit;
transition: transform .7s ease-in-out;
margin-left:10px;
}
#button1:hover{
transform: rotate(10deg);
}
#button2{
border: none;
cursor: pointer;
appearance: none;
background-color: inherit;
transition: transform .7s ease-in-out;
margin-left:10px;
}
#button2:hover{
transform: rotate(10deg);
}
img{
width: 110px;
height: 50px;
}
</style>
<div class = "text">
<button id = "button1">
<img src = "https://static.wixstatic.com/media/16c0c5_3fe6bfe914f24f0ca06ad57e8d80a77b~mv2.png" alt = "buttonpng" border = "0" />
</button>
<button id = "button2">
<img src = "https://static.wixstatic.com/media/16c0c5_85ea6942ee63447ba548a3e3b9b090f4~mv2.png" alt = "buttonpng" border = "0" />
</button>
</div>
<div id = "flip">
<button id = "flipButton">flip Image</button>
</div>
<div style = "text-align: center">
<h2 style = "color: #fff" id = "fomo-subheading">
Upload a picture to add FOMO shades
</h2>
</div>
<div id = "container-wrapper">
<div id = "canvas-container"><div class = "konvajs-content" role = "presentation" style = "position: relative; user-select: none; width: 450px; height: 450px;"><canvas width = "450" height = "450" style = "padding: 0px; margin: 0px; border: 0px; background: transparent; position: absolute; top: 0px; left: 0px; width: 450px; height: 450px; display: block;"></canvas></div></div>
<div style = "display: flex; flex-direction: column; align-items: center">
<button id = "uploadButton">Upload Picture</button>
<button id = "saveButton" style = "display: none;">Save Image</button>
</div>
<button id = "closeButton" style = "display: none;">✖</button>
</div>
<script>
let fixedCanvasWidth, maxCanvasHeight;
if (window.innerWidth <= 768) {
// 768px is a common breakpoint for mobile devices
fixedCanvasWidth = 250;
maxCanvasHeight = 250;
} else {
fixedCanvasWidth = 450;
maxCanvasHeight = 450;
}
const stage = new Konva.Stage({
container: "canvas-container",
width: fixedCanvasWidth,
height: maxCanvasHeight,
});
const layer = new Konva.Layer();
stage.add(layer);
let shades;
let shades2;
let canvasBorder;
let tr;
const addShadesToCanvas = () => {
const imgSrc =
"https://static.wixstatic.com/media/16c0c5_3fe6bfe914f24f0ca06ad57e8d80a77b~mv2.png";
canvasBorder = new Konva.Rect({
width: stage.width(),
height: stage.height(),
stroke: "white",
strokeWidth: 10,
});
layer.add(canvasBorder);
Konva.Image.fromURL(imgSrc, (img) => {
shades = img;
const aspectRatio = img.width() / img.height();
let newShadesWidth, newShadesHeight;
if (window.innerWidth <= 768) {
// Mobile devices
newShadesWidth = 100;
newShadesHeight = 100 / aspectRatio;
} else {
// Desktop
newShadesWidth = 250;
newShadesHeight = 250 / aspectRatio;
}
if (newShadesHeight > maxCanvasHeight) {
newShadesHeight = maxCanvasHeight;
newShadesWidth = maxCanvasHeight * aspectRatio;
}
shades.setAttrs({
width: newShadesWidth,
height: newShadesHeight,
x: (stage.width() - newShadesWidth) / 2,
y: (stage.height() - newShadesHeight) / 2,
name: "shades",
draggable: true,
});
tr = new Konva.Transformer({
nodes: [shades],
enabledAnchors: [
"top-left",
"top-right",
"bottom-left",
"bottom-right",
],
keepRatio: true,
boundBoxFunc: (oldBox, newBox) => {
if (
Math.abs(newBox.width) < 10 ||
Math.abs(newBox.height) < 10
) {
return oldBox;
}
return newBox;
},
padding: 10,
rotateEnabled: true /* NEW ADD */,
});
shades.on("click tap", () => {
if (window.innerWidth <= 768) {
// Mobile devices
tr.visible(!tr.visible());
layer.batchDraw();
} else {
// Desktop
tr.visible(!tr.visible());
layer.batchDraw();
}
});
layer.add(canvasBorder);
layer.add(shades);
layer.add(tr);
tr.visible(false);
// $("#saveButton").show();
layer.batchDraw();
});
};
//=============================================
const addShadesToCanvas2 = () => {
const imgSrc2 =
"https://static.wixstatic.com/media/16c0c5_85ea6942ee63447ba548a3e3b9b090f4~mv2.png";
canvasBorder = new Konva.Rect({
width: stage.width(),
height: stage.height(),
stroke: "white",
strokeWidth: 10,
});
layer.add(canvasBorder);
Konva.Image.fromURL(imgSrc2, (img) => {
shades2 = img;
const aspectRatio = img.width() / img.height();
let newShadesWidth, newShadesHeight;
if (window.innerWidth <= 768) {
// Mobile devices
newShadesWidth = 100;
newShadesHeight = 100 / aspectRatio;
} else {
// Desktop
newShadesWidth = 250;
newShadesHeight = 250 / aspectRatio;
}
if (newShadesHeight > maxCanvasHeight) {
newShadesHeight = maxCanvasHeight;
newShadesWidth = maxCanvasHeight * aspectRatio;
}
shades2.setAttrs({
width: newShadesWidth,
height: newShadesHeight,
x: (stage.width() - newShadesWidth) / 2,
y: (stage.height() - newShadesHeight) / 2,
name: "shades",
draggable: true,
});
tr = new Konva.Transformer({
nodes: [shades],
enabledAnchors: [
"top-left",
"top-right",
"bottom-left",
"bottom-right",
],
keepRatio: true,
boundBoxFunc: (oldBox, newBox) => {
if (
Math.abs(newBox.width) < 10 ||
Math.abs(newBox.height) < 10
) {
return oldBox;
}
return newBox;
},
padding: 10,
rotateEnabled: true /* NEW ADD */,
});
shades2.on("click tap", () => {
if (window.innerWidth <= 768) {
// Mobile devices
tr.visible(!tr.visible());
layer.batchDraw();
} else {
// Desktop
tr.visible(!tr.visible());
layer.batchDraw();
}
});
layer.add(canvasBorder);
layer.add(shades2);
layer.add(tr);
tr.visible(false);
// $("#saveButton").show();
layer.batchDraw();
});
};
//================================================
const changeCanvasBackground = (imageSrc) => {
const background = new Image();
background.onload = function () {
const aspectRatio = background.width / background.height;
let newCanvasWidth = fixedCanvasWidth;
let newCanvasHeight = fixedCanvasWidth / aspectRatio;
if (newCanvasHeight > maxCanvasHeight) {
newCanvasHeight = maxCanvasHeight;
newCanvasWidth = maxCanvasHeight * aspectRatio;
}
stage.width(newCanvasWidth);
stage.height(newCanvasHeight);
canvasBorder.width(newCanvasWidth);
canvasBorder.height(newCanvasHeight);
const bg = new Konva.Image({
image: background,
width: newCanvasWidth,
height: newCanvasHeight,
});
layer.destroyChildren();
layer.add(bg);
addShadesToCanvas();
layer.batchDraw();
$("#uploadButton").hide();
$("#closeButton").show();
$("#saveButton").show();
};
background.src = imageSrc;
};
const saveCanvasAsImage = () => {
tr.visible(false);
layer.batchDraw();
const dataURL = stage.toDataURL({
mimeType: "image/png",
quality: 1,
pixelRatio: 3,
});
const a = document.createElement("a");
a.href = dataURL;
a.download = "FOMO_shades.png";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
tr.visible(true);
layer.batchDraw();
};
const resetCanvas = () => {
$("#uploadButton").show();
addShadesToCanvas();
$("#closeButton").hide();
$("#saveButton").hide();
layer.destroyChildren();
stage.width(fixedCanvasWidth);
stage.height(maxCanvasHeight);
canvasBorder = new Konva.Rect({
width: stage.width(),
height: stage.height(),
stroke: "white",
strokeWidth: 10,
});
layer.add(canvasBorder);
layer.batchDraw();
};
const resetCanvas2 = () => {
$("#uploadButton").show();
addShadesToCanvas2();
$("#closeButton").hide();
$("#saveButton").hide();
layer.destroyChildren();
stage.width(fixedCanvasWidth);
stage.height(maxCanvasHeight);
canvasBorder = new Konva.Rect({
width: stage.width(),
height: stage.height(),
stroke: "white",
strokeWidth: 10,
});
layer.add(canvasBorder);
layer.batchDraw();
};
$(document).ready(function () {
$("#closeButton").hide();
$("#saveButton").hide();
addShadesToCanvas();
});
$("#uploadButton").click(function () {
const input = document.createElement("input");
input.type = "file";
input.accept = "image/*";
input.addEventListener("change", (event) => {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function (event) {
const imageSrc = event.target.result;
changeCanvasBackground(imageSrc);
};
reader.readAsDataURL(file);
}
});
input.click();
});
$("#saveButton").click(function () {
saveCanvasAsImage();
});
$("#closeButton").click(function () {
resetCanvas();
});
// $("#saveButton").hide(); /* NEW ADD */
// addMustacheToCanvas(); /* NEW ADD */
$("#button2").click(function () {
resetCanvas2();
});
$("#button1").click(function () {
resetCanvas();
});
</script>
</body>
</html>






Чтобы интегрировать несколько вариантов оттенков и разрешить переворачивание в существующем сценарии, мы обновим части HTML и JavaScript, чтобы обеспечить более плавную обработку этих функций. Вот как вы можете настроить свой код:
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<link rel = "stylesheet" href = "src/style.css">
<script src = "https://code.jquery.com/jquery-3.7.0.js"></script>
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src = "https://unpkg.com/[email protected]/konva.min.js"></script>
<script src = "https://code.jquery.com/jquery-3.6.4.min.js"></script>
<title>FOMO Shades</title>
<style>
/* Add your existing styles here */
</style>
</head>
<body>
<h1>Choose your FOMO Shades</h1>
<div class = "text">
<button class = "shade-button" data-shade = "shade1.png">
<img src = "https://static.wixstatic.com/media/16c0c5_3fe6bfe914f24f0ca06ad57e8d80a77b~mv2.png" alt = "Shade 1" border = "0" />
</button>
<button class = "shade-button" data-shade = "shade2.png">
<img src = "https://static.wixstatic.com/media/16c0c5_85ea6942ee63447ba548a3e3b9b090f4~mv2.png" alt = "Shade 2" border = "0" />
</button>
<!-- Add more buttons as needed -->
</div>
<div id = "flip">
<button id = "flipButton">Flip Image</button>
</div>
<div style = "text-align: center">
<h2 style = "color: #fff" id = "fomo-subheading">Upload a picture to add FOMO shades</h2>
</div>
<div id = "container-wrapper">
<div id = "canvas-container">
<div class = "konvajs-content" role = "presentation" style = "position: relative; user-select: none; width: 450px; height: 450px;">
<canvas width = "450" height = "450" style = "padding: 0px; margin: 0px; border: 0px; background: transparent; position: absolute; top: 0px; left: 0px; width: 450px; height: 450px; display: block;"></canvas>
</div>
</div>
<div style = "display: flex; flex-direction: column; align-items: center">
<button id = "uploadButton">Upload Picture</button>
<button id = "saveButton" style = "display: none;">Save Image</button>
</div>
<button id = "closeButton" style = "display: none;">✖</button>
</div>
<script>
$(document).ready(function () {
// Initialize canvas and variables
let fixedCanvasWidth = window.innerWidth <= 768 ? 250 : 450;
let maxCanvasHeight = window.innerWidth <= 768 ? 250 : 450;
const stage = new Konva.Stage({
container: 'canvas-container',
width: fixedCanvasWidth,
height: maxCanvasHeight,
});
const layer = new Konva.Layer();
stage.add(layer);
let shades;
let canvasBorder;
let tr;
// Function to add shades to canvas
const addShadesToCanvas = (imgSrc) => {
canvasBorder = new Konva.Rect({
width: stage.width(),
height: stage.height(),
stroke: 'white',
strokeWidth: 10,
});
layer.add(canvasBorder);
Konva.Image.fromURL(imgSrc, (img) => {
shades = img;
const aspectRatio = img.width() / img.height();
let newShadesWidth = window.innerWidth <= 768 ? 100 : 250;
let newShadesHeight = newShadesWidth / aspectRatio;
if (newShadesHeight > maxCanvasHeight) {
newShadesHeight = maxCanvasHeight;
newShadesWidth = maxCanvasHeight * aspectRatio;
}
shades.setAttrs({
width: newShadesWidth,
height: newShadesHeight,
x: (stage.width() - newShadesWidth) / 2,
y: (stage.height() - newShadesHeight) / 2,
name: 'shades',
draggable: true,
});
tr = new Konva.Transformer({
nodes: [shades],
enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right'],
keepRatio: true,
boundBoxFunc: (oldBox, newBox) => {
if (Math.abs(newBox.width) < 10 || Math.abs(newBox.height) < 10) {
return oldBox;
}
return newBox;
},
padding: 10,
rotateEnabled: true,
});
shades.on('click tap', () => {
tr.visible(!tr.visible());
layer.batchDraw();
});
layer.add(shades);
layer.add(tr);
tr.visible(false);
layer.batchDraw();
});
};
// Function to change canvas background
const changeCanvasBackground = (imageSrc) => {
const background = new Image();
background.onload = function () {
const aspectRatio = background.width / background.height;
let newCanvasWidth = fixedCanvasWidth;
let newCanvasHeight = fixedCanvasWidth / aspectRatio;
if (newCanvasHeight > maxCanvasHeight) {
newCanvasHeight = maxCanvasHeight;
newCanvasWidth = maxCanvasHeight * aspectRatio;
}
stage.width(newCanvasWidth);
stage.height(newCanvasHeight);
canvasBorder.width(newCanvasWidth);
canvasBorder.height(newCanvasHeight);
const bg = new Konva.Image({
image: background,
width: newCanvasWidth,
height: newCanvasHeight,
});
layer.destroyChildren();
layer.add(bg);
layer.add(canvasBorder);
addShadesToCanvas(currentShade);
layer.batchDraw();
$('#uploadButton').hide();
$('#closeButton').show();
$('#saveButton').show();
};
background.src = imageSrc;
};
// Function to save canvas as image
const saveCanvasAsImage = () => {
tr.visible(false);
layer.batchDraw();
const dataURL = stage.toDataURL({ mimeType: 'image/png', quality: 1, pixelRatio: 3 });
const a = document.createElement('a');
a.href = dataURL;
a.download = 'FOMO_shades.png';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
tr.visible(true);
layer.batchDraw();
};
// Function to reset canvas
const resetCanvas = () => {
$('#uploadButton').show();
$('#closeButton').hide();
$('#saveButton').hide();
layer.destroyChildren();
stage.width(fixedCanvasWidth);
stage.height(maxCanvasHeight);
canvasBorder = new Konva.Rect({
width: stage.width(),
height: stage.height(),
stroke: 'white',
strokeWidth: 10,
});
layer.add(canvasBorder);
addShadesToCanvas(currentShade);
layer.batchDraw();
};
// Handle image upload
$('#uploadButton').click(function () {
const input = document.createElement('input');
input.type = 'file';
input.accept = 'image/*';
input.addEventListener('change', (event) => {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function (event) {
const imageSrc = event.target.result;
changeCanvasBackground(imageSrc);
};
reader.readAsDataURL(file);
}
});
input.click();
});
// Handle save button click
$('#saveButton').click(function () {
saveCanvasAsImage();
});
// Handle close button click
$('#closeButton').click(function () {
resetCanvas();
});
// Handle shade button click
$('.shade-button').click(function () {
const shadeSrc = $(this).data('shade');
currentShade = shadeSrc;
resetCanvas();
});
// Handle flip button click
$('#flipButton').click(function () {
if (shades) {
shades.scaleX(shades.scaleX() * -1);
layer.batchDraw();
}
});
// Initialize with the first shade option
let currentShade = 'https://static.wixstatic.com/media/16c0c5_3fe6bfe914f24f0ca06ad57e8d80a77b~mv2.png';
addShadesToCanvas(currentShade);
});
</script>
</body>
</html>
Обратите внимание, что Генеративный ИИ (например, ChatGPT) запрещен , и прочтите Справочный центр: Политика ИИ. Запрещено использовать инструменты искусственного интеллекта для создания или изменения содержания контента, который вы публикуете в Stack Overflow.
Спасибо за помощь! Кнопка переворота и функции Shades 1 работают отлично, но скрипт перестает работать, когда я нажимаю Shades 2. addShadesToCanvas(), похоже, не загружает следующий оттенок