Comments (5)
lineLength = randomInt(10, 100);
lineWidth = lineLength / randomInt(6, 10);
var branchingAngle = randomInt(10,20);
var stumpiness = randomInt(0, 4);
var branchThinningRate = randomInt(35, 85) * 0.01;
var frothiness = randomInt(0, 10);
var maxCurliness = 0; // 0.5 for CRAZY curly trees
var curliness = Math.random() * maxCurliness;
var chanceToMakeSpindlyAssTree = Math.random() * 0.4;
var chanceToBearFruit = 0;
var maxLeafSize = randomInt(5,15);
var r = randomInt(60, 80);
var g = randomInt(0, 20) - 10;
var b = randomInt(0, 20) - 10;
ctx.strokeStyle = 'rgb(' + [r, r-g, r-g-b].join(',') + ')';
var tree = new LSystem({
productions: {
'X': () => Math.random() < 0.7 ? 'FFF-[[X]+X]+F[+FX]-X' : 'FF-[X+]+FF[-FX]-XF', // was 0.7
'F': () => {
let r = Math.random();
if (r < chanceToMakeSpindlyAssTree)
return 'F-+F+++---';
if (r < 0.8 - curliness) return 'F' // was 0.8, F, but try F-F+ with curliness 0.5 for crazy twisty vines
if (r < 0.97 - curliness) return 'FF' // was 0.97, FF
if (r < 1.0) return 'FF+' // was 1.0, FF+
}
},
finals: {
'F': () => {
ctx.lineWidth += (Math.random() - 0.5) * 0.01;
ctx.beginPath()
ctx.moveTo(0, 0)
ctx.lineTo(0, lineLength / (tree.iterations + 1))
ctx.stroke()
//======= DRAW LEAVES ========/
if (ctx.lineWidth < lineWidth * 0.2) {
var previousAlpha = ctx.globalAlpha;
ctx.globalAlpha = 0.9;
var rb = randomInt(50, 150);
var g = randomInt(20, 50);
ctx.fillStyle = 'rgb(' + [rb, rb + g, rb].join(',') + ')';
var leafSize = (Math.random() / 2 + 0.5) * maxLeafSize;
ctx.fillRect(0,0,leafSize * (Math.random() / 2 + 0.5),leafSize / 2);
leafSize = (Math.random() / 2 + 0.5) * maxLeafSize;
ctx.fillRect(-leafSize,leafSize,leafSize * (Math.random() / 2 + 0.5),leafSize / 2);
ctx.globalAlpha = previousAlpha;
}
//======= END DRAWING LEAVES ========/
ctx.translate(0, (lineLength / (tree.iterations + 1)) - stumpiness) // stumpiness was 1.5
},
'+': () => { ctx.rotate((Math.PI / 180) * (branchingAngle + randomInt(0, 10))) }, // was 22.5
'-': () => { ctx.rotate((Math.PI / 180) * (-branchingAngle - randomInt(0, 10))) }, // was 22.5
'[': () => {
ctx.save();
ctx.lineWidth *= branchThinningRate; // was 0.65
// Make strokes lighter in branches
// to simulate depth
ctx.globalAlpha *= Math.random() * (1.0 - 0.6) + 0.6;
lineLength -= (frothiness); // was 10
},
']': () => {
ctx.restore();
ctx.lineWidth*=0.9;
lineLength += (frothiness); // was 10
}
}
});
return tree;
from lindenmayer.
I'm drawing leaves in the DRAW LEAVES section, when branches get to a certain thinness.
Ideally, though, I'd be able to render the tree twice - once with just branches, once with just leaves. Not sure how to do that though, any advice would be appreciated!
from lindenmayer.
Here's a better screenshot of the problem:
https://www.dropbox.com/s/p1o0m14k4bbryt0/Screenshot%202016-06-18%2001.33.00.png?dl=0
from lindenmayer.
Hey @dkmooers, thanks for trying the library!
I have thought about your problem and came up with the following: demo (code). Please note, I modified some attributes like color and width.
Some explanation to that solution:
To render leaves after branches, I used an offpage canvas context to render the leaves to, instead of the regular ctx.
Then, after tree.final()
has eventually finished, the offpage canvas is drawn on top of the regular canvas with ctx.drawImage(leavesCanvas, 0, 0)
.
Before drawing leaves into the second invisible canvas, I copy the transformation matrix of the regular ctx
into the leavesCtx
via leavesCtx.currentTransform = ctx.currentTransform;
to have all the translates and rotations correct.
Unfortunately, .currentTransform
is not supported in all browsers yet, so I used a polyfill to be able to copy the matrices.
I am sure there are other solutions to that problem, but the one above seemed the most elegant to me with your existing code base. Happy coding! :)
from lindenmayer.
Ah, that's an elegant solution! I was attempting to render two separate passes, keeping the random seed intact between each pass... a mess, and not very performant. Layer compositing makes a lot more sense! Looks like currentTransform doesn't work in my Chrome/OSX, so I'm grateful for the polyfill link as well.
Thanks so much for doing this, it works perfectly!
from lindenmayer.
Related Issues (20)
- Should we have built-in support for conditional productions, stochastic productions? HOT 16
- better setProduction docs
- How to have a production with multiple parameterised inputs HOT 3
- Make LSystem an overrideable ES6 class HOT 8
- benchmark L-Systems that are functional equal but differ in data types
- auto-conversion strings/list
- improve documentation HOT 1
- multiple productions on same symbol: object order not preserved
- transformClassicCSProduction being passed two arguments but only accepting one HOT 3
- help wanted: audit/improve CS-matching function
- use multi-element push instead
- context sensitive productions with contexts for left and right are only checked for left side
- How to make this library work in Internet Explorer? HOT 13
- FR: Support (or error out) with string axioms if you have parametric productions HOT 5
- FR: Pseudorandom number generators for stochastic functions
- More diverse examples
- a-frame component
- multiple classic context sensitive productions
- add option to treat all production lists stochastically HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lindenmayer.