menu

WMatrix

WMatrix

جمعه 12 شهریور 1395

نمیدونم تا حالا شما فیلم ماتریکس را دیده اید یا نه

احتمال این که اون را دیده باشید خیلی زیاده!

از اون فیلم هایی هست که هر ساله 5-6 بار تلویزیون پخش میکنه!

یکی از فیلم های خوش ساخته، و فیلم خوبی هم هست

اگه فیلم را دیدید، حتما اون صحنه ای را که Neo به ماهیت اصلی ماتریکس پی میبره و ماتریکس را درک میکنه و یهویی همه جا را تشکیل شده از کد میبینه یادتونه

منظور من این صحنه است

بریم یه سری به دنیای ماتریکس بزنیم و اونو بیاریم توی وب

اگه یه کمی هم لینوکس کار کرده باشید (بازی کرده باشید) حتما با پکیج Cmatrix آشنایی دارید

به نقل از نویسنده اش:

CMatrix is a program I wrote one evening because I didn't want to have to run Wind*ws to see the cool scrolling lines from 'The Matrix', my fave movie.  If you haven't seen this movie and you are a fan of computers or sci-fi in general, go see this movie!!!  I have seen it twice, and I'm pondering seeing it again before it comes out on VHS.

امروز هم جمعه است، یه صبح دل انگیز، و من یکم حوصله ام سر رفته!

پس واسه ی تفریح هم که شده، تصمیم گرفتم که دور همی، یه کم کد بزنم و این پکیج را توی وب شبیه سازی کنم

با استفاده از CSS و JavaScript و البته Jquery

البته از اونجایی که وقت در مضیقه است(!) شاید نشه یه پکیج خوب از توش در آورد

من فعلا کد هاش را میزنم

بعد میشه به این گزینه هم فکر کرد که آروم آروم کد ها را منظم تر کنم و تبدیلش کنم به یه پلاگین کوچولوی جی کوئری

پس فعلا میریم کد زنی!

اولین چیزی که نیاز داریم، داشتن یه صفحه ی HTML تمیز هست

پس بهتره ابتدا، یه صفحه ی HTML بسازیم.

درون اون هم یه div میزاریم به اسم wmatrix

این div، المنت اصلی ما هست و تمام کاراکتر هایی که قراره از بالای صفحه بریزند پایین، توی این المنت قرار میگیرند.

ساختار html ما در همین حد کافیه!

بقیه ی کارها به عهده ی جاوا و کمی البته سی اس اس هست

پس یه فایل css میسازیم توی پوشه ی css به اسم wmatrix.css و یه فایل جاوااسکریپت به اسم wmatrix.js توی پوشه ای به اسم js

البته از اونجایی که این پلاگین بر اساس جی کوئری نوشته شده، یادتون نره که جی کوئری را هم توی صفحه ی HTML خودتون فراخوانی کنید

ساختار html ما آماده است!

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<meta http-equiv="content-language" content="fa-IR">
	<title>Wmatrix</title>
	<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
	<link href="./css/wmatrix.css" type="text/css" rel="stylesheet">
	<script type="text/javascript" src="./js/wmatrix.js"></script>
</head>
<body>
	<div class="container wmatrix">		
	</div>
</body>
</html>

حالا میریم سراغ بخش بعدی

یعنی جاوا اسکریپت های خودمون!

اولین قدم چیه؟

خب ما نیاز به متن داریم! دقیق ترش کاراکتر های جدا جدا

پس نیازه که یه تابع بنویسیم که بیاد یه کاراکتر رندوم ایجاد کنه

اینم از تابع من برای ایجاد یه کاراکتر رندوم!

function makeRandomChar(){
	return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 1);
}

میرسیم به قدم بعدی

قدم بعدی ما، ایجاد یه تابع هست که بقیه ی کارها را بکنه!

function wmatrix(){
    
}

بقیه ی کارهایی که باید با JS کرد چیا است؟

ما الان یه div داریم به اسم wmatrix که قراره کاراکتر هامون توش قرار بگیره

کارهایی که این تابع باید بکنه این هاست

1. باید یه استایل داخلی right بهشون بده، تا متن ها با فاصله های مختلف از هم قرار بگیرند و به هم نچسبند

2. باید داخل المنت wmatrix که ساخته ایم، هر n ثانیه یک کاراکتر بسازه (کاراکتر ها را داخل یه سری span با کلاس wm میزاریم و استایل right و بقیه ی استایل ها را به span ها میدیم تا کنترل بیشتری روی کاراکتر ها داشته باشیم)

