<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>etwas</title>
<script src="https://code.jquery.com/jquery-3.4.1.js"></script>
<style>
canvas {
border: 1px solid black;
}
.colors {
height: 20px;
width: 40px;
}
hor {
width: 1px;
height: 100%;
border: 1px solid black;
margin-right: 5px;
margin-left: 5px;
}
td {
user-select: none;
user-select: none;
user-select: none;
user-select: none;
text-align: center;
}
#white {
border: 1px solid black;
}
.ico {
width: 25px;
}
#rgbColor {
background-image: url('https://habrastorage.org/webt/-s/kq/ph/-skqphg-vs0139j4g8rylvgc0ja.png');
}
</style>
</head>
<body>
<table>
<tr>
<td onclick='changeMode("draw"); buttsCss("drawButt")' id='drawButt'><img src="https://i.ibb.co/k4k5GmL/88a2f7af241898f681e799b501d1e881.png" class='ico'></td>
<td onclick="changeMode('quadrat'); buttsCss('squareButt')" id='squareButt'><img src='https://upload.wikimedia.org/wikipedia/commons/thumb/a/a5/ГОСТ_2.410-68._Квадрат%2C_прямоугольник.svg/1200px-ГОСТ_2.410-68._Квадрат%2C_прямоугольник.svg.png' class='ico'></td>
<td>
<hor></hor>
</td>
<td onclick='changeColor("black")' class='colors' title='alt+b'></td>
<td onclick='changeColor("red")' class='colors' title='alt+r'></td>
<td>
<hor></hor>
</td>
<td>Line width:</td>
<td>
<hor></hor>
</td>
<td onclick='deleteLast()' title="ctrl+z">
<img src="https://habrastorage.org/webt/cv/g4/cq/cvg4cqypolpqtqpyfznhvcwhhki.png" class='ico'>
</td>
<td onclick='returnLast()' title='ctrl+y'>
<img src="https://i.ibb.co/HzL1pDP/download-428690.png" class='ico'>
</td>
<td>
<hor></hor>
</td>
<td id='fillButt' onclick='fillStroke("fill")' class='FS' title='f'>
fill
</td>
</tr>
<tr>
<td onclick="changeMode('string'); buttsCss('lineButt')" id='lineButt'><img src="https://free-images.com/or/3d5c/u_1d360_svg.jpg" class='ico'></td>
<td onclick="changeMode('rund'); buttsCss('circleButt')" id='circleButt'><img src="https://big-stirka.ru/wp-content/uploads/2017/08/pustoj-krug.png" class='ico'></td>
<td>
<hor></hor>
</td>
<td onclick='changeColor("blue")' class='colors' title='alt+n'></td>
<td onclick='changeColor("green")' class='colors' title='alt+g'></td>
<td>
<hor></hor>
</td>
<td>
<form name='selForm'>
<select id='selectWidth'>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='5' selected>5</option>
<option value='7'>7</option>
<option value='10'>10</option>
<option value='12'>12</option>
<option value='15'>15</option>
<option value='20'>20</option>
<option value='30'>30</option>
<option value='40'>40</option>
<option value='60'>60</option>
</select>
</form>
</td>
<td>
<hor></hor>
</td>
<td></td>
<td></td>
<td>
<hor></hor>
</td>
<td id='strokeButt' onclick='fillStroke("stroke")' class='FS' title='s'>
stroke
</td>
</tr>
<tr>
<td onclick='changeMode("fill"); buttsCss("fillButt1")' id='fillButt1'><img src="https://www.pinclipart.com/picdir/big/534-5348253_bucket-icon-png-ms-paint-paint-bucket-tool.png" class='ico'></td>
<td onclick='changeMode("triangle"); buttsCss("triangleButt")' id='triangleButt'><img src='https://i.ibb.co/vjCxp6J/aa29932f27044fe8b1140d111f525801.png' class='ico'></td>
<td>
<hor></hor>
</td>
<td onclick='changeColor("rgb(253, 254, 254)")' class='colors' id='white' title='alt+w'></td>
<td onclick="changeColor('yellow')" class='colors' title='alt+y'></td>
<td>
<hor></hor>
</td>
<td></td>
<td>
<hor></hor>
</td>
<td></td>
<td></td>
<td>
<hor></hor>
</td>
<td id='fill-strokeButt' onclick='fillStroke("fill-stroke")' class='FS' title='s'>
fill+stroke (console version)
</td>
</tr>
<tr>
<td id='eraserButt' onclick='changeMode("eraser"); buttsCss("eraserButt")'><img src="https://habrastorage.org/webt/xt/nb/s1/xtnbs1cdcdf30vmf30eqhlueooo.png" class="ico" /></td>
<td></td>
<td>
<hor></hor>
</td>
<td class='colors' id='rgbColor' onclick='rgbColor()'></td>
</tr>
</table>
<canvas id='canvas'></canvas>
<script>
class Line {
constructor(color) {
this.type = 'line';
this.pointsX = [];
this.pointsY = [];
this.color = color;
this.weight = weight;
this.isDraw = true;
this.i = 1;
}
draw() {
if (this.isDraw) {
ctx.lineWidth = this.weight;
ctx.strokeStyle = this.color;
ctx.beginPath();
ctx.moveTo(this.pointsX[this.i - 1], this.pointsY[this.i - 1]);
if (this.pointsX.length == this.pointsY.length) {
while (this.pointsX.length > this.i) {
ctx.lineTo(this.pointsX[this.i], this.pointsY[this.i]);
this.i++;
}
ctx.stroke();
}
}
}
}
class Eraser {
constructor() {
this.color = fillColor;
this.weight = weight;
this.pointsX = [];
this.pointsY = [];
this.type = 'eraser';
this.isDraw = true;
this.i = 1;
}
draw() {
if (this.isDraw) {
ctx.lineWidth = this.weight;
ctx.strokeStyle = this.color;
ctx.beginPath();
ctx.moveTo(this.pointsX[this.i - 1], this.pointsY[this.i - 1]);
if (this.pointsX.length == this.pointsY.length) {
while (this.pointsX.length > this.i) {
ctx.lineTo(this.pointsX[this.i], this.pointsY[this.i]);
this.i++;
}
ctx.stroke();
}
}
}
}
class String {
constructor(color) {
this.type = 'string';
this.color = color;
this.weight = weight;
this.startX = 0;
this.startY = 0;
this.endX = 0;
this.endY = 0;
this.isDraw = true;
}
makingEnd(posX, posY, isShift) {
if (!isShift) {
this.endX = posX;
this.endY = posY;
} else {
if (posX - this.startX > 0 && posY - this.startY > 0) { //правый низ
if (posX > posY) {
this.endX = posX;
this.endY = this.startY;
} else {
this.endX = this.startX;
this.endY = posY;
}
} else if (posX - this.startX < 0 && posY - this.startY > 0) { //левый низ
if (-(this.startX - posX) < this.startY - posY) {
this.endX = posX;
this.endY = this.startY;
} else {
this.endX = this.startX;
this.endY = posY;
}
} else if (posX - this.startX < 0 && posY - this.startY < 0) { //левый верх
if (-(this.startX - posX) < -(this.startY - posY)) {
this.endX = posX;
this.endY = this.startY;
} else {
this.endX = this.startX;
this.endY = posY;
}
} else if (posX - this.startX > 0 && posY - this.startY < 0) { //правый верх
if (this.startX - posX < -(this.startY - posY)) {
this.endX = posX;
this.endY = this.startY;
} else {
this.endX = this.startX;
this.endY = posY;
}
}
}
}
draw() {
if (this.isDraw) {
ctx.strokeStyle = this.color;
ctx.lineWidth = this.weight;
ctx.beginPath();
ctx.moveTo(this.startX, this.startY);
ctx.lineTo(this.endX, this.endY);
ctx.stroke();
}
}
}
class Quadrat {
constructor(color) {
this.type = 'quadrat';
this.colorFill = color;
this.colorStroke = color;
this.FS = fillOrStroke;
this.weight = weight;
this.startX = 0;
this.startY = 0;
this.endX = 0;
this.endY = 0;
this.isDraw = true;
}
makingEnd(posX, posY, isShift = false) {
if (!isShift) {
this.endX = -(this.startX - posX);
this.endY = -(this.startY - posY);
} else {
this.endX = -(this.startX - posX);
if (posY > this.startY) {
this.endY = this.endX;
} else {
this.endY = -this.endX;
}
}
}
draw() {
if (this.isDraw) {
ctx.strokeStyle = this.color;
ctx.lineWidth = this.weight;
if (this.FS == 'fill') {
ctx.fillStyle = this.colorFill;
ctx.fillRect(this.startX, this.startY, this.endX, this.endY);
} else if (this.FS == 'stroke') {
ctx.lineWidth = this.weight;
ctx.strokeStyle = this.colorStroke;
ctx.strokeRect(this.startX, this.startY, this.endX, this.endY);
} else {
ctx.lineWidth = this.weight;
ctx.strokeStyle = this.colorStroke;
ctx.strokeRect(this.startX, this.startY, this.endX, this.endY);
ctx.fillStyle = this.colorFill;
ctx.fillRect(this.startX, this.startY, this.endX, this.endY);
}
}
}
}
class Rund {
constructor(color) {
this.type = 'rund';
this.colorFill = color;
this.colorStroke = color;
this.FS = fillOrStroke;
this.weight = weight;
this.isDraw = true;
this.isArc = false;
this.startX = 0;
this.startY = 0;
this.radiusX = 0;
this.radiusY = 0;
this.rotation = 0;
}
makingEnd(radiusX, radiusY, isShift = false) {
if (isShift) {
this.radiusX = -(this.startX - radiusX);
if (this.radiusX < 0) {
this.radiusX = -this.radiusX;
}
this.isArc = true;
} else {
this.radiusX = -(this.startX - radiusX);
if (this.radiusX < 0) {
this.radiusX = -this.radiusX;
}
this.radiusY = -(this.startY - radiusY);
if (this.radiusY < 0) {
this.radiusY = -this.radiusY;
}
this.isArc = false;
}
}
draw() {
if (this.isDraw) {
ctx.strokeStyle = this.color;
ctx.lineWidth = this.weight;
ctx.beginPath();
if (this.isArc) {
ctx.arc(this.startX, this.startY, this.radiusX, 0, Math.PI * 2);
} else {
ctx.ellipse(this.startX, this.startY, this.radiusX, this.radiusY, this.rotation, 0, Math.PI * 2);
}
if (this.FS == 'fill') {
ctx.fillStyle = this.colorFill;
ctx.fill();
} else if (this.FS == 'stroke') {
ctx.lineWidth = this.weight;
ctx.strokeStyle = this.colorStroke;
ctx.stroke();
} else {
ctx.lineWidth = this.weight;
ctx.strokeStyle = this.colorStroke;
ctx.stroke();
ctx.fillStyle = this.colorFill;
ctx.fill();
}
}
}
}
class Fill {
constructor(color) {
this.color = color;
this.isDraw = true;
}
draw() {
this.isDraw = true;
ctx.fillStyle = this.color;
ctx.fillRect(0, 0, canvas.width, canvas.height);
fillColor = this.color;
}
}
class Triangle {
constructor(color) {
this.colorFill = color;
this.colorStroke = color;
this.weight = weight;
this.FS = fillOrStroke;
this.isDraw = true;
this.startX = 0;
this.startY = 0;
this.endX = 0;
this.endY = 0;
this.posX = 0;
this.posY = 0;
this.type = 'triangle';
}
makingEnd(posX, posY, isShift = false) {
if (!isShift) {
this.endX = -(this.startX - posX);
this.endY = -(this.startY - posY);
this.posX = posX;
this.posY = posY;
} else {
this.endX = -(this.startX - posX);
this.posX = posX;
if (posY > this.startY) {
this.endY = this.endX;
this.posY = this.startY + this.endY;
} else {
this.endY = -this.endX;
this.posY = -(this.startY + this.endY);
}
}
}
draw() {
if (this.isDraw) {
ctx.beginPath();
ctx.moveTo(this.startX, this.posY);
ctx.lineTo(this.posX, this.posY);
ctx.lineTo((this.posX - this.startX) / 2 + this.startX, this.startY);
ctx.lineTo(this.startX, this.posY);
if (this.FS == 'fill') {
ctx.fillStyle = this.colorFill;
ctx.fill();
} else if (this.FS == 'stroke') {
ctx.lineWidth = this.weight;
ctx.strokeStyle = this.colorStroke;
ctx.stroke();
} else {
ctx.lineWidth = this.weight;
ctx.strokeStyle = this.colorStroke;
ctx.stroke();
ctx.fillStyle = this.colorFill;
ctx.fill();
}
}
}
}
function betterDelete(array = [], isMany = false, isPoints = false) {
if (!isMany && !isPoints) {
let newArr = [];
for (let i = 0; i < array.length; i++) {
if (array[i].isDraw) {
if (array[i].type == 'line') {
if (array[i].pointsX.length > 0) {
newArr[newArr.length] = array[i];
}
} else if (array[i].type == 'rund') {
if (array[i].endX != 0) {
newArr[newArr.length] = array[i];
}
} else if (array[i].type == 'triangle') {
if (array[i].posX != 0 && array[i].posY != 0) {
newArr[newArr.length] = array[i];
}
} else if (array[i].type == 'quadrat') {
if (array[i].endX != 0 && array[i].endY != 0) {
newArr[newArr.length] = array[i];
}
} else {
newArr[newArr.length] = array[i];
}
}
}
return newArr;
} else if (!isPoints) {
let newArr = [];
let count = 0;
for (let i = array.length - 1; i > 0; i--) {
if (!array[i].isDraw && count < 5) {
count++;
} else {
newArr[newArr.length] = array[i];
}
}
return newArr;
} else {
let newArr = [];
for (let i = 0; i < array.length; i++) {
if (array[i].pointsX != undefined) {
if (array[i].pointsX > 1) {
newArr[newArr.length] = array[i];
}
}
}
return newArr;
}
}
function deleteLast() {
for (let i = points.length - 1; i >= 0; i--) {
if (points[i].isDraw) {
points[i].isDraw = false;
i = -1;
}
}
let empties = 0;
for (let i = 0; i < points.length; i++) {
if (!points[i].isDraw) {
empties++;
}
}
if (empties > 5) {
points = betterDelete(points, true);
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
draw();
}
function returnLast() {
for (let i = 0; i < points.length; i++) {
if (!points[i].isDraw) {
points[i].isDraw = true;
i = points.length;
}
}
draw();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < points.length; i++) {
points[i].draw();
if (points[i].i != undefined) {
points[i].i = 1;
}
}
}
function changeColor(nColor = '') {
color = nColor;
}
function rgbColor(r = 0, g = 0, b = 0) {
if (r != 0 && g != 0 && b != 0) {
color = `rgb(${r}, ${g}, ${b})`;
} else {
let rgb = prompt('Enter three comma-separated numbers (rgb color)'); //три числа через запятую просто вставить
if (rgb != null) {
color = `rgb(${rgb})`;
}
}
}
function changeMode(cMode) {
mode = cMode;
}
function chooseWidth(power) {
weight = power;
}
function fillStroke(mode) {
if (mode == 'fill') {
fillOrStroke = 'fill';
$('#fillButt').css('background-color', 'antiquewhite');
$('#strokeButt').css('background-color', '');
$('#fill-strokeButt').css('background-color', '');
} else if (mode == 'stroke') {
fillOrStroke = 'stroke';
$('#fillButt').css('background-color', '');
$('#strokeButt').css('background-color', 'antiquewhite');
$('#fill-strokeButt').css('background-color', '');
} else {
fillOrStroke = 'fill-stroke';
$('#fillButt').css('background-color', '');
$('#strokeButt').css('background-color', '');
$('#fill-strokeButt').css('background-color', 'antiquewhite');
}
}
function buttsCss(clicked) {
$('#drawButt').css('background-color', '')
$('#squareButt').css('background-color', '')
$('#lineButt').css('background-color', '')
$('#circleButt').css('background-color', '')
$('#fillButt1').css('background-color', '')
$('#triangleButt').css('background-color', '')
$('#eraserButt').css('background-color', '')
$(`#${clicked}`).css('background-color', 'antiquewhite')
}
function save() {
$('#canvas').contextmenu(function (e) {
alert('')
});
}
var canvas = document.getElementById('canvas');
var body = document.getElementsByTagName('body')[0];
var ctx = canvas.getContext('2d');
if (screen.width > 800 && screen.height > 500) {
canvas.height = 500;
canvas.width = 800;
} else {
canvas.width = screen.width - 20;
canvas.height = screen.height / 2;
}
var canvasPosX = canvas.getBoundingClientRect().left + pageXOffset + 2;
var canvasPosY = canvas.getBoundingClientRect().top + pageYOffset;
var points = [];
var color = 'black';
var fillColor = '';
var weight = 5;
var drawing = false;
var mode = 'draw';
var fillOrStroke = 'stroke';
fillStroke('stroke');
buttsCss("drawButt")
var colors = ['black', 'red', 'blue', 'green', 'rgb(253, 254, 254)', 'yellow'];
var tdsForColors = document.getElementsByClassName('colors');
for (let i = 0; i < tdsForColors.length - 1; i++) {
tdsForColors[i].id = `tdForColors${i}`;
$(`#tdForColors${i}`).css({ 'background-color': colors[i], 'border': '1px solid black' });
}
points[0] = new Fill('rgb(253, 254, 254)');
$('#selectWidth').change(function (e) {
e.preventDefault();
for (let i = 0; i < e.currentTarget.length; i++) {
if (e.currentTarget[i].selected) {
chooseWidth(e.currentTarget[i].value);
}
}
});
//сенсор
canvas.addEventListener('touchstart', function (e) {
Start(e.touches[0]);
}, false);
body.addEventListener('touchmove', function (e) {
Move(e.touches[0]);
}, false);
body.addEventListener('touchend', function (e) {
End(e.touches[0]);
}, false);
//мышь
canvas.addEventListener('mousedown', function (e) {
Start(e);
}, false)
body.addEventListener('mousemove', function (e) {
Move(e);
}, false)
body.addEventListener('mouseup', function (e) {
End(e);
}, false)
//управляшки
function Start(e) {
if (mode == 'draw') {
points[points.length] = new Line(color);
} else if (mode == 'string') {
points[points.length] = new String(color);
points[points.length - 1].startX = e.clientX - canvasPosX + document.getElementsByTagName('html')[0].scrollLeft;
points[points.length - 1].startY = e.clientY - canvasPosY + document.getElementsByTagName('html')[0].scrollTop;
} else if (mode == 'quadrat') {
points[points.length] = new Quadrat(color);
points[points.length - 1].startX = e.clientX - canvasPosX + document.getElementsByTagName('html')[0].scrollLeft;
points[points.length - 1].startY = e.clientY - canvasPosY + document.getElementsByTagName('html')[0].scrollTop;
} else if (mode == 'rund') {
points[points.length] = new Rund(color);
points[points.length - 1].startX = e.clientX - canvasPosX + document.getElementsByTagName('html')[0].scrollLeft;
points[points.length - 1].startY = e.clientY - canvasPosY + document.getElementsByTagName('html')[0].scrollTop;
} else if (mode == 'fill') {
points[0].color = color;
for(let i = 1; i < points.length; i++) {
if(points[i].type == 'eraser') {
points[i].color = color;
}
}
draw();
} else if (mode == 'triangle') {
points[points.length] = new Triangle(color);
points[points.length - 1].startX = e.clientX - canvasPosX + document.getElementsByTagName('html')[0].scrollLeft;
points[points.length - 1].startY = e.clientY - canvasPosY + document.getElementsByTagName('html')[0].scrollTop;
} else if (mode == 'eraser') {
points[points.length] = new Eraser(color);
}
drawing = true;
}
function Move(e) {
if (drawing && e.which == 1 || e.which == undefined) {
if (mode == 'draw' || mode == 'eraser') {
if (points.length > 0) {
points[points.length - 1].pointsX[points[points.length - 1].pointsX.length] = e.clientX - canvasPosX + document.getElementsByTagName('html')[0].scrollLeft;
points[points.length - 1].pointsY[points[points.length - 1].pointsY.length] = e.clientY - canvasPosY + document.getElementsByTagName('html')[0].scrollTop;
points[points.length - 1].draw();
}
} else if (mode == 'string') {
if (points.length > 0) {
points[points.length - 1].makingEnd(e.clientX - canvasPosX + document.getElementsByTagName('html')[0].scrollLeft, e.clientY - canvasPosY + document.getElementsByTagName('html')[0].scrollTop, e.shiftKey);
draw();
}
} else if (mode == 'quadrat' || mode == 'triangle') {
points[points.length - 1].makingEnd(e.clientX - canvasPosX + document.getElementsByTagName('html')[0].scrollLeft, e.clientY - canvasPosY + document.getElementsByTagName('html')[0].scrollTop, e.shiftKey);
draw();
} else if (mode == 'rund') {
points[points.length - 1].makingEnd(e.clientX - canvasPosX + document.getElementsByTagName('html')[0].scrollLeft, e.clientY - canvasPosY + document.getElementsByTagName('html')[0].scrollTop, e.shiftKey);
draw();
}
}
}
function End(e) {
if (mode == 'draw' || mode == 'eraser') {
if (points.length > 0) {
points[points.length - 1].i = 1;
}
}
drawing = false;
points = betterDelete(points);
draw();
}
//клава
$('body').keydown(function (e) {
//console.log(e.keyCode);
switch (e.keyCode) {
case 90:
if (e.ctrlKey) {
deleteLast();
}
break;
case 89:
if (e.ctrlKey) {
returnLast();
} else if (e.altKey) {
changeColor('yellow');
}
break;
case 70:
fillStroke('fill');
break;
case 83:
fillStroke('stroke');
break;
case 66:
if (e.altKey) {
changeColor('black')
}
break;
case 82:
if (e.altKey) {
changeColor('red')
}
break;
case 78:
if (e.altKey) {
changeColor('blue')
}
break;
case 71:
if (e.altKey) {
changeColor('green')
}
break;
case 87:
if (e.altKey) {
changeColor('rgb(253, 254, 254)')
}
break;
default:
break;
}
});
</script>
</body>
</html>
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.