Interesting read...
http://www.investopedia.com/articles/trading/04/120804.asp
Monday, November 25
Saturday, November 16
Particle Emitters - Part III
And here are the actual effects themselves. It generates the actual effect:
function WhirlEmitter(point,color)
{
this.position = point; // Vector
this.velocity = Vector.fromAngle(0,.5); // Vector
this.spread = Math.PI/1; // possible angles = velocity +/- spread
this.drawColor = "#999"; // So we can tell them apart from Fields later
this.particleColor = color;
this.maxParticles = 100;
this.particleSize = 1;
this.numParticles = 0;
this.emissionRate = 1;
this.tether = rand(60,100);
}
WhirlEmitter.prototype.emit = function()
{
var angle = this.velocity.getAngle() + this.spread - (Math.random() * this.spread * 2);
var magnitude = this.velocity.getMagnitude();
var velocity = new Vector(0,0);//Vector.fromAngle(angle, magnitude);
var position = new Vector(this.position.x + velocity.x * 25, this.position.y + velocity.y * 25);
var particle = new Particle(position,velocity,new Vector(0,0),this.particleColor,2);
particle.action = "whirlParticle";
particle.particleColor = this.particleColor;//'rgb(' + rand(0,255) + ','+ rand(0,255) + ','+ rand(0,255) + ')'
particle.tether = rand(1,360)/100;
particle.origin = new Vector(this.position.x, this.position.y);
//this.position.x++;
return particle;
};
function whirlParticle(particle)
{
//alert(particle.life + ":" + particle.tether);
var tmpX = particle.origin.x + particle.radius * Math.cos(particle.tether);
var tmpY = particle.origin.y + particle.radius * Math.sin(particle.tether);
particle.position = new Vector(tmpX, tmpY);
particle.tether+=.25;
particle.particleSize-=.01;
if(particle.tether > 7)
{
particle.tether = .36;
particle.radius-=5;
}
if(particle.radius < 0 || particle.particleSize <= 0)
{
return "";
}
return particle;
}
function WhirlEmitter(point,color)
{
this.position = point; // Vector
this.velocity = Vector.fromAngle(0,.5); // Vector
this.spread = Math.PI/1; // possible angles = velocity +/- spread
this.drawColor = "#999"; // So we can tell them apart from Fields later
this.particleColor = color;
this.maxParticles = 100;
this.particleSize = 1;
this.numParticles = 0;
this.emissionRate = 1;
this.tether = rand(60,100);
}
WhirlEmitter.prototype.emit = function()
{
var angle = this.velocity.getAngle() + this.spread - (Math.random() * this.spread * 2);
var magnitude = this.velocity.getMagnitude();
var velocity = new Vector(0,0);//Vector.fromAngle(angle, magnitude);
var position = new Vector(this.position.x + velocity.x * 25, this.position.y + velocity.y * 25);
var particle = new Particle(position,velocity,new Vector(0,0),this.particleColor,2);
particle.action = "whirlParticle";
particle.particleColor = this.particleColor;//'rgb(' + rand(0,255) + ','+ rand(0,255) + ','+ rand(0,255) + ')'
particle.tether = rand(1,360)/100;
particle.origin = new Vector(this.position.x, this.position.y);
//this.position.x++;
return particle;
};
function whirlParticle(particle)
{
//alert(particle.life + ":" + particle.tether);
var tmpX = particle.origin.x + particle.radius * Math.cos(particle.tether);
var tmpY = particle.origin.y + particle.radius * Math.sin(particle.tether);
particle.position = new Vector(tmpX, tmpY);
particle.tether+=.25;
particle.particleSize-=.01;
if(particle.tether > 7)
{
particle.tether = .36;
particle.radius-=5;
}
if(particle.radius < 0 || particle.particleSize <= 0)
{
return "";
}
return particle;
}
Saturday, November 9
Particle Emitters - Part II
Check out the Particle Emitters Series to get the full picture.
There are some basic functions that are needed for to make this work, they are as follows. We won't be modify this much except for the plotParticles function, where we have to change the if statements for each of our effects. (I know there must be a clever way to do this, but I ran outta time)
function Particle(point, velocity, acceleration,color,size) {
this.position = point || new Vector(0, 0);
this.velocity = velocity || new Vector(0, 0);
this.acceleration = acceleration || new Vector(0, 0);
this.origin = new Vector(0,0);
this.color = color
this.particleSize = size;
this.action = "";
this.life = 0;
this.tether = 0;
this.radius = 25;
}
function plotParticles(boundsX, boundsY)
{
// a new array to hold particles within our bounds
var currentParticles = [];
for (var i = 0; i < particles.length; i++)
{
var particle = particles[i];
var pos = particle.position;
if(particle.action == "warpParticle")
{
particle = warpParticle(particle);
particle.move();
}
if(particle.action == "whirlParticle")
{
particle = whirlParticle(particle);
}
if(particle.action == "beamParticle")
{
particle = beamParticle(particle);
}
if(particle != "")
{
// If we're out of bounds, drop this particle and move on to the next
if (pos.x < 0 || pos.x > boundsX || pos.y < 0 || pos.y > boundsY) continue;
if (particle.particleSize <= 0) continue;
// Add this particle to the list of current particles
currentParticles.push(particle);
}
}
// Update our global particles, clearing room for old particles to be collected
particles = currentParticles;
}
function rand(from,to)
{
return Math.floor(Math.random()*(to-from+1)+from);
}
function drawParticles()
{
// For each particle
for (var i = 0; i < particles.length; i++)
{
context.fillStyle = particles[i].color;
var position = particles[i].position;
//context.fillRect(position.x, position.y, particles[i].particleSize, particles[i].particleSize);
context.fillStyle = particles[i].particleColor;
context.beginPath();
context.arc(position.x, position.y, particles[i].particleSize, 0, Math.PI * 2);
context.closePath();
context.fill();
}
}
function addNewParticles()
{
for (var i = 0; i < emitters.length; i++)
{
if(emitters[i].numParticles < emitters[i].maxParticles)
{
for (var j = 0; j < emitters[i].emissionRate; j++)
{
particles.push(emitters[i].emit());
emitters[i].numParticles++;
}
}
}
}
Particle.prototype.move = function () {
// Add our current acceleration to our current velocity
this.velocity.add(this.acceleration);
// Add our current velocity to our position
this.position.add(this.velocity);
};
function Vector(x, y) {
this.x = x || 0;
this.y = y || 0;
}
// Add a vector to another
Vector.prototype.add = function(vector) {
this.x += vector.x;
this.y += vector.y;
}
// Gets the length of the vector
Vector.prototype.getMagnitude = function () {
return Math.sqrt(this.x * this.x + this.y * this.y);
};
// Gets the angle accounting for the quadrant we're in
Vector.prototype.getAngle = function () {
return Math.atan2(this.y,this.x);
};
// Allows us to get a new vector from angle and magnitude
Vector.fromAngle = function (angle, magnitude) {
return new Vector(magnitude * Math.cos(angle), magnitude * Math.sin(angle));
};
There are some basic functions that are needed for to make this work, they are as follows. We won't be modify this much except for the plotParticles function, where we have to change the if statements for each of our effects. (I know there must be a clever way to do this, but I ran outta time)
function Particle(point, velocity, acceleration,color,size) {
this.position = point || new Vector(0, 0);
this.velocity = velocity || new Vector(0, 0);
this.acceleration = acceleration || new Vector(0, 0);
this.origin = new Vector(0,0);
this.color = color
this.particleSize = size;
this.action = "";
this.life = 0;
this.tether = 0;
this.radius = 25;
}
function plotParticles(boundsX, boundsY)
{
// a new array to hold particles within our bounds
var currentParticles = [];
for (var i = 0; i < particles.length; i++)
{
var particle = particles[i];
var pos = particle.position;
if(particle.action == "warpParticle")
{
particle = warpParticle(particle);
particle.move();
}
if(particle.action == "whirlParticle")
{
particle = whirlParticle(particle);
}
if(particle.action == "beamParticle")
{
particle = beamParticle(particle);
}
if(particle != "")
{
// If we're out of bounds, drop this particle and move on to the next
if (pos.x < 0 || pos.x > boundsX || pos.y < 0 || pos.y > boundsY) continue;
if (particle.particleSize <= 0) continue;
// Add this particle to the list of current particles
currentParticles.push(particle);
}
}
// Update our global particles, clearing room for old particles to be collected
particles = currentParticles;
}
function rand(from,to)
{
return Math.floor(Math.random()*(to-from+1)+from);
}
function drawParticles()
{
// For each particle
for (var i = 0; i < particles.length; i++)
{
context.fillStyle = particles[i].color;
var position = particles[i].position;
//context.fillRect(position.x, position.y, particles[i].particleSize, particles[i].particleSize);
context.fillStyle = particles[i].particleColor;
context.beginPath();
context.arc(position.x, position.y, particles[i].particleSize, 0, Math.PI * 2);
context.closePath();
context.fill();
}
}
function addNewParticles()
{
for (var i = 0; i < emitters.length; i++)
{
if(emitters[i].numParticles < emitters[i].maxParticles)
{
for (var j = 0; j < emitters[i].emissionRate; j++)
{
particles.push(emitters[i].emit());
emitters[i].numParticles++;
}
}
}
}
Particle.prototype.move = function () {
// Add our current acceleration to our current velocity
this.velocity.add(this.acceleration);
// Add our current velocity to our position
this.position.add(this.velocity);
};
function Vector(x, y) {
this.x = x || 0;
this.y = y || 0;
}
// Add a vector to another
Vector.prototype.add = function(vector) {
this.x += vector.x;
this.y += vector.y;
}
// Gets the length of the vector
Vector.prototype.getMagnitude = function () {
return Math.sqrt(this.x * this.x + this.y * this.y);
};
// Gets the angle accounting for the quadrant we're in
Vector.prototype.getAngle = function () {
return Math.atan2(this.y,this.x);
};
// Allows us to get a new vector from angle and magnitude
Vector.fromAngle = function (angle, magnitude) {
return new Vector(magnitude * Math.cos(angle), magnitude * Math.sin(angle));
};
Saturday, November 2
Particle Emitters - Part I
I've been playing around with Particle Emitters. Those are the cool little animations like star bursts and flowing bubbles that you see in games.
I used the following as a blank canvas for me to work with:
(notice you will need particleFunctions,js and particleEffects.js which are coming in part II and III)
<html>
<head>
<script language=javascript src="particleFunctions.js"></script>
<script language=javascript src="particleEffects.js"></script>
</head>
<body>
<canvas style="width:300px; height:300px;border:1px solid black;background:black;" width=300 height=300></canvas>
<script>
var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');
var particles = [];
emitters = new Array();
emitters.push(new WhirlEmitter(new Vector(canvas.width/2+5,canvas.height/2),'green'));
emitters.push(new BeamEmitter(new Vector(canvas.width/2,canvas.height/2),'green'));
function loop() {
clear();
update();
draw();
queue();
}
function clear() {
context.clearRect(0, 0, canvas.width, canvas.height);
}
function queue() {
window.requestAnimationFrame(loop);
}
function update() {
addNewParticles();
plotParticles(canvas.width, canvas.height);
}
function draw() {
drawParticles();
}
loop();
</script>
</body>
</html>
I used the following as a blank canvas for me to work with:
(notice you will need particleFunctions,js and particleEffects.js which are coming in part II and III)
<html>
<head>
<script language=javascript src="particleFunctions.js"></script>
<script language=javascript src="particleEffects.js"></script>
</head>
<body>
<canvas style="width:300px; height:300px;border:1px solid black;background:black;" width=300 height=300></canvas>
<script>
var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');
var particles = [];
emitters = new Array();
emitters.push(new WhirlEmitter(new Vector(canvas.width/2+5,canvas.height/2),'green'));
emitters.push(new BeamEmitter(new Vector(canvas.width/2,canvas.height/2),'green'));
function loop() {
clear();
update();
draw();
queue();
}
function clear() {
context.clearRect(0, 0, canvas.width, canvas.height);
}
function queue() {
window.requestAnimationFrame(loop);
}
function update() {
addNewParticles();
plotParticles(canvas.width, canvas.height);
}
function draw() {
drawParticles();
}
loop();
</script>
</body>
</html>
Monday, October 28
Quote
Great leaders are almost always great simplifiers, who can cut through argument, debate and doubt, to offer a solution everybody can understand.
Saturday, October 26
Logi - Secure Key in 3 Steps
Secure Key Authorization or Single Sign On integration is a popular item that requires reviewing with a lot of the clients I have dealt with.
This might help.
First Step: Leave your current login/authorization in place. You won't need to make modifications to it.
Second Step:
When your users click a link in your site that opens a Logi report, or opens the Logi portal you have built you will need to perform the secure key authentication at this point. If I had a C# application I might code it up as follows:
protected void rptLink_Click(object sender, EventArgs e)
{
StringBuilder lgxSecureKeyUrl = new StringBuilder("http://localhost/myLogiApp/);
//add the constant location of secure key handler in Logi
lgxSecureKeyUrl.Append("rdTemplate/rdGetSecureKey.aspx");
//The username is required (this could also be the UserID that you use to secure the app)
lgxSecureKeyUrl.Append("?Username=99999");
//You can pass roles and rights if you have them allready
lgxSecureKeyUrl.Append("&Roles=Manager,Admin");
lgxSecureKeyUrl.Append("&Rights=ViewReportList,ViewReports,CreateDashboards");
//this needs to be the USERS ip address
lgxSecureKeyUrl.Append("&ClientBrowserAddress=127.0.0.1");
//shoot the request over to Logi
HttpWebRequest lgxSecureKeyReq = (HttpWebRequest) HttpWebRequest.Create(lgxSecureKeyUrl.ToString());
//the response will be a secure key that is good for a single one time use
HttpWebResponse lgxSecureKeyResp = (HttpWebResponse)lgxSecureKeyReq.GetResponse();
StreamReader sr = new StreamReader(lgxSecureKeyResp.GetResponseStream());
string lgxSecureKey = sr.ReadToEnd();
//you will now send the user to your Logi app with that secure key
//logi will take it from there
StringBuilder lgxReportUrl = new StringBuilder("http://localhost/myLogiApp/rdPage.aspx?rdReport=Default");
//dont forget the secure key
lgxReportUrl.Append("&rdSecureKey=");
lgxReportUrl.Append(lgxSecureKey);
//send the user in what ever way you want
Response.Redirect(lgxReportUrl.ToString());
This might help.
First Step: Leave your current login/authorization in place. You won't need to make modifications to it.
Second Step:
When your users click a link in your site that opens a Logi report, or opens the Logi portal you have built you will need to perform the secure key authentication at this point. If I had a C# application I might code it up as follows:
protected void rptLink_Click(object sender, EventArgs e)
{
StringBuilder lgxSecureKeyUrl = new StringBuilder("http://localhost/myLogiApp/);
//add the constant location of secure key handler in Logi
lgxSecureKeyUrl.Append("rdTemplate/rdGetSecureKey.aspx");
//The username is required (this could also be the UserID that you use to secure the app)
lgxSecureKeyUrl.Append("?Username=99999");
//You can pass roles and rights if you have them allready
lgxSecureKeyUrl.Append("&Roles=Manager,Admin");
lgxSecureKeyUrl.Append("&Rights=ViewReportList,ViewReports,CreateDashboards");
//this needs to be the USERS ip address
lgxSecureKeyUrl.Append("&ClientBrowserAddress=127.0.0.1");
//shoot the request over to Logi
HttpWebRequest lgxSecureKeyReq = (HttpWebRequest) HttpWebRequest.Create(lgxSecureKeyUrl.ToString());
//the response will be a secure key that is good for a single one time use
HttpWebResponse lgxSecureKeyResp = (HttpWebResponse)lgxSecureKeyReq.GetResponse();
StreamReader sr = new StreamReader(lgxSecureKeyResp.GetResponseStream());
string lgxSecureKey = sr.ReadToEnd();
//you will now send the user to your Logi app with that secure key
//logi will take it from there
StringBuilder lgxReportUrl = new StringBuilder("http://localhost/myLogiApp/rdPage.aspx?rdReport=Default");
//dont forget the secure key
lgxReportUrl.Append("&rdSecureKey=");
lgxReportUrl.Append(lgxSecureKey);
//send the user in what ever way you want
Response.Redirect(lgxReportUrl.ToString());
}
Third Step:
To setup Logi to handle the secure, you will edit the _Settings file.
Add a Security Element with the following settings:
To setup Logi to handle the secure, you will edit the _Settings file.
Add a Security Element with the following settings:
- Authentication Source: Secure Key
- Authentication Client Address: [server ip]
- Cache Rights and Roles: Session
- Restart Session: True
- Security Enabled: True
That should do it for you
Troubleshooting:
The secure key is only good for one request, so if you submit the link and then click refresh, you will get an error as authentication fails. This is intentional. Notice the secure key is in the url when you refreshed.
Passing your UserID in the username is the best way to handle authentication, as then you can query and store any additional information you need using that key.
Keep in mind the rdGetSecureKey request is taking place between your primary server and the logi application
Monday, October 21
Monday, October 14
Saturday, October 12
Kool Tool to pick Colors
I like Adobe's Khulr picker.
Easy to find a color, snag the HTML code and past it in. Plus it offsets my color blindness.
http://kuler.adobe.com
Easy to find a color, snag the HTML code and past it in. Plus it offsets my color blindness.
http://kuler.adobe.com
Monday, October 7
Followers
Copyright 2009 mobeamer. Powered by Blogger
Blogger Templates created by Deluxe Templates
Wordpress by Nattywp