پس میریم سراغ این تابع خودمون!

اول از همه، داخل اون یه setInterval میسازیم که هر n ثانیه یه کاراکتر بسازه. برای قشنگ تر شدن کار هم میزاریم که این n ثانیه که همون delay بین دوتا کاراکتر هست را کاربر بتونه با استفاده از آرگومان های تابع، خودش انتخاب کنه. البته یه پیشفرض هم براش میزاریم. فک کنم 60 هزارم ثانیه برای فاصله ی بین دوتا کاراکتر مناسب باشه

البته یه نکته ی مهم دیگه هم وجود داره. ما بعدا میخواهیم یه دکمه ی توقف هم بزاریم که با زدن اون دکمه پروسه ی ساختن و افزودن کاراکتر متوقف بشه. از اونجایی که قراره ساختن کاراکتر ها درون یه setInterval انجام شه و هر n ثانیه یه کاراکتر ساخته بشه، بعدا نیاز داریم که این setInterval را متوقفش کنیم. پس این setInterval را داخل یه متغیر تعریف میکنیم تا بعدا بتونیم از تابع clearInterval هم استفاده کنیم و این Interval خودمون را متوقف کنیم. یعنی اینجوری:

function wmatrix(delay = 60){
	mainWm = setInterval(function(){
					
	},delay);
}

میرسیم به قسمت بعد

الان اگه تمام کاراکتر هایی که از بالا به سمت پایین میان، با یه سرعت و یه جور بیان پایین، خیلی ضایع میشه! 

یعنی واقعا تفاوتی بین z و a وجود نداره!؟

حتی بین a و a هم تفاوت هس! (شاید هم نباشه دی:)

خلاصه این که ما میخواهیم بهشون سرعت بدیم

سرعت های متفاوت

و رندوم

به هر کدوم از کاراکتر ها. به نظرم 6 تا اسپید مختلف کافیه. یعنی سرعت 1 الی 6 را داشته باشن. برای این کار میایم و یه عدد رندوم میسازیم. این عدد رندوم بین 0 تا 1 هست که همینطور که طبق درس آمار و احتمال میدونید(!) با یه ضرب و جمع ساده میتونیم از این عدد رندوم بین 0 تا 1، عدد رندوم بین 1 تا 6 بسازیم!

اینجوری:

var speed = Math.floor((Math.random() * 6) + 1);

چالش بعدی ما، مکان کاراکتر هست.

فرض کنید div مورد نظر ما یعنی همون المنت wmatrix، طول 600 پیکسل داشته باشه. ما میخواهیم که کاراکتر هامون، به طور تصادفی، مکانشون بین 0 تا 600 پیکسل داخل این div باشه

پس یه تابع میخواهیم مثل همون بالایی! که اول بیاد و طول المنت wmatrix را پیدا کنه، و بعد از اون یه عدد رندوم بین 0 تا "طول المنت" بسازه تا بعدا از این عدد به عنوان استایل right کاراکتر استفاده کنیم

var w = Math.floor((Math.random() * $('.wmatrix').width() ) + 1);

پس تا اینجا یه چنین چیزی داریم

function wmatrix(delay = 60){
    mainWm = setInterval(function(){
        var w = Math.floor((Math.random() * $('.wmatrix').width() ) + 1);
        var speed = Math.floor((Math.random() * 6) + 1);
    },delay);
}

فک کنم همه ی مواد اولیه مون را تهیه کردیم!

فاصله از سمت راست را ساختیم؛ سرعتش را داریم؛ و یه setInterval هم داریم. تنها کاری که لازمه بکنیم اینه که داخل setInterval، هر n ثانیه، یه span بسازیم که کاراکترمون داخل اون باشه.

حالا مشخصات این span هم مهمه! واسه ی این span همون موقع ساختنش، میایم یه style بهش میدیم و داخل استایل، خصیصه ی right، مقدار متغیر w را که قبلا ساختیم بهش میدیم. یه سری کلاس مثل speed هم بهش میدیم که مشخص کنه این کاراکتر سرعتش چقدره.( البته سرعت هارا بعدا توی سی اس اس انجام میدیم)

مثلا کلاس های speed-1 و speed-2 تا speed-6 را بهشون میدیم. هر span یه کلاس wm هم بهش میدیم تا بعدا توی css ها بتونیم اندازه و فونت و .... را براش تعیین کنیم. و البته داخل span هم تابع تولید کاراکتر رندوممون را فرا میخونیم تا یه کاراکتر اتفاقی هم درونش بسازیم. و در نهایت، این span را که تولید کرده ایم با jquery، میچسبونیمش داخل المنت wmatrix! یعنی با append، اون را یکی از فرزندان wmatrix میکنیم 

