Properties unavailable on my player ship object [closed] - javascript

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
please help to fix the script.
js:
//--- PLUGIN kalininHuyak IMPLEMENTATION ---
function KalininHuyak(options){
// --- properties ---
var huyakWrap = options.huyakWrap,
playerOffset = 10,
player = document.getElementById('player'),
xPosition = 200,
yPosition = 500;
// --- methods ----
playerShip = {
createPlayer: function (){
var player = $('<div />',
{
class: 'player',
id: 'player'
}
);
return player;
},
appendPlayer: function ( player, xPosition, yPosition){
player.appendTo('#huyakWrap');
player.attr('style', 'left: ' + xPosition + 'px; top: ' +
yPosition + 'px'
);
},
movePlayer: function (direction, offset){
var playerPositionX = player.style.left,
currentOffset = parseInt(playerPositionX, 10),
preCurrentOffset = currentOffset + (offset * direction);
if(preCurrentOffset < 0){
preCurrentOffset = 0;
}
else
if(preCurrentOffset > 920){
preCurrentOffset = 920;
}
player.style.left = preCurrentOffset + 'px';
}
}
// --- init ---
playerShip.appendPlayer(playerShip.createPlayer(), xPosition, yPosition );
// --- handlers ---
function onKeypress(keyCode){
var direction;
if(keyCode == 49){
direction = -1;
}
else
if(keyCode == 50){
direction = 1;
};
playerShip.movePlayer(direction, playerOffset);
}
// --- events ---
$(window).keypress( function(e)
{
onKeypress(e.which);
}
);
};
var kalininHuyak = new KalininHuyak(
{
huyakWrap: document.getElementById('huyakWrap')
}
);
html:
<div id="huyakWrap" class="huyak_wrap">
</div>
the problem appears after pressing 1, 2. said console that is specified property player. but this property is defined as
player = document.getElementById ('player')
it is accessible to any method.
is a living demo http://prozaik.16mb.com/js3/huYak2/

JSFiddle here: http://jsfiddle.net/fjdC9/1/
appendPlayer: function (player, xPosition, yPosition){
player.appendTo('#huyakWrap');
player.attr('style', 'left: ' + xPosition + 'px; top: ' + yPosition + 'px');
$player = $('#player');
},
Once I figured out the actual problem, it was simply a case of you trying to find the element before it exists (as the first step of your KalininHuyak method/class).
I moved the selector into the append (for now). You simply need to find the player object after it has been appended.

Related

Javascript - changing widths of images

I'm creating a tug of war website as a small project. My problem is that my javascript doesn't seem to want to work.
<script>
function randomTeam(){
var TeamV = Math.floor((Math.random() *2 ) + 1)
document.getElementById("TeamHeader").innerHTML = "Team: " + TeamV;
return TeamV;
}
function changeWidth(TeamV){
var MetreLeftV = document.getElementById('MetreLeft');
var MetreRightV = document.getElementById('MetreRight');
if(TeamV == 1){
MetreLeftV.style.width += '10px';
MetreRightV.style.width -= '10px';
}
else if(TeamV == 2){
MetreRightV.style.width += '10px';
MetreLeftV.style.width -= '10px';
}
}
</script>
Basically, when the page is loaded the randomTeam function is called, and when the button is pressed, it increments the size of your teams side, and decrements the side of the enemy's team. The problem is, it doesn't work at all. Could anyone help me see where this is going wrong? Thank you in advance :')
You can not just add 10px to the width. Convert the width to a number, add 10, than add px to it.
MetreLeftV.style.width = (parseFloat(MetreLeftV.style.width) + 10) + "px"
Do the same for the others and you will need a check for negative numbers.
function randomTeam() {
var TeamV = Math.floor((Math.random() * 2) + 1)
document.getElementById("TeamHeader").innerHTML = "Team: " + TeamV;
return TeamV;
}
function changeWidth(TeamV) {
var MetreLeftV = document.getElementById('MetreLeft');
var MetreRightV = document.getElementById('MetreRight');
console.log(parseFloat(MetreLeftV.style.width) + 10 + 'px')
if (TeamV == 1) {
MetreLeftV.style.width = parseFloat(MetreLeftV.style.width) + 10 + 'px';
MetreRightV.style.width = parseFloat(MetreRightV.style.width) - 10 + 'px';
} else if (TeamV == 2) {
MetreLeftV.style.width = parseFloat(MetreLeftV.style.width) - 10 + 'px';
MetreRightV.style.width = parseFloat(MetreRightV.style.width) + 10 + 'px'
}
}
window.setInterval( function () {
var move = randomTeam();
changeWidth(move);
}, 1000);
#MetreLeft {
background-color: red
}
#MetreRight {
background-color: yellow
}
<div id="TeamHeader"></div>
<div id="MetreLeft" style="width:200px">Left</div>
<div id="MetreRight" style="width:200px">Right</div>

