I had a little problem today and thought I could try stack overflow. I'll be short and sweet (I removed lot of code to make this clear).
I recently discovered raphaeljs and I like it.
I make some circle draggable and it works fine like this:
Working script:
<script>
var paper = Raphael(100,100,500,500);
var circ = paper.circle(50,50,10)
var start = function(){ };
var move = function(dx,dy)
{
this.attr({cx: this.ox + dx, cy: this.oy + dy});
};
var up = function(){};
circ.drag(move,start,up);
<script>
Ok fine, it works and all functions are called properly!
BUT!
I want my move ,start ,up functions to be inside an object and not in the main page
SO
here's my next code
<script src="myobject.js"></script>
<script>
var paper = Raphael(100,100,500,500);
var myobj = new myobject("12","12","6");
<script>
Content of myobject.js :
function myobject(vx,vy,vr)
{
var x,y,r;
x=vx;y=vy;r=vr
paper.circle(x,y,r);
var start = function(){};
var move = function(dx,dy){};
var up = function(){};
this.drag(move,start,up); // error here this line crash
}
I cannot find how to use the drag function inside my object to make it draggable.
Well, that's it. I hope I've been clear and pardon me if there's anything wrong with the way I made this post but it is my first one!
Thanks to everyone that will try to help me!
Wilson
Inside myobject, this variable points to this object, and not to Raphael circle. As myobject does not have drag function, the code yields an error. To make it work, you must refer to Raphael object that has to be dragged, i.e.
function myobject(vx,vy,vr) {
...
this.circle = paper.circle(x,y,r);
...
this.circle.drag(move,start,up);
...
}
Fine, #Hubert OG was right but I also had to change the way I declared my function from
var start()=function
to
this.start() = function
WARNING: Fill your circle/forms because if you don't you have to click the fine border to move it around.
Related
I want to fade in and fade out one button in my web page using jQuery library. The problem is that the code below is not executing because of some syntax errors.
$(document).ready(y);
var y=function(){
$('div').mouseenter(z);
$('div').mouseleave(a);
};
var z=function(){
$('div').fadeTo('fast',1);
};
var a=function(){
$('div').fadeTo('fast',0.5);
};
Should anyone tell me what I am doing wrong here?
Variable and functions gets hosted to the top
this
$(document).ready(y);
var y = function(){
$('div').mouseenter(z);
$('div').mouseleave(a);
};
becomes like this when parsed by the browser
var y = undefined
$(document).ready(y); // undefined
// redefines y
y = function(){
$('div').mouseenter(z);
$('div').mouseleave(a);
};
so declering y first or chage it to a function helps
$(document).ready(y); // function
function y(){
$('div').mouseenter(z);
$('div').mouseleave(a);
};
EDIT:
I feel like you are doing an awful lot of work to fade in/out a button, try this instead?
$(document).ready(function(){
$('#button_id').fadeIn(1000);
$('#button_id').fadeOut(1000);
//fade in/out on the button click
$('#button_id').click(function(){
$('#button_id').fadeIn(1000);
$('#button_id').fadeOut(1000);
});
//the value parse into the fade methods will execute the animation over 1 second
});
I'm running a bit of javascript code in a loop, creating a chart (using google visualization). After all this code is run, I need to access these objects somewhere else. My problem is that I can't just call "chart" again, since it now has been over-written.
I've managed to figure out a really hacky solution which involves using the MVC # thing to dynamically generate something at run-time, which I then force as a variable name. It works, but I don't think it's the right way to approach this problem. Is there a way for me to dynamically change the name of the variable each time it's run?
The following code is run multiple times.
#{
var myChart = "cData" + Model.ChartId.ToString();
}
...
function () {
#myChart = new google visualization.ChartWrapper({ ... });
dashboard.bind(slider, #myChart);
dashboard.draw(data);
}
myChart changes every single time the code is run, giving me a really hacky string. By putting it without the ' marks, it becomes a variable at runtime.
After all that is run, I have a resize function which run the following:
#myChart .setOption('width', width);
#myChart .setOption('height', height);
#myChart .draw();
This is also super hacky. I took advantage of how javascript ignores spaces, so that I can treat #myChart like an object.
The result is riddled with syntax errors, but it still runs, and it runs with intended results. So my question is if there is a "proper" solution for this, instead of making separate javascript functions for each individual chart I need to make.
Thanks.
There's nothing wrong with what you've done, but it could be better.
First, you don't have to rely on a space to mix JavaScript and Razor.
#(myChart).setOption('width', width);
But that's still ugly.
Approach 1
<script>
// global (usual caveats about globals apply)
var charts = {};
</script>
#for( int i = 0; i < 10; i++ )
{
string chartId = "chart-" + i;
<script>
charts['#chartId'] = new Chart();
charts['#chartId'].setOption('width', width);
charts['#chartId'].setOption('height', height);
charts['#chartId'].draw();
</script>
}
Approach 2
<script>
function doResize(chart) {
chart.setOption('width', width);
chart.setOption('height', height);
chart.draw();
}
</script>
#for( int i = 0; i < 10; i++ )
{
<script>
(function () {
// limit the scope of the "chart" variable
var chart = new Chart();
// perform other init
// listen for resize in some manner
$(window).on("resize", function() {
doResize(chart);
});
})();
</script>
}
Approach #2 is my preferred method as it manages scope and is clear to read.
I've been looking through various tutorials on rayCasting with Box2D, but I haven't seen any clear examples. I was hoping someone familiar with box2dweb would be able to give a clear example of how one would go about setting up a simple function that would end up looking something like this:
var myRayCastFunction = function(p1,p2,maxFraction){
//Code here
}
The idea being that it would be usable like this:
var retVal = myRayCastFunction(p1,p2,maxFraction)
var fixture = retVal.fixture
var point = retVal.point
var normal = retVal.normal
var fraction = retVal.fraction
(in this case, I'm simply returning 1 intersection, say the nearest one, but would want to know how to make a similar one where retVel is a list of these outputs for each intersection)
I've been trying to understand all of the details of how RayCasting works in box2D, and I understand that this requires making a custom callback function (I think?), but I never figured out where that function needs to be placed, and what IT should be as well.
I started to answer this question because I happened to be about to add raycasting to my current project, and I realized there were actually some bugs in box2dweb that needed to be fixed before I could get it done. I'll link to the details instead of cluttering up this post:
http://www.iforce2d.net/box2dweb-fixes.txt
Here is how I've used the raycast callback successfully. Declare your callback class and give it a ReportFixture function:
var RaycastCallback = function() {
this.m_hit = false;
}
RaycastCallback.prototype.ReportFixture = function(fixture,point,normal,fraction) {
if ( ... not interested in this fixture ... )
return -1;
this.m_hit = true;
this.m_point = point;
this.m_normal = normal;
return fraction;
};
Now make an instance of that to pass to the worlds RayCast function:
var rayStart = ...;
var rayEnd = ...;
var callback = new RaycastCallback();
world.RayCast(callback, rayStart, rayEnd);
if ( callback.m_hit ) {
... use callback.m_point etc ...
}
Once the buttons are created, is there anyway I can add a link or use window.location method like this: `window.location = 'nextpage.html?foo=number'. I currently have this
var typeValue = location.search;
var typeStringValue= typeValue.replace("?type=","");
var containers = typeValue.replace("?type=multi","");
var containersValue = parseInt(containers);
var sampleLetter = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
function createButton(buttonName){
var buttonDivBlock = document.getElementById("sampleSets");
var buttonElement = document.createElement("input");
buttonElement.setAttribute("type","button");
buttonElement.setAttribute("name",buttonName);
buttonElement.setAttribute("value","Sample Set"+" "+buttonName);
buttonElement.setAttribute("id",buttonName);
buttonDivBlock.appendChild(buttonElement);
// document.getElementById(sampleLetter[i]).setAttribute('onclick',window.location='SampleInfo.html'+typeStringValue+bottonName);<!--add the button link -->
}
function setButtons(numberOfContainers){
for(i=0;i<numberOfContainers;i++){
createButton(sampleLetter[i]);
}
}
window.onload = function(){
setButtons(containersValue);
}
But document.getElementById("'"+sampleLetter[i]+"'").setAttribute('onclick',window.location='SampleInfo.html'+typeStringValue+bottonName);<!--add the button link -->
returns a null value.
Well, maybe I can help you along with an example:
function getFive() { return 5;}
callOtherFunction("stringArgument", getFive());
The second argument to callOtherFunction is going to be 5, not the getFive function. In many cases, like adding event listeners and AJAX code, you actually want to pass the function itself as an argument, so it can be called later. But if you don't want to bother declaring that function seperately, it looks like this:
callOtherFunction("stringArgument", function() { return 5; });
To make code look cleaner, you can press Enter after the { and make a multi-line function.
Now, all that in mind, take another look at the line you've commented out. Do you see what's missing? (PS. Apologies for the "egging-on" format - I find people get much better at figuring things out if I help them find the solution, rather than just showing it to them)
The sampleLetter variable is not defined where you are trying to use it (judging by commented code). Use the value you had just set to the id attribute a few lines earlier.
document.getElementById(buttonName).setAttribute( /* ... */ );
Or if you are trying to set it in the loop instead of in the createButton function, do not add the single quotes
document.getElementById(sampleLetter[i]).setAttribute( /* ... */ );
In the page I'm working on, when the user clicks on an object, one SVG group rotates out of the way while another rotates in.
The code as it is works just fine in WebKit, but it isn't working at all in Gecko. Here is the block of code that is not being executed by Gecko:
var totStep = dur*2/msrate, step=0;
window.timer = window.setInterval(function(){
if(step<totStep/2){
var inangle = -50*easeIn(step,totStep/2);
iris.setAttribute("transform","rotate("+inangle+" 23 -82)");}else{
var prog = easeOut2((step-(totStep/2)),totStep/2);
var outangle = 50*prog;
var down = 400*prog;
vinyl.setAttribute("transform","rotate("+(-50+outangle)+" 986 882)");
needle1.setAttribute("transform","translate(0 "+(-400+down)+")");
buttons.setAttribute("transform","translate(0 "+(-400+down)+")");}
step++;
if (step > totStep) {window.clearInterval(window.timer); return}
});
Most of this code is adapted from a function which opens the eye when the page is loaded, and that function works fine in Gecko, which is why this is enigmatic to me.
You can see the page with all of its source code at this page. The problematic function is written in the linked eye.js. The problem occurs when the user clicks on "DJ Docroot" under the "Music" section of the menu, which is accessed by clicking anywhere.
You're missing a second argument to setInterval to specify the interval at which the function should be called. So, for example, the following code works:
window.timer = window.setInterval(function(){
if(step<totStep/2){
var inangle = -50*easeIn(step,totStep/2);
iris.setAttribute("transform","rotate("+inangle+" 23 -82)");}else{
var prog = easeOut2((step-(totStep/2)),totStep/2);
var outangle = 50*prog;
var down = 400*prog;
vinyl.setAttribute("transform","rotate("+(-50+outangle)+" 986 882)");
needle1.setAttribute("transform","translate(0 "+(-400+down)+")");
buttons.setAttribute("transform","translate(0 "+(-400+down)+")");}
step++;
if (step > totStep) {window.clearInterval(window.timer); return}
},10);
Webkit probably just assumes a default value.
Also, just a suggestion, in the future, it might be easier to spot errors like these if you adopt code conventions that will make your code more legible: http://javascript.crockford.com/code.html
A tool like jslint will help with this.