Skip to content

Commit

Permalink
Merge pull request #24 from OSTERITE/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
Osterie authored Jan 24, 2023
2 parents 2b8c43e + 006265c commit 97183ae
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 90 deletions.
2 changes: 1 addition & 1 deletion color_function/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@

<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.3.0/math.min.js"></script> -->

<script src="./library/mathjs/node_modules/mathjs/lib/browser/math.js"></script>
<script src="./library/functions.js"></script> <!-- Can convert vectors to angles (degress or radians) -->
<script src="./library/mathjs/node_modules/mathjs/lib/browser/math.js"></script>
<script src="./library/classdefinitions.js"></script>
<!-- <script src="worker.js"></script> -->
<script src="script.js"> </script>
Expand Down
48 changes: 17 additions & 31 deletions color_function/library/classdefinitions.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
//IMPROVEMENT AREAS

//5 It might be more efficient to use a single method to handle the hue, saturation, and lightness calculations, instead of having separate methods for each in the Square class.

//6 The class Square_matrix is using the Math.abs function to keep the saturation and lightness values between 0 and 100. An alternative approach would be to use the modulo operator % to ensure that the value is within the desired range, which would be more efficient.

//7 The class Square_matrix is using the replace method to replace X and Y in the expressions, it could use a more powerful and efficient way like using a template string to replace the X and Y values.