Extending Touch EventListener to Additional DOM Element

I used a Codrops article/experiment to create an interactive environment for a local group to use at their conferences. The problem with this is the default interaction is not very intuitive. The template used Flickity.js and what seems like classie.js to create this sliding interface I am having trouble with.
The page can be found here:
www.eyeconic.tv/ky-ffa/
Issue: The only way to activate the view-full is by clicking on the html element:
<h2 class=".stack-title">
// After the stack is active you should be able to activate the full view by clicking on the first .stack-item used to create the thumbnail below it. This entire div should be clickable. Users are touching everywhere all over the screen and not actually clicking the title for the desired action. I hope this makes sense.
In other words you should be able to click the stack-title and the image below the title of each stack to pull the stack into the full view mode on the screen. Then click the x or anywhere else on the screen to close the full view.
The following is located in main.js and the reference I found to create the events I am referring to.
//
function initEvents() {
stacks.forEach(function(stack) {
var titleEl = stack.querySelector('.stack-title');
// expand/close the stack
titleEl.addEventListener('click', function(ev) {
ev.preventDefault();
if( classie.has(stack, 'is-selected') ) { // current stack
if( classie.has(bodyEl, 'view-full') ) { // stack is opened
var closeStack = function() {
classie.remove(bodyEl, 'move-items');
onEndTransition(slider, function() {
classie.remove(bodyEl, 'view-full');
bodyEl.style.height = '';
flkty.bindDrag();
flkty.options.accessibility = true;
canMoveHeroImage = true;
});
};
// if the user scrolled down, let's first scroll all up before closing the stack.
var scrolled = scrollY();
if( scrolled > 0 ) {
smooth_scroll_to(isFirefox ? docElem : bodyEl || docElem, 0, 500).then(function() {
closeStack();
});
}
else {
closeStack();
}
}
else if( canOpen ) { // stack is closed
canMoveHeroImage = false;
classie.add(bodyEl, 'view-full');
setTimeout(function() { classie.add(bodyEl, 'move-items'); }, 25);
bodyEl.style.height = stack.offsetHeight + 'px';
flkty.unbindDrag();
flkty.options.accessibility = false;
}
}
else if( classie.has(stack, 'stack-prev') ) {
flkty.previous(true);
}
else if( classie.has(stack, 'stack-next') ) {
flkty.next(true);
}
});
titleEl.addEventListener('mouseenter', function(ev) {
if( classie.has(stack, 'is-selected') ) {
canMoveHeroImage = false;
imghero.style.WebkitTransform = 'perspective(1000px) translate3d(0,0,0) rotate3d(1,1,1,0deg)';
imghero.style.transform = 'perspective(1000px) translate3d(0,0,0) rotate3d(1,1,1,0deg)';
}
});
titleEl.addEventListener('mouseleave', function(ev) {
// if current stack and it's not opened..
if( classie.has(stack, 'is-selected') && !classie.has(bodyEl, 'view-full') ) {
canMoveHeroImage = true;
}
});
});
window.addEventListener('mousemove', throttle(function(ev) {
if( !canMoveHeroImage ) return false;
var xVal = -1/(win.height/2)*ev.clientY + 1,
yVal = 1/(win.width/2)*ev.clientX - 1,
transX = 20/(win.width)*ev.clientX - 10,
transY = 20/(win.height)*ev.clientY - 10,
transZ = 100/(win.height)*ev.clientY - 50;
imghero.style.WebkitTransform = 'perspective(1000px) translate3d(' + transX + 'px,' + transY + 'px,' + transZ + 'px) rotate3d(' + xVal + ',' + yVal + ',0,2deg)';
imghero.style.transform = 'perspective(1000px) translate3d(' + transX + 'px,' + transY + 'px,' + transZ + 'px) rotate3d(' + xVal + ',' + yVal + ',0,2deg)';
}, 100));
// window resize
window.addEventListener( 'resize', throttle(function(ev) {
// recalculate window width/height
win = { width: window.innerWidth, height: window.innerHeight };
// reset body height if stack is opened
if( classie.has(bodyEl, 'view-full') ) { // stack is opened
bodyEl.style.height = stacks[flkty.selectedIndex].offsetHeight + 'px';
}
}, 50));
// Flickity events:
flkty.on('cellSelect', function() {
canOpen = false;
classie.remove(bodyEl, 'item-clickable');
var prevStack = stacksWrapper.querySelector('.stack-prev'),
nextStack = stacksWrapper.querySelector('.stack-next'),
selidx = flkty.selectedIndex,
cellsCount = flkty.cells.length,
previdx = selidx > 0 ? selidx - 1 : cellsCount - 1;
nextidx = selidx < cellsCount - 1 ? selidx + 1 : 0;
if( prevStack ) {
classie.remove(prevStack, 'stack-prev');
}
if( nextStack ) {
classie.remove(nextStack, 'stack-next');
}
classie.add(stacks[previdx], 'stack-prev');
classie.add(stacks[nextidx], 'stack-next');
});
flkty.on('dragStart', function() {
canOpen = false;
classie.remove(bodyEl, 'item-clickable');
});
flkty.on('settle', function() {
classie.add(bodyEl, 'item-clickable');
canOpen = true;
});
}
init();
})();
I wrapped the title and the first stack item in a div class .touch-me and it worked fairly well. I had previously tried to do this and received an error. But I may have mistyped something because it only made sense.
ISSUE: It works on mouseclick, but it is not working with touch on windows. I have untested it in any other environment because it will be deployed on a windows touch screen.
Although I cannot tell the layer not to close on touch when you swipe or touch the header image for the stack.... I'm afraid I do not have the skillset to properly modify the logic in the javascript since I do not entirely understand the plugins being used.

