Showing posts with label Javascript/jQuery. Show all posts
Showing posts with label Javascript/jQuery. Show all posts

Saturday 13 April 2013

JavaScript Cloth Simulation

http://codepen.io/anon/pen/khwqm
Take a look at the source c0d3 on the right in the link. Its there to be modified and try out different parameters. I’m posting the source below.  The author has it free to be re-used.
Check out more from the same guys at http://lonely-pixel.com/. There are some mind boggling examples..

/*
Copyright (c) 2013 lonely-pixel.com, Stuffit at codepen.io (http://codepen.io/stuffit)

View this and others at http://lonely-pixel.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/

document.getElementById('close').onmousedown = function(e) {
e.preventDefault();
document.getElementById('info').style.display = 'none';
return false;
};

// settings

var physics_accuracy = 5,
mouse_influence = 20,
mouse_cut = 6,
gravity = 900,
cloth_height = 30,
cloth_width = 50,
start_y = 20,
spacing = 7,
tear_distance = 60;


window.requestAnimFrame =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};

var canvas,
ctx,
cloth,
boundsx,
boundsy,
mouse = {
down: false,
button: 1,
x: 0,
y: 0,
px: 0,
py: 0
};

window.onload = function() {

canvas = document.getElementById('c');
ctx = canvas.getContext('2d');

canvas.width = canvas.clientWidth;
canvas.height = 376;

canvas.onmousedown = function(e) {
mouse.button = e.which;
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
mouse.x = e.clientX - rect.left,
mouse.y = e.clientY - rect.top,
mouse.down = true;
e.preventDefault();
};

canvas.onmouseup = function(e) {
mouse.down = false;
e.preventDefault();
};

canvas.onmousemove = function(e) {
mouse.px = mouse.x;
mouse.py = mouse.y;
var rect = canvas.getBoundingClientRect();
mouse.x = e.clientX - rect.left,
mouse.y = e.clientY - rect.top,
e.preventDefault();
};

canvas.oncontextmenu = function(e) {
e.preventDefault();
};

boundsx = canvas.width - 1;
boundsy = canvas.height - 1;

ctx.strokeStyle = 'rgba(222,222,222,0.6)';
cloth = new Cloth();
update();
};

var Point = function(x, y) {

this.x = x;
this.y = y;
this.px = x;
this.py = y;
this.vx = 0;
this.vy = 0;
this.pin_x = null;
this.pin_y = null;
this.constraints = [];
};

Point.prototype.update = function(delta) {

if (mouse.down) {

var diff_x = this.x - mouse.x,
diff_y = this.y - mouse.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y);

if (mouse.button == 1) {

if(dist < mouse_influence) {
this.px = this.x - (mouse.x - mouse.px) * 1.8;
this.py = this.y - (mouse.y - mouse.py) * 1.8;
}

} else if (dist < mouse_cut) this.constraints = [];
}

this.add_force(0, gravity);

delta *= delta;
nx = this.x + ((this.x - this.px) * .99) + ((this.vx / 2) * delta);
ny = this.y + ((this.y - this.py) * .99) + ((this.vy / 2) * delta);

this.px = this.x;
this.py = this.y;

this.x = nx;
this.y = ny;

this.vy = this.vx = 0
};

Point.prototype.draw = function() {

if (this.constraints.length <= 0) return;

var i = this.constraints.length;
while(i--) this.constraints[i].draw();
};

Point.prototype.resolve_constraints = function() {

if (this.pin_x != null && this.pin_y != null) {

this.x = this.pin_x;
this.y = this.pin_y;
return;
}

var i = this.constraints.length;
while(i--) this.constraints[i].resolve();

this.x > boundsx ? this.x = 2 * boundsx - this.x : 1 > this.x && (this.x = 2 - this.x);
this.y < 1 ? this.y = 2 - this.y : this.y > boundsy && (this.y = 2 * boundsy - this.y);
};

Point.prototype.attach = function(point) {

this.constraints.push(
new Constraint(this, point)
);
};

Point.prototype.remove_constraint = function(lnk) {

var i = this.constraints.length;
while(i--) if(this.constraints[i] == lnk) this.constraints.splice(i, 1);
};

Point.prototype.add_force = function(x, y ) {

this.vx += x;
this.vy += y;
};

Point.prototype.pin = function(pinx, piny) {
this.pin_x = pinx;
this.pin_y = piny;
};

var Constraint = function(p1, p2) {

this.p1 = p1;
this.p2 = p2;
this.length = spacing;
};

Constraint.prototype.resolve = function() {

var diff_x = this.p1.x - this.p2.x,
diff_y = this.p1.y - this.p2.y,
dist = Math.sqrt(diff_x * diff_x + diff_y * diff_y),
diff = (this.length - dist) / dist;

if (dist > tear_distance) this.p1.remove_constraint(this);

var px = diff_x * diff * 0.5;
var py = diff_y * diff * 0.5;

this.p1.x += px;
this.p1.y += py;
this.p2.x -= px;
this.p2.y -= py;
};

Constraint.prototype.draw = function() {

ctx.moveTo(this.p1.x, this.p1.y);
ctx.lineTo(this.p2.x, this.p2.y);
};

var Cloth = function() {

this.points = [];

var start_x = canvas.width / 2 - cloth_width * spacing / 2;

for(var y = 0; y <= cloth_height; y++) {

for(var x = 0; x <= cloth_width; x++) {

var p = new Point(start_x + x * spacing, start_y + y * spacing);

y == 0 && p.pin(p.x, p.y);
y != 0 && p.attach(this.points[x + (y - 1) * (cloth_width + 1)]);
x != 0 && p.attach(this.points[this.points.length - 1]);

this.points.push(p);
}
}
};

Cloth.prototype.update = function() {

var i = physics_accuracy;

while(i--) {
var p = this.points.length;
while(p--) this.points[p].resolve_constraints();
}

i = this.points.length;
while(i--) this.points[i].update(.016);
};

Cloth.prototype.draw = function() {

ctx.beginPath();

var i = cloth.points.length;
while(i--) cloth.points[i].draw();

ctx.stroke();
};

function update() {

ctx.clearRect(0, 0, canvas.width, canvas.height);

cloth.update();
cloth.draw();

requestAnimFrame(update);
}


CSS
Notice the canvas element..



* {
margin: 0;
overflow:hidden;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}

body {
background:#333;
}

canvas {
background:#333;
width:100%;
height:376px;
margin:0 auto;
display:block;
}

#info {
position:absolute;
left:-1px;
top:-1px;
width:auto;
max-width:380px;
height:auto;
background:#f2f2f2;
border-bottom-right-radius:10px;
}

#top {
background:#fff;
width:100%;
height:auto;
position:relative;
border-bottom:1px solid #eee;
}

p {
font-family:Arial, sans-serif;
color:#666;
text-align:justify;
font-size: 16px;
margin:10px;
}

a {
font-family:sans-serif;
color:#444;
text-decoration:none;
font-size: 20px;
}

#site {
float:left;
margin: 10px;
color: #38a;
border-bottom:1px dashed #888;
}

#site:hover {
color: #7af;
}

#close {
float:right;
margin: 10px;
}

#p {
font-family: Verdana, sans-serif;
position:absolute;
right:10px;
bottom:10px;
color:#adf;
border: 1px dashed #555;
padding:4px 8px;
}


HTML
Notice the canvas element


<canvas id = "c" > </canvas>

<a target="_blank" href="http://codepen.io/stuffit/pen/fhjvk" id="p">New pen: Like playing with physics? Click here!</a>

<div id="info">
<div id="top">
<a target="_blank" id="site" href="http://lonely-pixel.com">my website</a>
<a id="close" href="">close</a>
</div>
<p>
<br>
- Tear the cloth with your mouse.<br><br>
- Right click and drag to cut the cloth<br><br>
- Reduce physics_accuracy if it's laggy.<br><br>
</p>
</div>


Thursday 29 December 2011

Update On Long Running Server Tasks using ASP.Net, jQuery and Ajax.

          Often in distributed applications, There is a need to update the client on a long running server task. This becomes inherently difficult because of the ‘statelessness’ of the HTTP protocol, In that, Between every HTTP Get there is no state maintained on the server (well at-least in most cases). Therefore, when a client request starts and owns a process which is lengthy (often like uploading something, or communicating to/from a remote database server etc..), periodic updates on the progress of the lengthy process is very imperative for a good user experience, specially in the web 2.0 generation.

I’m going to discuss a few techniques to achieve this using an ASP.Net Ajax development model considering a Windows Server scenario here. Following are the most commonly used techniques for achieving it.

  • Server Push
  • Client Pooling

Server Push (COMET)

In very simple words, COMET is a technique/web application model where the server keeps the HTTP connection open for longer durations. This allows the server to push updates to the client. This can be achieved using techniques like HTTP Streaming, Hidden iFrame and XMLHttpRequests (AJAX) to name a few.

  • Advantages
    1. Saves Traffic –  The server needs to make just one call to the client to send an update.
    2. Efficient – From a logical architecture point of view of the application, it is a very simple and efficient way of updating the client. (This might come at a cost, see below). A very good example of COMET technique is the meebo messenger service. (check it out here) You can also check out the Google implementation here (Etherpad). This was used in Google Wave.
    3. Although a little tricky to achieve this using native ASP.Net architecture, You can leverage  HTML 5 Web Sockets to achieve it. A C# Implementation - Nugget is available on codeplex.
    4. Can be ideal for real-time or close to real-time update scenarios.
  • Drawbacks
    1. Server Memory – The more state that you would want to maintain on the server, the more server memory is required. This again, depends on a lot of factors. For instance, consider applications like Hotmail and Gmail, Here, the number of concurrent connections open can be  significantly higher, which means a lot of server state should be maintained, which will eventually require significant memory. On the other hand, if you are writing an ASP.Net Web App running on a intranet, your concurrent connections may be a couple of tens of them., which also means less server memory compared to the above scenario.
    2. Server I/O API -  This process itself depends on what I/O API is leveraged on the server. Asynchronous processes generally use Non-Blocking I/O, utilizing all cores on the server and increasing efficiency. Async process are handled by a separate thread, which also means the application can do something else while this Async thread executes. Blocking I/O requires a thread per connection and as the concurrent connections increase, the no. of threads processing that request will also increase. A good debate on Non-Blocking vs. Blocking I/O can be found here.
    3. COMET style model implementations have a tendency to run into difficulties as the application is scaled up for large user bases, simply because the server needs to maintain multiple connections between the same client and server. (This is not a claim, I will be supporting all these explanations with concrete implementations and load tests soon.)

Client Polling

Client Polling is done from the browser through AJAX requests. The browser repeatedly polls the server for updates through Ajax calls and updates the client from the server’s response.

  • Advantages
    1. Simple to implement
    2. Suitable for non-real-time applications (like chat-clients)
  • Drawbacks
    1. Latency -  There can be latency between the client’s poll and the server’s response. See the below scenarios. This is mainly due to the unpredictable progress of the server’s process and the constant time interval of the poll.
    2. Not efficient use of traffic and resources – Not every poll to the server might get a concrete response. Don’t get me wrong here, I’m not trying to say that not every pool might get a response, but between two consecutive polls, the state of the long process on the server would not have changed, forcing the server to repeat the previous response. i.e let’s say the the client polls the server every 20 milliseconds for an update, Now, the server might return a different value only after 100 milliseconds, by which time you can imagine the client would have polled the server 4 times already rendering the previous 4 calls to the server without result. This is not efficient use of traffic and reduces your application efficiency. There can be another scenario here, Consider the server’s process returns a state change response every 10 milliseconds. Now, if the client polls the server at intervals of 20 milliseconds, the server’s process has changed significantly since then, adding to a loss of update between every poll.

Both COMET and Client Polling have their ups and downs. As you’ve seen, there strictly isn’t a stereotypical way of achieving the end result, The most imperative of these points are that when it comes to what’s best to YOU, you might have to think on the above lines, scoping out various factors of your distributed application and then your choice will be obvious.

Below is my implementation of a client AJAX Polling to server for a update on the long running server process.

Example : Visual Studio 2010, Asp.NET 4.0, jQuery 1.7, jQuery UI 1.8

I’ve written a very simple AJAX client pooling demo here. The server starts a ‘BackgroundWorker’ process Asynchronously and the client polls the server at regular intervals by making AJAX calls and getting the updates on the server progress. I’ve used jQuery UI to draw a progress bar and update it asynchronously after every poll response from the server. I’ve used jQuery in the client to make use of $.ajax({}); call and the server response is a JSON data type. This is a demo implementation only. Here, the BackgroundWorker object is made static. Therefore this implementation sends the progress of the same job to all the client requests which are polling for an update. An enterprise application would need to have a separate web service running on the server to do the ‘long task’ and each request will then need to be INDEPENDENTLY made aware of it’s Async process’s progress.

Default.aspx.cs

  1: using System;
  2: using System.ComponentModel;
  3: using System.Threading;
  4: using System.Web.Services;
  5: 
  6: namespace ClientPoolServerProgress
  7: {
  8:     public partial class _Default : System.Web.UI.Page
  9:     {
 10:         static BackgroundWorker bwProcess; 
 11:         public static int Percentage { get; set; }
 12: 
 13:         protected void Page_Load(object sender, EventArgs e)
 14:         {
 15:             Percentage = 0;
 16:         }
 17: 
 18:         [WebMethod()]
 19:         public static int GetProgress()
 20:         {
 21:             return Percentage;
 22:         }
 23: 
 24:         protected void btnClick_Click(object sender, EventArgs e)
 25:         {
 26:             bwProcess = new BackgroundWorker
 27:             {
 28:                 WorkerReportsProgress = true,
 29:                 WorkerSupportsCancellation = true
 30:             };
 31: 
 32:             bwProcess.DoWork += new DoWorkEventHandler(bwProcess_DoWork);
 33:             bwProcess.ProgressChanged += new ProgressChangedEventHandler(bwProcess_ProgressChanged);
 34:             bwProcess.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwProcess_RunWorkerCompleted);
 35: 
 36:             bwProcess.RunWorkerAsync("AsyncWorker");
 37:         }
 38:         
 39:         void bwProcess_DoWork(object sender, DoWorkEventArgs e)
 40:         {  
 41:             for (int i = 0; i <= 100; i++)
 42:             {
 43:                 if (bwProcess.CancellationPending) 
 44:                 { 
 45:                     e.Cancel = true; 
 46:                     return;
 47:                 }
 48:                 bwProcess.ReportProgress(i);
 49:                 Thread.Sleep(20);
 50:             }
 51: 
 52:             e.Result = "100 %";
 53:         }
 54: 
 55:         void bwProcess_ProgressChanged(object sender, ProgressChangedEventArgs e)
 56:         {
 57:             Percentage = e.ProgressPercentage;
 58:         }
 59: 
 60:         void bwProcess_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
 61:         {
 62: 
 63:         }
 64:     }
 65: }
 66: 


Default.aspx



  1: <%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="false"
  2:     CodeBehind="Default.aspx.cs" Inherits="ClientPoolServerProgress._Default" 
  3:     Async="true" Buffer="True" EnableSessionState="ReadOnly" AsyncTimeout="300"%>
  4: 
  5: <asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
  6:     <script type="text/javascript">
  7: 
  8:         $(document).ready(function () {
  9:             updateProgress();
 10:             $("#pBar").progressbar({ value: 0 });
 11:         });
 12: 
 13:         function updateProgress() {
 14:             $.ajax({
 15:                 type: "POST",
 16:                 url: "Default.aspx/GetProgress",
 17:                 data: "{}",
 18:                 contentType: "application/json; charset=utf-8",
 19:                 dataType: "json",
 20:                 async: true,
 21:                 success: function (msg) {
 22:                     $("#lblProgress").text(msg.d);
 23:                     $("#pBar").progressbar({ value: msg.d });
 24: 
 25:                     if (msg.d < 100) {
 26:                         setTimeout(updateProgress, 10);
 27:                     }
 28:                 },
 29:                 cache:false 
 30:             });
 31:         }
 32:     </script>
 33: </asp:Content>
 34: <asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
 35:     <div>
 36: 
 37:      <asp:UpdatePanel ID="updPanel" UpdateMode="Always" runat="server" >
 38:         <ContentTemplate>
 39:             <table class="ui-widget ui-widget-content" width="400">
 40:                 <tr>
 41:                     <th class="ui-widget-header" style="width:150px;" >
 42:                         Item
 43:                     </th>
 44:                     <th class="ui-widget-header">
 45:                         Details
 46:                     </th>
 47:                 </tr>
 48:                 <tr>
 49:                     <td>
 50:                         Percent Progress
 51:                     </td>
 52:                     <td>
 53:                         <label id="lblProgress"> </label> 
 54:                     </td>
 55:                 </tr>
 56:                 <tr>    
 57:                     <td>
 58:                         Progress Indicator
 59:                     </td>
 60:                     <td>
 61:                         <div id="pBar"></div>
 62:                     </td>
 63:                 </tr>
 64:     
 65:                 <tr>
 66:                     <td colspan="2">
 67:                             <asp:button ID="btnClick" runat="server" Text="Start" CssClass="ui-button" 
 68:                              onclick="btnClick_Click" />
 69:                     </td>
 70:                 </tr>
 71:             </table> 
 72:           </ContentTemplate>
 73:     </asp:UpdatePanel>
 74:     </div>
 75: </asp:Content>
 76: 


Capture



Download Code (C#)


Friday 5 November 2010

JS Trick

Ever wondered how to close that damn browser window without getting a warning from the browser ?.

Well, I've gone through that many a times before when trying to close a window(subject)  from either the main window or any other window which did not create the subject.

and…and i remember the solution, which i had devised for IE. (not sure about other browsers and I'll leave that for you ).

You have to remember, the window.open method creates a reference to the window.opener ??    (Hint, Hint! )

function CloseWindow(){

//removes the previous window.opener reference and

//tricks the browser not to display the annoying warning message.

window.opener = ‘fake’;

window.close();

}

Winking smile

Thursday 4 December 2008

jQuery Basics

I’m going to demonstrate a few basic jQuery stuff that you should know before delving into jQuery. If you are new to Javascript you need to be starting here[link]. This might help[link] too. The audience for this tutor are ideally JavaScript novices who want to make a start with jQuery.Let’s start by understanding this small example -


the window.onload() event.




<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery Basics</title>
</head>
<body>
<script type="text/javascript">
window.onload = function(){ alert("Hello JavaScript!, document Loaded."); }
</script>
</body>
</html>



Now, As you are already aware, the window.onload event is fired when the HTML window loads. In the above code, look at the Javascript, on window.onload() event, we are calling a function, which alert’s the text “Hello Javascript!, document Loaded.”. This code usually runs smoothly unless for instance, if you are loading a lot of images, Then Javascript code isn’t run until all images have finished loaded, including banner ads etc.


Now, We have an interesting problem, In your window.onload() event, if you want to manipulate your document,( which is essentially the HTML DOM (document object model) ), then your document hasn’t loaded yet and your Javascript might not work correctly.


In order to over come this problem, jQuery gives you a basic construct the - ready event which looks like



$(document).ready(function(){
//Your Javascript code here..
});



Let’s now quickly try an example,



<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery Basics</title>
</head>
<body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script>
$(document).ready(function(){
alert("document has loaded, you can execute your js here..!");
});
});
</script>
</body>
</html>



First thing to note is that above example links to Google’s CDN to load the jQuery core file. You can download the latest version of this file from the jQuery website.Here, the alert statement is guaranteed to work only after the document has finished loading.


jQuery CSS example



<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery Basics</title>
<style>
label.test {font-weight: bold;}
</style>
</head>
<body>
<label>This is a label</label>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("label").addClass("test");
});
</script>
</body>
</html>



Here, we use the .addClass method to the label element to add a css class. Notice that this code is placed inside the $(document).ready(function(){}); To remove the class ‘test’ for the label element, replace the addClass(“"test”) with the removeClass(“test”);

jQuery Effects example



<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery Basics</title>
</head>
<body>
<labe>This is a label</label>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("label").click(function(){
$(this).hide("slow");
});
});
</script>
</body>
</html>

Click on the label and notice that it slows disappears.




jQuery Callback example


The syntax for executing a callback with no arguments



$.get('myhtmlpage.html',myCallBack);



Here, the function myCallBack() is executed after the page ‘myhtmlpage.html’ is got from the server.


What the above Javascript code is doing is, It’s registering the function ‘myCallBack’ (notice that when you write it, it’s without () ), to the get event. i.e ‘myCallBack’ will be executed after the get is done.


 


Now, Consider a scenario wherein you need to register a callback function by passing arguments.


Do not try doing this, this is Wrong



$.get('myhtmlpage.html', myCallBack(param1, param2));



The above line won’t work because, myCallBack(param1,param2) is executed before it’s registered. In other words, The returned value of myCallBack(param1, param2) is registered as a callback function, which is not write.Javascript is expecting a function pointer here. so, the right way to do this will be to enclose  myCallBack(param1, param2) with function(){ }. Yes, you guessed it, that’s the anonymous function. (I’m really really found of this Javascript feature, sometimes it makes me think, that’s where languages like C# got the ideas from, C++ is an obvious choice Smile with tongue out)



$.get('myhtmlpage.html', function(){
myCallBack(param1, param2);
});

In the above example, an anonymous function is created (just a block of statements) and is registered as the callback function. Note the use of 'function(){'. The anonymous function does exactly one thing: calls myCallBack, with the values of param1 and param2 in the outer scope.


I’ll soon be writing more on jQuery and jQuery UI which i’ve started to use extensively off late. The following is worth reading for more.





Next Steps