The code included below generates and displays several swatches of procedurally-generated textures. To see it in action, copy it into a .html file and open that file in a web browser that runs JavaScript.
It’s still very much a work in progress. Only the “Rectangles” particle type is working right now, and there’s yet-unused code in there to build images from strings that came from a previous post. The “Ellipses” particle type might allow for some interesting effects, and it would be nice to have some way to control particle distribution, but I wasn’t able to figure out how all the transformations should work.
<html> <body> <script type='text/javascript'> // main function TextureGeneratorTest() { this.main = function() { var textureGenerator = new TextureGenerator(); var textureSizeInPixels = new Coords(100, 100); var particleMethod = TextureGenerator.ParticleMethods.Rectangles; var textureImages = [ textureGenerator.buildTextureImage ( "Sand", textureSizeInPixels, 1500, // numberOfParticles new Coords(3, 3), // particleSizeMin new Coords(3, 3), // particleSizeMax particleMethod ), textureGenerator.buildTextureImage ( "Cells", textureSizeInPixels, 800, // numberOfParticles new Coords(5, 5), // particleSizeMin new Coords(5, 5), // particleSizeMax particleMethod ), textureGenerator.buildTextureImage ( "Blotches", textureSizeInPixels, 500, // numberOfParticles new Coords(5, 5), // particleSizeMin new Coords(15, 15), // particleSizeMax particleMethod ), textureGenerator.buildTextureImage ( "Streaks", textureSizeInPixels, 100, // numberOfParticles new Coords(100, 5), // particleSizeMin new Coords(100, 5), // particleSizeMax particleMethod ), textureGenerator.buildTextureImage ( "Grain", textureSizeInPixels, 700, // numberOfParticles new Coords(50, 1), // particleSizeMin new Coords(30, 1), // particleSizeMax particleMethod ) ]; for (var i = 0; i < textureImages.length; i++) { var textureImage = textureImages[i]; document.write ( textureImage.name + ":" ); document.body.appendChild ( textureImage.systemImage ); } } } // classes // classes function Color(name, symbol, systemColor) { this.name = name; this.symbol = symbol; this.systemColor = systemColor; } { // static methods Color.getBySymbol = function(symbolToGet) { var returnValue = Color.Instances._SymbolToColorLookup.getByKey(symbolToGet); return returnValue; } // instances function Color_Instances() { // Not sure why rgba is necessary, but it is. this.Transparent = new Color("Transparent", ".", "rgba(0, 0, 0, 0)"); this.Black = new Color("Black", "k", "#000000"); this.Blue = new Color("Blue", "b", "#0000ff"); this.Gray = new Color("Gray", "a", "#808080"); this.Green = new Color("Green", "g", "#00ff00"); this.Orange = new Color("Orange", "o", "#ff8800"); this.Purple = new Color("Purple", "p", "#ff00ff"); this.Red = new Color("Red", "r", "#ff0000"); this.White = new Color("White", "w", "#ffffff"); this.Yellow = new Color("Yellow", "y", "#ffff00"); this._All = new Array ( this.Transparent, this.Black, this.Blue, this.Gray, this.Green, this.Orange, this.Purple, this.Red, this.White, this.Yellow ); for (var i = 0; i < this._All.length; i++) { var color = this._All[i]; this._All[color.symbol] = color; } } Color.Instances = new Color_Instances(); } function Coords(x, y) { this.x = x; this.y = y; } { // constants Coords.NumberOfDimensions = 2; // instance methods Coords.prototype.absolute = function() { this.x = Math.abs(this.x); this.y = Math.abs(this.y); return this; } Coords.prototype.add = function(other) { this.x += other.x; this.y += other.y; return this; } Coords.prototype.clear = function() { this.x = 0; this.y = 0; return this; } Coords.prototype.clone = function() { var returnValue = new Coords(this.x, this.y); return returnValue; } Coords.prototype.dimension = function(dimensionIndex) { var returnValue; if (dimensionIndex == 0) { returnValue = this.x; } else { returnValue = this.y; } return returnValue; } Coords.prototype.directions = function() { if (this.x > 0) { this.x = 1; } else if (this.x < 0) { this.x = -1; } if (this.y > 0) { this.y = 1; } else if (this.y < 0) { this.y = -1; } return this; } Coords.prototype.divide = function(other) { this.x /= other.x; this.y /= other.y; return this; } Coords.prototype.divideScalar = function(scalar) { this.x /= scalar; this.y /= scalar; return this; } Coords.prototype.equals = function(other) { return (this.x == other.x && this.y == other.y); } Coords.prototype.floor = function() { this.x = Math.floor(this.x); this.y = Math.floor(this.y); return this; } Coords.prototype.magnitude = function() { var returnValue = Math.sqrt(this.x * this.x + this.y * this.y); return returnValue; } Coords.prototype.multiply = function(other) { this.x *= other.x; this.y *= other.y; return this; } Coords.prototype.multiplyScalar = function(scalar) { this.x *= scalar; this.y *= scalar; return this; } Coords.prototype.normalize = function() { return this.divideScalar(this.magnitude()); } Coords.prototype.overwriteWith = function(other) { this.x = other.x; this.y = other.y; return this; } Coords.prototype.overwriteWithDimensions = function(x, y) { this.x = x; this.y = y; return this; } Coords.prototype.round = function() { this.x = Math.round(this.x); this.y = Math.round(this.y); return this; } Coords.prototype.subtract = function(other) { this.x -= other.x; this.y -= other.y; return this; } Coords.prototype.sumOfXAndY = function() { return this.x + this.y; } Coords.prototype.toString = function() { return "<Coords x='" + this.x + "' y='" + this.y + "' />" } Coords.prototype.trimToRange = function(rangeToTrimTo) { if (this.x < 0) { this.x = 0; } else if (this.x > rangeToTrimTo.x) { this.x = rangeToTrimTo.x; } if (this.y < 0) { this.y = 0; } else if (this.y > rangeToTrimTo.y) { this.y = rangeToTrimTo.y; } return this; } } function Image(name, systemImage) { this.name = name; this.systemImage = systemImage; } { // instance methods Image.prototype.clone = function() { var returnValue = new Image(); returnValue.filePath = this.filePath; returnValue.htmlElement = document.createElement("img"); returnValue.htmlElement.src = this.htmlElement.src; return returnValue; } } function ImageHelper() {} { // static methods ImageHelper.buildImageFromStrings = function(scaleMultiplier, stringsForPixels) { var sizeInPixels = new Coords ( stringsForPixels[0].length, stringsForPixels.length ); var canvas = document.createElement("canvas"); canvas.width = sizeInPixels.x * scaleMultiplier; canvas.height = sizeInPixels.y * scaleMultiplier; var graphics = canvas.getContext("2d"); var pixelPos = new Coords(0, 0); var colorForPixel = Color.Instances.Transparent; for (var y = 0; y < sizeInPixels.y; y ++) { var stringForPixelRow = stringsForPixels[y]; pixelPos.y = y * scaleMultiplier; for (var x = 0; x < sizeInPixels.x; x ++) { var charForPixel = stringForPixelRow[x]; pixelPos.x = x * scaleMultiplier; colorForPixel = Color.getBySymbol(charForPixel); graphics.fillStyle = colorForPixel.systemColor; graphics.fillRect ( pixelPos.x, pixelPos.y, scaleMultiplier, scaleMultiplier ); } } var imageFromCanvasURL = canvas.toDataURL("image/png"); var htmlImageFromCanvas = document.createElement("img"); htmlImageFromCanvas.width = canvas.width; htmlImageFromCanvas.height = canvas.height; htmlImageFromCanvas.src = imageFromCanvasURL; var returnValue = new Image(htmlImageFromCanvas); return returnValue; } } function TextureGenerator() {} { TextureGenerator.prototype.buildTextureImage = function ( name, sizeInPixels, numberOfParticles, particleSizeMin, particleSizeMax, particleMethod ) { var canvas = document.createElement("canvas"); canvas.width = sizeInPixels.x; canvas.height = sizeInPixels.y; var graphics = canvas.getContext("2d"); graphics.fillStyle = "rgba(0, 0, 0, .1)"; //graphics.strokeStyle = "rgba(0, 0, 0, .1)"; var particleSizeRange = particleSizeMax.clone().subtract ( particleSizeMin ); for (var n = 0; n < numberOfParticles; n++) { var particleSize = new Coords ( particleSizeMin.x + Math.random() * particleSizeRange.x, particleSizeMin.y + Math.random() * particleSizeRange.y ); var particlePos = new Coords ( Math.floor(Math.random() * sizeInPixels.x), Math.floor(Math.random() * sizeInPixels.y) ) particleMethod(graphics, particlePos, particleSize); } var imageFromCanvasURL = canvas.toDataURL("image/png"); var htmlImageFromCanvas = document.createElement("img"); htmlImageFromCanvas.width = canvas.width; htmlImageFromCanvas.height = canvas.height; htmlImageFromCanvas.src = imageFromCanvasURL; var returnValue = new Image(name, htmlImageFromCanvas); return returnValue; } TextureGenerator.ParticleMethods = new TextureGenerator_ParticleMethods() function TextureGenerator_ParticleMethods() { this.Ellipses = function(graphics, pos, size) { var scaleFactor = size.y / size.x; graphics.scale(1, scaleFactor); pos.divide(new Coords(scaleFactor, 1)); graphics.beginPath(); graphics.arc ( pos.x, pos.y, size.x / 2, 0, 2 * Math.PI ); graphics.fill(); graphics.closePath(); graphics.restore(); } this.Rectangles = function(graphics, pos, size) { pos.subtract ( size.clone().divideScalar(2) ); graphics.fillRect ( pos.x, pos.y, size.x, size.y ); } } } // run new TextureGeneratorTest().main(); </script> </body> </html>
i have a lot of jealous on you man
are you using json over here man?????????????
Er, not that I know of. Do you mean that syntax where you declare objects like:
var myObject = { myPropertyOne : 1, myPropertyTwo: ‘Two’ };
If so, I personally just don’t like that syntax. I guess it just doesn’t look enough like Java for me. I understand that you have to use it if you’re going to be a Real JavaScript Guy. I have no real interest in being one of those, though.
better you can write a own library man like query.Because you are much familiar with unobtrusive JavaScript right??? now iam learning unobtrusive JavaScript step by step