My teacher let me make the website for his class a couple of years ago and I'm still developing for it.
I recently added a 3D turntable (Render out so many frames from a camera spinning around an object) feature. I want buttons on the side so that you can just click and hold and it'll go at a certain rate. (I used a CSS Triangle Generator to create it, but Jquery isn't picking up mousedown events... I'll figure this out ...). There's an HTML5 range in between that's been stylized.
The problem occurs when I get around 9 or 10 depending on the direction arrow clicked. No matter how many frames, it wants to just jump to the end. I assume it has something to do with my logic:
function Turntable(ttMethod) {
var slider;
if(typeof ttMethod !== 'undefined') slider = $('#tt-slider-input');
if(ttMethod == 'rotate') padVal = slider.val();
else if(ttMethod == 'rotate-r') { // ERROR POSSIBLY IN THESE STATEMENTS
padVal = slider.val();
//if(padVal >= slider.attr('max')) padVal = '0000';
if(padVal >= 0 && padVal < slider.attr('max')) padVal++;
else if(padVal == slider.attr('max')) padVal = 0;
else padVal = slider.attr('max');
//console.log(padVal);
slider.val(padVal);
}
else if(ttMethod == 'rotate-l') { // ERROR POSSIBLY IN THESE STATEMENTS
padVal = slider.val();
if(padVal <= slider.attr('max') && padVal > 0) padVal--;
else if(padVal == 0) padVal = slider.attr('max');
else padVal = 0;
//else if(padVal <= 0) padVal = slider.attr('max');
//console.log(padVal);
slider.val(padVal);
}
else return;
padVal = pad_with_zeroes(padVal,4);
$('#turntable').css('background-image','url('+slider.attr('data-folder')+slider.attr('data-base')+padVal+'.'+slider.attr('data-format')+'), url(images/loading.png)');
}
An example of a turntable might look like this: http://jsfiddle.net/ybDy8/4/
(A working version is at http://greengoosemarketing.com/ .. Just click on a thumbnail with a light grey and dark grey circle that resembles a turntable in the bottom left-hand corner. Those are turntables.)
Related
I am trying to create a simple project, using TypeScript and React, to be able to generate a new <div> that has random width and height (min/max 50/300px), and is randomly placed inside a wrapper (which for this example is 1920x1080).
Goal is to check if newly generated div rectangle is overlapping or not existing divs.
If not, create the element, else generate new position and size and check again, goal being to fill up the wrapper as much as possible since min/max size of div is set and have no overlapping ones.
So far I managed to write code for generating random positions and sizes, but I am stuck at checking collisions and sending message when empty space isn't left.
const [count,setCount]=useState(0)
const wrapper = document.getElementById('wrapper');
var posX:number,posY:number,divSizeH:number,divSizeW:number;
var willOverlap:boolean=false;
function createRandomRectangle(){
divSizeW = Math.round(((Math.random()*250) + 50));
divSizeH = Math.round(((Math.random()*250) + 50));
if (wrapper!=null) {
const width = wrapper.offsetWidth , height = wrapper.offsetHeight;
posX = Math.round( (Math.random() * ( width - divSizeW )) );
posY = Math.round( (Math.random() * ( height - divSizeH )) );
//checking collision
document.querySelectorAll('.Rectangle').forEach(element=>{
var r2 = element.getBoundingClientRect();
//my attempt //if(((posX>=r2.x&&posX<=r2.right)&&(posY>=r2.top&&posY<=r2.bottom))||((posX+divSizeW>=r2.x&&posX+divSizeW<=r2.right)&&(posY>=r2.top&&posY<=r2.bottom))||((posX>=r2.x&&posX<=r2.right)&&(posY+divSizeH>=r2.top//&&posY+divSizeH<=r2.bottom))||((posX+divSizeW>=r2.x&&posX+divSizeW<=r2.right)&&(posY+divSizeH>=r2.top&&posY+divSizeH<=r2.bottom))){
//copied from someone elses code for checking collisions
if((posX <= r2.x && r2.x <= posX+divSizeW) && (posY <= r2.y && r2.y <= posY+divSizeH) ||
(posX <= r2.x && r2.x <= posX+divSizeW) && (posY <= r2.bottom && r2.bottom <= posY+divSizeH) ||
(posX <= r2.x+r2.height && r2.x+r2.height <= posX+divSizeW) && (posY <= r2.y+r2.width && r2.y+r2.width <= posY+divSizeW) ||
(posX <= r2.x+r2.height && r2.x+r2.height <= posX+divSizeW) && (posY <= r2.y && r2.y <= posY+divSizeW)){
willOverlap=true;
while(willOverlap){
posX = Math.round((Math.random() * ( width- divSizeW)));
posY = Math.round((Math.random() * ( height- divSizeH)));
divSizeW = Math.round(((Math.random()*250) + 50));
divSizeH = Math.round(((Math.random()*250) + 50));
if(!(((posX>=r2.x&&posX<=r2.right)&&(posY>=r2.top&&posY<=r2.bottom))||((posX+divSizeW>=r2.x&&posX+divSizeW<=r2.right)&&(posY>=r2.top&&posY<=r2.bottom))||((posX>=r2.x&&posX<=r2.right)&&(posY+divSizeH>=r2.top&&posY+divSizeH<=r2.bottom))||((posX+divSizeW>=r2.x&&posX+divSizeW<=r2.right)&&(posY+divSizeH>=r2.top&&posY+divSizeH<=r2.bottom)))){
willOverlap=false;
}
}
}
})
}
}
//if there is no more place send message and dont create....
const newDiv = document.createElement('div');
newDiv.classList.add('Rectangle');
newDiv.style.width=divSizeW+"px";
newDiv.style.height=divSizeH+"px";
newDiv.style.left=posX+"px";
newDiv.style.top=posY+"px";
boxxy?.appendChild(newDiv);
setCount(count+1);
}
As you started to guess, you need to repeat your code (here new position & size + check collision) in case you find a collision.
But since you implement the repetition within the forEach loop of your list of already existing Rectangles, the newly generated position & size is not re-checked against the previous Rectangles (beginning of the list). Hence you may end up with still colliding elements.
Another issue, much more difficult, is to detect when your wrapper is "full", or rather when the empty space can no longer take any new of your Rectangles, given their minimum size. Because this step is so much more complex, let's leave it aside for now, and use a much more simplistic approach, by using a maximum number of repetitions.
With this simplification, your algorithm could look like:
const existingRectangles = document.querySelectorAll('.Rectangle');
let repCount = 0; // Number of repetitions
do {
var overlapping = false;
var newPositionAndSize = generateRandomPositionAndSize();
// Check for collision with any existing Rectangle.
// Use a classic for loop to be able to break it
// on the first collision (no need to check further)
for (let i = 0: i < existingRectangles.length; i += 1) {
if (checkCollision(existingRectangles[i], newPositionAndSize)) {
overlapping = true;
repCount += 1;
break; // No need to check the rest of the list
}
}
} while (overlapping && repCount < 1000);
if (overlapping) {
// If still overlapping, it means we could not find
// a new empty spot (here because of max repetitions reached)
showMessageWrapperIsFull();
} else {
// If we checked through the entire list without raising
// the overlapping flag, it means we have found
// a suitable empty spot
createNewRectangleAndInsertIt(newPositionAndSize);
}
I'm trying to do a sort of a multi element carousel:
I implemented left and right but I have problems with auto:
function addCarouselListener() {
data.forEach(function (carousel) {
carousel.previous.addEventListener('click', moveLeft);
carousel.next.addEventListener('click', moveRight);
});
}
function autoslide() {
var max =10, visible=6, count=visible;
max = 10
while (count < max) {
moveRight();
count +=1;
}
if (count=max) // go back
while(count > visible) {
moveLeft( )
count -=1;
}
First this is not really working always, I need to always work and have a timer.
Second, I need to pause if the user click on left,right(previous/next).
Please don't send me links to already done scripts, because I want to understand, plus I need something more custom.
I can clearly tell you that this line doesn't work as you'd expect :
if (count = max)
To compare equality between two variables you must use == or === if you'd like to also compare their type.
Also if you just do that like this, the slider will loop so fast that your browser will probably crash.
You want to use setInterval()
Here is a simple not-tested example :
var direction = 'right'
var current_position = 0
var max = 10
var delay = 500
var timer = false
function move_slider(){
if(direction == 'right')
current_position += 1
if(direction == 'left')
current_position -= 1
// move the slider
}
function auto_slide(){
console.log(current_position, direction)
move_slider()
if(current_position <= 0)
direction = 'right'
if(current_position >= max)
direction = 'left'
}
function set_auto_mode(){
timer = window.setInterval(auto_slide, delay)
}
function unset_auto_mode(){
window.clearInterval(timer)
timer = false
}
I implemented this example of hammertime in my website to swipe between images:
https://rawgit.com/hammerjs/hammer.js/master/tests/manual/nested.html
Now I want to create a voting like in a "HOT OR NOT"-voting, so at the the beginning there are only 2 images. But depending on if I swipe right to vote for HOT or swipe left to vote for NOT.
So it would look like this, but the user can't see the next (2nd) image before swiping:
[2] [1] [2]
So if I swipe right image [2] is appearing and [3] will be the next image and so on, no matter if I swipe right or left, because swiping just says if I think someone is hot or not. So this whole system is unlimited.
What should I change in the code to be able to swipe in both directions instead of only to the right like in the example and see the next image in both directions?
Do I have to change something in these lines?
onPan : function (ev) {
var indexNow = this.currentIndex;
var delta = dirProp(this.direction, ev.deltaX, ev.deltaY);
var percent = (100 / this.containerSize) * delta;
var animate = false;
if (ev.type == 'panend' || ev.type == 'pancancel') {
if (Math.abs(percent) > 20 && ev.type == 'panend') {
this.currentIndex += (percent < 0) ? 1 : -1;
}
percent = 0;
animate = true;
}
this.show(this.currentIndex, percent, animate);
For some reason, my Game of Life algorithm for JavaScript won't work. I tried to test it with a Blinker
but it very quickly did not work
(note, this is an infinite plane so those 2 at the bottom are actually above the top.)
It makes a very interesting design, but it isn't the Game of Life.
My code runs as
var RxC = []; //the array to hold information about the plane
var drawGame = function(first) {
for (var i=0;10000>i;i++) {//for each box
var x = i%100;//gets what x block it is
var y = Math.floor((i-x)/100);//gets what y block it is
var box = canvas.getContext('2d');
if (first) {
if (!RxC[y]) RxC[y] = [];
RxC[y][x] = Math.round(Math.random()) === 1;//random alive or dead
}else {
//get all neighbors
//I am using 99 because the plane is 100 wide and 100 tall, but since arrays count from 0, I have to use 99 instead of 100
var neighbors = 0;
var topY = (y-1 < 0) ? 99 : y-1;
var bottomY = (y+1 > 99) ? 0 : y+1;
var leftX = (x-1 < 0) ? 99 : x-1;
var rightX = (x+1 > 99) ? 0 : x+1;
//N
if (RxC[topY][x]) neighbors++;
//NE
if (RxC[topY][rightX]) neighbors++;
//E
if (RxC[y][rightX]) neighbors++;
//SE
if (RxC[bottomY][rightX]) neighbors++;
//S
if (RxC[bottomY][x]) neighbors++;
//SW
if (RxC[bottomY][leftX]) neighbors++;
//W
if (RxC[y][leftX]) neighbors++;
//NW
if (RxC[topY][leftX]) neighbors++;
if (RxC[y][x]) {//if block is alive
if (neighbors === 0 || neighbors >= 4) //kill block?
RxC[y][x] = false;
}else {//block is dead
if (neighbors === 3) //revive block?
RxC[y][x] = true;
}
}
if (RxC[y][x]) {//block is alive
box.fillStyle = '#000';
}else {//block is dead
box.fillStyle = '#eee';
}
box.fillRect(5*x,5*y,5,5);
box.strokeRect(5*x,5*y,5,5);
}
};
drawGame(true);//run game for first time, this will create the board originally
setInterval(drawGame, 25);
The code will basically
make the board randomly
run the rules
if the block is alive, and it has 0 neighbors or 4 or more neighbors, it will die
if the block is dead, and it has 3 neighbors, it will revive
I got the rules from here, but the rules seem to not work...at all.
I have tried to remove the infinite plane (the shorthand if else statements in the neighbor section), checked my code repeatedly, and I have tried to use Google and Wikipedia etc. to see if the rules I am using is incorrect, but I can't find anything saying different.
So my question is, are the rules I am using correct? If they are correct, is there something obviously incorrect in my code?
your rules are wrong. conways game of life.
if on then if(neighbors >3||neighbors<2) turn off.
if off then if(neighbors==3) turn on.
I am attempting to make objects move on screen based on force on the x-axis and y-axis. It seems to work properly when a force is applied to an object, but when the force is no longer applied, instead of the object continuing at the same velocity and direction, it goes off in a different direction with a different velocity. Is the error in this section of code? This is the only part I can think would be the problem.
var update = function (modifier) {
// rock going up/down wh
if(rocks[i].y > 0 && rocks[i].y < worldSizeY){
if(rocks[i] != null){
rocks[i].accelerationy = rocks[i].forcey/rocks[i].mass;
rocks[i].velocityy += (modifier*1000)*rocks[i].accelerationy;
rocks[i].y += (modifier*1000)*rocks[i].velocityy;
}
}
// rock going right/left
if(rocks[i].x < worldSizeX && rocks[i].x > 0){
if(rocks[i] != null){
rocks[i].accelerationx = rocks[i].forcex/rocks[i].mass;
rocks[i].velocityx += (modifier*1000)*rocks[i].accelerationx;
rocks[i].x += (modifier*1000)*rocks[i].velocityx;
}
}
rocks[i].forcex = 0;
rocks[i].forcey = 0;
}