Canvas drawing lines creating 1 curved & 1 non-curved at same time - javascript

I'm trying to make it so that it's just 1 curved line but for some reason it's creating it behind the jagged one I don't want.
I tried adding & removing and for some reason the line still draws when I deleted "beginPath()." But with the bezierCurveTo, it remains jagged but forms a smooth line again when I add "beginPath()" again.
const canvas = document.querySelector('#draw');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx.strokeStyle = 'hue(100%, 75%, 50%)';
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.lineWidth = 5;
ctx.globalCompositeOperation = 'multiply';
let isDrawing = false;
let lastX = 0;
let lastY = 0;
let points = [];
function draw(e) {
if (!isDrawing) return;
var px2 = points.map(point => point.x)[2];
var py2 = points.map(point => point.y)[2];
var px1 = points.map(point => point.x)[1];
var py1 = points.map(point => point.y)[1];
var px0 = points.map(point => point.x)[0];
var py0 = points.map(point => point.y)[0];
ctx.stroke();
ctx.beginPath();
ctx.moveTo(px2, py2);
if (points.length > 3) {
ctx.bezierCurveTo(px1, py1, px0, py0, e.offsetX, e.offsetY);
}
var slope = ((lastY - e.offsetY) + 1) / (Math.abs(lastX - e.offsetX) + 1);
if (slope < -0.5) {
if (ctx.lineWidth < 15) {
ctx.lineWidth++;
}
} else {
if (ctx.lineWidth > 3) {
ctx.lineWidth -= 1;
}
}
[lastX, lastY] = [e.offsetX, e.offsetY];
points.unshift({
x: lastX,
y: lastY,
size: ctx.lineWidth,
color: ctx.strokeStyle,
mode: "draw"
});
}
canvas.addEventListener('mousedown', (e) => {
isDrawing = true;
[lastX, lastY] = [e.offsetX, e.offsetY];
ctx.lineWidth = 5;
points = [];
});
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', () => isDrawing = false);
canvas.addEventListener('mouseout', () => isDrawing = false);
<canvas id="draw"></canvas>
I'm expecting the end result to just have 1 curved line and remove the jagged one layered on top.
You'll also only be able to see the 2 layers when you draw a curve really fast.
Any help is appreciated.

Related

Draw line after zoom and pan in canvas on cursor point correcting-coordinates

