এইচটি এম এল-৫ এর রয়েছে অসাধারণ গ্রাফিক্স ডিজাইন এর পাশাপাশি অসাধারণ এনিমেশন তৈরির সক্ষমতা। এইচটি এম এল-৫ এ তৈরি গ্রাফিক্স এবং এনিমেশন আমাদের সকলের পরিচিত জনপ্রিয় ফটোশপ এবং ফ্লাসে তৈরি গ্রাফিক্স এবং এনিমেশনকেও অনেক সময় হার মানায়। এছাড়াও আরো কিছু বাড়তি সুবিধা রয়েছে এইচটি এম এল-৫ এর গ্রাফিক্স এবং এনিমেশনে। এর মধ্যে সবচেয়ে উল্লেখযোগ্য বিষয় হচ্ছে, ফাইলের সাইজ।
ফটোশপ এবং ফ্লাসে তৈরি যে কোন ভালমানের গ্রাফিক্স এবং এনিমেশন এর সাইজ অনেক বেশি হয়ে থাকে। যা কোন ওয়েব পেজে ব্যবহার করলে একদিকে যেমন ব্যান্ডওয়াইডথ খরচ বেশি হয়; অন্যদিকে পেজ লোড হতেও সময় বেশি লাগে। কিন্তু এইচটি এম এল-৫ এ কোডিং এর মাধ্যমেই গ্রাফিক্স এবং এনিমেশনকে জীবন্ত করে তোলা হয় তাই এক্ষেত্রে গ্রাফিক্স এবং এনিমেশন এর সাইজ অনেক কম হয়। আজ এইচটি এম এল-৫ দিয়ে তৈরি একটা মজার প্রজেক্ট সকলের সাথে শেয়ার করছি। প্রজেক্টটি হচ্ছে বাউনসিং বাবল টেক্সট।
আর কথা না বাড়িয়ে এক নজরে দেখে নেয়া যাক “বাউনসিং বাবল টেক্সট” প্রজেক্টটি।
প্রজেক্ট সম্পর্কিত কিছু কথা
প্রজেক্টটিতে “TUTO HOST” লেখাটিকে বিভিন্ন কালারের বাবল দিয়ে লেখা হয়েছে। যখন মাউস পয়েন্টার টেক্সটির উপর নিয়ে যাওয়া হয় তখন বাবল গুলো এলোমেল এবং মিশ্রিত হয়ে ছুটাছুটি করতে থাকে। মাউস পয়েন্টার সরিয়ে নিলে বাবল গুলো আস্তে আস্তে আবার পূর্বের অবস্থানে চলে আসে।
অনুশীলণ প্রজেক্ট
<!DOCTYPE HTML> <html> <head> <style> body { margin: 0px; padding: 0px; background:#099; } #myCanvas { border: 1px solid #9C9898; } </style> <script> window.requestAnimFrame = (function(callback){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback){ window.setTimeout(callback, 1000 / 60); }; })(); function initBalls(){ balls = []; var blue = "#3A5BCD"; var red = "#EF2B36"; var yellow = "#FFC636"; var green = "#02A817"; //t balls.push(new Ball(30, 30, 0, 0, red)); balls.push(new Ball(50, 30, 0, 0, red)); balls.push(new Ball(70, 30, 0, 0, red)); balls.push(new Ball(90, 30, 0, 0, red)); balls.push(new Ball(110, 30, 0, 0, red)); balls.push(new Ball(70, 50, 0, 0, red)); balls.push(new Ball(70, 70, 0, 0, red)); balls.push(new Ball(70, 90, 0, 0, red)); balls.push(new Ball(70, 110, 0, 0, red)); balls.push(new Ball(70, 130, 0, 0, red)); //u balls.push(new Ball(150, 30, 0, 0, blue)); balls.push(new Ball(150, 50, 0, 0, blue)); balls.push(new Ball(150, 70, 0, 0, blue)); balls.push(new Ball(153, 90, 0, 0, blue)); balls.push(new Ball(160, 110, 0, 0, blue)); balls.push(new Ball(180, 120, 0, 0, blue)); balls.push(new Ball(200, 110, 0, 0, blue)); balls.push(new Ball(210, 90, 0, 0, blue)); balls.push(new Ball(210, 70, 0, 0, blue)); balls.push(new Ball(210, 50, 0, 0, blue)); balls.push(new Ball(210, 30, 0, 0, blue)); //t balls.push(new Ball(250, 30, 0, 0, red)); balls.push(new Ball(270, 30, 0, 0, red)); balls.push(new Ball(290, 30, 0, 0, red)); balls.push(new Ball(310, 30, 0, 0, red)); balls.push(new Ball(330, 30, 0, 0, red)); balls.push(new Ball(290, 50, 0, 0, red)); balls.push(new Ball(290, 70, 0, 0, red)); balls.push(new Ball(290, 90, 0, 0, red)); balls.push(new Ball(290, 110, 0, 0, red)); balls.push(new Ball(290, 130, 0, 0, red)); // O balls.push(new Ball(390, 30, 0, 0, yellow)); balls.push(new Ball(370, 40, 0, 0, yellow)); balls.push(new Ball(410, 40, 0, 0, yellow)); balls.push(new Ball(363, 60, 0, 0, yellow)); balls.push(new Ball(417, 60, 0, 0, yellow)); balls.push(new Ball(363, 82, 0, 0, yellow)); balls.push(new Ball(417, 82, 0, 0, yellow)); balls.push(new Ball(363, 102, 0, 0, yellow)); balls.push(new Ball(417, 102, 0, 0, yellow)); balls.push(new Ball(370, 122, 0, 0, yellow)); balls.push(new Ball(410, 122, 0, 0, yellow)); balls.push(new Ball(390, 132, 0, 0, yellow)); //H balls.push(new Ball(30, 180, 0, 0, green)); balls.push(new Ball(30, 200, 0, 0, green)); balls.push(new Ball(30, 220, 0, 0, green)); balls.push(new Ball(30, 240, 0, 0, green)); balls.push(new Ball(30, 260, 0, 0, green)); balls.push(new Ball(30, 280, 0, 0, green)); balls.push(new Ball(110, 180, 0, 0, green)); balls.push(new Ball(110, 200, 0, 0, green)); balls.push(new Ball(110, 220, 0, 0, green)); balls.push(new Ball(110, 240, 0, 0, green)); balls.push(new Ball(110, 260, 0, 0, green)); balls.push(new Ball(110, 280, 0, 0, green)); balls.push(new Ball(50, 230, 0, 0, green)); balls.push(new Ball(70, 230, 0, 0, green)); balls.push(new Ball(90, 230, 0, 0, green)); // O balls.push(new Ball(180, 180, 0, 0, yellow)); balls.push(new Ball(160, 190, 0, 0, yellow)); balls.push(new Ball(200, 190, 0, 0, yellow)); balls.push(new Ball(153, 210, 0, 0, yellow)); balls.push(new Ball(207, 210, 0, 0, yellow)); balls.push(new Ball(153, 230, 0, 0, yellow)); balls.push(new Ball(207, 230, 0, 0, yellow)); balls.push(new Ball(153, 250, 0, 0, yellow)); balls.push(new Ball(207, 250, 0, 0, yellow)); balls.push(new Ball(200, 270, 0, 0, yellow)); balls.push(new Ball(160, 270, 0, 0, yellow)); balls.push(new Ball(180, 280, 0, 0, yellow)); //S balls.push(new Ball(310, 190, 0, 0, blue)); balls.push(new Ball(290, 180, 0, 0, blue)); balls.push(new Ball(270, 190, 0, 0, blue)); balls.push(new Ball(265, 210, 0, 0, blue)); balls.push(new Ball(280, 225, 0, 0, blue)); balls.push(new Ball(295, 240, 0, 0, blue)); balls.push(new Ball(303, 260, 0, 0, blue)); balls.push(new Ball(290, 280, 0, 0, blue)); balls.push(new Ball(270, 270, 0, 0, blue)); //t balls.push(new Ball(425, 180, 0, 0, red)); balls.push(new Ball(405, 180, 0, 0, red)); balls.push(new Ball(385, 180, 0, 0, red)); balls.push(new Ball(365, 180, 0, 0, red)); balls.push(new Ball(345, 180, 0, 0, red)); balls.push(new Ball(385, 200, 0, 0, red)); balls.push(new Ball(385, 220, 0, 0, red)); balls.push(new Ball(385, 240, 0, 0, red)); balls.push(new Ball(385, 260, 0, 0, red)); balls.push(new Ball(385, 280, 0, 0, red)); return balls; } function getMousePos(canvas, evt){ // get canvas position var obj = canvas; var top = 0; var left = 0; while (obj.tagName != 'BODY') { top += obj.offsetTop; left += obj.offsetLeft; obj = obj.offsetParent; } // return relative mouse position var mouseX = evt.clientX - left + window.pageXOffset; var mouseY = evt.clientY - top + window.pageYOffset; return { x: mouseX, y: mouseY }; } function updateBalls(canvas, balls, timeDiff, mousePos){ var context = canvas.getContext("2d"); var collisionDamper = 0.3; var floorFriction = 0.0005 * timeDiff; var mouseForceMultiplier = 1 * timeDiff; var restoreForce = 0.002 * timeDiff; for (var n = 0; n < balls.length; n++) { var ball = balls[n]; // set ball position based on velocity ball.y += ball.vy; ball.x += ball.vx; // restore forces if (ball.x > ball.origX) { ball.vx -= restoreForce; } else { ball.vx += restoreForce; } if (ball.y > ball.origY) { ball.vy -= restoreForce; } else { ball.vy += restoreForce; } // mouse forces var mouseX = mousePos.x; var mouseY = mousePos.y; var distX = ball.x - mouseX; var distY = ball.y - mouseY; var radius = Math.sqrt(Math.pow(distX, 2) + Math.pow(distY, 2)); var totalDist = Math.abs(distX) + Math.abs(distY); var forceX = (Math.abs(distX) / totalDist) * (1 / radius) * mouseForceMultiplier; var forceY = (Math.abs(distY) / totalDist) * (1 / radius) * mouseForceMultiplier; if (distX > 0) { // mouse is left of ball ball.vx += forceX; } else { ball.vx -= forceX; } if (distY > 0) { // mouse is on top of ball ball.vy += forceY; } else { ball.vy -= forceY; } // floor friction if (ball.vx > 0) { ball.vx -= floorFriction; } else if (ball.vx < 0) { ball.vx += floorFriction; } if (ball.vy > 0) { ball.vy -= floorFriction; } else if (ball.vy < 0) { ball.vy += floorFriction; } // floor condition if (ball.y > (canvas.height - ball.radius)) { ball.y = canvas.height - ball.radius - 2; ball.vy *= -1; ball.vy *= (1 - collisionDamper); } // ceiling condition if (ball.y < (ball.radius)) { ball.y = ball.radius + 2; ball.vy *= -1; ball.vy *= (1 - collisionDamper); } // right wall condition if (ball.x > (canvas.width - ball.radius)) { ball.x = canvas.width - ball.radius - 2; ball.vx *= -1; ball.vx *= (1 - collisionDamper); } // left wall condition if (ball.x < (ball.radius)) { ball.x = ball.radius + 2; ball.vx *= -1; ball.vx *= (1 - collisionDamper); } } } function Ball(x, y, vx, vy, color){ this.x = x; this.y = y; this.vx = vx; this.vy = vy; this.color = color; this.origX = x; this.origY = y; this.radius = 10; } function animate(canvas, balls, lastTime, mousePos){ var context = canvas.getContext("2d"); // update var date = new Date(); var time = date.getTime(); var timeDiff = time - lastTime; updateBalls(canvas, balls, timeDiff, mousePos); lastTime = time; // clear context.clearRect(0, 0, canvas.width, canvas.height); // render for (var n = 0; n < balls.length; n++) { var ball = balls[n]; context.beginPath(); context.arc(ball.x, ball.y, ball.radius, 0, 2 * Math.PI, false); context.fillStyle = ball.color; context.fill(); } // request new frame requestAnimFrame(function(){ animate(canvas, balls, lastTime, mousePos); }); } window.onload = function(){ var canvas = document.getElementById("myCanvas"); var balls = initBalls(); var date = new Date(); var time = date.getTime(); /* * set mouse position really far away * so the mouse forces are nearly obsolete */ var mousePos = { x: 9999, y: 9999 }; canvas.addEventListener("mousemove", function(evt){ var pos = getMousePos(canvas, evt); mousePos.x = pos.x; mousePos.y = pos.y; }); canvas.addEventListener("mouseout", function(evt){ mousePos.x = 9999; mousePos.y = 9999; }); animate(canvas, balls, time, mousePos); }; </script> </head> <body onmousedown="return false;"> <center> <canvas id="myCanvas" width="450" height="400" style="background:#000;"> </canvas> <h2 style=" color:#fff;">Bouncing Bubble Text By HTML 5.</h2> </center> </body> </html>
একটা নোটপ্যাড open করে উপরের code টুকু লিখে file মেনু থেকে Save as এ ক্লিক করে File name: index.html , Save as type : All files, দিয়ে save করে index.html ফাইলটি Mozilla Firefox দিয়ে open করলে নিচে প্রদর্শিত ছবির মত দেখাবে।
প্রজেক্ট বিশ্লেষণ
<canvas id="myCanvas" width="450" height="400" style="background:#000;"> </canvas>
উপরের কোডটুকুর মাধ্যমে ক্যানভাসের আকার আকৃতি ও ব্যকগ্রাউন্ড কালার নির্ধারণ করা হয়েছে।
var blue = "#3A5BCD"; var red = "#EF2B36"; var yellow = "#FFC636"; var green = "#02A817";
এই কোডটুকুর মাধ্যমে বাবল গুলোর কালার তৈরির জন্য ভেরিয়েবল ঘোষনা করা হয়েছে। এখানকার কালার কোড সমূহ; যেমন #EF2B36 পরিবর্তন করে বাবলের কালার পরিবর্তন করা যাবে।
//t balls.push(new Ball(30, 30, 0, 0, red)); balls.push(new Ball(50, 30, 0, 0, red)); balls.push(new Ball(70, 30, 0, 0, red)); balls.push(new Ball(90, 30, 0, 0, red)); balls.push(new Ball(110, 30, 0, 0, red)); balls.push(new Ball(70, 50, 0, 0, red)); balls.push(new Ball(70, 70, 0, 0, red)); balls.push(new Ball(70, 90, 0, 0, red)); balls.push(new Ball(70, 110, 0, 0, red)); balls.push(new Ball(70, 130, 0, 0, red));
উপরের কোড গুলোর মাধ্যমে T লেটার টি প্রদর্শন করা হয়েছে। এখানে balls.push(new Ball(30, 30, 0, 0, red)); এর প্রথম 30 দ্বারা T লেটারের প্রথম বাবলটির দ্বিমাত্রিক স্থানাংক ব্যবস্থায় X অক্ষের দূরত্ব নির্দেশ করা হয়েছে দ্বিতীয় 30 দ্বারা দ্বিমাত্রিক স্থানাংক ব্যবস্থায় Y অক্ষের দূরত্ব নির্দেশ করা হয়েছে। শেষের red দ্বারা কালার এর মান নেয়ার জন্য ভেরিয়েবলকে কল করা হয়েছে।
অন্যান্য বাবলগুলো অনূরূপভাবে বসিয়ে সবগুলো লেটার গঠন করা হয়েছে।
………………………………………………………………………………..
জ্ঞন বিজ্ঞানের সংস্পর্শে আলোকিত একটা সুন্দর সমৃদ্ধ পৃথিবীর প্রত্যাশায় আজ এখানেই শেষ করছি। সকলের জন্য শুভকামনা রইল।
পোস্টটির মূল লেখক টিউটোহোস্ট টিম সদস্য অসিম কুমার
পোস্টটি ইতোপূর্বে এখানে প্রকাশিত
আমি টিউটোহোস্ট। বিশ্বের সর্ববৃহৎ বিজ্ঞান ও প্রযুক্তির সৌশল নেটওয়ার্ক - টেকটিউনস এ আমি 12 বছর 6 মাস যাবৎ যুক্ত আছি। টেকটিউনস আমি এ পর্যন্ত 162 টি টিউন ও 69 টি টিউমেন্ট করেছি। টেকটিউনসে আমার 1 ফলোয়ার আছে এবং আমি টেকটিউনসে 0 টিউনারকে ফলো করি।
টিউটোহোস্ট বাংলাদেশের একটি জনপ্রিয় ওয়েব হোস্টিং সেবাদানকারী প্রতিষ্ঠান। যুক্তরাস্ট্র এবং যুক্তরাজ্য ভিত্তিক দ্রুতগতির বেশ কিছু ওয়েব সারভারে গুরুত্বপূর্ণ তথ্যগুলো নিরাপদে সংরক্ষণ করা হয়। আমরা এদেশে ২৪ ঘন্টা এবং বছরে ৩৬৫ দিন অনলাইন এবং ফোন সাপোর্টের ব্যবস্থা রেখেছি। বাংলেদশসহ অনেক দেশের জনপ্রিয় ওয়েবসাইট আমাদের সারভার ব্যবহার করছে।
দারুন তো !!!