- vừa được xem lúc

Hướng dẫn làm mấy cái chấm bay bay và có dây nối nó với nhau và nối với chuột bằng Canvas

0 0 37

Người đăng: Nagi

Theo Viblo Asia

Mở đầu

Sau vài bài thì tôi nhận ra là mềnh hông có khiếu viết mấy bài giới thiệu, phân tích, nên là tôi lại quay lại viết mấy bài hướng dẫn làm mấy thứ làng nhàng vui vui vậy.

Hôm nay hướng dẫn ae làm cái ae làm cái mấy cái chấm bay lung tung, khi di chuột qua thì nó có cái tơ nối với con trỏ nhé, tôi gọi nó là connecting đốt-s

Thực ra là lúc bắt đầu, tôi cũng phân vân có nên làm cái random ra 108 câu tỏ tình hiệu ứng lung linh cực đẹp để ae dùng luôn dịp noen này luôn không, nhưng thấy đài báo bảo giờ đang thừa nam thiếu nữ, ae tỏ tình thành công thì tôi cũng vui, nhưng nguy cơ ế thì gần thêm một đoạn, nên là đợi tôi có người yêu rồi sẽ hỗ trợ ae sau vậy.

Trông như vậy này

Như các bạn có thể thấy, một thứ rất hay, rất thú vị nhưng vô dụng

Bắt đầu nào!

Bắt đầu thực hiện

Step 1: HTML + CSS

Một dòng HTML và CSS thôi, nhưng vì đoạn sau cũng sẽ chia ra nên tôi cũng chia đoạn này ra luôn

<canvas id="canvas"></canvas>
<style> canvas {background: #000}
</style>

Step 2: Khai báo canvas

var canvas = document.getElementById("canvas"), ctx = canvas.getContext('2d'); canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

Như các bạn thấy, tôi tạo kích thước rộng, dài của canvas trong js thay vì dùng css ở trên. Nhìn thì tưởng giống nhau, nhưng có chút khác biệt, css nhận định các selector như nhau, còn js sẽ nhận địch canvas là 1 thuộc tính ảnh, nên khi đẩy chiểu rộng, dài vào, nó sẽ dùng attribute widthheight, chính cái này mới là cái xác định của kích thước thật sự của canvas.

Step 3: Khởi tạo mảng "sao"

var stars = [], number = 300, mouse = { x: 0, y: 0 }; // khởi tạo từng sao
for (var i = 0; i < number; i++) { stars.push({ x: Math.random() * canvas.width, y: Math.random() * canvas.height, radius: Math.random() * 1 + 1, vx: Math.floor(Math.random() * 50) - 25, vy: Math.floor(Math.random() * 50) - 25, speed: Math.floor(Math.random() * 41) - 10, });
}

number là số lượng sao.

mouse là vị trí của con trỏ, chúng ta cần nó để có thể tạo cái tơ nối các sao xung quang con trỏ tới nó

xy là vị trị tri ban đầu của sao

radius là kích thước của chấm sao

vxvy là hướng di chuyển của sao, kiểu kẻ vector ấy

speed tất nhiên là tốc độ của sao rồi, đặt số cố định thì các sao sẽ chạy cũng tốc độ, đây tôi đặt random tốc độ từ 50->10, càng nhỏ thì chạy càng nhanh nhé

Bonus thêm cho mn thông thức lấy số random trong 1 khoảng này: Math.random() * (max - min + 1) + min)

Step 4: Chuẩn bị

Không có gì đặc biệt, tạo cái hàm tính khoảng cách 2 điểm và lấy vị trị của chuột thôi. Hình như có cái hàm để tính luôn, nhưng ngồi 1 lúc không nhớ ra nên tôi dùng luôn bitato Pythagoras cho nhẹ đầu, là cái định lý "bình phương cạnh huyền tam giác vuông bằng tổng bình phương các cạnh góc vuông" trong trường hợp bạn không nhớ =))

function distance( point1, point2 ){ var xs = 0; var ys = 0; xs = (point2.x - point1.x) ** 2; ys = (point2.y - point1.y) ** 2; return Math.sqrt( xs + ys );
} canvas.addEventListener('mousemove', function(e){ mouse.x = e.clientX; mouse.y = e.clientY;
});

Step 5: Vẽ bầu trời sao

Đây là tạo sao này~

function drawStars() { stars.map((star) => { ctx.beginPath(); ctx.fillStyle = "#fff"; ctx.arc(star.x, star.y, star.radius, 0, 2 * Math.PI); ctx.fill(); });
}

arc là để vẽ vòng tròn, tâm ở tọa độ star.xstar.y , bán kính là star.radius

Tiếp theo là vị trí bắt đầu vẽ và vị trí kết thúc nét vẽ, 0 là vị trí hướng 3h, vẽ xuôi chiều kim đồng hồ, 6h là 0.5PI, 9h là 1PI... là lượng giác ấy =)))