I am creating a canvas with multiple image which have zoom and pan action in Svelte application. And now want to draw line on it after disable zoom and pan. Zoom and pan working well but I cannot draw line on the canvas after zoom and pan disabled as expected. Unable to draw line on cursor point or correcting-coordinates. It's drawing far from cursor and moving the line too far on mouse move.
I am giving full code here so that any one can run it in Svelte application to see it
I tried so many ways but can't solve it.
<script>
import { onMount } from "svelte";
import { f7ready } from "framework7-svelte";
let canvasWidth = 500;
let canvasHeight = 500;
let ctx;
let canvas;
let isDrawing = false;
let start;
var scaleFactor = 1.1;
var factor = 1.1;
let canDragAndZoom = true;
let t, l;
$: ctx;
$: canvas;
$: isDrawing;
$: start;
$: t;
$: l;
$: scaleFactor;
$: factor;
$: canDragAndZoom;
let lastX = canvasWidth;
let lastY = canvasHeight;
$: lastX;
$: lastY;
onMount(() => {
f7ready(async () => {
canvas = document.getElementById("myCanvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
var gkhead1 = new Image();
var gkhead2 = new Image();
var gkhead3 = new Image();
var gkhead4 = new Image();
var gkhead5 = new Image();
gkhead1.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg1.jpeg";
gkhead2.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg2.jpeg";
gkhead3.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg3.jpeg";
gkhead4.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg4.jpeg";
gkhead5.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg5.jpeg";
ctx = canvas.getContext("2d");
ctx.lineWidth = 1;
trackTransforms(ctx);
function redraw() {
// Clear the entire canvas
var p1 = ctx.transformedPoint(0, 0);
var p2 = ctx.transformedPoint(canvas.width, canvas.height);
ctx.clearRect(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y);
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.restore();
ctx.drawImage(gkhead1, 50, 150, 100, 129);
ctx.drawImage(gkhead2, 135, 150, 100, 194);
ctx.drawImage(gkhead3, 240, 150, 100, 141);
ctx.drawImage(gkhead4, 345, 150, 100, 125);
ctx.drawImage(gkhead5, 50, 300, 100, 75);
}
redraw();
var dragStart, dragged;
canvas.addEventListener(
"mousedown",
function (evt) {
document.body.style.mozUserSelect =
document.body.style.WebkitUserSelect =
document.body.style.userSelect =
document.body.style.msUserSelect =
"auto";
// drag code
lastX = evt.offsetX || evt.pageX - canvas.offsetLeft;
lastY = evt.offsetY || evt.pageY - canvas.offsetTop;
dragStart = ctx.transformedPoint(lastX, lastY);
// drag code
dragged = false;
},
false
);
canvas.addEventListener(
"mousemove",
function (evt) {
lastX = evt.offsetX || evt.pageX - canvas.offsetLeft;
lastY = evt.offsetY || evt.pageY - canvas.offsetTop;
dragged = true;
dragStart = canDragAndZoom ? dragStart : null;
if (dragStart) {
var pt = ctx.transformedPoint(lastX, lastY);
ctx.translate(pt.x - dragStart.x, pt.y - dragStart.y);
redraw();
}
},
false
);
canvas.addEventListener(
"mouseup",
function (evt) {
dragStart = null;
if (!dragged) zoom(evt.shiftKey ? -1 : 1);
},
false
);
// var scaleFactor = 1.1;
var zoom = function (clicks) {
if (!canDragAndZoom) {
return false;
}
var pt = ctx.transformedPoint(lastX, lastY);
ctx.translate(pt.x, pt.y);
factor = Math.pow(scaleFactor, clicks);
ctx.scale(factor, factor);
ctx.translate(-pt.x, -pt.y);
redraw();
};
var handleScroll = function (evt) {
var delta = evt.wheelDelta
? evt.wheelDelta / 40
: evt.detail
? -evt.detail
: 0;
if (delta) zoom(delta);
return evt.preventDefault() && false;
};
canvas.addEventListener("DOMMouseScroll", handleScroll, false);
canvas.addEventListener("mousewheel", handleScroll, false);
// };
});
});
$: if (ctx) {
ctx.strokeStyle = "red";
}
const handleStart = ({ offsetX: x, offsetY: y }) => {
isDrawing = true;
start = { x, y };
};
const handleEnd = () => {
isDrawing = false;
};
const dragEnable = () => {
canDragAndZoom = canDragAndZoom ? false : true;
};
const handleMove = (event) => {
if (!isDrawing) return;
let canvas = document.getElementById("myCanvas");
let context = canvas.getContext("2d");
let rect = canvas.getBoundingClientRect();
let currentX = event.clientX - rect.left;
let currentY = event.clientY - rect.top;
const { x, y } = start;
context.beginPath();
context.moveTo(x, y);
context.lineTo(currentX, currentY);
context.stroke();
start = { x: currentX, y: currentY };
};
function trackTransforms(ctx) {
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var xform = svg.createSVGMatrix();
ctx.getTransform = function () {
return xform;
};
var savedTransforms = [];
var save = ctx.save;
ctx.save = function () {
savedTransforms.push(xform.translate(0, 0));
return save.call(ctx);
};
var restore = ctx.restore;
ctx.restore = function () {
xform = savedTransforms.pop();
return restore.call(ctx);
};
var scale = ctx.scale;
ctx.scale = function (sx, sy) {
xform = xform.scaleNonUniform(sx, sy);
return scale.call(ctx, sx, sy);
};
var rotate = ctx.rotate;
ctx.rotate = function (radians) {
xform = xform.rotate((radians * 180) / Math.PI);
return rotate.call(ctx, radians);
};
var translate = ctx.translate;
ctx.translate = function (dx, dy) {
xform = xform.translate(dx, dy);
return translate.call(ctx, dx, dy);
};
var transform = ctx.transform;
ctx.transform = function (a, b, c, d, e, f) {
var m2 = svg.createSVGMatrix();
m2.a = a;
m2.b = b;
m2.c = c;
m2.d = d;
m2.e = e;
m2.f = f;
xform = xform.multiply(m2);
return transform.call(ctx, a, b, c, d, e, f);
};
var setTransform = ctx.setTransform;
ctx.setTransform = function (a, b, c, d, e, f) {
xform.a = a;
xform.b = b;
xform.c = c;
xform.d = d;
xform.e = e;
xform.f = f;
return setTransform.call(ctx, a, b, c, d, e, f);
};
var pt = svg.createSVGPoint();
ctx.transformedPoint = function (x, y) {
pt.x = x;
pt.y = y;
return pt.matrixTransform(xform.inverse());
};
}
</script>
<canvas
id="myCanvas"
bind:this={canvas}
on:mousedown={handleStart}
on:mouseup={handleEnd}
on:mouseleave={handleEnd}
on:mousemove={handleMove}
/>
<a href="#" on:click={dragEnable}>
<i class="f7-icons presc_icon">pencil_outline</i>
</a>
After so many try and lots of effort i was able to solve the issue and now it is working as expected .
just had to add some line in handleMove function .
I am posting the solution as answer here so that any one next time can learn it and use the whole code with answer .
const handleMove = (event) => {
if (!isDrawing) return;
let currentX = event.offsetX;
let currentY = event.offsetY;
const { x, y } = start;
let startx = ctx.transformedPoint(x, y);
let endy = ctx.transformedPoint(currentX, currentY);
ctx.beginPath();
ctx.moveTo(startx.x, startx.y);
ctx.lineTo(endy.x, endy.y);
ctx.stroke();
start = { x: currentX, y: currentY };
};

How i can draw new lines with convas js

i want to draw lines with convas but my previous lines was deleted when i try create a new line. I wark with convas the first time and i will be happy if you can say me about my mistakes and solutions of the problem
const convas = document.querySelector(".v");
const ctx = convas.getContext("2d");
let startPositionLine = { x: 0, y: 0 };
let endPositionLine = { x: 0, y: 0 };
let { xStart, yStart } = startPositionLine;
let { xEnd, yEnd } = endPositionLine;
function moveMouseEvent(e) {
xEnd = e.offsetX;
yEnd = e.offsetY;
ctx.beginPath();
ctx.clearRect(0, 0, convas.width, convas.height);
ctx.moveTo(xStart, yStart);
ctx.lineTo(xEnd, yEnd);
ctx.stroke();
}
convas.onmousedown = (e) => {
ctx.beginPath();
xStart = e.offsetX;
yStart = e.offsetY;
ctx.stroke();
convas.onmousemove = (e) => moveMouseEvent(e);
};
convas.onmouseup = () => {
convas.onmousemove = null;
};
I mentioned this in my comment to your post above, but thought I would just give an example you can run and test here. So you are correct in what you are doing, but you just need to save each drawn line to an array AS YOU DRAW THEM. You will see the code for this in the mousedown event handler here. Then you need to redraw those saved lines each time after you clear the canvas in mousemove event handler.
const canvas = document.getElementById('canvas');
var canvasrect = canvas.getBoundingClientRect();
var Xstart = 0;
var Ystart = 0;
var Xend = 0
var Yend = 0
var isDrawing = false;
var linesArray = [{}];
// MOUSE CLICK / BUTTON DOWN LISTENER
canvas.addEventListener('mousedown', e => {
e.preventDefault();
e.stopPropagation();
canvasrect = canvas.getBoundingClientRect();
Xstart = e.clientX - canvasrect.left;
Ystart = e.clientY - canvasrect.top;
// We need to know if the user is actuallydrawing or not.
// Each time the user clicks their canvas we toggle whether to start or stop drawing.
if (isDrawing) {
// If this is the end of a line, save the end coordinates to the latest array element.
linesArray[linesArray.length - 1].xe = Xend;
linesArray[linesArray.length - 1].ye = Yend;
isDrawing = false;
} else {
// If this is the start of a new line, save the start coordinates in a new array element along with end coordinate placeholders.
linesArray.push({
xs: Xstart,
ys: Ystart,
xe: 0,
ye: 0
})
isDrawing = true;
}
});
// MOUSE MOVE
canvas.addEventListener('mousemove', e => {
e.preventDefault();
e.stopPropagation();
// get the current mouse x & y locations along with any scrolling and window resizing offsets.
Xend = e.clientX - canvasrect.left;
Yend = e.clientY - canvasrect.top;
if (isDrawing === true) {
var ctx = canvas.getContext('2d');
//clear the canvas
ctx.clearRect(0, 0, canvasrect.width, canvasrect.height);
// Draw a line from the initial click coordinates to the current mouse pointer coordinates.
ctx.strokeStyle = '#fe0101';
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(Xstart, Ystart);
ctx.lineTo(Xend, Yend);
ctx.stroke();
// now redraw the previous lines saved in the linesArray
if (linesArray.length >= 1) {
for (let i = 0; i < linesArray.length; i++) {
if (linesArray[i].xe != 0) {
ctx.strokeStyle = '#fe0101';
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(linesArray[i].xs, linesArray[i].ys);
ctx.lineTo(linesArray[i].xe, linesArray[i].ye);
ctx.stroke();
}
}
}
}
});
<canvas id="canvas" width="500" height="500" style="background-color:lightGray"></canvas>

How to draw parallelogram with draggable points

I have been studying JS for a few days, but I need to draw a parallelogram and allow user to change its angles by dragging one of its points. I took a code from a related question, and tried to change it (I know, it's a nightmare). But the 4th point doesn't work properly. I get this:
https://i.stack.imgur.com/PAjE6.png
How can I make the 4th point create a parallelogram?
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
var mouse = {};
var draggable = false;
context.lineWidth = 2;
context.strokeStyle = "blue";
var coordinates = [];
var isDone = false;
var clicks = 0;
canvas.addEventListener("mousedown", function(e) {
handleMouseDown(e);
});
function GetMassCenterAndFourthPoint(knownpoints) {
let point4X = knownpoints[2].x - knownpoints[1].x + knownpoints[0].x;
let point4Y = knownpoints[2].y - knownpoints[1].y + knownpoints[0].y;
coordinates.push({
x: point4X,
y: point4Y
});
}
function handleMouseDown(e) {
mouse = oMousePos(canvas, e);
//if isDone you can drag
if (isDone) {
for (index = 0; index < coordinates.length; index++) {
// you draw a small circle no stroke, no fill
context.beginPath();
context.arc(
coordinates[index].x,
coordinates[index].y,
5,
0,
2 * Math.PI
);
// if the mouse is inside the circle
if (context.isPointInPath(mouse.x, mouse.y)) {
// you can drag this point
// I'm using index + 1 because index == 0 is false
draggable = index + 1;
// if I have a point a can break the loop
break;
}
}
} else {
coordinates.push({
x: mouse.x,
y: mouse.y
});
drawPolygon();
clicks++;
if (clicks === 3) {
isDone = true;
}
}
}
function drawPolygon() {
context.clearRect(0, 0, cw, ch);
if (isDone) {
GetMassCenterAndFourthPoint(coordinates);
}
context.beginPath();
context.moveTo(coordinates[0].x, coordinates[0].y);
for (index = 1; index < coordinates.length; index++) {
context.lineTo(coordinates[index].x, coordinates[index].y);
}
context.closePath();
context.stroke();
// Additionaly I'm drawing a small circle around every point
// you can delete this.
for (index = 0; index < coordinates.length; index++) {
context.beginPath();
context.arc(coordinates[index].x, coordinates[index].y, 5, 0, 2 * Math.PI);
context.stroke();
}
}
canvas.addEventListener("mousemove", function(e) {
if (isDone) {
if (draggable) {
mouse = oMousePos(canvas, e);
// draggable - 1 is the index of the point in the coordinates array
coordinates[draggable - 1].x = mouse.x;
coordinates[draggable - 1].y = mouse.y;
drawPolygon();
}
}
});
canvas.addEventListener("mouseup", function(e) {
if (draggable) {
draggable = false;
}
});
// a function to detect the mouse position
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return {
//objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
};
}
canvas {
border: 1px solid black;
}
<canvas id="canvas" width="600" height="600"></canvas>
I also tried to draw my own parallelogram, but can't do it draggable
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
startX;
startY;
}
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var cw = canvas.width;
var ch = canvas.height;
var mouse = {};
var draggable = false;
var points = [];
let isDone = false;
var clicks =0;
let click = false;
canvas.addEventListener("click", function(e) {
console.log(clicks);
clicks++;
if(!isDone){
const point = new Point(e.offsetX, e.offsetY);
points.push(point);
context.beginPath();
context.arc(point.x, point.y, 5, 0, 2 * Math.PI);
context.fillStyle = "red";
context.fill();
if(clicks===3){
isDone=true;
}
}
if(isDone){
GetMassCenterAndFourthPoint(points);
drawParallelogramAndCircle();
}
});
function GetMassCenterAndFourthPoint(knownpoints){
const point4X = knownpoints[2].x-knownpoints[1].x+knownpoints[0].x;
const point4Y = knownpoints[2].y-knownpoints[1].y+knownpoints[0].y;
context.beginPath();
context.arc(point4X, point4Y, 5, 0, 2 * Math.PI);
context.fillStyle = "red";
context.fill();
points.push(new Point(point4X, point4Y));
const massCenterX = (knownpoints[1].x+knownpoints[3].x)/2;
const massCenterY = (knownpoints[1].y+knownpoints[3].y)/2;
points.push(new Point(massCenterX, massCenterY));
}
function drawParallelogramAndCircle(){
context.beginPath();
context.moveTo(points[0].x, points[0].y);
for(let i=1;i<points.length-1;i++){
context.lineTo(points[i].x, points[i].y);
if(i===3){
context.lineTo(points[0].x, points[0].y);
}
}
context.strokeStyle = "blue";
context.closePath();
context.stroke();
// find square. Here will be the logic to calculate square
let square = 250;
context.beginPath();
context.arc(points[4].x, points[4].y, 30, 0, 2 * Math.PI);
context.strokeStyle = "yellow";
context.closePath();
context.stroke();
}
canvas {
border: 1px solid black;
}
<canvas id="canvas" width="600" height="600"></canvas>

