<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="assets/favicon.ico" rel="shortcut icon" />
<link href="https://fonts.gstatic.com" rel="preconnect" />
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;800&display=swap" rel="stylesheet" />
<link href="style.css" rel="stylesheet" />
<title>photo-filter</title>
</head>
<body>
<header class="header">
<h1 class="header-title">Photo-filter</h1>
</header>
<main class="main">
<div class="filters">
<label class="container">
Blur:
<input class="input blur" name="blur" data-sizing="px" data-name="blur" type="range" min="0" max="10" value="0" />
<output class="output" name="result">0</output>
</label>
<label class="container">
Invert:
<input class="input" name="invert" data-sizing="%" data-name="invert" type="range" min="0" max="100" value="0" />
<output class="output" name="result">0</output>
</label>
<label class="container">
Sepia:
<input class="input" name="sepia" data-sizing="%" data-name="sepia" type="range" min="0" max="100" value="0" />
<output class="output" name="result">0</output>
</label>
<label class="container">
Saturate:
<input class="input saturate" name="saturate" data-name="saturate" data-sizing="%" type="range" min="0" max="200" value="100" />
<output class="output" id="saturate" name="result">100</output>
</label>
<label class="container">
Hue rotate:
<input class="input" name="hue" data-name = "hue-rotate" data-sizing="deg" type="range" min="0" max="360" value="0" />
<output class="output" name="result">0</output>
</label>
</div>
<div class="editor">
<div class="btn-container">
<button class="btn btn-reset">Reset</button>
<button class="btn btn-next btn-active">Next picture</button>
<label class="btn btn-load" for="btnInput">
Load picture
<input class="btn-load--input" id="btnInput" name="upload" type="file" placeholder="Load picture" />
</label>
<button class="btn btn-save">Save picture</button>
</div>
<div class="img-container">
<img id="image" src="assets/img/img.jpg" alt="image" />
<canvas id="canvas"></canvas>
</div>
</div>
</main>
<footer class="footer">
<div class="footer-container">
<a class="github" href="https://github.com/KseniyaMirosha" target="_blank" rel="noopener noreferrer"
title="Open my github page">Kseniya Lazovskaya</a>
<a class="rss" href="https://rs.school/js/" target="_blank" rel="noopener noreferrer"
title="Read about the course">
<span class="rss-year">'21</span>
</a>
</div>
</footer>
<button class="fullscreen openfullscreen" onclick="fullscreen();"></button>
<script defer src="canvas.js"></script>
</body>
</html>
// Вешаем обработчик события с делегированием для применения фильтров
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let canvasFilter;
const input = document.querySelector('.filters')
.addEventListener('input', event => {
if (event.target.matches("input")) {
const suffix = event.target.dataset.sizing;
if (event.target.dataset.name === "blur") {
filter = event.target.dataset.name + "(" + (event.target.value * 2) + suffix + ")";
} else {
filter = event.target.dataset.name + "(" + event.target.value + suffix + ")";
}
canvasFilter = filter;
document.documentElement.style.setProperty(`--${event.target.name}`, event.target.value + suffix);
}
});
// Отображаем значение ползунков в output
const allInputs = document.querySelectorAll(".container");
allInputs.forEach(element => {
const input = element.querySelector(".input");
const output = element.querySelector(".output");
input.addEventListener("input", () => {
setValue(input, output);
});
setValue(input, output);
});
function setValue(input, output) {
const val = input.value;
output.innerHTML = val;
}
// Настройки для кнопки reset
const inputs = document.querySelectorAll('input');
const outputs = document.querySelectorAll('output');
let button = document.querySelector('.btn-reset');
button.addEventListener('click', event => {
if (button.matches(".btn-reset")) {
inputs.forEach(element => {
if (element.value) {
element.value = 0;
filter = element.name + "(" + element.value + element.sizing + ")";
canvasFilter = filter;
document.documentElement.style.setProperty(`--${element.name}`, element.value);
}
});
outputs.forEach(element => {
element.innerHTML = 0;
});
let saturateOutput = document.getElementById("saturate");
saturateOutput.innerHTML = 100;
let saturateInput = document.querySelector(".saturate");
saturateInput.value = 100;
document.documentElement.style.setProperty(`--saturate`, "100%");
};
});
// Настройки для кнопки next picture
const base = new Array();
base[0] = 'https://raw.githubusercontent.com/rolling-scopes-school/stage1-tasks/assets/images/night/';
base[1] = 'https://raw.githubusercontent.com/rolling-scopes-school/stage1-tasks/assets/images/morning/';
base[2] = 'https://raw.githubusercontent.com/rolling-scopes-school/stage1-tasks/assets/images/day/';
base[3] = 'https://raw.githubusercontent.com/rolling-scopes-school/stage1-tasks/assets/images/evening/';
const images = ['01.jpg', '02.jpg', '03.jpg', '05.jpg', '06.jpg', '07.jpg', '08.jpg', '09.jpg', '10.jpg', '11.jpg', '12.jpg', '13.jpg', '14.jpg', '15.jpg', '16.jpg', '17.jpg', '18.jpg', '19.jpg', '20.jpg'];
let i = 0;
let x = 0;
let date = new Date();
let j = date.getHours();
const image = document.querySelector('img');
const btn = document.querySelector('.btn-next');
function viewImage(src) {
const img = new Image();
img.src = src;
img.onload = () => {
image.src = `${src}`;
};
}
function getImage() {
i = Math.floor(j / 6);
const imgIndex = x % images.length;
const imageSrc = base[i] + images[imgIndex];
viewImage(imageSrc);
x++;
btn.disabled = true;
setTimeout(function() {
btn.disabled = false
}, 1000);
return imageSrc;
}
btn.addEventListener('click', getImage);
// Настройки для кнопки Load
const fileInput = document.querySelector('input[type="file"]');
const imageContainer = document.querySelector('.img-container');
let currentImg = {};
fileInput.addEventListener('change', function(e) {
const file = fileInput.files[0];
const reader = new FileReader();
reader.onload = () => {
const img = new Image();
img.src = reader.result;
imageContainer.innerHTML = "";
imageContainer.append(img);
currentImg.src = img.src;
}
reader.readAsDataURL(file);
});
// Настройки для кнопки Save picture
const download = document.querySelector('.btn-save');
let currentImage = image;
function drawImage() {
const img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
if (currentImg.src) {
console.log(1);
img.src = currentImg.src;
} else {
console.log(2);
img.src = currentImage.src;
}
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext("2d");
ctx.filter = canvasFilter;
ctx.drawImage(img, 0, 0);
};
}
download.addEventListener('click', function(e) {
drawImage();
console.log(canvas.toDataURL());
const dataURL = canvas.toDataURL("image/jpeg");
let link = document.createElement('a');
link.download = 'download.png';
link.href = dataURL;
link.click();
link.delete;
});
// Функция на полный экран
function fullscreen() {
let checkFullScreen = (document.fullscreenElement && document.fullscreenElement !== null) ||
(document.webkitFullscreenElement && document.webkitFullscreenElement !== null);
let docElement = document.documentElement;
if (!checkFullScreen) {
if (docElement.requestFullscreen) {
docElement.requestFullscreen();
} else if (docElement.webkitRequestFullScreen) {
docElement.webkitRequestFullScreen();
}
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
}
}
function drawImage(callback) {
const img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
if (currentImg.src) {
console.log(1);
img.src = currentImg.src;
} else {
console.log(2);
img.src = currentImage.src;
}
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext("2d");
ctx.filter = canvasFilter;
ctx.drawImage(img, 0, 0);
callback();
};
}
download.addEventListener('click', function(e) {
drawImage(function () {
console.log(canvas.toDataURL());
const dataURL = canvas.toDataURL("image/jpeg");
let link = document.createElement('a');
link.download = 'download.png';
link.href = dataURL;
link.click();
});
});
function drawImage(callback) {
return new Promise(function (resolve) {
const img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
if (currentImg.src) {
console.log(1);
img.src = currentImg.src;
} else {
console.log(2);
img.src = currentImage.src;
}
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext("2d");
ctx.filter = canvasFilter;
ctx.drawImage(img, 0, 0);
resolve();
};
});
}
download.addEventListener('click', function(e) {
drawImage().then(function () {
console.log(canvas.toDataURL());
const dataURL = canvas.toDataURL("image/jpeg");
let link = document.createElement('a');
link.download = 'download.png';
link.href = dataURL;
link.click();
});
});
// или
download.addEventListener('click', async function(e) {
await drawImage();
console.log(canvas.toDataURL());
const dataURL = canvas.toDataURL("image/jpeg");
let link = document.createElement('a');
link.download = 'download.png';
link.href = dataURL;
link.click();
});