Made a 3d cube. When a button is clicked, it rotates 50 deg left or right. I want it rotate an additional 50deg further when I click the same button. How do I achieve this? Here is my code right now:
//code to rotate cube
var rotateCube = document.getElementById('cube');
var moveLeft = document.getElementById('button-one');
var moveRight = document.getElementById('button-two');
moveLeft.onclick = function() {
rotateCube.style.webkitTransform = "rotateY(-50deg)";
}
moveRight.onclick = function() {
rotateCube.style.webkitTransform = "rotateY(50deg)";
}
in full here:
http://jsfiddle.net/camlatimer/6xp2dwe7/1/
I've searched around. There are examples like this one:
http://paulrhayes.com/experiments/cube-3d/
But I'm new to programming (2 months of fiddling with javascript in my free time) and don't understand much. I thought I could complete my objective pretty easily, but I'm stuck. I don't want to use any plugins. Just want to learn to really program things on my own. Any help would be appreciated.
LcSalazar is correct in regards to handling to rotation state of your cube, but my impression is that you're also interested in animating the rotation? If so, you'll want to check out CSS animations to handle those in-between states. This question covers dynamic values in CSS keyframed animations, which might be a bit beyond your current knowledge of CSS/JS, but spend some time with it and you'll be surprised how quickly it starts making sense.
Good luck!
The problem is with your premise:
"When a button is clicked, it rotates 50 deg left or right"
Actually, when a button is clicked, you are setting the rotation to be exactly -50deg or 50deg. It's an absolute assignment, not an increment.
In order to increment (since the rotation property is assigned by a text composed value), you'd need to store the value in a way where you can control it. For example, storing it in an external variable, and use it to increment the final value.
Something like this:
See working example
//Here's where you will store the actual value
var rotationValue = 0;
moveLeft.onclick = function() {
rotationValue -= 50;
rotateCube.style.webkitTransform = "rotateY("+ rotationValue +"deg)";
}
moveRight.onclick = function() {
rotationValue += 50;
rotateCube.style.webkitTransform = "rotateY("+ rotationValue +"deg)";
}
Related
I am trying to create an interface using PIXI JS where I have one main canvas i.e. the stage. After that I have a graphics element as a child to the stage. On clicking the graphic element I want to be able to zoom in on the element so that it fills up 80% of my canvas. My main goal is to have multiple elements and on clicking each of them the canvas zooms in and only that element is visible.
What I have done so far:
this.renderer = this.PIXI.autoDetectRenderer(window.innerWidth, window.innerHeight, {
transparent: true,
anitalias: true
});
this.stage = new this.PIXI.Container();
this.graphics = new this.PIXI.Graphics();
this.graphics.beginFill(0x2F7455);
this.graphics.drawRect(100, 100, 75, 50);
this.graphics.endFill();
this.graphics.interactive = true;
this.graphics.click = function (){
self.animate = true;
self.grow();
console.log("I WAS CLICKED");
}
this.stage.addChild(this.graphics);
animation() {
requestAnimationFrame(this.animation.bind(this));
this.renderer.render(this.stage);
}
grow() {
this.stage.pivot.x = this.graphics.width / 2;
this.stage.pivot.y = this.graphics.height / 2;
if (this.stage.scale.x < 20) {
this.stage.scale.x = (this.stage.scale.x * 1.25).toFixed(1);
}
if (this.stage.scale.y < 20) {
this.stage.scale.y = (this.stage.scale.y * 1.25).toFixed(1);
}
}
So on clicking the graphics element the canvas zooms in. But it's not what I want and I can't seem to wrap my head around the logic that will help me achieve what I want.
Anyone has any ideas on the approach I should take?
when asking something special like this you should always create a demonstration on plnkr.co or codepen so that the audience can quickly try out what you have done so far. This will lower the barrier for people to help you.
Regarding your problem. You need to know what size you want to achieve (the stage size), you want to know what size your object has (bounding box) and then you can calculate how much you have to resize. This would be the value 1.25 you just have hardcoded.
You also have to think about what you want to do when the object has another ratio (width vs. height) as the stage. Cut off, fit in or stretch ? This is the idiomatic way.
I also recommend you that you read through the sources of the pixi camera js library. You will quickly notice that I worked with matrix multiplications.
Don't let this fear you but encourage you to learn something new. Matrix calculations is the key for being very flexible here and useful in so many other areas of programming.
Good luck.
I decided to build a game in an effort to build up my skills as a developer. Although my game works at a basic level, I am unsatisfied with the architecture of the game. Basically, the player controls a fixed div with health at the bottom of the screen. The goal is for the player to collect black divs, dodge damage divs, and grab health and power ups along the way.
Codepen
All non player divs are the same size and generated the with the same function. The 'falling divs' are also assigned randomly being assigned a class with a bias.
function random(min,max){
return Math.round(Math.random() * (max-min) + min);
}
function dropDiv(){
var length = random(0, 54) * 22.5;
var velocity = 5000;
var size = 1.5;
var dropDivType = ["stack","stack","stack","stack","health",
"health", "power", "poison","poison","poison","poison","poison","poison","poison","poison","poison","poison"];
var typePicker = dropDivType[Math.floor(Math.random() * dropDivType.length)];
var thisBox = $("<div/>", {
class: `falling-box ${typePicker}` ,
style: `width:${size}%; height:0%;padding-bottom:${size}%;
left:${length}px; transition: transform ${velocity}ms linear;`
});
//insert box element
$(".game-container").append(thisBox);
//random start for animation
setTimeout(function(){
thisBox.addClass("move");
}, 40 );
//remove this object when animation is over
thisBox.one("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend",
function(event) {
$(this).remove();
});
}
Since all non-player, 'falling' divs are being generated with the same function, and are all fundamentally the same, I am thinking of prototype chaining for their generation. This isn't something I have done before and I was wondering if someone would give me advice on how to implement this. I am also not sure if I should put collision cases inside the falling div object or the player object.
Another concern I had was with the fact that I had multiple clocks in my game; one for player movement and one for generating the divs. I would like to integrate these clocks.
I am so very sorry to post such a wall of text on this wonderful site, but to be quite frank, I feel very lost and alone in my endeavor to get this done. Since I am not using HTML5 Canvas, my resources on creating a game engine/environment are very slim. Perhaps I should have dumbed down my game...
I have figured out a nice effect from application that needs several UI elements but also requires as much screen space as possible.
Idea of the effect is, that the UI buttons almost dissapear as soon as you move the mouse too away from them.
I have made a jsFiddle in case you'd like to see it.
It's quite simple:
window.addEventListener("mousemove", function(e) {
var rect = element.getBoundingClientRect();
//Measuring distance from top-left corner of the div
var top = rect.top+(rect.bottom-rect.top)/2;
var left = rect.left+(rect.right-rect.left)/2;
//Mouse position
var x = e.clientX;
var y = e.clientY;
//Thank pythagoras for this
var distance = Math.sqrt(Math.pow(x-left, 2)+Math.pow(y-top, 2));
//Brightness in interval <1, 0.1>
var brightness = Math.min(1, Math.max(0.1, 100/distance));
element.style.opacity = brightness+"";
});
This jsFiddle was also supposed to demonstrate problem I have - but it runs unexpectedly smoothly.
The problem is, that the browsers seem to buffer the CSS changes if they are too frequent. This is a very smart performance strategy but in my case it quite breaks the effect.
I have also uploaded test script here. In Google Chrome, buffering appeared to be so strong (and unsynchronized), that the buttons sometimes flickered.
Should I implement some frame-skip so that the browser buffer is not initiated by the animation effect?
My buttons have their bottom border cut off. If you'd know why this happens, please let me know in comments
I'm trying to create an animation with rotation. Now I first used a transition loop, but the rotation stops when the animation is done, and then repeats. I'm trying to achieve an animation in rotation which constantly goes on with the same speed. The effect is like using an ENTER_FRAME event in ActionScript 3 and giving the rotation some speed. I tried moving the objects x position succesfully with LimeJS:
lime.scheduleManager.schedule(function()
{
var pos = this.getPosition();
pos.x += 4;
this.setPosition(pos);
}, redsquare)
I try to achieve this with rotation aswell, but I don't know if this is possible. I tried this:
lime.scheduleManager.schedule(function()
{
var rotation = this.getRotation();
rotation.rotate += 4;
this.setRotation(rotation);
}, redsquare)
That doesn't work. How can I do this?
Try using lime.animation.RotateBy.
The documentation is here.
I'm trying to make LEAP motion to zoom in and out of a Canvas element and it works fine.
Right now when you put your hand in the active zone and move vertically or horizontally, the object moves accordingly. Fine.
When you put your hand towards the screen, the element decreases in size, when you pull it towards yourself, it increases in size. Also good.
The problems start when you want to move your hand away from the zone.
The element follows you to the extreme, which means it becomes very big (if you pull your hand back to yourself). I managed to implement a control where if I put away some fingers (e.g. point with a finger to a screen – PIN it), then the image freezes. Good.
Now, the problem and the question: how to make it that when I put my hand back in the control zone, the element starts from the same position where I left it? I've been struggling with it all night, and it was difficult and I didn't manage. So if you manage to do it, at least I owe you a beer :)
Here's the code (s is my canvas element, cameras[0] has the x,y properties, .ratio is the depth):
var defaultRatio = s.cameras[0].ratio;
var firstValidFrame = null;
var started = null;
var controller = new Leap.Controller({enableGestures: true});
controller.loop(function(frame) {
if(frame.hands.length > 0)
{
if (!firstValidFrame && frame.valid) firstValidFrame = frame;
var hand = frame.hands[0];
var position = hand.stabilizedPalmPosition;
var fingers = hand.fingers;
var center = hand.sphereCenter;
if (position[2] < 60) {
started = 1;
}
if (fingers.length > 2 && started) {
s.cameras[0].x = - position[0]*2;
s.cameras[0].y = position[1]*2-360;
s.cameras[0].ratio = defaultRatio - (position[2]*2/360);
}
}
});
I'm using it with Leap.Js library in my Node.Js app on Sigma.Js graph visualization in case you're interested...
Thank you so much!
I can think of two ways to do this:
Make the user move their hand to back to the same spot where the moving element was "dropped" before starting to move it again.
Move the element relative to the hand position. In other words, when you put your hand back into the active zone, save that position and as the hand moves, move the element by the same relative amount.