#codevember 13 - Geometry
How do I make an #codevember 13 - geometry?
A simpler way to draw shapes on canvas. Based on math geometries, this is a part of my future framework for drawing on canvas with js.. What is a #codevember 13 - geometry? How do you make a #codevember 13 - geometry? This script and codes were developed by Pedro Cacique on 20 November 2022, Sunday.
#codevember 13 - Geometry - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>#codevember 13 - Geometry</title> <link rel="stylesheet" href="css/style.css">
</head>
<body> <canvas id="canvas"></canvas> <section> <h1>Geometry Pack</h1> <h2>Shape:</h2> <p>Determines a visible object, described by a specific geometry. Attributes:</p> <ul> <li>Geometry - <b>Point, Rect, Rectangle, Circle, Polygon, Heart</b></li> <li>Position - <b>Point</b> element</li> <li>Color - <b>Color</b> or <b>Gradient</b> element</li> <li>Properties: <ul> <li>lineColor</li> <li>lineWidth</li> <li>scale</li> <li>decay</li> </ul> </li> </ul> <p>Methods:</p> <ul> <li>setProperties(properties)</li> <li>draw(canvas)</li> </ul> <p>Example:</p> <p style="font-family: 'Courier New'">var star = new Shape(new Polygon(50, 5, true), new Point(0, 0), new Color(0, 0, 255, 1));<br> star.draw(canvas);</p> <h2>Geometries:</h2> <h3>Point:</h3> <p>2D Spatial point. Attributes:</p> <ul> <li>x</li> <li>y</li> </ul> <p>Methods:</p> <ul> <li>add(p2) - add another point to the current one and return a copy</li> <li>distance(p2) - return the euclidean distance from the current to the other point</li> <li>manhatan(p2) - return the manhatan distance from the current to the other point</li> <li>multiply(p2) - multiply the current point by another and return a copy</li> <li>isNear(p2, offset) - verify if the distance of two points is less than the offset</li> </ul> <h3>Rect:</h3> <p>Rect between two points. Attributes:</p> <ul> <li>p1 - start point</li> <li>p2 - end point</li> </ul> <p>Methods:</p> <ul> <li>getX(y) - calculate the new X, given Y</li> <li>getY(x) - calculate the new Y, given X</li> <li>isParallel(r2) - check if r2 is parallel to the current rect</li> </ul> <h3>Circle:</h3> <p>Circle geometry. Attributes:</p> <ul> <li>radius</li> </ul> <p>Methods:</p> <ul> <li>getPositionByX(x) - calculate the Y value and return a point </li> <li>getPositionByAngle(angle) - calculate the X and Y values and return a point </li> </ul> <h3>Rectangle:</h3> <p>Rectangle geometry. Attributes:</p> <ul> <li>width</li> <li>height</li> </ul> <h3>Polygon:</h3> <p>Polygon geometry. Attributes:</p> <ul> <li>isStar - true to draw a star or false to draw a polygon</li> <li>radius - radius of the container circle</li> <li>innerRadius - radius of the middle circle</li> <li>points - points of the star or sides of the polygon</li> </ul> <h3>Heart:</h3> <p>Heart geometry.</p> <p>Methods:</p> <ul> <li>getPositionByAngle(angle) - calculate the X and Y values and return a point </li> </ul> <h2>Colors</h2> <h3>Color</h3> <p>Simple color element. Attributes:</p> <ul> <li>r - Red channel (0 - 255)</li> <li>g - Green channel (0 - 255)</li> <li>b - Blue channel (0 - 255)</li> <li>a - Alpha channel (0 - 1)</li> </ul> <p>Methods:</p> <ul> <li>toHex - convert channels to hexadecimal value</li> <li>toRGBA - return string of rgba values</li> <li>setHex - recieve an hex value and set the new color</li> </ul> <h3>Gradient</h3> <p>Gradient color element. Attributes:</p> <ul> <li>rect - Rect element to represent the linear direction or the center points fo the radial gradient circles</li> <li>colors - array of Color elements</li> <li>radius1 - radius of the inner circle (optional)</li> <li>radius2 - radius of the out circle (optional)</li> </ul> <p>Methods:</p> <ul> <li>addColor(color) - add a color to the colors array</li> <li>getGradient() - return the gradient element for painting in canvas</li> </ul> <h2>GenericObject</h2> <p>Every element is child of the Generic Object. That allow you to clone an object without breaking references, get an String that represent it, trace it on console and compare it with another object.</p> </section> <footer> <span>made by <a href="http://www.pedrocacique.com"><img alt="avatar" src="https://scontent.fcgh7-1.fna.fbcdn.net/t31.0-8/p960x960/11958099_10200916172781826_3235614628416290419_o.jpg"/></a> </span> </footer> <script src="js/index.js"></script>
</body>
</html>
#codevember 13 - Geometry - Script Codes CSS Codes
html, body{height: 100%;}
body { margin: 0; font-family: Helvetica, Arial; font-weight: 100; overflow: hidden;
}
canvas { background-color: rgb(244, 244, 244);
}
section{ padding: 10px; overflow: auto; height: 45%;
}
footer{ position: fixed; top:50%; width: 100%;
}
footer img{ border-radius: 100%; width: 30px; height: 30px; margin-left: 10px;
}
footer span{ display: block; padding: 10px; display: flex; justify-content: flex-end; align-items: center;
}
#codevember 13 - Geometry - Script Codes JS Codes
//---------- MAIN FUNCTION ----------
function init() { //-- CIRCLE -- var grd1 = new Gradient([], new Rect(new Point(cw / 4, ch / 4), new Point(cw / 4 , ch / 4)), 1, 50); grd1.addColor(new Color(81, 157, 239, 1)); grd1.addColor(new Color(97, 117, 137, 1)); var circle = new Shape(new Circle(10), new Point(cw / 4, ch / 4), grd1, { scale: 4 }); circle.draw(canvas); //-- HEART -- var grd = new Gradient([], new Rect(new Point(cw / 2 - 10, ch / 4), new Point(cw / 2 + 50, ch / 4))); grd.addColor(new Color(173, 60, 15, 1)); grd.addColor(new Color(229, 140, 105, 1)); var heart = new Shape(new Heart(), new Point(cw / 2, ch / 4), grd, { scale: 3 }); heart.draw(canvas); //-- Rectangle -- var rectangle = new Shape(new Rectangle(100, 50), new Point(3 * cw / 4 - 50, ch / 4 - 25), new Color(135, 206, 130, 1)); rectangle.draw(canvas); //-- Polygon: Triangle -- var rectangle = new Shape(new Polygon(50, 3), new Point(cw / 4, 3 * ch / 4), new Color(62, 74, 188, 1)); rectangle.draw(canvas); //-- Polygon: Star -- var star = new Shape(new Polygon(50, 5, true), new Point(cw / 2, 3 * ch / 4), new Color(242, 173, 55, 1)); star.draw(canvas); //-- Polygon -- var star = new Shape(new Polygon(50, 10), new Point(3 * cw / 4, 3 * ch / 4), new Color(191, 131, 193, 1)); star.draw(canvas);
}
//-----------------------------------
var canvas, ctx, cw, ch;
var FPS = 60;
var requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { return setTimeout(callback, FPS);
};
window.onload = function () { initCanvas(); ctx.clearRect(0, 0, cw, ch); init();
}
window.onresize = function () { initCanvas(); ctx.clearRect(0, 0, cw, ch); init();
};
function initCanvas() { canvas = document.getElementById('canvas'); ctx = canvas.getContext('2d'); cw = window.innerWidth; ch = window.innerHeight / 2; canvas.width = cw; canvas.height = ch;
}
//---------------- APP UTIL ------------------
function getRandomNumber(min, max) { return Math.random() * (max - min + 1) + min;
}
//---------- MY FRAMEWORK ------------
//----------- PROTOTYPES -------------
//===== GEOMETRY =====
//----- SHAPE -----
function Shape(geometry, position, color, properties) { this.position = (position == null || position.classname != "Point") ? new Point() : position; this.geometry = (geometry == null || geometry.constructor.name != "GenericObject") ? new Circle() : geometry; this.color = (color != null && geometry.constructor.name == "GenericObject" && ((color.classname == "Color") || color.classname == "Gradient")) ? color : null; this.lineColor = null; this.lineWidth = 1; this.scale = 1; this.decay = 0; if (properties != null) this.setProperties(properties); GenericObject.call(this, "Shape");
}
Shape.prototype = new GenericObject();
Shape.prototype.setProperties = function (properties) { for (var p in properties) { this[p] = properties[p]; }
}
Shape.prototype.draw = function (canvas) { if (this.scale > 0) { var ctx = canvas.getContext('2d'); var cw = canvas.width; var ch = canvas.height; ctx.beginPath(); if (this.lineWidth > 0 && (this.lineColor != null && (this.lineColor.classname == "Color" || this.lineColor.classname == "Gradient"))) { ctx.strokeStyle = (this.lineColor.classname == "Color") ? this.lineColor.toRGBA() : this.lineColor.getGradient(); ctx.lineWidth = this.lineWidth; } if (this.color != null && (this.color.classname == "Color" || this.color.classname == "Gradient")) { ctx.fillStyle = (this.color.classname == "Color") ? this.color.toRGBA() : this.color.getGradient(); } switch (this.geometry.classname) { case "Circle": ctx.arc(this.position.x, this.position.y, this.geometry.radius * this.scale, 0, Math.PI * 2); break; case "Rectangle": ctx.rect(this.position.x, this.position.y, this.geometry.width * this.scale, this.geometry.height * this.scale); break; case "Rect": ctx.moveTo(this.position.x, this.position.y); ctx.lineTo(this.geometry.p2.x * this.scale, this.geometry.p2.y * this.scale); break; case "Heart": for (var i = 0; i < Math.PI * 2; i += 0.05) { var p = this.geometry.getPositionByAngle(i); p.multiply(this.scale); p.add(this.position); if (i == 0) ctx.moveTo(p.x, p.y); else ctx.lineTo(p.x, p.y); } break; case "Polygon": var step = Math.PI * 2 / this.geometry.points; var angle = -Math.PI / 2; this.geometry.circle.radius *= this.scale; this.geometry.innerCircle.radius *= this.scale; for (var i = 0; i <= this.geometry.points; i++) { var p = this.geometry.circle.getPositionByAngle(angle); var p2 = this.geometry.innerCircle.getPositionByAngle(angle - step / 2); angle += step; if (i == 0) ctx.moveTo(this.position.x + p.x, this.position.y + p.y); else { if (this.geometry.isStar) { ctx.lineTo(this.position.x + p2.x, this.position.y + p2.y); } ctx.lineTo(this.position.x + p.x, this.position.y + p.y); } } break; } if (this.lineColor != null && this.lineColor.classname == "Color") ctx.stroke(); if (this.color != null) ctx.fill(); this.scale -= this.decay; }
}
//----- POINT -----
function Point(x, y) { this.x = (x != null && !isNaN(x)) ? x : 0; this.y = (y != null && !isNaN(y)) ? y : 0; GenericObject.call(this, "Point");
}
Point.prototype = new GenericObject();
Point.prototype.add = function (p2) { if (p2.classname != this.classname) return null; this.x += p2.x; this.y += p2.y; return this;
}
Point.prototype.distance = function (p2) { if (p2.classname != this.classname) return null; //Euclidean Disctance return Math.sqrt(Math.pow(this.x - p2.x, 2) + Math.pow(this.y - p2.y, 2) + Math.pow(this.z - p2.z, 2));
}
Point.prototype.manhatan = function (p2) { if (p2.classname != this.classname) return null; return (p2.x - p1.x) + (p2.y - p1.y) + (p2.z - p1.z);
}
Point.prototype.multiply = function (scale) { this.x *= scale; this.y *= scale; return this;
}
Point.prototype.isNear = function (p2, offset) { if (p2.classname != this.classname) return false; return (this.x > p2.x - offset && this.x < p2.x + offset && this.y > p2.y - offset && this.y < p2.y + offset)
}
//----- RECT -----
function Rect(p1, p2) { this.p1 = (p1 == null || p1.classname != "Point") ? new Point() : p1; this.p2 = (p2 == null || p2.classname != "Point") ? new Point(10, 0) : p2; this.m = (this.p2.y - this.p1.y) / (this.p2.x - this.p1.x); this.n = this.p2.y - this.m * this.p2.x; GenericObject.call(this, "Rect");
}
Rect.prototype = new GenericObject();
Rect.prototype.getX = function (y) { if (y == null || isNaN(y)) return null; return (y - this.n) / this.m;
}
Rect.prototype.getY = function (x) { if (x == null || isNaN(x)) return null; return this.m * x + this.n;
}
Rect.prototype.isParallel = function (r2) { if (r2.classname != this.classname) return false; else return this.m == r2.m;
}
//----- CIRCLE -----
function Circle(radius) { this.center = new Point(); this.radius = (radius != null && !isNaN(radius)) ? radius : 1; GenericObject.call(this, "Circle");
}
Circle.prototype = new GenericObject();
Circle.prototype.getPositionByX = function (x) { if (x == null || isNaN(x)) return null; else return new Point(x, Math.sqrt(Math.pow(this.radius, 2) - Math.pow(x, 2)));
}
Circle.prototype.getPositionByAngle = function (angle) { if (angle == null || isNaN(angle)) return null; var x = this.center.x + this.radius * Math.cos(angle); var y = this.center.y + this.radius * Math.sin(angle); return new Point(x, y);
}
//----- RECTANGLE -----
function Rectangle(width, height) { this.width = (width != null && !isNaN(width)) ? width : 1; this.height = (height != null && !isNaN(height)) ? height : this.width; GenericObject.call(this, "Rectangle");
}
Rectangle.prototype = new GenericObject();
//----- POLYGON/STAR -----
function Polygon(radius, points, isStar, innerRadius) { this.isStar = (isStar != null) ? isStar : false; this.radius = (radius != null && !isNaN(radius)) ? radius : 5; this.innerRadius = (innerRadius != null && !isNaN(innerRadius)) ? innerRadius : ((isStar) ? (this.radius / 2) : this.radius); this.points = (points != null && !isNaN(points)) ? points : 5; this.circle = new Circle(this.radius); this.innerCircle = new Circle(this.innerRadius); GenericObject.call(this, "Polygon");
}
Polygon.prototype = new GenericObject();
//----- HEART -----
function Heart() { GenericObject.call(this, "Heart");
}
Heart.prototype = new GenericObject();
Heart.prototype.getPositionByAngle = function (angle) { if (angle == null || isNaN(angle)) return null; var x = 16 * Math.pow(Math.sin(angle), 3); var y = -(13 * Math.cos(angle) - 5 * Math.cos(2 * angle) - 2 * Math.cos(3 * angle) - Math.cos(4 * angle)); return new Point(x, y);
}
//===== COLOR =====
//----- Color -----
function Color(r, g, b, a) { this.r = (r != null && !isNaN(r)) ? r : 0; this.g = (g != null && !isNaN(g)) ? g : 0; this.b = (b != null && !isNaN(b)) ? b : 0; this.a = (a != null && !isNaN(a)) ? a : 1; this.hex = this.toHex(); GenericObject.call(this, "Color");
}
Color.prototype = new GenericObject();
Color.prototype.toHex = function () { var bin = this.r << 16 | this.g << 8 | this.b; return (function (h) { return "#" + new Array(7 - h.length).join("0") + h })(bin.toString(16).toUpperCase())
}
Color.prototype.toRGBA = function () { return "rgba(" + this.r + "," + this.g + "," + this.b + "," + this.a + ")";
}
Color.prototype.setHex = function (hex) { this.r = hex >> 16; this.g = hex >> 8 & 0xFF; this.b = hex & 0xFF; this.hex = this.toHex();
}
//----- GRADIENT -----
function Gradient(colors, rect, radius1, radius2) { this.rect = (rect != null && (rect.constructor.name == "GenericObject" && rect.classname == "Rect")) ? rect : new Rect(); this.colors = (colors != null && Array.isArray(colors)) ? colors : []; this.radius1 = (radius1 == null || isNaN(radius1)) ? 0 : radius1; this.radius2 = (radius2 == null || isNaN(radius2)) ? 0 : radius2; GenericObject.call(this, "Gradient");
}
Gradient.prototype = new GenericObject();
Gradient.prototype.addColor = function (color) { if (color.constructor.name == "GenericObject" && color.classname == "Color") { this.colors.push(color); }
}
Gradient.prototype.getGradient = function () { var grd = null; if (this.radius1 == 0 || this.radius2 == 0) { grd = ctx.createLinearGradient(this.rect.p1.x, this.rect.p1.y, this.rect.p2.x, this.rect.p2.y); } else { grd = ctx.createRadialGradient(this.rect.p1.x, this.rect.p1.y, this.radius1, this.rect.p2.x, this.rect.p2.y, this.radius2); } for (var i = 0; i < this.colors.length; i++) { grd.addColorStop(i, this.colors[i].toHex()); } return grd;
}
//===== GENERICOBJECT =====
function GenericObject(name) { this.classname = name;
}
GenericObject.prototype.clone = function () { var copy = new GenericObject(this.classname); for (var attr in this) { if (this.hasOwnProperty(attr)) { if (this[attr].constructor.name == "GenericObject") copy[attr] = this[attr].clone(); else copy[attr] = this[attr]; } } return copy;
}
GenericObject.prototype.equals = function (obj2) { var isEquals = true; if (this.classname != obj2.classname) return false; for (var attr in this) { if (this.hasOwnProperty(attr) && obj2.hasOwnProperty(attr)) { if (this[attr].constructor.name == "GenericObject" && obj2[attr].constructor.name == "GenericObject") { if (!this[attr].equals(obj2[attr])) isEquals = false; } else if (this[attr] != obj2[attr]) isEquals = false; } } return isEquals;
}
GenericObject.prototype.toString = function () { var str = this.classname + "{"; for (var attr in this) { if (attr != "classname" && this.hasOwnProperty(attr)) { var obj2 = this[attr]; var substr = ""; if (obj2.constructor.name == "GenericObject") substr = obj2.toString(); else substr = this[attr]; str += attr + ": " + substr + ","; } } str = str.substring(0, str.length - 1); str += "}"; return str;
}
GenericObject.prototype.trace = function () { console.log(this.toString())
}
Developer | Pedro Cacique |
Username | phcacique |
Uploaded | November 20, 2022 |
Rating | 3 |
Size | 6,642 Kb |
Views | 18,216 |
Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!
Name | Size |
Web Theremin | 3,970 Kb |
Grid Interaction | 3,469 Kb |
Platform game mechanics | 2,799 Kb |
One page scrolling | 2,113 Kb |
Page transition | 2,127 Kb |
Aside Hover Menu | 1,938 Kb |
Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!
Name | Username | Size |
Owl Carousel - jumpTo | OwlFonk | 2,553 Kb |
Canvas Background Effect | Sonick | 3,513 Kb |
Free css icon set v2 - one div | Ben_jammin | 0 Kb |
Side Sliding Menu CSS | EduardL | 4,388 Kb |
Tooltip in table | Roine | 3,713 Kb |
Acorrdian 2016 | Milanodituti | 3,720 Kb |
Heartbeat | Apetrov | 2,079 Kb |
CSS eye follow | Pedrocampos | 2,592 Kb |
Simple jQuery Slider | Jurbank | 2,874 Kb |
Responsive Section hover effect to show content | Berdejitendra | 2,540 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!