how to loop the dynamically generated id? [duplicate]

This question already has answers here:
jQuery or CSS selector to select all IDs that start with some string [duplicate]
(4 answers)
Closed 8 years ago.
/**Script**/
function AnimateFish() {
var Fish3 = $("#fish1").not(".HoverFish"),
theContainer = $("#container"),
maxLeft = theContainer.width() - Fish3.width() - 50,
maxTop = theContainer.height() - Fish3.height(),
leftPos = Math.floor(Math.random() * maxLeft),
topPos = Math.floor(Math.random() * maxTop) + 100,
imgRight = "Assets/fish-glow3-right.gif",
imgLeft = "Assets/fish-glow3.gif";
if (Fish3.position().left <= leftPos) {
$(this).css("background-image", 'url("' + imgRight + '")');
} else {
$(this).css("background-image", 'url("' + imgLeft + '")');
}
Fish3.animate({
"left": leftPos,
"top": topPos
}, 1800, AnimateFish);
}
AnimateFish();
Hi here the id "#fish1" that will generate dynamically like #fish1, #fish2 #fish3 ... actually i want this function should be run for all the id's that generate please give me the slution and ONE MAIN PROBLEM FISH IS GOING REVERSE FOR THIS CODE I TRIED LOT PLZ CAN U PPL HELP ME...
Add a class 'fish' to your #Fishes elements. Then:
$(".fish").each(function () {
//do your stuff here, $(this) representing your #Fish element
});
If you want to continue using ids for your "fish" (#fish1, #fish2, etc.)
See this question's answer
$("[id^=fish]")
This reads, "For each element with id that starts with 'fish'..."
Disclaimer : this is untested, but it should help you get a good pattern
function AnimateFish()
{
var aFish = $('[id^="fish"]:not(.HoverFish)'); // get the fish that aren't hovering
var oContainer = $("#container");
aFish.each(function(nIndex, oFish)
{
var nMaxLeft = oContainer.width() - oFish.width() - 50;
var nMaxTop = oContainer.height() - oFish.height();
var nLeftPos = Math.floor(Math.random() * nMaxLeft);
var nTopPos = Math.floor(Math.random() * nMaxTop) + 100;
var sImgRight = "Assets/fish-glow3-right.gif";
var sImgLeft = "Assets/fish-glow3.gif";
if (oFish.position().left <= nLeftPos)
$(this).css("background-image", 'url("' + sImgRight + '")');
else
$(this).css("background-image", 'url("' + sImgLeft + '")');
oFish.animate({
"left": nLeftPos,
"top" : nTopPos
}, 1800, AnimateFish);
}
}
AnimateFish();

Javascript better way to code this animation [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I first off all tried passing around the value of y back on the function but this caused the browser to slow as if an infinite loop had been created, the external frame variable stops this but I'd prefer to keep all the variables inside functions, is there a way I can achieve this without getting 'feedback'?
var frame=0;
function launch(){
var el=document.getElementById("selection");
setInterval(function(){ drawer(el,frame);},300);
}
function drawer(el,y){
if(y<20){
frame++;
el.style.top=20+frame+"px";
setInterval(function(){ drawer(el,frame);},300);
}
Use a closure, you also want to be using setTimeout or alternatively killing the interval when it's done:
function launch(){
var animator = function(el) {
var frame = 0;
var _this = {
draw : function() {
frame += 1;
el.style.top=20+frame+"px";
if(frame < 20) {
setTimeout(_this.draw, 300);
}
}
}
return _this;
}(document.getElementById("selection"));
setTimeout(animator.draw, 300);
}
Here's the updated code. You only have to create an interval once. Store it in a variable and clear it when the maximum is reached.
var frame = 0;
var running = null;
var max = 20;
var e = document.getElementById("selection");
function drawer() {
++frame
e.style.top = 20 + frame + "px";
if (frame == max) {
clearInterval(running);
running = null;
}
}
running = setInterval(drawer, 300);
Demo
Try before buy
Edit
As you said in your question you want to keep all variables inside the function, you can use this:
function drawer(e, frame) {
if ('undefined' == typeof e) {
var e = document.getElementById("selection");
}
if ('undefined' == typeof frame) {
var frame = 0;
}
++frame
e.style.top = 20 + frame + "px";
if (frame <= 20) {
setTimeout(function() { drawer(e, frame); }, 300);
}
}
drawer();
Demo
Try before buy
Here are few advices for you to improve your coding style:
Try to make a meaningful functions
Try to parametize numbers with meaningful and clear names
Write clean codes
Let me give you my version of what I understand you are trying to do.
As you can see, it is more clean and easy to read/understand for others.
I included a live demo at the bottom for you to fiddle with.
function launch() {
var el = document.getElementById('selection'),
maxY = 300,
stepY = 20,
interval = 100;
animateY(el, maxY, stepY, interval);
}
function moveToY(el, y) {
el.style.top = y + "px";
}
function animateY(el, maxY, stepY, interval) {
var y = 0;
var id = setInterval(function () {
if (y < maxY) {
y += stepY;
moveToY(el, y);
}
else {
clearInterval(id);
}
}, interval);
}
Here's a live demo: http://jsfiddle.net/A53sy/2/

jquery prototype for a commonly used function

I'm not too experienced in JQuery beyond standard api functionality, but I have a number of scrollers on my page which all use the same code, only they each have a few of their own settings (for example, separate heights and scroll limits, and current number of times they have been scrolled). I want to be able to use the code over and over again, but with each reference receiving its own set of variables. I think that prototypes are what I'm after, but I can't quite wrap my head around the examples I've seen of this. This is my scroller code:
$(document).ready(function() {
var scrollAmt = 50; //distance in pixels;
var scrollableAmt = $('#weblinks .container').outerHeight();
var viewAmt = $('#weblinks').outerHeight();
var maxScroll = Math.ceil((scrollableAmt-viewAmt) / scrollAmt);
var currentItem = 0;
function setScrollButtons(scrollRef,scrollAmount){
}
$("#weblinks .scrollDownBtn").click(function(){
if (currentItem <= maxScroll){
$('#weblinks .container:not(:animated)').animate({'top' : '-='+ scrollAmt + ''},500,function(){
currentItem++
});
} else {
currentItem = 0;
$('#weblinks .container:not(:animated)').animate({'top' : currentItem},500);
}
});
$("#weblinks .scrollUpBtn").click(function(){
if (currentItem > 0){
$('#weblinks .container:not(:animated)').animate({'top' : '+='+ scrollAmt + ''},500,function(){
currentItem--;
});
} else {
$('#weblinks .container:not(:animated)').animate({'top' : currentItem},500);
}
});
});
So essentially what I'd want to do is create a function or class, I guess, which accomplishes all of the above code, but be able to pass it a div reference to take the place of #weblinks, and maybe pass it a scroll amount, and multiple instances of this functionality be able to exist on the same page together. Anybody have any advice about the best way to go about this?
EDIT: I've added the HTML that will always exist for each scroller.
<div id="weblinks" class="scrollbar_container">
<div class="customScrollBox">
<div class="container">
<div class="content">
</div>
</div>
<a class="scrollUpBtn" href="javascript:void(0);"></a> <a class="scrollDownBtn" href="javascript:void(0);"></a>
</div>
</div>
My Bid:
(function($){
$.fn.extend({
customScroller: function(options){
return this.each(function(i,e){
var container = $(e).find('.container'),
content = $(e).find('.content'),
scrollUpBtn = $(e).find('.scrollUpBtn'),
scrollDownBtn = $(e).find('.scrollDownBtn');
var self = $(e);
var o = $.extend({}, $.fn.customScroller.defaults, options);
o.scrollableAmt = container.outerHeight();
o.viewAmt = self.outerHeight();
o.maxScroll = Math.ceil((o.scrollableAmt - o.viewAmt) / o.scrollAmt);
scrollDownBtn.click(function(){
console.log('DOWN -- current: '+o.currentItem);
if (o.currentItem <= o.maxScroll){
container.filter(':not(:animated)').animate({
top: '-='+o.scrollAmt
},500,function(){
o.currentItem++;
});
}else{
o.currentItem = 0;
container.filter(':not(:animated)').animate({
top: o.currentItem
},500);
}
});
scrollUpBtn.click(function(){
console.log('UP -- current: '+o.currentItem);
if (o.currentItem > 0){
container.filter(':not(:animated)').animate({
top: '+='+o.scrollAmt
},500,function(){
o.currentItem--;
});
}else{
container.filter(':not(:animated)').animate({
top: o.currentItem
},500);
}
});
});
}
});
$.fn.customScroller.defaults = {
scrollAmt: 50,
scrollableAmt: 0,
viewAmt: 0,
maxScroll: 0,
currentItem: 0
};
})(jQuery);
$('#weblinks').customScroller();
To answer your question, I use extend in a couple of places: one for the options, and the other for jQuery addon ability.
$.fn.extend tells jQuery this is extending its functionality.
$.extend({},$.fn.customScroller.defaults, option); allows you to call .customScroller({ scrollAmount: 10 }) and change the behavior of the scroll.
any other questions, please just ask.
This is a good candidate for jQuery plugin you can create for yourself. Of course if you want to spend some time and learn this principle :)
How to develop a jQuery plugin for some details of what and how jQuery plugins do
You could pretty simply refactor it in the case that all div's will have a sub container class. Something like:
function scrollExample(divId) {
var scrollAmt = 50; //distance in pixels;
var scrollableAmt = $(divId + ' .container').outerHeight();
var viewAmt = $(divId).outerHeight();
var maxScroll = Math.ceil((scrollableAmt-viewAmt) / scrollAmt);
var currentItem = 0;
function setScrollButtons(scrollRef,scrollAmount){
}
$(divId + " .scrollDownBtn").click(function(){
if (currentItem <= maxScroll){
$(divId + ' .container:not(:animated)').animate({'top' : '-='+ scrollAmt + ''},500,function(){
currentItem++
});
} else {
currentItem = 0;
$(divId + ' .container:not(:animated)').animate({'top' : currentItem},500);
}
});
$(divId + " .scrollUpBtn").click(function(){
if (currentItem > 0){
$(divId + ' .container:not(:animated)').animate({'top' : '+='+ scrollAmt + ''},500,function(){
currentItem--;
});
} else {
$(divId + ' .container:not(:animated)').animate({'top' : currentItem},500);
}
});
});
Then call it with something like:
$(document).ready(function() {
scrollExample('#webLinks');
}
If you had the actual reference to the object it would be slightly different, but still follow a similar principle.

Categories