Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #21172 > unrolled thread
| Started by | jonas.thornvall@gmail.com |
|---|---|
| First post | 2013-09-06 01:12 -0700 |
| Last post | 2013-09-09 19:38 +0100 |
| Articles | 6 — 4 participants |
Back to article view | Back to comp.lang.javascript
Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral jonas.thornvall@gmail.com - 2013-09-06 01:12 -0700
Re: Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral Ken <usenet-so@abdiassoftware.com> - 2013-09-06 18:37 -0500
Re: Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral jonas.thornvall@gmail.com - 2013-09-06 23:15 -0700
Re: Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral Dr J R Stockton <reply1300@merlyn.demon.co.uk.invalid> - 2013-09-07 21:21 +0100
Re: Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral Stefan Weiss <krewecherl@gmail.com> - 2013-09-08 02:04 +0200
WAS: Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral Dr J R Stockton <reply1300@merlyn.demon.co.uk.invalid> - 2013-09-09 19:38 +0100
| From | jonas.thornvall@gmail.com |
|---|---|
| Date | 2013-09-06 01:12 -0700 |
| Subject | Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral |
| Message-ID | <2c5d4c48-eb2b-4ade-9a00-6dc5f50c8c87@googlegroups.com> |
What i basicly want to do is to call the function anime plotting it again and again from different offsets -> numberGlobal. ( The divisor set size of square, font)
But i can not get it to work, anyone good at canvas?
<!DOCTYPE html>
<html>
<head></head>
<canvas id="myCanvas" width="4000" height="4000">Your browser does not support the HTML5 canvas tag.</canvas>
<script type="text/javascript">
var divisorGlobal=10;
var numberGlobal=1;
function isPrime(n) {
if (isNaN(n) || !isFinite(n) || n%1 || n<2) return false;
var m=Math.sqrt(n);
for (var i=2;i<=m;i++) if (n%i==0) return false;
return true;
}
function clear() {
ctx.clearRect(0,0,4000,4000);
}
function anime() {
divisor=10;
number=1;
divisor=divisorGlobal;
number=numberGlobal;
asize=62/divisor;
storlek=54;
fstor=15/divisor;
afonten="bold "+fstor+"px Arial";
height=storlek/divisor;
width=storlek/divisor;
v_inner=0;
h_inner=0;
h_outer=0;
v_outer=0;
down=1;
back=2;
ctx.fillStyle='yellow';
ctx.fillRect(h_inner,v_outer,width,height);
ctx.fillStyle = "blue";
ctx.font = afonten;
if (divisor<3)ctx.fillText(number, h_inner+3, v_inner+12);
h_inner=h_inner+15;
h_outer=h_outer+asize;
number++;
while(number<10000){
vertical=0;
v_outer=0;
v_inner=v_outer;
h_inner=h_outer;
while(vertical<down){
ctx.fillStyle='yellow';
if(isPrime(number)){ctx.fillStyle='blue';}
ctx.fillRect(h_inner,v_inner,width,height);
ctx.fillStyle = "black";
if (divisor<3)ctx.fillText(number, h_inner+1, v_inner+12);
v_inner=v_inner+asize;
vertical++;
number++;
}
down++;
q=0;
h_inner=h_outer;
while(q<back){
ctx.fillStyle='yellow';
if(isPrime(number)){ctx.fillStyle='blue';}
ctx.fillRect(h_inner,v_inner,width,height);
ctx.fillStyle = "black";
if (divisor<3)ctx.fillText(number, h_inner+3, v_inner+12);
h_inner=h_inner-asize;
q++;
number++;
}
back++;
h_outer=h_outer+asize;
}
number++;
}
function draw() {
clear();
anime(divisorGlobal,numberGlobal);
numberGlobal++;
}
function init() {
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
return setInterval(anime,10);
}
init();
</script>
[toc] | [next] | [standalone]
| From | Ken <usenet-so@abdiassoftware.com> |
|---|---|
| Date | 2013-09-06 18:37 -0500 |
| Message-ID | <l0dp0n$lf4$1@speranza.aioe.org> |
| In reply to | #21172 |
On 06.09.2013 03:12, jonas.thornvall@gmail.com wrote:
> function draw() {
> clear();
> anime(divisorGlobal,numberGlobal);
> numberGlobal++;
> }
There are a lot of issues in the code but to target the essential -
To animate call like this:
function draw() {
clear();
anime(divisorGlobal,numberGlobal);
numberGlobal++;
requestAnimationFrame(draw);
}
requestAnimationFrame is a more low-level approach which works more
efficiently and guarantees to synchronize to the monitors VBLANK
(contrary to setInterval and setTimeout which can only approximate this
as they only takes integer value (60 fps is about 16.7 ms per frame).
This means smoother animations and less resources used.
Which of course implies that the setInterval call is removed and
replaced with a call to:
draw();
instead to start the loop.
requestAnimationFrame must be prefixed in some browsers (Firefox is
about to release version without need for prefix) so you can use this
shim by Paul Irish to get around that and to support older versions
(http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/)
(I corrected the name below):
window.requestAnimationFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
You might want to implement a condition in your loop so you are able to
stop it from running, something like this:
var isPlaying = true,
requestId;
function loop() {
// render here
if (isPlaying === true)
requestId = requestAnimationFrame(loop);
}
function stop() {
isPlaying = false;
cancelAnimationFrame(requestId);
}
(see link above for shim for cancelAnimationFrame - it's strictly not
necessary but it doesn't hurt to support it)
PS: 4000x4000 canvas is very huge... you /will/ run into performance
problems especially since you clear the whole canvas for each frame
(which will probably result in a lower framerate depending on computer).
When you are doing this:
function anime() {
divisor=10;
number=1;
divisor=divisorGlobal;
....
you are setting /properties/ on the *window* object. This is not
advicable. You should declare all of your variables like this:
function anime() {
var divisor=10;
var number=1;
var divisor=divisorGlobal;
....
or simply (this helps minifiers):
var divisor=10,
number=1,
divisor=divisorGlobal,
....
Local scoped variables are faster to look up for the parser than global
object properties so you may (or may not) notice performance gain
depending on various factors (browser implementation being one). And
setting things on window can accidentely override stuff.
Also, in your anime function include this line at the beginning:
ctx.beginPath();
Looking at it roughly it does not appear you are adding to path (can't
remeber on the fly if fillText() do or not, but in any case, if you do
these paths will accumulate and things will be slower and slower for
each frame. beginPath() resets the path.
Hope this is of some help.
--
Ken Fyrstenberg
Abdias Software
http://abdiassoftware.com/
(remove usenet- from address)
[toc] | [prev] | [next] | [standalone]
| From | jonas.thornvall@gmail.com |
|---|---|
| Date | 2013-09-06 23:15 -0700 |
| Message-ID | <0a7113fa-26a2-4b2d-ad12-4c53a49c1ba2@googlegroups.com> |
| In reply to | #21177 |
Den lördagen den 7:e september 2013 kl. 01:37:34 UTC+2 skrev Ken:
> On 06.09.2013 03:12, jonas.thornvall@gmail.com wrote:
>
> > function draw() {
>
> > clear();
>
> > anime(divisorGlobal,numberGlobal);
>
> > numberGlobal++;
>
> > }
>
>
>
> There are a lot of issues in the code but to target the essential -
>
>
>
> To animate call like this:
>
>
>
> function draw() {
>
>
>
> clear();
>
> anime(divisorGlobal,numberGlobal);
>
> numberGlobal++;
>
>
>
> requestAnimationFrame(draw);
>
> }
>
>
>
> requestAnimationFrame is a more low-level approach which works more
>
> efficiently and guarantees to synchronize to the monitors VBLANK
>
> (contrary to setInterval and setTimeout which can only approximate this
>
> as they only takes integer value (60 fps is about 16.7 ms per frame).
>
> This means smoother animations and less resources used.
>
>
>
> Which of course implies that the setInterval call is removed and
>
> replaced with a call to:
>
>
>
> draw();
>
>
>
> instead to start the loop.
>
>
>
> requestAnimationFrame must be prefixed in some browsers (Firefox is
>
> about to release version without need for prefix) so you can use this
>
> shim by Paul Irish to get around that and to support older versions
>
> (http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/)
>
> (I corrected the name below):
>
>
>
> window.requestAnimationFrame = (function(){
>
> return window.requestAnimationFrame ||
>
> window.webkitRequestAnimationFrame ||
>
> window.mozRequestAnimationFrame ||
>
> function( callback ){
>
> window.setTimeout(callback, 1000 / 60);
>
> };
>
> })();
>
>
>
> You might want to implement a condition in your loop so you are able to
>
> stop it from running, something like this:
>
>
>
> var isPlaying = true,
>
> requestId;
>
>
>
> function loop() {
>
> // render here
>
> if (isPlaying === true)
>
> requestId = requestAnimationFrame(loop);
>
> }
>
>
>
> function stop() {
>
> isPlaying = false;
>
> cancelAnimationFrame(requestId);
>
> }
>
>
>
> (see link above for shim for cancelAnimationFrame - it's strictly not
>
> necessary but it doesn't hurt to support it)
>
>
>
> PS: 4000x4000 canvas is very huge... you /will/ run into performance
>
> problems especially since you clear the whole canvas for each frame
>
> (which will probably result in a lower framerate depending on computer).
>
>
>
> When you are doing this:
>
>
>
> function anime() {
>
>
>
> divisor=10;
>
> number=1;
>
> divisor=divisorGlobal;
>
> ....
>
>
>
> you are setting /properties/ on the *window* object. This is not
>
> advicable. You should declare all of your variables like this:
>
>
>
> function anime() {
>
>
>
> var divisor=10;
>
> var number=1;
>
> var divisor=divisorGlobal;
>
> ....
>
>
>
> or simply (this helps minifiers):
>
>
>
> var divisor=10,
>
> number=1,
>
> divisor=divisorGlobal,
>
> ....
>
>
>
> Local scoped variables are faster to look up for the parser than global
>
> object properties so you may (or may not) notice performance gain
>
> depending on various factors (browser implementation being one). And
>
> setting things on window can accidentely override stuff.
>
>
>
> Also, in your anime function include this line at the beginning:
>
>
>
> ctx.beginPath();
>
>
>
> Looking at it roughly it does not appear you are adding to path (can't
>
> remeber on the fly if fillText() do or not, but in any case, if you do
>
> these paths will accumulate and things will be slower and slower for
>
> each frame. beginPath() resets the path.
>
>
>
> Hope this is of some help.
>
>
>
> --
>
> Ken Fyrstenberg
>
> Abdias Software
>
> http://abdiassoftware.com/
>
> (remove usenet- from address)
Thanks Ken i will try to implement your suggestions to see if i can get any extra performance. The primality test can of course be better.
I did realise i called wrong function...
I aim to call the program frome form in a frameset and pass parameter so i can set distance between primes +1,+2,+3... and startvalue and so one.
At redraw i will also make it possible to set separation in start compared with previous frame so you could set 1,2,3... numbers apart or square apart.
Also i will try to incorporate a geometrical offset, see example two below.
And of course the ability to set size of drawed squares and fonts from the form.
If you want to try 2 examples of what the script is intended to do copy below.
Thanks for your suggestions will try to implement them.
<!DOCTYPE html>
<html>
<head></head>
<canvas id="myCanvas" width="4000" height="4000">Your browser does not support the HTML5 canvas tag.</canvas>
<script type="text/javascript">
var divisorGlobal=10;
var numberGlobal=1;
function isPrime(n) {
if (isNaN(n) || !isFinite(n) || n%1 || n<2) return false;
var m=Math.sqrt(n);
for (var i=2;i<=m;i++) if (n%i==0) return false;
return true;
}
function clear() {
ctx.clearRect(0,0,800,800);
}
function anime() {
divisor=2;
//divisor=divisorGlobal;
number=numberGlobal;
asize=67/divisor;
storlek=54;
fstor=15/divisor;
afonten="bold "+fstor+"px Arial";
height=storlek/divisor;
width=storlek/divisor;
v_inner=0;
h_inner=0;
h_outer=0;
v_outer=0;
down=1;
back=2;
ctx.fillStyle='yellow';
ctx.fillRect(h_inner,v_outer,width,height);
ctx.fillStyle = "blue";
ctx.font = afonten;
if (divisor<3)ctx.fillText(number, h_inner+3, v_inner+12);
h_inner=h_inner+15;
h_outer=h_outer+asize;
number++;
while(number<10000){
vertical=0;
v_outer=0;
v_inner=v_outer;
h_inner=h_outer;
while(vertical<down){
ctx.fillStyle='yellow';
if(isPrime(number)){ctx.fillStyle='blue';}
ctx.fillRect(h_inner,v_inner,width,height);
ctx.fillStyle = "black";
if (divisor<3)ctx.fillText(number, h_inner+1, v_inner+12);
v_inner=v_inner+asize;
vertical++;
number++;
}
down++;
q=0;
h_inner=h_outer;
while(q<back){
ctx.fillStyle='yellow';
if(isPrime(number)){ctx.fillStyle='blue';}
ctx.fillRect(h_inner,v_inner,width,height);
ctx.fillStyle = "black";
if (divisor<3)ctx.fillText(number, h_inner+3, v_inner+12);
h_inner=h_inner-asize;
q++;
number++;
}
back++;
h_outer=h_outer+asize;
}
number++;
}
function draw() {
clear();
anime(divisorGlobal,numberGlobal);
numberGlobal++;
}
function init() {
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
return setInterval(draw,0);
//draw();
}
init();
</script>
Or this one with offset 1.
<!DOCTYPE html>
<html>
<head></head>
<canvas id="myCanvas" width="4000" height="4000">Your browser does not support the HTML5 canvas tag.</canvas>
<script type="text/javascript">
var divisorGlobal=10;
var numberGlobal=1;
function isPrime(n) {
if (isNaN(n) || !isFinite(n) || n%1 || n<2) return false;
var m=Math.sqrt(n);
for (var i=2;i<=m;i++) if (n%i==0) return false;
return true;
}
function clear() {
ctx.clearRect(0,0,800,800);
}
function anime() {
divisor=2;
//divisor=divisorGlobal;
number=numberGlobal;
asize=67/divisor;
storlek=54;
fstor=15/divisor;
afonten="bold "+fstor+"px Arial";
height=storlek/divisor;
width=storlek/divisor;
v_inner=0;
h_inner=0;
h_outer=0;
v_outer=0;
down=1;
back=2;
//ctx.fillStyle='yellow';
//ctx.fillRect(h_inner,v_outer,width,height);
//ctx.fillStyle = "blue";
//ctx.font = afonten;
//if (divisor<3)ctx.fillText(number, h_inner+3, v_inner+12);
//h_inner=h_inner+15;
h_outer=h_outer+asize;
//number++;
while(number<10000){
vertical=0;
v_outer=0;
v_inner=v_outer;
h_inner=h_outer;
while(vertical<down){
ctx.fillStyle='yellow';
if(isPrime(number)){ctx.fillStyle='blue';}
ctx.fillRect(h_inner,v_inner,width,height);
ctx.fillStyle = "black";
if (divisor<3)ctx.fillText(number, h_inner+1, v_inner+12);
v_inner=v_inner+asize;
vertical++;
number++;
}
down++;
q=0;
h_inner=h_outer;
while(q<back){
ctx.fillStyle='yellow';
if(isPrime(number)){ctx.fillStyle='blue';}
ctx.fillRect(h_inner,v_inner,width,height);
ctx.fillStyle = "black";
if (divisor<3)ctx.fillText(number, h_inner+3, v_inner+12);
h_inner=h_inner-asize;
q++;
number++;
}
back++;
h_outer=h_outer+asize;
}
number++;
}
function draw() {
clear();
anime(divisorGlobal,numberGlobal);
numberGlobal++;
}
function init() {
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
return setInterval(draw,0);
//draw()
}
init();
</script>
[toc] | [prev] | [next] | [standalone]
| From | Dr J R Stockton <reply1300@merlyn.demon.co.uk.invalid> |
|---|---|
| Date | 2013-09-07 21:21 +0100 |
| Message-ID | <4L3Y5fIEr4KSFwEb@invalid.uk.co.demon.merlyn.invalid> |
| In reply to | #21172 |
In comp.lang.javascript message <2c5d4c48-eb2b-4ade-9a00-6dc5f50c8c87@go oglegroups.com>, Fri, 6 Sep 2013 01:12:03, jonas.thornvall@gmail.com posted: >What i basicly want to do is to call the function anime plotting it again and again from different offsets -> numberGlobal. ( The divisor set >size of square, font) > >But i can not get it to work, anyone good at canvas? > The first thing you should do is learn how English should be written. The second is to read the newsgroup FAQ and see how to write questions for the group. And the third is to start with the simplest possible Canvas and draw the simplest lines on that, getting that right and advancing stepwise whenever your understanding increases. For your primes, I suggest the Sieve of Eratosthenes; on my P4/3G WinXP PC, that takes about 4ms in FF23 & 1ms in Opera 12.16 to calculate primes up to 11111. Consider also those of Atkin and Sundaram, if more speed is needed. FOR OTHERS ALSO : My pages contain shown code actuated by buttons. Usually, it is thought to be obvious that a given button just calls a certain function, but sometimes that is not the case, even though onClick has been set to a shortish string. I **NEVER** like to duplicate code so that one change needs two edits. I have something partly like the following Form, in js-misc0.htm#SE : <form action="#"> <input type=text name=X size=6 value=333> <input type=button value=" B " onClick="TA1.value=EratoB(+X.value)"> <input type=button value=" ? " onClick="TF=this.form ; eval(this.title)" title="TF.TA1.value=EratoB(+TF.X.value)"> <br><textarea name=TA1 rows=6 cols=66 readonly></textarea> </form> There, the buttons do the same when clicked, except that the second pollutes TF, wherever that may be, and hovering over the button reveals its effective code. Of course, 'value' can be used instead of 'title'. Untested : I suppose that I can use onClick="Oozlum(this)" and define Oozlum elsewhere. Any suggestions for improvements? TNNR. FYI - Jibbering may be slow, but patience is a rewarded virtue. -- (c) John Stockton, nr London UK Reply address via Home Page. news:comp.lang.javascript FAQ <http://www.jibbering.com/faq/index.html>. <http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources. <http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
[toc] | [prev] | [next] | [standalone]
| From | Stefan Weiss <krewecherl@gmail.com> |
|---|---|
| Date | 2013-09-08 02:04 +0200 |
| Message-ID | <l0getk$ksp$1@news.albasani.net> |
| In reply to | #21192 |
On 2013-09-07 22:21, Dr J R Stockton wrote:
> FOR OTHERS ALSO :
>
> My pages contain shown code actuated by buttons. Usually, it is thought
> to be obvious that a given button just calls a certain function
It's the most common case, but with event bubbling and capturing, and
the possibility of attaching multiple listeners to an event, no such
assumption should be made.
> I have something partly like the following Form, in js-misc0.htm#SE :
>
> <form action="#">
>
> <input type=text name=X size=6 value=333>
>
> <input type=button value=" B " onClick="TA1.value=EratoB(+X.value)">
>
> <input type=button value=" ? "
> onClick="TF=this.form ; eval(this.title)"
> title="TF.TA1.value=EratoB(+TF.X.value)">
>
> <br><textarea name=TA1 rows=6 cols=66 readonly></textarea>
>
> </form>
>
>
> There, the buttons do the same when clicked, except that the second
> pollutes TF, wherever that may be, and hovering over the button reveals
> its effective code.
Without leakage:
<input type=button value=" ? "
onClick="eval('TA1.value=' + this.title)"
title="EratoB(+X.value)">
Still shows the relevant code in the title (which, I think, is what you
wanted).
> Untested : I suppose that I can use onClick="Oozlum(this)" and define
> Oozlum elsewhere.
Of course you can. Personally, I would much prefer a helper function,
compared to relying on the rather unintuitive identifier resolution in
event attributes (even more so in form elements).
> Any suggestions for improvements? TNNR.
If two buttons (or two *anything*) do the same thing, they should be
combined into a single function (DRY). You can still eval() code from
there, if you must.
- stefan
[toc] | [prev] | [next] | [standalone]
| From | Dr J R Stockton <reply1300@merlyn.demon.co.uk.invalid> |
|---|---|
| Date | 2013-09-09 19:38 +0100 |
| Subject | WAS: Make an anime that draws primes different from offsets number++ , it's a variant of ulam spiral |
| Message-ID | <FanH9boAXhLSFwaH@invalid.uk.co.demon.merlyn.invalid> |
| In reply to | #21197 |
In comp.lang.javascript message <l0getk$ksp$1@news.albasani.net>, Sun, 8
Sep 2013 02:04:04, Stefan Weiss <krewecherl@gmail.com> posted:
>On 2013-09-07 22:21, Dr J R Stockton wrote:
>> FOR OTHERS ALSO :
>>
>> My pages contain shown code actuated by buttons. Usually, it is thought
>> to be obvious that a given button just calls a certain function
>
>It's the most common case, but with event bubbling and capturing, and
>the possibility of attaching multiple listeners to an event, no such
>assumption should be made.
I meant that "obvious" to be taken in the context of the page section in
question and on the assumption that the page is intended to be helpful.
>> I have something partly like the following Form, in js-misc0.htm#SE :
>>
>> <form action="#">
>>
>> <input type=text name=X size=6 value=333>
>>
>> <input type=button value=" B " onClick="TA1.value=EratoB(+X.value)">
>>
>> <input type=button value=" ? "
>> onClick="TF=this.form ; eval(this.title)"
>> title="TF.TA1.value=EratoB(+TF.X.value)">
>>
>> <br><textarea name=TA1 rows=6 cols=66 readonly></textarea>
>>
>> </form>
>>
>>
>> There, the buttons do the same when clicked, except that the second
>> pollutes TF, wherever that may be, and hovering over the button reveals
>> its effective code.
>
>Without leakage:
>
> <input type=button value=" ? "
> onClick="eval('TA1.value=' + this.title)"
> title="EratoB(+X.value)">
>
>Still shows the relevant code in the title (which, I think, is what you
>wanted).
As title or as value; the preference depends on circumstances.
>> Untested : I suppose that I can use onClick="Oozlum(this)" and define
>> Oozlum elsewhere.
>
>Of course you can. Personally, I would much prefer a helper function,
>compared to relying on the rather unintuitive identifier resolution in
>event attributes (even more so in form elements).
I was uncertain there. Your code works in IE8, and in current Firefox
Opera Safari & Chrome. Thanks.
--
(c) John Stockton, nr London UK. ?@merlyn.demon.co.uk DOS 3.3, 6.20; WinXP.
Web <http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms and links.
PAS EXE TXT ZIP via <http://www.merlyn.demon.co.uk/programs/00index.htm>
My DOS <http://www.merlyn.demon.co.uk/batfiles.htm> - also batprogs.htm.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.javascript
csiph-web