diff --git a/apollo.css b/apollo.css
index d01fff5..e8d747a 100644
--- a/apollo.css
+++ b/apollo.css
@@ -7,17 +7,19 @@
}
.light {
- --bg-color: #D6A99D ;
- --button-background-color: #FBF3D5;
+ --button-background-color:#DFD0B8;
--button-highlight-color: black;
- --button-fill-color: black;
- --button-active-color: #1b8b98;
+ --button-fill-color: #4a4a4a;
+ --button-active-color:#6d8196 ;
}
* {
box-sizing: border-box;
}
body {
background-color: var(--bg-color) ;
+ padding: 0;
+ margin: 0 0 0 0;
+ overflow: hidden;
}
button {
background: none;
@@ -30,30 +32,43 @@ button {
align-items: center;
justify-content: center;
}
-
+.crosshair {
+ cursor : crosshair;
+}
+.textcursor {
+ cursor : text;
+}
+.grabbing {
+ cursor : grabbing;
+}
+.erasing {
+ cursor: url("data:image/svg+xml;utf8,") 12 12, pointer;
+}
#top_buttons {
background-color: var(--button-background-color);
- position: absolute;
+ position: fixed;
display: flex;
align-items: stretch;
gap: 1%;
+ margin: 0 0 0 0;
border:0;
padding:0;
- width: clamp(12rem,50%,50rem);
+ width: 50%;
left: 25%;
- top: 5%;
+ top: 2vh;
right : 25%;
height: 5%;
border-radius: 8rem;
border-style:none;
}
-
.tools {
flex-grow: 1;
+ z-index: 1;
}
-.tools:active {
+.selected {
background-color: var(--button-active-color);
}
+
.tools:focus {
outline: none;
box-shadow: none;
@@ -66,15 +81,12 @@ button {
transition: stroke 0.3s ;
}
-.tools:focus svg, .tools:hover svg {
+.tools:hover svg {
stroke: var(--button-highlight-color);
stroke-width: 3;
}
-#toggle_theme {
- position: fixed;
- top:20px;
- right:20px;
+.extra_functionality {
height: 6vh;
aspect-ratio: 1/1;
display: flex;
@@ -82,21 +94,84 @@ button {
padding:0;
margin:0;
background-color: var(--button-background-color);
+ z-index:1;
}
-#toggle_theme:hover, #toggle_theme:focus {
+.extra_functionality:hover {
outline:none;
box-shadow: none;
}
-
-#toggle_theme:hover svg, #toggle_theme:focus svg {
- stroke: black;
- stroke-width: 3;
+.extra_functionality:hover svg {
+ stroke: var(--button-highlight-color);
+ stroke-width: 1.5;
+}
+.history {
+ position: fixed;
+ top:2vh;
+ left:2vw;
+ height: 5vh;
+ aspect-ratio: 2.5/1;
+ width: auto;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border-radius: 1rem;
+ margin: 0;
+ gap:1vw;
+ background-color: var(--button-background-color);
+ z-index:1;
+}
+.history button svg{
+ height:2vw;
+ width:2vw;
+ min-height: 30px;
+ min-width: 30px;
+ fill:none;
+ stroke: var(--button-fill-color);
}
-#toggle_theme svg {
- height:80%;
- width:100%;
- stroke: var(--button-fill-color)
+.history button:hover {
+ outline:none;
+ box-shadow: none;
+}
+.history button:hover svg {
+ stroke: var(--button-highlight-color);
+ stroke-width: 1.5;
+}
+#theme {
+ position: fixed;
+ right:1vw;
+ top:2vh;
+ height: 5vh;
+ display:flex;
+ gap:1vw;
+ background-color: var(--button-background-color);
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
+ padding:0 1vw;
+ margin:0 0;
+ border-radius: 4rem;
+}
+#toggle_theme {
+ height: 100%;
+ aspect-ratio: 1/1;
+ display: flex;
+ border-radius: 50%;
+ padding:0;
+ margin:0;
+ background-color: transparent;
+ z-index:1;
+}
+#canvas_color{
+ height:3.5vh;
+ border:none;
+ cursor:pointer;
+ background-color: transparent;
+}
+
+#toggle_theme svg:hover{
+ stroke: var(--button-highlight-color)
}
+
#toggle_theme svg:last-child {
display: none;
}
@@ -106,8 +181,122 @@ button {
.light #toggle_theme svg:first-child {
display: none;
}
+#hint{
+ display: none;
+}
+#test {
+ position: fixed;
+ background-color: transparent;
+ top:0;
+ left:0;
+}
+#final {
+ position: fixed;
+ background-color: transparent;
+ top:0;
+ left:0;
+}
+
+#test, #final{
+ touch-action: none;
+}
-#toggle_theme:hover svg, #toggle_theme:focus svg {
- stroke-color: var(--button-highlight-color);
- stroke-width: 2.5;
+.beautifiers{
+ border:0;
+ margin:0;
+ padding:1rem 1rem 1rem 1rem;
+ display:flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ background-color: var(--button-background-color);
+ border-radius: 1rem;
+ position: fixed;
+ top: 20vh;
+ left:1vw;
+ height:auto;
+ max-height: 70vh;
+ gap: 0.7rem;
+}
+.beautifiers pre{
+ margin:0;
+ font-size:1rem;
+ color: var(--button-fill-color);
}
+.beautifiers input{
+ padding: 0;
+ margin:0;
+ border : none;
+}
+.beautifiers input:hover{
+ cursor: pointer;
+}
+.beautifiers div{
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap:1rem;
+}
+.beautifiers div button{
+ width:3rem;
+}
+.beautifiers div button:hover svg{
+ stroke: var(--button-highlight-color);
+ stroke-width: 2.70;
+}
+.beautifiers div button svg{
+ stroke: var(--button-fill-color);
+ height: 80%;
+ width:100%;
+ fill:none;
+}
+output{
+ color: var(--button-fill-color);
+}
+#options{
+ display : none;
+}
+
+@media (max-width: 620px) {
+ #options{
+ display: flex;
+ position: fixed;
+ top:auto;
+ background-color: var(--button-background-color);
+ font-size: 1rem;
+ color: var(--button-fill-color);
+ bottom: 2vh;
+ height:6vh;
+ left:40vw;
+ right:40vw;
+ width:20vw;
+ }
+ #options :hover{
+ color: var(--button-highlight-color);
+ }
+ #top_buttons{
+ width:90vw;
+ left:5vw;
+ height:6vh;
+ right:5vw;
+ padding : 0 1vw;
+ }
+ #theme{
+ top:auto;
+ height:6vh;
+ bottom:2vh;
+ }
+ .history{
+ top:auto;
+ height:6vh;
+ bottom:2vh;
+ }
+ .beautifiers{
+ left:15vw;
+ right: 15vw;
+ height:50vh;
+ width:70vw;
+ }
+
+}
+
diff --git a/apollo.html b/apollo.html
deleted file mode 100644
index 0622b08..0000000
--- a/apollo.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
- Apollo
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/canvas.js b/canvas.js
new file mode 100644
index 0000000..327d37e
--- /dev/null
+++ b/canvas.js
@@ -0,0 +1,1091 @@
+const canvas = document.getElementById('test');
+const ctx = canvas.getContext("2d");
+const canvas2 = document.getElementById('final');
+const ctx2 = canvas2.getContext("2d");
+canvas.width = window.innerWidth;
+canvas.height = window.innerHeight;
+canvas2.width = window.innerWidth;
+canvas2.height = window.innerHeight;
+ctx.lineJoin = "round";
+ctx2.lineJoin = "round";
+
+let is_drawing = false;
+let startX = 0;
+let startY = 0;
+let pencil_array = [];
+let in_poly_mode = false;
+let prev_undo = false;
+let curr_tool = localStorage.getItem("curr_tool");
+let stroke_style = localStorage.getItem("stroke_style");
+let text_box = 0;
+let pointer_downed_text = 0;
+let state_array = [];
+let move_mode = 0;
+let image_cache = {};
+let is_selected = 0;
+let toolbar_state = 1;
+let curr_cursor_class = "dummy_class"; //to speed up remove only this
+let current_handles = {tl:{},tr:{},bl:{},br:{},rot:{}};
+let mode = 'none';
+let curr_object = {};
+let s_index = -1;
+let active_handle = 'none';
+//pointerdown -> draw dotted lines
+//-----------------------------------------------------------------------------------------
+//main funcs
+
+//convert to path2d:
+function convert_to_path2d(object){
+ let path = new Path2D();
+ if(object.type === "line"){
+ path.moveTo(object.startX,object.startY);
+ path.lineTo(object.endX,object.endY);
+ }
+ else if(object.type === "rectangle" || object.type === "text" || object.type === "image"){
+ path.rect(object.startX,object.startY,object.endX-object.startX,object.endY-object.startY);
+ }
+ else if(object.type === "circle"){
+ path.ellipse((object.startX+object.endX)/2, (object.endY+object.startY)/2,(object.endX-object.startX)/2,(object.endY-object.startY)/2,0,0,2*Math.PI)
+ }
+ else if(object.type === "pencil" || object.type === "polygon")
+ {
+ path.moveTo(object.pencil_array[0].x,object.pencil_array[0].y);
+ for(let i = 1; i < object.pencil_array.length; i++){
+ path.lineTo(object.pencil_array[i].x,object.pencil_array[i].y);
+ }
+ if(object.type === "polygon"){
+ path.closePath();
+ }
+ }
+ return path;
+}
+
+//to convert pointer coordinates to local coordinates relative to new axes:
+function change_coordinates(X,Y,object){
+ let a = X - object.centre.x;
+ let b = Y - object.centre.y;
+ const cosA = Math.cos(-object.angle); //rotate pointer coords opposite
+ const sinA = Math.sin(-object.angle);
+ return {x: a*cosA - b*sinA, y: a*sinA + b*cosA};
+}
+//canvas2 drawing function
+function canvas2draw(object) {
+ ctx2.save();
+ ctx2.translate(object.centre.x,object.centre.y);
+ ctx2.rotate(object.angle);
+ ctx2.strokeStyle = object.stroke_color;
+ ctx2.globalAlpha = object.opacity;
+ ctx2.lineDashOffset = 0;
+ ctx2.lineWidth = object.stroke_width;
+ if(object.stroke_style === "dashed-line"){
+ ctx2.lineCap = "butt";
+ ctx2.setLineDash([2*object.stroke_width, 2*object.stroke_width]);
+ }
+ else if(object.stroke_style === "dotted-line"){
+ ctx2.lineCap = "round";
+ ctx2.setLineDash([0,3*object.stroke_width]);
+ }
+ else{
+ ctx2.lineCap = "butt";
+ ctx2.setLineDash([]);
+ }
+ if(object.type === "line"){
+ ctx2.beginPath();
+ ctx2.moveTo(object.startX,object.startY);
+ ctx2.lineTo(object.endX,object.endY);
+ ctx2.stroke();
+ }
+ else if(object.type === "circle"){
+ ctx2.beginPath();
+ ctx2.ellipse((object.startX+object.endX)/2, (object.endY+object.startY)/2,(object.endX-object.startX)/2,(object.endY-object.startY)/2,0,0,2*Math.PI);
+ ctx2.stroke();
+ }
+ else if(object.type === "rectangle"){
+ ctx2.strokeRect(object.startX,object.startY,object.endX-object.startX,object.endY-object.startY);
+ }
+ else if(object.type === "pencil"){
+ for(let i = 1; i < object.pencil_array.length; i++){
+ ctx2.beginPath();
+ ctx2.moveTo(object.pencil_array[i-1].x, object.pencil_array[i-1].y);
+ ctx2.lineTo(object.pencil_array[i].x,object.pencil_array[i].y);
+ ctx2.stroke();
+ }
+ }
+ else if(object.type === "polygon"){
+ for(let i = 1; i < object.pencil_array.length; i++){
+ ctx2.beginPath();
+ ctx2.moveTo(object.pencil_array[i-1].x, object.pencil_array[i-1].y);
+ ctx2.lineTo(object.pencil_array[i].x,object.pencil_array[i].y);
+ ctx2.stroke();
+ }
+ for(let i = 0; i < 2 ; i++){
+ ctx2.beginPath();
+ ctx2.moveTo(object.pencil_array[object.pencil_array.length-1].x, object.pencil_array[object.pencil_array.length-1].y);
+ ctx2.lineTo(object.pencil_array[0].x,object.pencil_array[0].y);
+ ctx2.stroke();
+ }
+ }
+ else if(object.type === "text"){
+ ctx2.textBaseline = "top";
+ ctx2.font = `${object.font_size} ${object.font_family}`;
+ ctx2.fillStyle = object.font_color;
+ ctx2.fillText(`${object.text}`,object.startX,object.startY);
+ }
+ else if(object.type === "image"){
+ const x = object.startX;
+ const y = object.startY;
+ const w = (object.endX - object.startX);
+ const h = (object.endY - object.startY);
+ if (image_cache[object.imgdata]) {
+ ctx2.drawImage(image_cache[object.imgdata], x, y, w, h);
+ } else {
+ const img = new Image();
+ img.src = object.imgdata;
+ img.onload = () => {
+ image_cache[object.imgdata] = img;
+ ctx2.save();
+ ctx2.globalAlpha = 1;
+ ctx2.translate(object.centre.x,object.centre.y);
+ ctx2.rotate(object.angle);
+ ctx2.drawImage(img, x, y, w, h);
+ ctx2.restore();
+
+ }
+ }
+ }
+ ctx2.restore();
+
+}
+//function to rerender the second canvas
+function rerender(){
+ ctx2.save();
+ ctx2.resetTransform();
+ ctx2.clearRect(0,0,canvas2.width,canvas2.height);
+ ctx2.restore();
+ const undo_stack = JSON.parse(localStorage.getItem("undo_stack"));
+ for(let item of undo_stack){
+ canvas2draw(item);
+}}
+//Object constructors
+function update_handles(object){
+ if(object.type !== "line"){
+ object.tl_handle = {x: object.startX - 15, y: object.startY - 15};
+ object.tr_handle = {x: object.endX + 15, y: object.startY - 15};
+ object.br_handle = {x: object.endX + 15, y: object.endY + 15};
+ object.bl_handle = {x: object.startX - 15, y: object.endY + 15};
+ object.rotate_handle = {
+ x: (object.startX + object.endX) / 2,
+ y: object.startY - 45
+ };
+ }
+ else if(object.type === "line"){
+ const sx = Math.min(object.startX, object.endX);
+ const ex = Math.max(object.endX, object.startX);
+ const sy = Math.min(object.startY,object.endY);
+ const ey = Math.max(object.endY,object.startY);
+ object.tl_handle = {x: sx - 15, y: sy - 15};
+ object.tr_handle = {x: ex + 15, y: sy - 15};
+ object.br_handle = {x: ex + 15, y: ey + 15};
+ object.bl_handle = {x: sx - 15, y: ey + 15};
+ object.rotate_handle = {
+ x: (sx + ex) / 2,
+ y: sy - 45
+ };
+ }
+}
+//function to initialize objects
+function createObject(e){
+ ctx.clearRect(0,0,canvas.width,canvas.height);
+ is_drawing = false;
+ if(curr_tool === "eraser"){
+ return;
+ }
+ let object = {};
+ if (curr_tool === "image"){
+ let obj = new Shape_obj(e.clientX, e.clientY);
+ const width = Math.round(Math.max(30,Math.abs(obj.endX - obj.startX)));
+ const height = Math.round(Math.max(30,Math.abs(obj.endY - obj.startY)));
+ obj.startX = Math.min(obj.startX,obj.endX);
+ obj.startY = Math.min(obj.startY,obj.endY);
+ obj.endX = obj.startX + width;
+ obj.endY = obj.startY + height;
+
+ const img = new Image();
+ img.crossOrigin = "anonymous";
+ img.src = `https://picsum.photos/${width}/${height}`;
+ const reader = new FileReader();
+ fetch(img.src)
+ .then(response => {
+ return response.blob();
+ })
+ .then(blob => {
+ reader.readAsDataURL(blob);
+ })
+
+ reader.onloadend = () => {
+ let object = obj;
+ object.type = "image";
+ object.imgdata = reader.result;
+ object.angle = 0;
+
+ object.centre = {x: (object.startX + object.endX)/2, y: (object.startY + object.endY)/2};
+ object.startX = object.startX - object.centre.x;
+ object.startY = object.startY - object.centre.y;
+ object.endX = object.endX - object.centre.x;
+ object.endY = object.endY - object.centre.y;
+
+ object.tl_handle = {x: object.startX - 15, y: object.startY - 15};
+ object.tr_handle = {x: object.endX + 15, y: object.startY - 15};
+ object.br_handle = {x: object.endX + 15, y: object.endY + 15};
+ object.bl_handle = {x: object.startX - 15, y: object.endY + 15};
+ object.rotate_handle = {
+ x: (object.startX + object.endX) / 2,
+ y: object.startY - 45
+ };
+ let undo_stack = JSON.parse(localStorage.getItem("undo_stack"));
+ undo_stack.push(object);
+ localStorage.setItem("undo_stack", JSON.stringify(undo_stack));
+ state_array.push(convert_to_path2d(object));
+ canvas2draw(object);
+ };
+ return;
+ }
+ else if(curr_tool === "line"){
+ let obj = new Shape_obj(e.clientX,e.clientY);
+ object = obj;
+ object.type = "line";
+ }
+ else if(curr_tool === "draw_circle"){
+ let obj = new Shape_obj(e.clientX,e.clientY);
+ object = obj;
+ object.type = "circle";
+ }
+ else if(curr_tool === "draw_rectangle"){
+ let obj = new Shape_obj(e.clientX,e.clientY);
+ object = obj;
+ object.type = "rectangle";
+ }
+ else if(curr_tool === "pencil"){
+ object.type = "pencil";
+ object.pencil_array = pencil_array;
+ }
+ else if(curr_tool === "polygon"){
+ object.type = "polygon";
+ object.pencil_array = pencil_array;
+ }
+ else if(curr_tool === "text"){
+ object.type = "text";
+ object.font_family = document.getElementById("font_family").value;
+ object.font_size = `${document.getElementById("font_size").value}px`;
+ object.font_color = document.getElementById("font_color").value;
+ const tb = document.getElementById("textbox");
+ object.text = tb.value;
+ object.startY = parseFloat(tb.style.top);
+ object.startX = parseFloat(tb.style.left);
+ object.endY = parseFloat(tb.scrollHeight) + object.startY;
+ object.endX = parseFloat(tb.scrollWidth) + object.startX;
+ document.body.removeChild(tb);
+ }
+ if(object.type === "pencil" || object.type === "polygon"){
+ let max_x = object.pencil_array[0].x;
+ let min_x = object.pencil_array[0].x;
+ let max_y = object.pencil_array[0].y;
+ let min_y = object.pencil_array[0].y;
+ for(let i = 1 ; i < object.pencil_array.length; i++){
+ max_x = Math.max(object.pencil_array[i].x,max_x);
+ max_y = Math.max(object.pencil_array[i].y,max_y);
+ min_x = Math.min(object.pencil_array[i].x,min_x);
+ min_y = Math.min(object.pencil_array[i].y,min_y);
+ }
+ object.startX = min_x;
+ object.endX = max_x;
+ object.startY = min_y;
+ object.endY = max_y;
+ }
+ object.stroke_color = document.getElementById("stroke_color").value;
+ object.opacity = document.getElementById("opacity").value/100;
+ object.stroke_width = document.getElementById("stroke_width").value;
+ object.stroke_style = stroke_style;
+ object.angle = 0;
+
+ object.centre = {x: (object.startX + object.endX)/2, y: (object.startY + object.endY)/2};
+ object.startX = object.startX - object.centre.x;
+ object.startY = object.startY - object.centre.y;
+ object.endX = object.endX - object.centre.x;
+ object.endY = object.endY - object.centre.y;
+ update_handles(object);
+
+ if(object.type === "pencil" || object.type === "polygon"){
+ for(let i = 0 ; i < object.pencil_array.length; i++){
+ object.pencil_array[i].x -= object.centre.x;
+ object.pencil_array[i].y -= object.centre.y;
+ }
+ }
+ let undo_stack = JSON.parse(localStorage.getItem("undo_stack"));
+ undo_stack.push(object);
+ localStorage.setItem("undo_stack", JSON.stringify(undo_stack));
+ state_array.push(convert_to_path2d(object));
+ canvas2draw(object);
+}
+//function to create corners
+function Shape_obj(endX,endY){
+ if(curr_tool !== "line"){
+ this.startX = Math.min(startX,endX);
+ this.startY = Math.min(startY,endY);
+ this.endX = Math.max(startX,endX);
+ this.endY= Math.max(startY,endY);
+ }
+ else if(curr_tool === "line"){
+ this.startX = startX;
+ this.startY = startY;
+ this.endX = endX;
+ this.endY = endY;
+ }
+}
+//function to do the hittesting, x and y are pointer coordinates wr to og coords
+function hit_test(index,obj,x,y){
+ const p = change_coordinates(x,y,obj);
+ ctx2.save();
+ ctx2.lineWidth = obj.stroke_width;
+ ctx2.resetTransform();
+ const ans = (ctx2.isPointInPath(state_array[index],p.x,p.y) || ctx2.isPointInStroke(state_array[index],p.x,p.y)) ? 1 : 0;
+ ctx2.restore();
+ return ans;
+}
+//function to switch between font toolbar and shapes toolbar
+function change_toolbar(s){
+ if(toolbar_state === 1){
+ if(s === "font"){
+ document.getElementById("font_manipulation").style.display = "flex";
+ document.getElementById("stroke_manipulation").style.display = "none";
+ }
+ else if(s === "stroke"){
+ document.getElementById("font_manipulation").style.display = "none";
+ document.getElementById("stroke_manipulation").style.display = "flex";
+ }
+ else if(s === "selection"){
+ document.getElementById("font_manipulation").style.display = "none";
+ document.getElementById("stroke_manipulation").style.display = "none";
+ }
+ }
+}
+
+//function to change the cursor
+function change_cursor(){
+ canvas.classList.remove("crosshair", "textcursor", "erasing", "grabbing");
+ if(curr_tool === "text"){
+ canvas.classList.add("textcursor");
+ }
+ else if(curr_tool === "eraser"){
+ canvas.classList.add("erasing");
+ }
+ else if (curr_tool !== "selection") {
+ canvas.classList.add("crosshair");
+ }
+}
+
+//function to change the stroke style
+function change_style(){
+ const stroke_width = JSON.parse(localStorage.getItem("stroke_width"));
+ if(stroke_style === "dashed-line"){
+ ctx.lineCap = "butt";
+ ctx2.lineCap = "butt";
+ ctx.setLineDash([2*stroke_width, 2*stroke_width]);
+ ctx2.setLineDash([2*stroke_width, 2*stroke_width]);
+ }
+ else if(stroke_style === "dotted-line"){
+ ctx.lineCap = "round";
+ ctx2.lineCap = "round";
+ ctx.setLineDash([0,3*stroke_width]);
+ ctx2.setLineDash([0,3*stroke_width]);
+ }
+ else{
+ ctx.lineCap = "butt";
+ ctx2.lineCap = "butt";
+ ctx.setLineDash([]);
+ ctx2.setLineDash([]);
+ }
+ ctx.lineDashOffset = 0;
+ ctx2.lineDashOffset = 0;
+}
+
+function add_element(s,startX,startY,endX,endY){
+ if(s === "text"){
+ const input = document.createElement("textarea");
+ input.style.position = "absolute";
+ input.id = "textbox";
+ input.style.resize = "none";
+ input.wrap = "off";
+ input.style.top = `${Math.min(startY,endY)}px`;
+ input.style.left = `${Math.min(startX,endX)}px`;
+ input.style.color = `${localStorage.getItem("font_color")}`;
+ input.style.fontFamily = `${localStorage.getItem("font_family")}`;
+ input.style.fontSize = `${document.getElementById("font_size").value}px`
+ input.style.backgroundColor = "transparent";
+ input.style.overflow = "hidden";
+ input.style.height = `${Math.abs(startY-endY)}px`;
+ input.style.width = `${Math.abs(startX-endX)}px`;
+ document.body.appendChild(input);
+ input.addEventListener("input",(e)=>{
+ input.style.width = `${Math.abs(startX-endX)}px`;
+ input.style.width = `${input.scrollWidth}px`;
+ })
+ input.focus();
+ input.addEventListener("pointerdown",(e)=>{e.stopPropagation()},true);
+ }
+}
+function erase(e){
+ let arr = JSON.parse(localStorage.getItem("undo_stack"));
+ for(let i = state_array.length - 1 ; i > -1;i--){
+ if(hit_test(i,arr[i],e.clientX,e.clientY) === 1){
+ state_array.splice(i,1);
+ arr.splice(i,1);
+ localStorage.setItem("undo_stack",JSON.stringify(arr));
+ }
+ }
+ rerender();
+}
+
+
+//------------------------------Initializers-----------------------------------------------
+if(!localStorage.getItem("font_color")){
+ localStorage.setItem("font_color","#226e08");
+}
+if(!localStorage.getItem("font_size")){
+ localStorage.setItem("font_size",'16');
+}
+if(!localStorage.getItem("font_family")){
+ localStorage.setItem("font_family","Arial");
+}
+if(!localStorage.getItem("toolbar")){
+ localStorage.setItem("toolbar","selection");
+ change_toolbar("selection");
+}
+if(!localStorage.getItem("undo_stack")){
+ localStorage.setItem("undo_stack", "[]");
+}
+
+if(!localStorage.getItem("redo_stack")){
+ localStorage.setItem("redo_stack", "[]");
+}
+
+if(!localStorage.getItem("stroke_width")){
+ localStorage.setItem("stroke_width", "1");
+}
+if(!localStorage.getItem("opacity")){
+ localStorage.setItem("opacity","1");
+}
+if (!curr_tool) {
+ localStorage.setItem("curr_tool", "selection");
+ curr_tool = "selection";
+ canvas.classList.remove("crosshair", "textcursor");
+}
+if (!localStorage.getItem("stroke_color")) {
+ if(localStorage.getItem("light") === 'false')
+ localStorage.setItem("stroke_color", "#f5b811");
+ else {
+ localStorage.setItem("stroke_color","#a60818");
+ }
+}
+if (!stroke_style) {
+ localStorage.setItem("stroke_style", "straight-line");
+ stroke_style = "straight-line";
+}
+
+document.getElementById("font_size").value = localStorage.getItem("font_size");
+document.getElementById("font_color").value = localStorage.getItem("font_color");
+document.getElementById("font_family").value = localStorage.getItem("font_family");
+document.getElementById("stroke_color").value = localStorage.getItem("stroke_color");
+document.getElementById("stroke_width").value = localStorage.getItem("stroke_width");
+document.getElementById("opacity").value = localStorage.getItem("opacity")*100;
+document.getElementById(curr_tool).classList.add("selected");
+document.getElementById(stroke_style).classList.add("selected");
+
+change_toolbar(localStorage.getItem("toolbar"))
+change_cursor();
+change_style();
+{const undo_stack = JSON.parse(localStorage.getItem("undo_stack"));
+ for(let item of undo_stack){
+ state_array.push(convert_to_path2d(item));
+}}
+ctx.lineWidth = JSON.parse(localStorage.getItem("stroke_width"));
+ctx.globalAlpha = JSON.parse(localStorage.getItem("opacity"));
+ctx.strokeStyle = localStorage.getItem("stroke_color");
+change_style();
+ctx2.lineWidth = JSON.parse(localStorage.getItem("stroke_width"));
+ctx2.globalAlpha = JSON.parse(localStorage.getItem("opacity"));
+ctx2.strokeStyle = localStorage.getItem("stroke_color");
+rerender();
+
+const tools = document.getElementsByClassName('tools');
+for (const tool of tools) {
+ tool.addEventListener("click", (event) => {
+ if(tool.id === "text"){
+ change_toolbar("font");
+ localStorage.setItem("toolbar", "font")
+ }
+ else if(tool.id === "selection" || tool.id === "eraser" || tool.id === "image"){
+ change_toolbar("selection");
+ localStorage.setItem("toolbar","selection");
+ }
+ else
+ {
+ change_toolbar("stroke");
+ localStorage.setItem("toolbar","stroke");
+ }
+ if(tool.id === "polygon"){
+ document.getElementById("hint").style.display = "flex";
+ }
+ else{
+ document.getElementById("hint").style.display = "none";
+ }
+ document.getElementById(curr_tool).classList.remove("selected");
+ localStorage.setItem("curr_tool", event.currentTarget.id);
+ curr_tool = localStorage.getItem("curr_tool");
+ document.getElementById(curr_tool).classList.add("selected");
+ change_cursor();
+ })}
+
+const stroke_buttons = document.getElementsByClassName('stroke_button');
+for (const butt of stroke_buttons){
+ butt.addEventListener("click", (event) => {
+ document.getElementById(stroke_style).classList.remove("selected");
+ localStorage.setItem("stroke_style", event.currentTarget.id);
+ stroke_style = localStorage.getItem("stroke_style");
+ document.getElementById(stroke_style).classList.add("selected");
+ change_style();
+ }
+)};
+document.getElementById("stroke_width").addEventListener("change", (event) => {
+ localStorage.setItem("stroke_width", event.target.value);
+ ctx.lineWidth = event.target.value;
+ ctx2.lineWidth = event.target.value;
+ change_style();
+
+});
+document.getElementById("font_color").addEventListener("change", (e) => {
+ localStorage.setItem("font_color",e.currentTarget.value);
+});
+document.getElementById("font_family").addEventListener("change", (e) => {
+ localStorage.setItem("font_family", e.currentTarget.value);
+});
+document.getElementById("font_size").addEventListener("change", (e) => {
+ localStorage.setItem("font_size", e.currentTarget.value);
+});
+document.getElementById("options").addEventListener("click", (e)=>{
+ if(toolbar_state === 0){
+ toolbar_state = 1;
+ if(curr_tool === "eraser" || curr_tool === "selection" || curr_tool === "image"){
+ change_toolbar("selection");
+ }
+ else if(curr_tool === "text"){
+ change_toolbar("font");
+ }
+ else{
+ change_toolbar("stroke");
+ }
+
+ }
+ else{
+ change_toolbar("selection");
+ toolbar_state = 0;
+ }
+})
+//----------------------------------------------------------------------------------------
+//live drawing functions :
+function draw_line(endX,endY) {
+ ctx.clearRect(0,0,canvas.width,canvas.height);
+ ctx.beginPath();
+ ctx.moveTo(startX,startY);
+ ctx.lineTo(endX,endY);
+ ctx.stroke();
+}
+function draw_rectangle(endX,endY) {
+ ctx.clearRect(0,0,canvas.width,canvas.height);
+ ctx.strokeRect(startX,startY,endX-startX,endY-startY);
+}
+
+function draw_ellipse(endX, endY) {
+ ctx.clearRect(0,0,canvas.width,canvas.height);
+ ctx.beginPath();
+ ctx.ellipse((startX+endX)/2, (endY+startY)/2,Math.abs((endX-startX)/2),Math.abs((endY-startY)/2),0,0,2*Math.PI);
+ ctx.stroke();
+}
+
+function draw_free(endX, endY) {
+ ctx.beginPath();
+ ctx.moveTo(startX, startY);
+ ctx.lineTo(endX, endY);
+ ctx.stroke();
+ startX = endX;
+ startY = endY;
+}
+function return_box_outline(object){
+ ctx2.save();
+ ctx2.resetTransform();
+ let path = new Path2D();
+ ctx2.beginPath();
+ path.moveTo(object.tl_handle.x, object.tl_handle.y);
+ path.arc(object.tl_handle.x,object.tl_handle.y,5,0,2*Math.PI);
+ path.moveTo(object.bl_handle.x,object.bl_handle.y);
+ path.arc(object.bl_handle.x,object.bl_handle.y,5,0,2*Math.PI);
+ path.moveTo(object.br_handle.x,object.br_handle.y);
+ path.arc(object.br_handle.x,object.br_handle.y,5,0,2*Math.PI);
+ path.moveTo(object.tr_handle.x,object.tr_handle.y);
+ path.arc(object.tr_handle.x,object.tr_handle.y,5,0,2*Math.PI);
+ path.moveTo(object.rotate_handle.x,object.rotate_handle.y);
+ path.arc(object.rotate_handle.x,object.rotate_handle.y,5,0,2*Math.PI);
+ path.moveTo(object.tl_handle.x,object.tl_handle.y);
+ path.lineTo(object.bl_handle.x,object.bl_handle.y);
+ path.lineTo(object.br_handle.x,object.br_handle.y);
+ path.lineTo(object.tr_handle.x,object.tr_handle.y);
+ path.closePath();
+ ctx2.restore();
+ return path;
+}
+function draw_box_outline(object){
+ ctx2.save();
+ rerender();
+ ctx2.resetTransform();
+ ctx2.translate(object.centre.x,object.centre.y);
+ ctx2.rotate(object.angle);
+ ctx2.lineWidth = "2";
+ ctx2.lineJoin = "round";
+ ctx2.lineCap = "round";
+ ctx2.strokeStyle = "#16a7f5"
+ ctx2.fillStyle = "#16a7f5"
+ ctx2.globalAlpha = "1";
+ ctx2.setLineDash([]);
+ ctx2.beginPath();
+ ctx2.moveTo(object.tl_handle.x, object.tl_handle.y);
+ ctx2.arc(object.tl_handle.x,object.tl_handle.y,5,0,2*Math.PI);
+ ctx2.moveTo(object.bl_handle.x,object.bl_handle.y);
+ ctx2.arc(object.bl_handle.x,object.bl_handle.y,5,0,2*Math.PI);
+ ctx2.moveTo(object.br_handle.x,object.br_handle.y);
+ ctx2.arc(object.br_handle.x,object.br_handle.y,5,0,2*Math.PI);
+ ctx2.moveTo(object.tr_handle.x,object.tr_handle.y);
+ ctx2.arc(object.tr_handle.x,object.tr_handle.y,5,0,2*Math.PI);
+ ctx2.moveTo(object.rotate_handle.x,object.rotate_handle.y);
+ ctx2.arc(object.rotate_handle.x,object.rotate_handle.y,5,0,2*Math.PI);
+ ctx2.fill();
+ ctx2.moveTo(object.tl_handle.x,object.tl_handle.y);
+ ctx2.lineTo(object.bl_handle.x,object.bl_handle.y);
+ ctx2.lineTo(object.br_handle.x,object.br_handle.y);
+ ctx2.lineTo(object.tr_handle.x,object.tr_handle.y);
+ ctx2.closePath();
+ ctx2.stroke();
+ ctx2.restore();
+}
+
+
+//select func:
+function OOB(e){ //takes event for coordinates and path2d object for restricting to one object
+ const x = e.clientX;
+ const y = e.clientY;
+ if(is_selected === 0){
+ const arr = JSON.parse(localStorage.getItem("undo_stack"))
+ for(let i = state_array.length - 1 ; i >= 0 ; i--){
+ if(hit_test(i,arr[i],x,y) === 1){
+ s_index = i;
+ return 0;
+ }
+ }
+ return -1;
+ }
+ else {
+ const object = JSON.parse(localStorage.getItem("undo_stack"))[s_index];
+ let ans = 0;
+ ctx2.save();
+ ctx2.resetTransform();
+ ctx2.lineWidth = object.stroke_width;
+ const pt = change_coordinates(x,y,object);
+ if(ctx2.isPointInPath(curr_object,pt.x,pt.y) || ctx2.isPointInStroke(curr_object,pt.x,pt.y)){
+ if((Math.abs(pt.x - object.tl_handle.x) <= 11) && (Math.abs(pt.y - object.tl_handle.y) <= 11)){
+ ans = 1;
+ active_handle = 0;
+ }
+ else if((Math.abs(pt.x - object.bl_handle.x) <= 11) && (Math.abs(pt.y - object.bl_handle.y) <= 11)){
+ ans = 2;
+ active_handle = 1;
+ }
+ else if((Math.abs(pt.x - object.br_handle.x) <= 11) && (Math.abs(pt.y - object.br_handle.y) <= 11)){
+ ans = 3;
+ active_handle = 2;
+ }
+ else if((Math.abs(pt.x - object.tr_handle.x) <= 11) && (Math.abs(pt.y - object.tr_handle.y) <= 11)){
+ ans = 4;
+ active_handle = 3;
+ }
+ else if((Math.abs(pt.x - object.rotate_handle.x) <= 11) && (Math.abs(pt.y - object.rotate_handle.y) <= 11)){
+ ans = 5;
+ }
+ else{
+ ans = 0;
+ }
+ }
+ else{
+ ans = -1;
+ }
+ ctx2.restore();
+ return ans;
+ }
+}
+function cursor_setter(x){
+ canvas.classList.remove(curr_cursor_class); //call with -1 to remove all curosrs
+ if(x !== -1){
+ canvas.classList.add("grabbing");
+ curr_cursor_class = "grabbing";
+ }
+ else{
+ curr_cursor_class = "dummy_class"
+ }
+}
+function change_main_coords(pointer,handle,object){
+ let arr = [object.tl_handle,object.bl_handle,object.br_handle,object.tr_handle];
+ let scale = {x: 1,y: 1};
+ if(Math.abs(pointer.x - arr[(handle+2)%4].x) <= 35 || Math.abs(arr[(handle+2)%4].y - pointer.y) <= 35 ){
+ return scale;
+ }
+ else{
+ arr[handle].x = pointer.x;
+ arr[handle].y = pointer.y;
+ if(handle % 2 === 0){
+ arr[(handle + 1)%4].x = pointer.x;
+ arr[(handle + 3)%4].y = pointer.y;
+ }
+ else{
+ arr[(handle + 1)%4].y = pointer.y;
+ arr[(handle + 3)%4].x = pointer.x;
+ }
+ }
+ scale.x = (Math.abs(arr[0].x - arr[2].x) - 30)/Math.abs(object.startX - object.endX);
+ scale.y = (Math.abs(arr[0].y - arr[1].y) - 30)/Math.abs(object.startY - object.endY);
+ const cd_x = (arr[0].x + arr[2].x)/2;
+ const cd_y = (arr[0].y + arr[1].y)/2;
+ const cosA = Math.cos(object.angle);
+ const sinA = Math.sin(object.angle);
+ object.centre.x = object.centre.x + cd_x*cosA - cd_y*sinA;
+ object.centre.y = object.centre.y + cd_y*cosA + cd_x*sinA;
+ for(let i = 0 ; i < 4 ; i++){
+ arr[i].x -= cd_x;
+ arr[i].y -= cd_y;
+ }
+ object.rotate_handle.x = 0.5*(arr[0].x + arr[2].x);
+ object.rotate_handle.y = arr[0].y - 30;
+ return scale;
+}
+function move(e){
+ let arr = JSON.parse(localStorage.getItem("undo_stack"));
+ let object = arr[s_index];
+ object.centre.x += (e.clientX - startX);
+ object.centre.y += (e.clientY - startY);
+ arr[s_index] = object;
+ localStorage.setItem("undo_stack",JSON.stringify(arr));
+ rerender();
+ draw_box_outline(object);
+ return;
+}
+
+function rotate(e){
+ let arr = JSON.parse(localStorage.getItem("undo_stack"));
+ let object = arr[s_index];
+ object.angle = Math.atan2(e.clientY - object.centre.y,e.clientX - object.centre.x) + 0.5*Math.PI;
+ arr[s_index] = object;
+ localStorage.setItem("undo_stack", JSON.stringify(arr));
+ rerender();
+ draw_box_outline(object);
+ return;
+}
+
+function resize(e){
+ let arr = JSON.parse(localStorage.getItem("undo_stack"));
+ let object = arr[s_index];
+ let pt = change_coordinates(e.clientX,e.clientY,object);
+ const scale = change_main_coords(pt,active_handle,object);
+ const height = object.endY - object.startY;
+ object.startX *= scale.x;
+ object.startY *= scale.y;
+ object.endX *= scale.x;
+ object.endY *= scale.y;
+ if(object.type === "pencil" || object.type === "polygon"){
+ for(let i = 0 ; i < object.pencil_array.length ; i++)
+ {
+ object.pencil_array[i].x *= scale.x;
+ object.pencil_array[i].y *= scale.y;
+ }
+ }
+ else if(object.type === "text"){
+ object.font_size = (`${parseFloat(object.font_size) + object.endY - object.startY - height}px`);
+ }
+ arr[s_index] = object;
+ state_array[s_index] = convert_to_path2d(object);
+ localStorage.setItem("undo_stack", JSON.stringify(arr));
+ rerender();
+ draw_box_outline(object);
+ return;
+}
+//-----------------------------------------------------------------------------------------
+//event listeners
+canvas.addEventListener("pointerdown", (event) => {
+ is_drawing = true;
+ startX = event.clientX;
+ startY = event.clientY;
+ if(curr_tool === "pencil"){
+ pencil_array = [{x: startX, y: startY}];
+ }
+ else if(curr_tool === "selection"){
+ if(is_selected === 0){
+ is_drawing = false;
+ const x = OOB(event);
+ if(x === 0){
+ is_selected = 1;
+ curr_object = return_box_outline(JSON.parse(localStorage.getItem("undo_stack"))[s_index]);
+ draw_box_outline(JSON.parse(localStorage.getItem("undo_stack"))[s_index]);
+ }
+ }
+ else{
+ const x = OOB(event);
+ startX = event.clientX;
+ startY = event.clientY;
+ if(x === -1){
+ is_selected = 0;
+ curr_object = {};
+ s_index = -1;
+ rerender();
+ cursor_setter(-1);
+ mode = 'none';
+ }
+ else if(x === 0){
+ cursor_setter(0);
+ mode = "move";
+ }
+ else if(x === 5){
+ cursor_setter(5);
+ mode = "rotate";
+ }
+ else{
+ cursor_setter(x);
+ mode = "resize";
+ }
+ }
+ }
+ else if(curr_tool === "text"){
+ if(text_box === 0){
+ pointer_downed_text = 1;
+ ctx.lineWidth = 1;
+ if(localStorage.getItem('light') === 'true'){
+ ctx.strokeStyle = "black";
+ }
+ else{
+ ctx.strokeStyle = "white";
+ }
+ }
+ }
+})
+document.body.addEventListener("pointerdown" , (e) => {
+ if(curr_tool === "text" && text_box === 1){
+ if(document.getElementById("textbox").value !== null){createObject(e);}
+ else{document.body.removeChild(document.getElementById("textbox"));
+ }
+ }
+},false)
+
+canvas.addEventListener("click", (event) => {
+ if(curr_tool === "polygon"){
+ is_drawing = true;
+ startX = event.clientX;
+ startY = event.clientY;
+ if(in_poly_mode === false){
+ in_poly_mode = true;
+ pencil_array = [{x: startX, y: startY}];
+ }
+ else{
+ ctx.clearRect(0,0,canvas.width,canvas.height);
+ pencil_array.push({x: startX, y: startY});
+ ctx2.beginPath();
+ ctx2.moveTo(startX,startY);
+ ctx2.lineTo(pencil_array[pencil_array.length-2].x,pencil_array[pencil_array.length-2].y);
+ ctx2.stroke();
+ }
+ }
+})
+canvas.addEventListener("dblclick", (e) => {
+ if(curr_tool === "polygon"){
+ startX = e.clientX;
+ startY = e.clientY;
+ in_poly_mode = false;
+ pencil_array.push({x: startX, y: startY});
+ ctx.beginPath();
+ ctx.moveTo(startX,startY);
+ ctx.lineTo(pencil_array[0].x,pencil_array[0].y);
+ ctx.stroke();
+ createObject(e)
+ }
+})
+canvas.addEventListener("pointermove", (event) => {
+ if (is_drawing === true) {
+ prev_undo = false;
+ localStorage.setItem("redo_stack","[]");
+ if(curr_tool === "line"){
+ draw_line(event.clientX, event.clientY);
+ }
+ else if(curr_tool === "draw_rectangle"){
+ draw_rectangle(event.clientX, event.clientY);
+ }
+ else if(curr_tool === "draw_circle"){
+ draw_ellipse(event.clientX, event.clientY);
+ }
+ else if(curr_tool === "pencil"){
+ pencil_array.push({x: event.clientX, y: event.clientY});
+ draw_free(event.clientX, event.clientY);
+ }
+ else if(curr_tool === "polygon"){
+ draw_line(event.clientX, event.clientY);
+ }
+ else if(curr_tool === "text"){
+ if(text_box === 0 && pointer_downed_text === 1){
+ draw_rectangle(event.clientX, event.clientY);
+ }
+ }
+ else if(curr_tool === "eraser"){
+ erase(event);
+ }
+ else if(curr_tool === "image"){
+ draw_rectangle(event.clientX,event.clientY);
+ }
+
+ }
+ if(curr_tool === "selection"){
+ if(is_selected === 1){
+ if(mode === 'none'){
+ const x = OOB(event);
+ cursor_setter(x);
+ }
+ else if(mode === 'rotate' ){
+ rotate(event);
+ }
+ else if(mode === 'resize'){
+ resize(event);
+ }
+ else if(mode === 'move'){
+ move(event);
+ }
+ }
+ startX = event.clientX;
+ startY = event.clientY;
+
+ }
+})
+canvas.addEventListener("pointerup", (e) => {
+ if(curr_tool === "text" && text_box === 0){
+ ctx.lineWidth = localStorage.getItem("stroke_width");
+ ctx.strokeStyle = localStorage.getItem("stroke_color");
+ add_element("text",startX,startY,e.clientX,e.clientY);
+ is_drawing = false;
+ text_box = 1;
+ pointer_downed_text = 0;
+ }
+ else if(curr_tool === "text" && text_box === 1){
+ text_box = 0;
+ }
+ else if(curr_tool === "selection"){
+ mode = 'none';
+ }
+ else if(curr_tool !== "polygon"){
+ createObject(e);
+ }
+
+
+});
+
+//to prevent glitches when pointer leaves canvas
+canvas.addEventListener("pointerleave", (e) => {
+ if(e.pointerType !== "mouse"){
+ return;
+ }
+ in_poly_mode = false;
+ if(curr_tool === "selection"){
+ is_selected = 0;
+ curr_object = {};
+ s_index = -1;
+ ctx2.clearRect(0,0,canvas2.width,canvas2.height);
+ rerender();
+ cursor_setter(-1);
+ mode = 'none';
+ }
+ else if(is_drawing === true){
+ createObject(e);
+ }
+ })
+
+document.getElementById("stroke_color").addEventListener("change", (event) => {
+ localStorage.setItem("stroke_color", event.currentTarget.value);
+ ctx.strokeStyle = event.currentTarget.value;
+ ctx2.strokeStyle = event.currentTarget.value;
+})
+document.getElementById("opacity").addEventListener("change", (event) => {
+ localStorage.setItem("opacity", event.currentTarget.value/100);
+ ctx.globalAlpha = event.currentTarget.value/100;
+ ctx2.globalAlpha = event.currentTarget.value/100;
+})
+
+
+
+/*-------------------------------------------------------------------------------------------------------*/
+//Undo redo logic:
+
+function undo(e){
+ prev_undo = true;
+ let arr = JSON.parse(localStorage.getItem("undo_stack"));
+ let arr2 = JSON.parse(localStorage.getItem("redo_stack"));
+ if(arr.length !== 0)
+ {
+ const obj = arr.pop();
+ state_array.pop();
+ arr2.push(obj);
+ localStorage.setItem("undo_stack", JSON.stringify(arr));
+ localStorage.setItem("redo_stack", JSON.stringify(arr2));
+ rerender();
+ }
+}
+
+function redo(e){
+ let arr = JSON.parse(localStorage.getItem("undo_stack"));
+ let arr2 = JSON.parse(localStorage.getItem("redo_stack"));
+ if(arr2.length !== 0){
+ const obj = arr2.pop();
+ arr.push(obj);
+ state_array.push(convert_to_path2d(obj));
+ localStorage.setItem("undo_stack", JSON.stringify(arr));
+ localStorage.setItem("redo_stack", JSON.stringify(arr2));
+ canvas2draw(obj);
+ }
+}
+document.getElementById("undo").addEventListener("click", undo);
+document.addEventListener('keydown', (event) => {
+ if (event.ctrlKey && event.key === 'z'){
+ undo();
+}})
+
+document.getElementById("redo").addEventListener("click", redo);
+document.addEventListener('keydown', (event) => {
+ if (event.ctrlKey && event.key === 'y'){
+ redo();
+}})
+
+//-----------------------------------------------------------------------------------------
+//Interactive sliders:
+document.getElementById("font_size_value").textContent = `${document.getElementById("font_size").value}px`;
+document.getElementById("font_size").addEventListener("input", (event) => {
+document.getElementById("font_size_value").textContent = `${event.currentTarget.value}px`;
+});
+
+document.getElementById("opacity_value").textContent = `${document.getElementById("opacity").value/100}`;
+document.getElementById("opacity").addEventListener("input", (event) => {
+document.getElementById("opacity_value").textContent = `${event.currentTarget.value/100}`;
+});
+
+document.getElementById("stroke_width_value").textContent = `${document.getElementById("stroke_width").value}px`;
+document.getElementById("stroke_width").addEventListener("input", (event) => {
+document.getElementById("stroke_width_value").textContent = `${event.currentTarget.value}px`;
+});
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..593045b
--- /dev/null
+++ b/index.html
@@ -0,0 +1,80 @@
+
+
+
+
+
+ Apollo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/toggle_theme.js b/toggle_theme.js
index 585457d..9f1bbd2 100644
--- a/toggle_theme.js
+++ b/toggle_theme.js
@@ -1,13 +1,29 @@
let theme = localStorage.getItem('light')
const themeSwitch = document.getElementById('toggle_theme')
-
-const enableLightmode = () => {
- document.body.classList.add('light')
+if(!localStorage.getItem("canvas_color")){
+ localStorage.setItem("canvas_color","#222831")
+}
+document.documentElement.style.setProperty('--bg-color', `${localStorage.getItem("canvas_color")}`);
+document.getElementById("canvas_color").value = localStorage.getItem("canvas_color");
+document.getElementById("canvas_color").addEventListener("change",(e)=>{
+ localStorage.setItem("canvas_color",`${e.currentTarget.value}`)
+ document.documentElement.style.setProperty('--bg-color', `${e.currentTarget.value}`);
+})
+const enableLightmode = () =>{
+ document.documentElement.style.setProperty('--button-background-color', '#ffffe3');
+ document.documentElement.style.setProperty('--button-highlight-color', 'black');
+ document.documentElement.style.setProperty('--button-fill-color', '#4a4a4a');
+ document.documentElement.style.setProperty('--button-active-color', '#6d8196');
+ document.body.classList.add("light");
localStorage.setItem('light', 'true')
}
const disableLightmode = () => {
- document.body.classList.remove('light')
+ document.documentElement.style.setProperty('--button-background-color', '#393E46');
+ document.documentElement.style.setProperty('--button-highlight-color', '#DFD0B8');
+ document.documentElement.style.setProperty('--button-fill-color', 'white');
+ document.documentElement.style.setProperty('--button-active-color', 'purple');
+ document.body.classList.remove("light");
localStorage.setItem('light', 'false')
}