xxxxxxxxxx
// Global object to store Canvas Size and Resize functions
const Canvas = {
width: 2100,
height: 2100,
prop() {return this.height/this.width},
pixelDensity: 2,
isLandscape() {return window.innerHeight <= window.innerWidth * this.prop()},
resize () {
if (this.isLandscape()) {
this.fitWidth = window.innerHeight / this.prop();
this.fitHeight = window.innerHeight;
document.getElementById("mainCanvas").style.height = "100%";
document.getElementById("mainCanvas").style.removeProperty('width');
} else {
this.fitWidth = window.innerWidth;
this.fitHeight = window.innerWidth * this.prop();
document.getElementById("mainCanvas").style.removeProperty('height');
document.getElementById("mainCanvas").style.width = "100%";
}
this.fitMult = this.fitHeight / this.height;
},
mouseX: null,
mouseY: null,
};
// Instanced P5 Canvas where we will show the shape while drawing and from which we will get the Mouse Coordinates
const handBuffer = function(p) {
p.setup = function() {
let hand = p.createCanvas(floor(Canvas.fitWidth), floor(Canvas.fitHeight));
hand.id('drawingCanvas');
};
p.draw = function() {
Canvas.mouseX = int(p.mouseX / Canvas.fitMult);
Canvas.mouseY = int(p.mouseY / Canvas.fitMult);
if (Sketch.isDrawing && !Sketch.isDrawn && !Sketch.isAboveLimit) {
p.strokeWeight(2)
p.stroke(0)
p.circle(p.mouseX,p.mouseY,2)
}
else if (Sketch.isDrawn) {
p.clear();
}
};
p.windowResized = function() {
p.resizeCanvas(floor(Canvas.fitWidth), floor(Canvas.fitHeight));
};
}
// THIS IS WHERE WE DEAL WITH HAND-DRAWING DATA
const Sketch = {
isDrawn: false,
isDrawing: false,
isAboveLimit: false,
maxDoodles: 2,
currentDoodle: 0,
doodles_data: [],
encodedData: null,
doodles: [],
calcAngle() {
let angle = int(atan(-(Canvas.mouseY-this.temp.y)/(Canvas.mouseX-this.temp.x)));
if (Canvas.mouseX-this.temp.x < 0) angle += 180;
return angle;
},
startDoodle() {
// If it is not drawn and not above char limit
if (!this.isDrawn && !this.isAboveLimit) {
// Initiate Doodle Data with Origin
this.doodles_data.push(Canvas.mouseX,Canvas.mouseY);
// Store first point on a temp object that will change
this.temp = {x:Canvas.mouseX,y:Canvas.mouseY};
// Start Drawing
this.isDrawing = true;
}
},
recordDoodle() {
// If it is not drawn and not above char limit
if (!this.isDrawn && !this.isAboveLimit) {
if(mouseIsPressed) {
// Calculate distance between current mouse coordinates and temporal coordinates
let distance = int(dist(Canvas.mouseX,Canvas.mouseY,this.temp.x,this.temp.y));
// Set Resolution
let res = 50;
// If the mouse has travelled enough distance, we store a new segment
if (distance >= res) {
// Calculate angle in Degrees
let angle = this.calcAngle()
// Push info to data
this.doodles_data.push(angle,distance);
// Set new temporal coordinates
this.temp.x = Canvas.mouseX;
this.temp.y = Canvas.mouseY;
}
// If the data is above our params char limit, we stop drawing
if (btoa(this.doodles_data).length >= 1850) {
this.isAboveLimit = true;
this.finishDoodle();
}
}
}
},
finishDoodle() {
// If it is not drawn already
if (!this.isDrawn) {
// Calculate and push last angle with 'x' as closing character
let angle = this.calcAngle();
this.doodles_data.push(angle,'x');
// Stop Drawing and iterate doodlenumber
this.currentDoodle++
this.isDrawing = false;
// Encode and store data
this.encodedData = "drawn" + btoa(this.doodles_data);
}
// If number of max nr. of doodles has been reached, finish capturing
if (this.currentDoodle >= this.maxDoodles || this.aboveLimit) {
this.isDrawn = true;
this.isAboveLimit = false;
}
},
decodeDrawing() {
// Check if param exists and add data to doodle object
/*
if ($fx.getParam("draw_string").slice(0, 5) == "drawn") {
this.isDrawn = true;
this.encodedData = $fx.getParam("draw_string")
}
*/
if (this.isDrawn) {
// Remove check and decode base64
let segments = atob(this.encodedData.slice(5))
// We split the info as an array
segments = segments.split(",")
// This code goes through the data string and extracts origin, angles and segments
let new_doodle = true;
let num_doodle = 0;
for (let i = 1; i < segments.length; i+=2) {
if (new_doodle) {
this.doodles[num_doodle] = {
origin: {x: parseFloat(segments[i-1]), y: parseFloat(segments[i])},
angles: [],
segments: []
};
new_doodle = false;
} else {
let angle = segments[i-1]
let dist = segments[i]
if (dist == "x") {
this.doodles[num_doodle].angles.push(angle)
num_doodle++
new_doodle = true
} else {
this.doodles[num_doodle].angles.push(angle)
this.doodles[num_doodle].segments.push(dist)
}
}
}
}
},
copyToClipboard() {
var el = document.createElement('textarea');
el.value = this.encodedData;
el.setAttribute('readonly', '');
el.style = {position: 'absolute', left: '-9999px'};
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
}
}
// MOUSE FUNCTIONS
// When CLICKED
function mousePressed () {
Sketch.startDoodle();
return null;
}
// While MOVING
function mouseDragged() {
Sketch.recordDoodle();
return null;
}
// When RELEASED
function mouseReleased () {
Sketch.finishDoodle();
return null;
}
// KEYBOARD FUNCTIONS
function keyReleased() {
// IF USER PRESSES "C", copy DRAWING info to CLIPBOARD
if (keyCode === 67) {
Sketch.copyToClipboard()
console.log(Sketch.encodedData)
}
return null;
}
// BASIC p5 FUNCTIONS
function windowResized () {
Canvas.resize();
}
function setup () {
Canvas.main = createCanvas(Canvas.width,Canvas.height);
pixelDensity(Canvas.pixelDensity), Canvas.main.id('mainCanvas')
// Helps my brain
angleMode(DEGREES)
// Fit Canvas to Screen at start
Canvas.resize();
// Create Independent Canvas for Drawing
Canvas.handBuffer = new p5(handBuffer)
background ('#e2e7dc')
}
function draw() {
// If drawing data already exists, we decode it
Sketch.decodeDrawing()
// This is just to test that the decodedData is right
if (Sketch.isDrawn) {
stroke(0)
strokeWeight(20)
noFill();
for (let d of Sketch.doodles) {
beginShape()
vertex(d.origin.x,d.origin.y)
let currentPos = {x:d.origin.x,y:d.origin.y}
for (let i = 0; i < d.segments.length; i++) {
currentPos.x += d.segments[i] * cos(-d.angles[i])
currentPos.y += d.segments[i] * sin(-d.angles[i])
vertex(currentPos.x,currentPos.y)
}
endShape();
}
noLoop();
}
}