How to clear a circle drawn with arc in javascript?

I am having problems when drawing a circle. How do I clear it?
I also still want to maintain the transparent background as much as possible as I am planning on making particles rain down. I also would want to not use images to lower the load on the server.
var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var ctx = canvas.getContext("2d");
const ParticleFactory = function(){
this.interval = 100;
this.lastOutput = Date.now();
this.particles = [];
}
ParticleFactory.prototype.tick = function(){
if (Date.now() > this.lastOutput + this.interval) {
const particle = new Particle(500, 100, 4);
this.particles.push(particle);
this.lastOutput = Date.now();
}
for (var i=0; i < this.particles.length; i++) {
this.particles[i].tick();
};
}
ParticleFactory.prototype.draw = function(){
for (var i=0; i < this.particles.length; i++) {
this.particles[i].draw();
};
}
ParticleFactory.prototype.del = function(toDelete){
this.particles = this.particles.filter(item => item !== toDelete);
}
const Particle = function(x, y, r){
this.x = x;
this.y = y;
this.r = r;
}
Particle.prototype.tick = function(){
this.x -= 0.1;
}
Particle.prototype.draw = function(){
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
ctx.fillStyle = "rgb(0, 0, 255)";
ctx.fill();
ctx.closePath();
}
// Definitions
let particleFactory = new ParticleFactory;
function draw(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
particleFactory.draw();
}
function tick(){
particleFactory.tick();
draw()
window.requestAnimationFrame(tick)
}
document.addEventListener("DOMContentLoaded", function() {
tick();
});
ctx.clearRect() doesn't clear the curcle that is being draws every tick by Particle.draw()
The dot moves and leaves a trail behind even when ctx.clearRect() is run before every draw.