Giờ gặp thằng nhóc nào bảo "Cháu muốn là lập trình viên/ lập trình game/ làm hacker" mà không chịu học toán thì ae cứ đấm nó mấy phát cho tỉnh cơn mơ. Quay được về quá khứ, thì tôi cũng muốn đấm mình nữa ?

Quay lại vấn đề, fillStyle là chọn màu và fill là đổ màu vào, nếu các bạn dùng stroke thay cho fill thì nó sẽ chỉ vẽ ra một vòng tròn thôi, viền thì có màu, nhưng bên trong thì không.

Đây là lối các ông sao với nhau này~

function drawLines() { stars.map((starI) => { ctx.moveTo(starI.x, starI.y); if (distance(mouse, starI) < 250) ctx.lineTo(mouse.x, mouse.y); stars.map((starII) => { if (distance(starI, starII) < 50) ctx.lineTo(starII.x, starII.y); }); }); ctx.lineWidth = 0.1; ctx.strokeStyle = "white"; ctx.stroke();
}

Tôi đặt khoảng cách các sao đến mouse là 250, và các sao nỗi với nhau trong khoảng 50px. Bạn nên để khoảng cách này là biến, khai báo luôn đoạn bước 3 nay trên ấy, vậy cho dễ chỉnh sửa, ở đây, tôi viết luôn đây là do quên thích =))

Độ dày của line cũng không nên quá lớn, 0.2 trở xuống là đẹp, tôi để 0.1 cho dễ nhìn thôi, chứ 0.05 nó mới chuẩn.

Giờ thì vẽ bầu trời sao

function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.globalCompositeOperation = "lighter"; drawStars(); ctx.beginPath(); drawLines();
}

clearRect là vẽ hình chữ nhật, là cái nền ấy đen ấy, bắt đầu tại vị trị 0, 0 và có chiều rộng là canvas.width, chiều dài là canvas.height

globalCompositeOperation là để giúp chúng ta xử lý việc các bản vẽ trên canvas sẽ chèn đè, xếp lớp thế nào, ở đây chúng ta muốn "sao" trên nền "trời", mà thường thì bản vẽ sau sẽ đè lên bản vẽ trước thôi, nhưng cứ thêm vào cho chắc =))

ctx.globalCompositeOperation = "lighter" nghĩ là nó sẽ trông vậy canvas lighter 2 màu sẽ được trộn lại với nhau.

Sao lại dùng cái globalCompositeOperation này hả?

I've no idea. ?

Bỏ đi, tôi thấy nó vẫn chạy, nhưng thêm vào thì trông code nguy hiểm hơn ?

Step 6: Update vị trị sao

function update() { stars.map((star) => { star.x += star.vx / star.speed; star.y += star.vy / star.speed; if (star.x < 0 || star.x > canvas.width) star.vx = -star.vx; if (star.y < 0 || star.y > canvas.height) star.vy = -star.vy; });
}

function này sẽ update vị trị của từng sao, trong trường hợp sao chạm vào cạnh của khung canvas (đoạn if ấy) thì sẽ nảy ngược lại bằng 1 góc bằng với góc vào, như cái gương ấy, là cái hàm đồ thị bậc 1 thôi =))

Final

function tick() { draw(); update(); requestAnimationFrame(tick);
} tick();

cuối cùng là tổng hợp những gì đã làm và thêm cái requestAnimationFrame để có thể chạy được.

Kết

Cái connecting dots này bạn có thể dùng nó làm nền cho website tăng độ "nguy hiểm" khi chào mời khách, nhưng performance sẽ giảm kha khá nhé.

Source code các bạn có thể xem theo link tôi để ngay dưới đây.

Chúc ae thành công và qua được mùa noen lạnh lẽo ?

souce code: https://codepen.io/hungba124/pen/ZEbxKjw

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 525

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 433

- vừa được xem lúc

Một số phương thức với object trong Javascript

Trong Javascript có hỗ trợ các loại dữ liệu cơ bản là giống với hầu hết những ngôn ngữ lập trình khác. Bài viết này mình sẽ giới thiệu về Object và một số phương thức thường dùng với nó.

0 0 153

- vừa được xem lúc

Tìm hiểu về thư viện axios

Giới thiệu. Axios là gì? Axios là một thư viện HTTP Client dựa trên Promise.

0 0 145

- vừa được xem lúc

Imports và Exports trong JavaScript ES6

. Giới thiệu. ES6 cung cấp cho chúng ta import (nhập), export (xuất) các functions, biến từ module này sang module khác và sử dụng nó trong các file khác.

0 0 110

- vừa được xem lúc

Bài toán đọc số thành chữ (phần 2) - Hoàn chỉnh chương trình dưới 100 dòng code

Tiếp tục bài viết còn dang dở ở phần trước Phân tích bài toán đọc số thành chữ (phần 1) - Phân tích đề và những mảnh ghép đầu tiên. Bạn nào chưa đọc thì có thể xem ở link trên trước nhé.

0 0 245