What I would like to know is: Is it possible to make the hard coded values of x1,y1, x2,y2
to be scaled to a world range?
For example, if I define the "world" view to be 1000 wide an 800 high,
and given the actual screen if 300 pixels wide by 200 pixels high,
I could calculate the world positions on the screen as:
Code:
<script>
var World = [1000,800];
var Actual = [300,200];
var x1 = 175;
var y2 = 125;
var x2 = 200;
var y2 = 225;
sx1 = x1 / World[0] * Actual[0];
sy1 = y1 / World[1] * Actual[1];
sx2 = x2 / World[0] * Actual[0];
sy2 = y2 / World[1] * Actual[1];
</script>
<!-- following line does not work -->
<line x1=sx1 y1=sy1 x2=sx2 y2=sy2 style="stroke-width:6; stroke:#006600;"/>
I want to use real world numbers like feet, yards, meters, etc
and scale them to the actual size of the graphics display
but I don't know how to NOT hard code into the SVG tags.
Since I know almost nothing about SVG graphics, I thought I'd share my lack of wisdom with you in the great tradition of online forums.... Actually, I have been curious about SVG, and just thought I might pick up something in your discussion - especially about the scaling parts. Anyway, it just struck me that as long as you could write the JavaScript that corresponds to your needs, you could always output the SVG tags in your HTML mark-up using that code. That would get you by until you can find the 'real' solution.
I am truly rotten when it comes to graphics, so when I need something like this, I generally rely on ImageMagick via PHP (or Perl, in days gone by). I've played with the HTML 5 <canvas> and managed to create a single SVG image, and I think there's a lot of ways I could use it once IE8 use is no longer significant. Good luck!
I've played around with it some more and can now do what I originally wanted in post #1.
It is not a clean as I would like as it requires defining a scaled SVG command for every normal SVG command.
Would still be interested in making the change using variables within the normal commands,
but this will suffice for my needs at this time.
I had a hunch that searching with the keyword "dynamic" might be helpful, but all of the references I found relied on JavaScript, so I think that's the only viable approach at the moment.
It might be a bit neater if you create SVG elements and append them to the world element instead of creating a string and updating the innerHTML, you could create a function that automates the creation of an SVG element like so
HTML Code:
function svgElement(element,attributes) {
var element = document.createElementNS("http://www.w3.org/2000/svg",element);
for(key in attributes) {
element.setAttribute(key,attributes[key]);
}
return element;
}
function scaleLine(x1,y1,x2,y2,stkW,stkC) {
x1 = scaleX(x1); y1 = scaleY(y1);
x2 = scaleX(x2); y2 = scaleY(y2);
var attributes = {
"x1":x1,
"x2":x2,
"y1":y1,
"y2":y2,
"style":"stroke-width:"+stkW+"; stroke:"+stkC
};
var line = svgElement("line",attributes);
return line;
}
function scaleCircle(x,y,r,stkW,stkC,stkF) {
x = scaleX(x); y = scaleY(y); r = scaleX(r);
var attributes = {
"cx":x,
"cy":y,
"r":r,
"stroke":stkC,
"stroke-width":stkW,
"fill":stkF
};
var circle = svgElement("circle",attributes);
return circle;
}
function init() {
var sx1 = sy1 = sx2 = sy2 = 0;
var world = document.getElementById('world');
sx1 = 0; sy1 = 10; sx2 = 0; sy2 = 110;
world.appendChild(scaleLine(sx1,sy1,sx2,sy2,'3','#ff0000'));
sx1 = 20; sy1 = 20; sx2 = 120; sy2 = 50;
world.appendChild(scaleLine(sx1,sy1,sx2,sy2,'3','#00ff00'));
sx1 = 30; sy1 = 30; sx2 = 140; sy2 = 100;
world.appendChild(scaleLine(sx1,sy1,sx2,sy2,'3','#0000ff'));
sx1 = 40; sy1 = 40; sx2 = 150; sy2 = 150;
world.appendChild(scaleLine(sx1,sy1,sx2,sy2,'3','#006600'));
sx1 = 75; sy1 = 25; sx2 = 200; sy2 = 25;
world.appendChild(scaleLine(sx1,sy1,sx2,sy2,'3','#006600'));
sx1 = 175; sy1 = 125; sx2 = 200; sy2 = 225;
world.appendChild(scaleLine(sx1,sy1,sx2,sy2,'3','#000000'));
sx1 = 100; sy1 = 150; sx2 = 40;
world.appendChild(scaleCircle(sx1,sy1,sx2,'#000000','3','#ff0000'));
}
You can also scale SVG images by using the viewbox attribute, so for example if you want to scale an SVG image that is 300 x 250 up to 1000 x 800 you can add a viewbox attribute to do so by setting the viewbox to the original size and then setting the height and width attributes to the size you want it to appear
It might be a bit neater if you create SVG elements and append them to the world element instead of creating a string and updating the innerHTML, you could create a function that automates the creation of an SVG element like so
HTML Code:
...
You can also scale SVG images by using the viewbox attribute, so for example if you want to scale an SVG image that is 300 x 250 up to 1000 x 800 you can add a viewbox attribute to do so by setting the viewbox to the original size and then setting the height and width attributes to the size you want it to appear
HTML Code:
...
Thank you, both versions work well.
Version 1 is a little closer to what I was trying to accomplish,
but I can see some other applications for the second as well.
I was not aware of the 'viewbox' command.
My ultimate goal is to be able to create dynamic optical ray diagrams
from user input for the display of simple and complex optical systems such as,
thin lens, telescopes, compound microscopes and simple optical principles like,
Snell's law, prismatic refraction and critical angles.
I want the user to be able to input values for the formulas to see the actions that occur.
Actual input values can be large and the resulting graphics would need to be scaled down
to be able to be displayed on the screen.
You have given me some possibilities that I shall investigate further. Thanks!
I'll post back if I come up with some acceptable designs for the displays.
Bookmarks