در نهایت میشه این!

$('.wmatrix').append('<span data-number="' + i +'" data-speed="' + speed + '" class="wm wm-' + i +' speed-' + speed +'" style="right:' + w + 'px">' + makeRandomChar() +'</span>');

و تا الان این را داریم:

function wmatrix(delay = 60){
    var i = 0;
    mainWm = setInterval(function(){
        var speed = Math.floor((Math.random() * 6) + 1);
        var w = Math.floor((Math.random() * $('.wmatrix').width() ) + 1);
        $('.wmatrix').append('<span data-number="' + i +'" data-speed="' + speed + '" class="wm wm-' + i +' speed-' + speed +'" style="right:' + w + 'px">' + makeRandomChar() +'</span>');
        i = i + 1;
    },delay);
}

شاید فک کنید کار تمومه! اما هنوز کار هست

اگه کد را اجرا کنید با یه مشکل فجیع روبرو میشیم!

یه چیزی به اسم رم!

دقیق تر توضیح بدم؟ این کد میاد هر 60 هزارم ثانیه، یه span میسازه و اونو append میکنه به المنت wmatrix

6 ثانیه ی بعد، 100 تا المنت داریم

ولی یک دقیقه پس از اجرای صفحه، هزار تا span داریم و کمی بعد خیلی خیلی زیاد میشه تعداد span ها!

و مرورگر نمیتونه پردازش کنه و هنگ میکنه و سرعت صفحه آروم میشه و همه چی میریزه به هم!

واسه ی رفع این مشکل باید یه محدودیت بزاریم!

مثلا بگیم نهایتا 400 تا کاراکتر همزمان توی صفحه باشه

یا هر مقداری که کاربر تعیین کنه!

و وقتی به اون مقدار رسید، Interval ما را متوقف کنه

برای متوقف کردن Interval هم میتونیم از clearInterval استفاده کنیم و برای این که ببینیم چند تا span با کلاس wm داریم، از متد lenght استفاده میکنیم.

در نهایت، تابع wmatrix ما به شکل زیر میشه

function wmatrix(number = 400, delay = 60){
    var i = 0;
    mainWm = setInterval(function(){
        if ($('.wmatrix .wm').length < number) {
            var w = Math.floor((Math.random() * $('.wmatrix').width() ) + 1);
            var speed = Math.floor((Math.random() * 6) + 1);
            $('.wmatrix').append('<span data-number="' + i +'" data-speed="' + speed + '" class="wm wm-' + i +' speed-' + speed +'" style="right:' + w + 'px">' + makeRandomChar() +'</span>');
            i = i + 1;						
        } else{
            clearInterval(mainWm);
        };					
    },delay);
}

تا اینجا، دیگه کار ما تموم شده

اما حیفه وقتی تا اینجاش را نوشته ایم، نیمه کاره رهاش کنیم!

بهتره دوتا تابع دیگه هم بنویسیم

یکی برای پاک کردن صفحه و تمام span ها

یکی هم برای pause کردن Interval و Resume کردن اون

البته pause و resume کردن نه به این معنی که تموم کاراکتر ها سرجاشون freeze بشن ها!

بلکه به این معنا که دیگه span جدید نسازه یا دوباره شروع کنه به ساختن span

پس این سه تا تابع دو سه خطی را هم مینویسیم

function wmatrixend(){
	clearInterval(mainWm);
	$('.wmatrix .wm').remove();
}
function wmatrixpause(){
	clearInterval(mainWm);
}
function wmatrixresume(){
	wmatrix();
}

و الان هم تابع wmatrix را آخر فایلمون فراخوانی میکنیم.

در نهایت فایل js/wmatrix ما به شکل زیر میشه

function makeRandomChar(){
    return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 1);
}
function wmatrix(number = 400, delay = 60){
    var i = 0;
    mainWm = setInterval(function(){
        if ($('.wmatrix .wm').length < number) {
            var w = Math.floor((Math.random() * $('.wmatrix').width() ) + 1);
            var speed = Math.floor((Math.random() * 6) + 1);
            $('.wmatrix').append('<span data-number="' + i +'" data-speed="' + speed + '" class="wm wm-' + i +' speed-' + speed +'" style="right:' + w + 'px">' + makeRandomChar() +'</span>');
            i = i + 1;						
        } else{
            clearInterval(mainWm);
        };					
    },delay);
}
function wmatrixend(){
    clearInterval(mainWm);
    $('.wmatrix .wm').remove();
}
function wmatrixpause(){
    clearInterval(mainWm);
}
function wmatrixresume(){
    wmatrix();
}
wmatrix();