HTML5 canvas color and JS

I have a project where i am trying to only use plain JS without any libraries. This project is about some HTML5 canvas, and the idea is:
There is a colorpicker, but if it is not set yet, the stroke should have rainbow-colors. Else it should have the color of the colorpicker.
The stroke thickness varies constantly, but when it becomes over 100 it starts decreasing and when it becomes under 2 it starts increasing.
But i can't really seem to get the color in set or unset condition
Here is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML5 Canvas</title>
</head>
<body>
<input id="base" type="color" name="base" value="#ffc600">
<canvas id="draw" width="800" height="800"></canvas>
<script>
const canvas = document.querySelector('#draw');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx.strokeStyle = '#BADA55';
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.lineWidth = 100;
let isDrawing = false;
let lastX = 0;
let lastY = 0;
let hue = 0;
let direction = true;
const colorpicker = document.querySelector('input');
colorpicker.addEventListener('change', () => {
// This weird if-statement checks if the color of the colorpicker is not set
if (typeof this.value !== 'undefined') {
rainbow = false;
color = this.value;
} else {
rainbow = true;
}
});
function draw(e) {
if (!isDrawing) return; // stop the fn from running when they are not moused down
console.log(e);
hue ++;
if (hue >= 360) {
hue = 0;
}
if (rainbow === true) {
color = `hsl(${hue}, 50%, 100%)`;
} else {
rainbow = false;
}
ctx.strokeStyle = color;
ctx.beginPath();
// start from
ctx.moveTo(lastX, lastY);
// go to
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
// getting our new offset
[lastX, lastY] = [e.offsetX, e.offsetY];
// if linewidth becomes over 100 it will start decreasing
// and if it becomes lesser than 2 it will start increasing
if (ctx.lineWidth >= 100 || ctx.lineWidth <= 2) {
direction = !direction;
}
if(direction) {
ctx.lineWidth += 2;
} else {
ctx.lineWidth -= 2;
}
}
canvas.addEventListener('mousedown', (e) => {
isDrawing = true;
[lastX, lastY] = [e.offsetX, e.offsetY];
});
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', () => isDrawing = false);
canvas.addEventListener('mouseout', () => isDrawing = false);
</script>
<style>
html, body {
margin:0;
}
</style>
</body>
</html>
Anyone that can see what is wrong with my code or have an idea on how to do it, please help!
Observation 1: when you are using arrow functions you can not use this anymore. So is if (typeof colorpicker.value !== 'undefined')instead of if (typeof this.value !== 'undefined')
Observation 2: you need to declare color and rainbow as globals. Also, in the beginning rainbow should be true since the user didn't choose a color, and in your HTML you should remove the input value, otherwise the value is defined.
Observation 3 You have color = hsl(${hue}, 50%, 100%); This will always give you white since the lightness is 100%; you will need color = hsl(${hue}, 100%, 50%);
const canvas = document.querySelector('#draw');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
//ctx.strokeStyle = '#BADA55';
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.lineWidth = 100;
let isDrawing = false;
let lastX = 0;
let lastY = 0;
let hue = 0;
let direction = true;
let rainbow = true;
let color;
const colorpicker = document.querySelector('input');
colorpicker.addEventListener('change', () => {
//console.log(typeof colorpicker.value);
// This weird if-statement checks if the color of the colorpicker is not set
if (typeof colorpicker.value !== 'undefined') {
rainbow = false;
color = colorpicker.value;
} else {
rainbow = true;
}
//console.log(rainbow);
});
function draw(e) {
if (!isDrawing) return; // stop the fn from running when they are not moused down
//console.log(e);
if (rainbow === true) {
color = `hsl(${hue}, 100%, 50%)`;
hue ++;
if (hue >= 360) {
hue = 0;
}
} else {
rainbow = false;
}
ctx.strokeStyle = color;
ctx.beginPath();
// start from
ctx.moveTo(lastX, lastY);
// go to
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
// getting our new offset
[lastX, lastY] = [e.offsetX, e.offsetY];
// if linewidth becomes over 100 it will start decreasing
// and if it becomes lesser than 2 it will start increasing
if (ctx.lineWidth >= 100 || ctx.lineWidth <= 2) {
direction = !direction;
}
if(direction) {
ctx.lineWidth += 2;
} else {
ctx.lineWidth -= 2;
}
}
canvas.addEventListener('mousedown', (e) => {
isDrawing = true;
[lastX, lastY] = [e.offsetX, e.offsetY];
});
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', () => isDrawing = false);
canvas.addEventListener('mouseout', () => isDrawing = false);
<input id="base" type="color" name="base" >
<canvas id="draw" width="800" height="800"></canvas>

Categories