Linking two.js with dat.GUI - javascript

I want to link the change letter.linewidth = 10 with a control in dat.GUI.
Here is the code for the full letter variable:
var letter = two.interpret(document.querySelector('.assets svg'));
letter.linewidth = 10;
letter.cap = letter.join = 'round';
letter.noFill().stroke = '#333';
To add an element to dat.GUI it says in the docs "The property must be public, i.e. defined by this.prop = value", though when I add this. in front of letter.linewidth it breaks the functionality of two.js and does not interpret the SVG.
I'm kinda' new to JavaScript and having a tough time figuring this one out.
Any help would be greatly appreciated.

So after lots of playing around, I found the fix.
Here is the code to draw the SVG through two.js:
var letter = two.interpret(document.querySelector('.assets svg'));
letter.linewidth = 100;
letter.cap = letter.join = 'round';
letter.noFill().stroke = '#272727';
letter.scale = 1;
I was calling the letter wrong with dat.GUI. Here is my code for dat.GUI:
window.onload = function() {
var gui = new dat.GUI();
gui.add(letter, 'linewidth', 1, 100);
}
I don't know if this will be useful for anyone, but hey, hopefully this will help if somebody is running into the same problem.

Related

THREE JS applying Gradient to imported Models

The difference between the following two spheres - in terms of how their gradient colors were applied, comes down to one statement:
sphereGeometry = sphereGeometry.toNonIndexed();
Being that I really like the smoother look that .toNonIndexed() gives us, I tried applying it to some of the imported “.glb” models available on the THREE.js GIT - but it’s not working.
For example, here’s what happens when I use the horse model available here: https://github.com/mrdoob/three.js/blob/master/examples/models/gltf/Horse.glb
It basically completely ignore my colors and defaults to red and black for some reason.
But when I comment out the .toNonIndexed() line, it gives me the colors I asked for - except you definitely see the triangles, which is the look I'm trying to avoid:
Here's my code for loading the object:
function loadAny3DModel() {
loader.load("./Horse.glb", function(theHorse) {
console.log("===>'theHorse' has arrived!!!\n");
var horseScene = theHorse.scene;
horseMesh = horseScene.children[0];
var horseGeometry = horseMesh.geometry;
let horseMat = horseMesh.material;
var horseVertexPositionsArray = horseGeometry.attributes.position;
// Here's the command that isn't working:
// horseGeometry = horseGeometry.toNonIndexed();
// horseVertexPositionsArray = horseGeometry.attributes.position;
let theColor = new THREE.Color();
let colorsArray = [];
for(let i = 0; i < horseVertexPositionsArray.count; i++) {
let randC1 = "purple";
let randC2 = "white";
let chosenColor = i % 2 == 0 ? randC1 : randC2;
theColor.set(chosenColor);
colorsArray.push(theColor.r, theColor.g, theColor.b);
}
horseGeometry.setAttribute("color", new THREE.Float32BufferAttribute(colorsArray, 3));
horseMat.vertexColors = true;
render();
scene.add(horseScene);
}
}
What should I be doing to get the smoother gradients going?
=====================================================================
UPDATE:
Here is a very rough idea of what I'm trying to do: extend a gradient over an entire model, as opposed to every single triangle that is forming the model. (Compare this image to the one above.)
If you comment in the following line...
horseGeometry = horseGeometry.toNonIndexed();
...it means you create a new (!) geometry. As long as you don't assign the geometry back to Mesh.geometry, this code won't have any effect. So the fix is to add the following line after using toNonIndexed():
horseMesh.geometry = horseGeometry;

Javascript function for simple slider not executing onclick

Hello and thanks for looking up.
I have decided to learn Javascript by trial and error and Googling the stuff that I need. So far so good, but when I tried something a bit tricky, a slider, things got tough.
I dont really have good knowledge about syntax in Javascript and how expressions should be written in functions but I am trying.
So here we have a simple 4 images in a div with 2 arrows slider. When we click the arrow we want the counter to decrease by 1, we want to be sure it doesnt equal 0 and if it does we change it to 4, and when this is done we give the respective image ( img[counter] ) a z index of 50 for example. But it doesnt work. For some reason.
Here is a fiddle of the whole thing and hope I dont trouble you guys too much with this.
https://jsfiddle.net/wu2Lysrv/3/
function slideEngine() {
var img1 = document.querySelector("#img1");
var img2 = document.querySelector("#img2");
var img3 = document.querySelector("#img3");
var img4 = document.querySelector("#img4");
var counter = 1;
function slideL() {
counter--;
if (counter == 0) {
counter = 4;
}
img[counter].setAttribute("z-index", "50");
}
}
I would understand if someone goes aggro, since I bet this piece of code over there is very very wrong. Still I would like to learn how do I do it right.
The slideL function lives inside slideEngine, so your html doesn't have direct access to it.
One potential fix is to simply remove the wrapping function, since it doesn't seem to be used anywhere. However, there are other issues with the code that will prevent it from working. I've attempted to fix some below.
var img1 = document.querySelector("#img1");
var img2 = document.querySelector("#img2");
var img3 = document.querySelector("#img3");
var img4 = document.querySelector("#img4");
var counter = 1;
function slideL() {
counter--;
if (counter == 0) {
counter = 4;
}
window['img'+counter].style.zIndex = 50;
}
I didn't tes this, but try it out.

Building a grid of circles with text inside and... moving things around

I'm desperately trying to build a grid with circles and text inside. So far so good, I can do that... My real problem is being able to find each set and move it around (text AND circle). I've tried to look at similar issues, but I can't find out by myself... If someone could give me a clue, I'd greatly appreciate.
Here's a simplified code (only 1 line) that doesn't work :
$(function() {
// Prepare drawing zone
var paper = Raphael(document.getElementById('question'), '100%', '100%');
var word = 'Sunday';
var group = new Array();
// Draw 5 circles with text inside
for (i=0; i<5; i++) {
group[i] = paper.set();
group[i].push(paper.circle(50+i*60, 50, 30));
group[i].push(paper.text(50+i*60, 50, word));
group[i].click(function() {
group[i].translate(20,20); // HERE'S THE PROBLEM group[i] DOESN'T WORK !
group[i].rotate(Math.random() * 90);
});
}
});
I can't find out a way of 'calling' my sets for further reference...
Of course, If I have only 1 set (and no array=, it works...
Thanks for your help!
Celfred.
Edit : jsfiddle : http://jsfiddle.net/rrWqM/
Edit : I'm not sure I'm clear enough. What I would like is to be able to click on 1 circle (and text), and see THIS circle AND text move. If I click on another one, then the other one moves... It sounds so simple I can't believe I'm stuck on that... Thanks for the help.
Here is a [fiddle][http://jsfiddle.net/DusKv/1/]
The problem in your code is that the i variable does not have the right value when the click callback function is invoked. You can work around this by defining a local variable in the enclosing scope.
// Prepare drawing zone
var paper = Raphael(document.getElementById('question'), '100%', '100%');
var word = 'Sunday';
var group = new Array();
// Draw 10 circles with text inside
for (i = 0; i < 10; i++) {
var set = paper.set();
set.push(paper.circle(50 + i * 30, 50, 50));
set.push(paper.text(50 + i * 30, 50, word));
set.click(function() {
set.translate(Math.random() * 350, Math.random() * 380); // HERE'S THE PROBLEM group[i] DOESN'T WORK !
set.rotate(Math.random() * 90);
});
group[i] = set;
}
Eventually, I found a turnaround this way : jsfiddle
Now I get a correct reference in my click event.
I must admit I didn't quite understand my initial problem. If you could at least tell me if this new 'solution' sounds good to you, I'd appreciate ;-)
Celfred.

Is it possible to use multiple images in an HTML5 canvas?

I'm trying to load 10 different images into a canvas. My plan is to eventually animate these images but right now they seem to be overwriting one another. Here is my code:
var DrawLetters = function()
{
for (i = 0; i < howManyLetters; i++)
{
thisWidth = letters[i][0];
thisHeight = letters[i][1];
imgSrc = letters[i][2];
letterImg = new Image();
letterImg.onload = function()
{
context.drawImage(letterImg,thisWidth,thisHeight);
}
letterImg.src = imgSrc;
}
};
letters is an array with 10 elements where each element contains a path to the image. Any help on this would be greatly appreciated.
I've tried your code and the onload method always use the LAST value of the vars, not the value when the array was iterated.
Try setting the X and the Y to properties of the image object:
// I assume you are storing the coordinates where the letters must be
letterImg.setAtX = letter[i][XPOS];
letterImg.setAtY = letter[i][YPOS];
and on the onload:
context.drawImage(this, this.setAtX, this.setAtY);
this is the image raising the onload event.
Edit I've changed the properties used to carry the coordinates. Now they're setAtX/Y. You cannot use x and y because they're reserved.
You're drawing them on the same point. drawImage doesn't care about the height or width with your given parameters; it just wants an image and a coordinate. See https://developer.mozilla.org/en/Canvas_tutorial/Using_images
So, you're gonna need to give your images more data; something like:
thisWidth = letters[i][0];
thisHeight = letters[i][1];
imgSrc = letters[i][2];
thisX = letters[i][3]; //<---
thisY = letters[i][4]; //<---
letterImg = new Image();
letterImg.onload = function()
{
context.drawImage(letterImg, thisX, thisY, thisWidth, thisHeight);
//or, just
context.drawImage(letterImg, thisX, thisY);
}
letterImg.src = imgSrc;
Edit: Just had a thought - you can do it dymagically:
context.drawImage(letterImg, letters[i-1][0]+thisWidth, letters[i-1]+thisHeight, thisWidth, thisHeight);
With this way you'll have to check for stuff, but I think you get the overall intention.
You have to reposition the draw start position every time so the images arent overwritten.
[context . drawImage(image, dx, dy, dw, dh)][1]
There's an image on the link explaning what every parameter means.

Is There An Efficient jQuery Hittest?

I am creating a simple game with HTML, CSS, and JavaScript (jQuery). There is main ship, where all of the particles (bullets) originate from. They are each just divs. Then, enemy divs are places randomly throughout the screen.
I am looking for an efficient way to test if each particle is hitting a particular enemy. I have something that starts to work out fine, but gets bogged down incredibly fast. I am new to js, so my code is pretty messy and probably inefficient in many other ways. Any suggestions would be greatly appreciated!
Here is my section that creates enemies and tests for hitting:
var createEnemy = function(){
var xRandom = Math.floor(Math.random() * (containerW-50));
var yRandom = Math.floor(Math.random() * (containerH-50));
var newEnemy = $('<div class="enemy"></div>');
$(newEnemy).css({'left':xRandom,'top':yRandom}).appendTo('#container').fadeTo(200, .7);
var hitTest = setInterval(function(){
var enemy = $(newEnemy);
var particle = $('.particle');
var enemyT = enemy.offset().top;
var enemyB = enemy.height()+enemyT;
var enemyL = enemy.offset().left;
var enemyR = enemy.width()+enemyL;
var particleT = particle.offset().top;
var particleB = particle.height();
var particleL = particle.offset().left;
var particleR = particle.width();
if(particleT >= enemyT-particleB && particleT <= enemyB && particleL >= enemyL-particleR && particleL <= enemyR){
enemy.hide();
var removeEnemy = setTimeout(function(){
newEnemy.remove();
clearInterval(hitTest, 0);
},500);
}
}, 20);
}
var enemyInt = setInterval(createEnemy, 1000);
Is getting something like this to run smoothly in a browser realistic? Does my code just need some changes? You will probably need more context so:
EDIT 1/12/2012: Game Link Removed // Not Relevant
NOTE: This works best in Chrome and Safari at the moment.
EDIT 3/22/2011: Changed enemy fadeOut() to hide() so that you can see exactly when an enemy disappears (it is sometimes delayed). The hitTest only seems to trigger when you click on the actual enemy, so if it passes through, it is not being triggered.Also, I forgot to clearInterval on hitTest. This seemed to boost performance dramatically, but still isn't quite there.
If you want the best performance, drop jQuery and use native JavaScript.
If that isn't an option, profile the slowest parts and use native DOM there, e.g.
var newEnemy = $('<div class="enemy"></div>');
...becomes...
var newEnemy = document.createElement('div');
newEnemy.className = 'enemy';

Categories

Resources