خسته شدید؟!

امیدوارم که نشده باشید!

چون هنوز یه مرحله ی دیگه مونده

و اون هم css هاشه

توی css هامون یه انیمیشن (keyframe) میسازیم که توش بیاد بر اساس سرعت هر span که قبلا بهش داده ایم، span ها را از بالا به پایین حرکت بده

@-webkit-keyframes godown {
    from {
        top: 0
    }
    to {
        top: 100%
    }
}
@-moz-keyframes godown {
    from {
        top: 0
    }
    to {
        top: 100%
    }
}
@keyframes godown {
    from {
        top: 0
    }
    to {
        top: 100%
    }
}

یکم هم به body مون قیافه میدیم که زیاد زشت نباشه!

body, html{
    width: 100%;
    height: 100%;
}
body{
    position: relative;
    background-color: #1d2b2a;    
    font-smooth: never;
    line-height: 2em;    
    -webkit-font-smoothing: none;
    -moz-font-smoothing: none;
    -ms-font-smoothing: none;
    text-shadow: -2px 0 0px rgba(0, 0, 225, 0.4), -1px 0 3px rgba(103, 171, 236, 0.6), 1px 0 4px rgba(69, 112, 204, 0.5);
    
}

و البته برای المنت wmatrix و wm خودمون هم فونت و ظاهر و اینا را تعیین میکنیم و به span هامون میگیم از انیمیشن godown که دوخط بالاتر تعریف کردیم استفاده کنند!

.wmatrix{
    width: 100%;
    height: 100%;
    position: relative;
    overflow: hidden;
    color: #d4f8e3;
    font-size: 21px;
    font-family: Inconsolata, "Lucida Console", Monaco, Courier, monospace;

}
.wmatrix .wm{
    position: absolute;
    top: 0;
    -webkit-animation-timing-function: linear;
    -ms-animation-timing-function: linear;
    -moz-animation-timing-function: linear;
    animation-timing-function: linear;
    -webkit-animation-name: godown;
    -moz-animation-name: godown;
    -ms-animation-name: godown;
    -webkit-animation-iteration-count: infinite;
    -moz-animation-iteration-count: infinite;
    -ms-animation-iteration-count: infinite;
    animation-name: godown;
    animation-iteration-count: infinite;
}

و در نهایت هم برای span هایی با کلاس های speed-1 تا speed-6، سرعت های متفاوت در نظر میگیریم

.wmatrix .wm.speed-1 {
    -webkit-animation-duration: 4s;
    -moz-animation-duration: 4s;
    -ms-animation-duration: 4s;
    animation-duration: 4s;
}
.wmatrix .wm.speed-2 {
    -webkit-animation-duration: 3.5s;
    -moz-animation-duration: 3.5s;
    -ms-animation-duration: 3.5s;
    animation-duration: 3.5s;
}
.wmatrix .wm.speed-3 {
    -webkit-animation-duration: 3s;
    -moz-animation-duration: 3s;
    -ms-animation-duration: 3s;
    animation-duration: 3s;
}
.wmatrix .wm.speed-4 {
    -webkit-animation-duration: 2s;
    -moz-animation-duration: 2s;
    -ms-animation-duration: 2s;
    animation-duration: 2s;
}
.wmatrix .wm.speed-5 {
    -webkit-animation-duration: 1.5s;
    -moz-animation-duration: 1.5s;
    -ms-animation-duration: 1.5s;
    animation-duration: 1.5s;
}
.wmatrix .wm.speed-6 {
    -webkit-animation-duration: 1s;
    -moz-animation-duration: 1s;
    -ms-animation-duration: 1s;
    animation-duration: 1s;
}

Thats it!

تموم شد

آخیش

منم خسته شدم از بس نوشتم!

من یکم دیگه روی ظاهرش کار کردم و شما میتونید دو تا مثالی که ازش استفاده کردم را در اینجا و اینجا مشاهده کنید و یا این دو مثال را از اینجا دانلود کنید.

و البته این کد ها را در نهایت منسجم تر به صورت یک پلاگین کوچولو روی گیت هاب هم گذاشتم که میتونید خیلی سریع تر بدون نیاز به کد زدن ازش استفاده کنید؛ میتونین اون را اینجا ببینین

امیدوارم از این پلاگین لذت برده باشید

تا درودی دیگر، بدرود


    ارسال نظر
    خوانا نیست؟تعویض کد