class Square {
constructor(ctx, xpos, ypos, hue, saturation, lightness, square_size) {
this.xpos = xpos;
Expand All @@ -16,7 +7,6 @@ class Square {
this.lightness = lightness;
this.square_size = square_size;
this.ctx = ctx;
// this.draw();
}

draw() {
Expand All @@ -36,17 +26,15 @@ class Square {
}

hue_changed(expression, x, y) {

this.hue = math.evaluate(`${expression}`.replace(/X/g, x).replace(/Y/g, y));
this.hue = Function( `return ${expression.replace(/X/g, x).replace(/Y/g, y)}` )();
this.draw();
}
saturation_changed(expression, x, y) {
this.saturation = Math.abs( ((100 + math.evaluate(`${expression}`.replace(/X/g, x).replace(/Y/g, y))) % 200) - 100 );

this.saturation = Math.abs( ((100 + Function(`return ${expression.replace(/X/g, x).replace(/Y/g, y)}`)()) % 200) - 100 );
this.draw();
}
lightness_changed(expression, x, y) {
this.lightness = Math.abs( ((100 + math.evaluate(`${expression}`.replace(/X/g, x).replace(/Y/g, y))) % 200) - 100 );
this.lightness = Math.abs( ((100 + Function(`return ${expression.replace(/X/g, x).replace(/Y/g, y)}`)()) % 200) - 100 );
this.draw();
}
}
Expand Down Expand Up @@ -88,12 +76,12 @@ class Square_matrix {
}

for (let y = start_y, runs = length; y <= runs; y++) {
let color_x = x * this.pixel_ratio;
let color_y = y * this.pixel_ratio;
const color_x = x * this.pixel_ratio;
const color_y = y * this.pixel_ratio;

const hue = math.evaluate(`${this.hue_expression}`.replace(/X/g, color_x).replace(/Y/g, color_y));
const saturation = Math.abs( ((100 + math.evaluate(`${this.saturation_expression}`.replace(/X/g, color_x).replace(/Y/g, color_y))) % 200) - 100 );
const lightness = Math.abs( ((100 + math.evaluate(`${this.lightness_expression}`.replace(/X/g, color_x).replace(/Y/g, color_y))) % 200) - 100 );
const hue = Function( `return ${this.hue_expression .replace(/X/g, color_x) .replace(/Y/g, color_y)}` )();
const saturation = Math.abs( ((100 + Function( `return + ${this.saturation_expression .replace(/X/g, color_x) .replace(/Y/g, color_y)}` )()) % 200) - 100 );
const lightness = Math.abs( ((100 + Function( `return + ${this.lightness_expression .replace(/X/g, color_x) .replace(/Y/g, color_y)}` )()) % 200) - 100 );

this.square_matrix[x][y] = new Square(
this.ctx,
Expand All @@ -115,12 +103,12 @@ class Square_matrix {
// row
for (let x = start_y, runs = length; x <= runs; x++) {
for (let y = start_x, runs = width; y <= runs; y++) {
let color_x = x * this.pixel_ratio;
let color_y = y * this.pixel_ratio;
const color_x = x * this.pixel_ratio;
const color_y = y * this.pixel_ratio;

const hue = math.evaluate(`${this.hue_expression}`.replace(/X/g, color_x).replace(/Y/g, color_y));
const saturation = Math.abs( ((100 + math.evaluate(`${this.saturation_expression}`.replace(/X/g, color_x).replace(/Y/g, color_y))) % 200) - 100 );
const lightness = Math.abs( ((100 + math.evaluate(`${this.lightness_expression}`.replace(/X/g, color_x).replace(/Y/g, color_y))) % 200) - 100 );
const hue = Function( `return ${this.hue_expression .replace(/X/g, color_x) .replace(/Y/g, color_y)}` )();
const saturation = Math.abs( ((100 + Function( `return + ${this.saturation_expression .replace(/X/g, color_x) .replace(/Y/g, color_y)}` )()) % 200) - 100 );
const lightness = Math.abs( ((100 + Function( `return + ${this.lightness_expression .replace(/X/g, color_x) .replace(/Y/g, color_y)}` )()) % 200) - 100 );

this.square_matrix[x][y] = new Square(
this.ctx,
Expand Down Expand Up @@ -160,7 +148,7 @@ class Square_matrix {
}

else if (method === "lightness") {
this.lightness = component;
this.lightness_expression = component;
var class_method = Square.prototype.lightness_changed;
}

Expand All @@ -179,7 +167,7 @@ class Square_matrix {
this.size_lower = size_lower;
this.size_upper = size_upper;

//old_size_bipartite means its either the old size_lower or old size_upper
// old_size_bipartite means its either the old size_lower or old size_upper
switch (true) {

//size_upper changed
Expand All @@ -201,16 +189,14 @@ class Square_matrix {
}

zoom(cursor_start_x, cursor_end_x, cursor_start_y, cursor_end_y) {

const zoom_area = largest_drawable_square( cursor_start_x, cursor_end_x, cursor_start_y, cursor_end_y );

const canvas_current_x = cursor_start_x + zoom_area.width;
const canvas_current_y = cursor_start_y + zoom_area.height;

const canvas_start_x = 0;
const canvas_start_y = 0;

//zooms if a perfect square is makeable, guiding box fits the canvas
if ( canvas_start_x < canvas_current_x && canvas_current_x < this.canvas.width && canvas_start_y < canvas_current_y && canvas_current_y < this.canvas.height ) {
if ( 0 < canvas_current_x && canvas_current_x < this.canvas.width && 0 < canvas_current_y && canvas_current_y < this.canvas.height ) {

//start is the smallest value, while end is the largest, opposite for y value because it is distance from top of canvas
const start_x = Math.min( ~~(cursor_start_x / this.absolute_width) + this.distance_left_x, ~~((cursor_start_x + zoom_area.width) / this.absolute_width) + this.distance_left_x );
Expand Down
39 changes: 21 additions & 18 deletions color_function/library/functions.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
//Returns angle between two vectors, unit can be "deg" or radians
function v2a(vector1, vector2, unit) {
vector1_length = Math.sqrt(vector1[0] ** 2 + vector1[1] ** 2);
vector2_length = Math.sqrt(vector2[0] ** 2 + vector2[1] ** 2);
vector_product = vector1[0] * vector2[0] + vector1[1] * vector2[1];
const vector1_length = Math.sqrt(vector1[0] ** 2 + vector1[1] ** 2);
const vector2_length = Math.sqrt(vector2[0] ** 2 + vector2[1] ** 2);

if (vector1_length == 0 || vector2_length == 0) {
return NaN;
}
const vector_product = vector1[0] * vector2[0] + vector1[1] * vector2[1];
//angle as degrees
if (unit == "deg") {
var angle = (Math.acos(vector_product / (vector1_length * vector2_length)) * 180) / Math.PI;
const angle = (Math.acos(vector_product / (vector1_length * vector2_length)) * 180) / Math.PI;
return angle;
}

//angle as radians
else {
var angle = Math.acos(vector_product / (vector1_length * vector2_length));
const angle = Math.acos(vector_product / (vector1_length * vector2_length));
return angle;
}
}

function largest_drawable_square(cursor_start_x, cursor_end_x, cursor_start_y, cursor_end_y) {

let height = 0; //Positive values down, negative values up.
let width = 0; //positive values to the right, negative to the left.
let width = 0; //positive values to the right, negative to the left.

//checks which quadrant mouse is in relation to the initially clicked point (think unit circle quadrants or whatever)
let quadrant = "top_right";
Expand All @@ -36,8 +38,8 @@ function largest_drawable_square(cursor_start_x, cursor_end_x, cursor_start_y, c
}
}

const square_width = cursor_end_x - cursor_start_x
const square_height = cursor_end_y - cursor_start_y
const square_width = cursor_end_x - cursor_start_x;
const square_height = cursor_end_y - cursor_start_y;
//finds the cursor x or y position which would give the greatest width or height (both?)
//current mouse position is in top right or bottom left quadrant (quadrant top_right or bottom_left)
if (quadrant == "top_right" || quadrant == "bottom_left") {
Expand All @@ -61,26 +63,27 @@ function largest_drawable_square(cursor_start_x, cursor_end_x, cursor_start_y, c
height = width;
}
}
return {cursor_start_x, cursor_end_x, cursor_start_y, cursor_end_y, width, height, };
return { cursor_start_x, cursor_end_x, cursor_start_y, cursor_end_y, width, height, };
}

function draw_square(canvas_info, background_img, cursor_start_x, cursor_end_x,cursor_start_y, cursor_end_y) {
let canvas = canvas_info;
function draw_square(canvas_info, background_img, cursor_start_x, cursor_end_x, cursor_start_y, cursor_end_y) {
const canvas = canvas_info;
const ctx = canvas.getContext("2d", { alpha: false });
let current_square = largest_drawable_square(cursor_start_x, cursor_end_x, cursor_start_y, cursor_end_y);
const current_square = largest_drawable_square(cursor_start_x, cursor_end_x, cursor_start_y, cursor_end_y);

let parameter_x = cursor_start_x + ~~current_square.width;
let parameter_y = cursor_start_y + ~~current_square.height;
const parameter_x = cursor_start_x + ~~current_square.width;
const parameter_y = cursor_start_y + ~~current_square.height;

//Draws the guiding box if it fits the canvas
if ( (parameter_x < canvas.width && parameter_x > 0) && (parameter_y < canvas.height && parameter_y > 0) ) {
if ( (0 < parameter_x && parameter_x < canvas.width) && (0 < parameter_y && parameter_y < canvas.height ) ) {
ctx.drawImage(background_img, 0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.rect(cursor_start_x, cursor_start_y, current_square.width, current_square.height);
ctx.rect( cursor_start_x, cursor_start_y, current_square.width, current_square.height );
ctx.stroke();
}
}

function get_cursor_position(canvas, event) {
//finds the absolute coordinates clicked, given as distence from top left.
return [event.offsetX, event.offsetY];
}
}
73 changes: 33 additions & 40 deletions color_function/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,66 @@

const c = console.log.bind(console);

const get_hue_expression = document.getElementById("hue_expression");
const get_saturation_expression = document.getElementById("saturation_expression");
const get_lightness_expression = document.getElementById("lightness_expression");
const get_size_lower = document.getElementById("size_lower");
const get_size_upper = document.getElementById("size_upper");
const get_pixel_ratio = document.getElementById("pixel_ratio");
const get_upscale_button = document.getElementById("upscale");
const get_hue_expression = document.querySelector("#hue_expression");
const get_saturation_expression = document.querySelector("#saturation_expression");
const get_lightness_expression = document.querySelector("#lightness_expression");
const get_size_lower = document.querySelector("#size_lower");
const get_size_upper = document.querySelector("#size_upper");
const get_pixel_ratio = document.querySelector("#pixel_ratio");
const get_upscale_button = document.querySelector("#upscale");

get_hue_expression.addEventListener("change", function () {
hue_expression = get_hue_expression.value;
// hue_expression = get_hue_expression.value;
ctx.clearRect(0, 0, canvas.width, canvas.height)
matrix_squares.class_method_loop("hue", hue_expression);
matrix_squares.class_method_loop("hue", get_hue_expression.value);
update_images(canvas)
});

get_saturation_expression.addEventListener("change", function () {
saturation_expression = get_saturation_expression.value;
// saturation_expression = get_saturation_expression.value;
ctx.clearRect(0, 0, canvas.width, canvas.height)
matrix_squares.class_method_loop("saturation", saturation_expression);
matrix_squares.class_method_loop("saturation", get_saturation_expression.value);
update_images(canvas)
});

get_lightness_expression.addEventListener("change", function () {
lightness_expression = get_lightness_expression.value;
// lightness_expression = get_lightness_expression.value;
ctx.clearRect(0, 0, canvas.width, canvas.height)
matrix_squares.class_method_loop("lightness", lightness_expression);
matrix_squares.class_method_loop("lightness", get_lightness_expression.value);
update_images(canvas)
});

get_pixel_ratio.addEventListener("change", function () {
pixel_ratio = +get_pixel_ratio.value;
size_upper = ~~(+get_size_upper.value / pixel_ratio);
size_lower = ~~(+get_size_lower.value / pixel_ratio);
size_upper = Math.floor(+get_size_upper.value / pixel_ratio);
size_lower = Math.floor(+get_size_lower.value / pixel_ratio);
distance_left_x_zooming = size_lower
distance_top_y_zooming = size_lower

matrix_squares.create_squares(size_lower, size_lower, size_upper, size_upper, pixel_ratio)
update_images(canvas)
});

get_size_lower.addEventListener("change", function () {
let old_size = size_lower
size_lower = ~~(+get_size_lower.value / pixel_ratio);


size_lower = Math.floor(+get_size_lower.value / pixel_ratio);
const absolute_width = canvas.width / (size_upper - size_lower + index_zero);
var distance_from_top_left = (absolute_width) * (old_size - size_lower)
var image_size = ((absolute_width) * (size_upper - old_size + index_zero ))
ctx.drawImage(resizing_img, distance_from_top_left, distance_from_top_left, image_size, image_size);




matrix_squares.change_size(size_lower, size_upper, old_size, 'lower');
update_images(canvas)
});

get_size_upper.addEventListener("change", function () {
let old_size = size_upper
size_upper = ~~(+get_size_upper.value / pixel_ratio);
size_upper = Math.floor(+get_size_upper.value / pixel_ratio);

const absolute_width = canvas.width / (size_upper - size_lower + index_zero);
var image_size = ((absolute_width) * (old_size - size_lower + index_zero))
ctx.drawImage(resizing_img, 0, 0, image_size, image_size);



matrix_squares.change_size(size_lower, size_upper, old_size, 'higher');
update_images(canvas)
});
Expand All @@ -78,7 +73,7 @@ get_upscale_button.addEventListener("click", function () {

//-----------------------Canvas-----------------------------

let canvas = document.getElementById("canvas");
let canvas = document.querySelector("#canvas");
const ctx = canvas.getContext("2d", { alpha: false });

//Check class for these settings!
Expand All @@ -87,24 +82,22 @@ const ctx = canvas.getContext("2d", { alpha: false });

//----------------Creation of pixels--------------------------------

const index_zero = 1
let matrix_pixels = [];
let size_lower = +get_size_lower.value;
let size_upper = +get_size_upper.value;
let size = size_upper - size_lower + index_zero;
var pixel_ratio = parseFloat(get_pixel_ratio.value);
var pixel_ratio= +(get_pixel_ratio.value);
const index_zero = 1

let hue_expression = get_hue_expression.value;
let saturation_expression = get_saturation_expression.value;
let lightness_expression = get_lightness_expression.value;
// let hue_expression = get_hue_expression.value;
// let saturation_expression = get_saturation_expression.value;
// let lightness_expression = get_lightness_expression.value;

//-------------------------------ZOOMING--------------------

let initial_cursor_position = []
let current_cursor_position = []
let mouse_is_down = false


// Event listener for all cursor on canvas events
function handle_canvas_event_zoom(event) {
switch (event.type) {
Expand Down Expand Up @@ -170,9 +163,10 @@ var distance_top_y_zooming = size_lower
window.onload = winInit;
function winInit() {
// ctx.filter = "hue-rotate(200deg)" //INTERESTING!
matrix_squares = new Square_matrix(canvas, hue_expression, saturation_expression, lightness_expression)
matrix_squares = new Square_matrix(canvas, get_hue_expression.value, get_saturation_expression.value, get_lightness_expression.value)
matrix_squares.create_squares(size_lower, size_lower, size_upper, size_upper, pixel_ratio)
update_images(canvas)

}

//\\\\\\\\\\\\\\\\\\\\FUNCTIONS\\\\\\\\\\\\\\\\\\\\\\\
Expand Down Expand Up @@ -201,20 +195,19 @@ function update_images(canvas){
// }
// runspeed = get_runspeed.value;
// animId = setInterval(draw_pixels, 1000 / runspeed);
//TODO: the draw_pixels function must be made again if i want make a changing variable that changes every second or whatever
// }
// }
//------------------END--------------------

//!HUGE? TODO: use webworkers, ask chat gpt-3 for help, not viable? passing information between webworker and main script removes class

//TODO: Research complex plotting or whatever, make an option to change to using complex numbers?
//TODO: !Research complex plotting or whatever, make an option to change to using complex numbers?

//TODO: Create a settings button where settings can be changed/toggled?
//TODO:! Add a button for the option to redraw the black background, creates very interesting patterns when the size of the pixels are < 1
//TODO: Make an option to turn on the sawtooth pattern for hue too? and create lower and upper limit, this.hue = Math.abs(( (100 + Function("return " + hue_expression)()) % 200) - 100)
//TODO: create a settings button where settings can be changed/toggled?
//TODO:! add a button for the option to redraw the black background, creates very interesting patterns when the size of the pixels are < 1
//TODO: make an option to turn on the sawtooth pattern for hue too? and create lower and upper limit, this.hue = Math.abs(( (100 + Function("return " + hue_expression)()) % 200) - 100)
//!TODO: Create a option to toggle between clicking a button to run script and running script when a variable is changed.
//!TODO: Performance mode and fast mode, ise ctx.drawimage method for fast and redraw every pixel every time for fast mode.
//!TODO: quality mode and fast mode, ise ctx.drawimage method for fast and redraw every pixel every time for fast mode.
//TODO: save settings in localstorage

//TODO: Create option to make a variable that changes every second f.eks. goes from 1 to 10 then 10 to 1, call it n and then n can be used in the color chooser
Expand All @@ -239,4 +232,4 @@ function update_images(canvas){
//* WONTFIX Minor fix in the new_pixels function, it creates the corner piece twice
//* make it possible to zoom in on inzoomed image.
//* made zooming more general
//* made functions into methods
//* made functions into methods

0 comments on commit 97183ae

Please sign in to comment.