Vẽ trong trình duyệt. Cách dùng thử các tính năng của trình duyệt Edge trong Chrome. Đầu vào của người dùng

Có nhiều thuật ngữ được sử dụng để mô tả các thử nghiệm trực quan trên máy tính, chẳng hạn như dev art, code sketch, demo và nghệ thuật tương tác, nhưng cuối cùng tôi đã chọn thuật ngữ bài thơ chương trình. Ý tưởng của bài thơ là văn xuôi trau chuốt, dễ truyền tải, ngắn gọn và có tính thẩm mỹ.

Nó không phải là một ý tưởng chưa hoàn thành mà là một tác phẩm đã hoàn thiện và thú vị khi xem. Bài thơ không phải là một công cụ, nhiệm vụ của nó là gợi lên cảm xúc.

niềm vui riêng Tôi đọc sách về toán học, thuật toán tính toán, vật lý và sinh học. Rất nhanh chóng, tôi nhận ra rằng nếu bạn chỉ chạy quanh quẩn với một ý tưởng, mọi người sẽ nhanh chóng cảm thấy nhàm chán với nó.

Nhưng tôi có thể lấy một số ý tưởng mà tôi thấy hấp dẫn và trình bày chúng một cách trực quan, sau đó mọi người sẽ có cảm giác ngạc nhiên ngay cả khi họ không hiểu lý thuyết đằng sau cách trình bày trực quan và các khái niệm khiến nó hoạt động.

Bạn không cần bất kỳ triết lý hay toán học phức tạp nào để viết một bài thơ cho chương trình, chỉ cần mong muốn được nhìn thấy thứ gì đó sống động và sống động trên màn hình.

Mã và các ví dụ mà tôi đã thu thập dưới đây sẽ giúp bạn hiểu cách thực hiện quá trình ngắn nhưng rất căng thẳng này. Nếu bạn muốn hiểu mã song song, bạn có thể Tải xuống tập tin nguồnĐây.

Khó khăn chính khi sáng tác một bài thơ là mọi thứ phải đơn giản và dễ dàng. Đừng dành ba tháng để tạo một bản demo thực sự thú vị. Thay vào đó, hãy sáng tác 10 bài thơ phát triển ý tưởng. Viết mã thử nghiệm ấn tượng, thú vị và không sợ thất bại.

Giới thiệu về Canvas

Nói tóm lại, canvas về cơ bản là một phần tử hình ảnh bitmap hai chiều tồn tại trong DOM và có thể được vẽ bằng nó.

Bản vẽ có thể được tạo bằng ngữ cảnh 2d hoặc ngữ cảnh WebGL. Bối cảnh là Đối tượng JavaScript, mà bạn sử dụng để truy cập các công cụ vẽ. Sự kiện JavaScript Những cái có sẵn cho canvas rất ngắn gọn, không giống như SVG.

Bất kỳ sự kiện nào xảy ra đều áp dụng cho toàn bộ thành phần chứ không phải cho bất kỳ thành phần riêng lẻ nào được vẽ trên khung vẽ, như với các thành phần hình ảnh thông thường. Đây là một ví dụ canvas đơn giản:

var canvas = document.getElementById("example-canvas"); var context = canvas.getContext("2d"); // Vẽ một hình chữ nhật màu xanh context.fillStyle = "#91C0FF"; context.fillRect(100, // x 100, // y 400, // rộng 200 // cao); // Vẽ văn bản context.fillStyle = "#333"; context.font = "18px Helvetica, Arial"; bối cảnh.textAlign = "trung tâm"; context.fillText("Thế giới canvas tuyệt vời", // text 300, // x 200 // y);

Nó khá dễ dàng để bắt đầu. Điều duy nhất có thể hơi phức tạp một chút là bối cảnh, trong đó các cài đặt như kiểu tô, độ rộng dòng, phông chữ và kiểu nét phải được đặt trước khi bản vẽ thực tế có thể bắt đầu.

Bạn rất dễ quên rằng những cài đặt này cần được cập nhật hoặc khôi phục và sau đó bạn nhận được kết quả không mong muốn.

Đưa các phần tử vào chuyển động

Trong ví dụ đầu tiên, hình chữ nhật chỉ được truyền qua toàn bộ màn hình một lần và vẫn ở dạng hình ảnh tĩnh trên khung vẽ. Đó không phải là một điều xấu, nhưng hình ảnh động thực sự mang lại cảm giác tốt khi hình ảnh được làm mới ở tốc độ 60 khung hình/giây.

Các trình duyệt hiện đại có chức năng requestAnimationFrame tích hợp sẵn để đồng bộ hóa mã vẽ tùy chỉnh với vòng lặp vẽ của trình duyệt. Điều này giúp ích về mặt hiệu quả và chất lượng. Mục tiêu hiển thị phải là mã chạy ở tốc độ 60 khung hình/giây.

(Lưu ý liên quan đến hỗ trợ trình duyệt: Có một số polyfill đơn giản nếu bạn cần cung cấp hỗ trợ trong các trình duyệt cũ hơn):

var canvas = document.getElementById("example-canvas"); var context = canvas.getContext("2d"); bộ đếm var = 0; var regWidth = 40; var regHeight = 40; var xMovement; //Đặt hình chữ nhật vào giữa màn hình var y = (canvas.height / 2) - (orthHeight / 2); context.fillStyle = "#91C0FF"; function draw() ( //Có một cách thông minh hơn để tăng thời gian, nhưng cách này sẽ đủ cho bộ đếm trình diễn++; //Đây là một số phép toán hay. Xem bài viết bên dưới để được giải thích chi tiết hơn. xMovement = Math.sin(counter / 25) * canvas .width * 0.4 + canvas.width / 2 - orthWidth / 2; //Xóa kết quả đã vẽ trước đó context.clearRect(0, 0, canvas.width, canvas.height); // Vẽ trực tiếp lên canvas context.fillRect(xMovement, y, orthWidth, orthHeight); // Sau khi được yêu cầu, khung hoạt ảnh mới có thể gọi lại hàm này requestAnimationFrame(draw); ) draw();

Vẽ bằng Toán

Bây giờ hãy chú ý, chúng ta đã nói về lập trình và vẽ trên màn hình, vì vậy tôi sẽ chuyển sang môn toán. Toán học là thứ tạo nên sự kỳ diệu sau đó được hiển thị trên màn hình. Thành thật mà nói, tôi luôn yêu thích toán học ( nhưng nhiều nghệ sĩ thì không).

Bất chấp tình yêu này, tôi có phần thất vọng về cách dạy nó ở trường. Tất cả đều rất hình thức, tất nhiên là rất tốt cho các nhà toán học, nhưng nó thiếu sự hứng thú, sự khám phá sâu sắc và tính thực dụng có thể giúp học một số khái niệm rất đơn giản. Tuy nhiên, các lập trình viên bỏ qua các bằng chứng trừu tượng và tập trung vào các ứng dụng thú vị.

Hãy để tôi dành vài giây để giải thích cách hoạt động của hàm sin. Điều này sẽ hữu ích khi nghĩ về cách bạn có thể tạo ra chuyển động bằng cách sử dụng các hàm toán học. Các hình thu nhỏ bên dưới là liên kết đến biểu đồ tương tác của hàm sin.

Lưu ý rằng chúng ta có nhiều biến hơn chỉ x trong hàm sin(x). Hàm tôi tạo là sin(a * x + b) * c + d . Chơi với thanh trượt bật đồ họa tương tác và bạn có thể thấy việc thay đổi bất kỳ giá trị nào trong số này ảnh hưởng đến đồ thị của hàm.

Bây giờ tôi sẽ viết lại công thức từ ví dụ mã trước đó và tạo một phiên bản khác dễ đọc hơn:

var a = 1 / 25, //Làm cho đồ thị dao động ít thường xuyên hơn x = counter, //Dịch chuyển đồ thị một chút mỗi lần draw() được gọi b = 0, //Không cần di chuyển đồ thị lên hoặc xuống c = width * 0.4, //Đặt chiều rộng của sóng nhỏ hơn một nửa canvas một chút d = canvas.width / 2 - orthWidth / 2; //Di chuyển hình chữ nhật về giữa xMovement = Math.sin(a * x + b) * c + d;

Nếu bạn muốn thử nghiệm mã mà tôi đã hiển thị, tôi khuyên bạn nên thử thêm chuyển động dọc theo trục y. Hãy thử thay đổi các giá trị trong hàm sin hoặc sử dụng một giá trị khác hàm lượng giácđể thử nghiệm nó và xem điều gì sẽ xảy ra.

Đầu vào của người dùng

Trong khi chúng ta xem xét chuyển động bằng toán học, tôi muốn dành chút thời gian để xem xét bạn có thể làm gì với các thiết bị đầu vào khác nhau để di chuyển một hình chữ nhật quanh trang. Trình duyệt hỗ trợ tất cả các tùy chọn đầu vào có thể có, bao gồm micrô, webcam, chuột, bàn phím và gamepad.

Cũng có thể kết nối tùy chọn bổ sung nhập dữ liệu bằng các plugin như Leap Motion hoặc Kinect. Bằng cách sử dụng WebSockets và máy chủ, bạn có thể kết nối phần cứng của mình với hình ảnh trực quan.

Kết nối micrô của bạn với API âm thanh trên web và bạn có thể điều khiển pixel của mình bằng âm thanh. Bạn thậm chí có thể tạo cảm biến chuyển động dựa trên webcam của mình và xua đuổi cá ảo ( Tôi đã làm điều gì đó tương tự trong Flash cách đây khoảng 5 năm).

Bây giờ chúng ta đã giải quyết được vấn đề đó, hãy quay lại và xem thêm một số ví dụ. Một hình vuông là nhàm chán, hãy tăng tiền cược. Đầu tiên, hãy tạo một hàm bình phương có thể làm được nhiều việc. Chúng ta sẽ gọi nó là Chấm.

Một thứ khác giúp ích rất nhiều khi làm việc với các đối tượng chuyển động là vectơ, thay vì sử dụng các biến x và y riêng biệt.

Trong các ví dụ mã này mà tôi lấy từ Three.js, có lớp Vector2. Việc sử dụng vector.x và vector.y cùng một lúc sẽ dễ dàng hơn nhiều, nhưng lớp này cũng chứa một số phương thức tiện lợi. Để có được nhiều hơn thông tin chi tiết bạn có thể kiểm tra tài liệu.

Chấm toàn năng

Trong ví dụ này, mọi thứ phức tạp hơn một chút vì nó tương tác với các đối tượng, nhưng nó đáng giá. Hãy xem ví dụ về mã để xem đối tượng Cảnh mới điều khiển hoạt động vẽ trên khung vẽ.

Lớp Dot mới của chúng tôi sẽ làm việc với đối tượng này để truy cập các biến mà nó cần, chẳng hạn như bối cảnh canvas:

hàm Dot(x, y, scene) ( var speed = 0,5; this.color = "#000000"; this.size = 10; this.position = new THREE.Vector2(x,y); this.direction = new BA .Vector2(tốc độ * Math.random() - tốc độ / 2, tốc độ * Math.random() - tốc độ / 2); this.scene = scene; )

Để bắt đầu phát triển hàm tạo cho Dot, chúng ta định cấu hình hành vi của nó và đặt một số biến mà chúng ta sẽ sử dụng. Một lần nữa, sử dụng lớp vectơ Three.js.

Khi hiển thị nội dung ở tốc độ 60 khung hình/giây, điều quan trọng là phải khởi tạo đối tượng trước thay vì tạo đối tượng mới trong quá trình hoạt ảnh. Bởi vì nó ngốn tài nguyên bộ nhớ và có thể gây ra hình ảnh động bị giật. Ngoài ra, hãy chú ý cách một bản sao của cảnh được chuyển qua liên kết trong Dot. Điều này giúp giữ mã sạch:

Tất cả các phần khác của mã sẽ được cài đặt trong nguyên mẫu của đối tượng Dot để mọi Dot mới được tạo sẽ có quyền truy cập vào các phương thức này. Dưới đây tôi sẽ chia nhỏ từng chức năng một:

Dot.prototype = ( cập nhật: function() ( ... ), draw: function() ( ... ) )

Tôi đang cập nhật mã bản vẽ từ mã đã cập nhật. Điều này giúp việc duy trì mã dễ dàng hơn nhiều và tăng hiệu suất của đối tượng. Tương tự, mẫu thiết kế MVC nhấn mạnh vào logic điều khiển và trình bày. Biến dt bắt đầu thay đổi mỗi mili giây kể từ thời điểm cuộc gọi cuối cập nhật.

Cái tên này hay, ngắn gọn và xuất phát từ phép tính đạo hàm (đừng lo lắng). Điều này tách rời chuyển động khỏi tốc độ khung hình. Bằng cách này, bạn sẽ tránh được tình trạng chậm lại kiểu NES khi mọi thứ trở nên quá phức tạp. Nếu tải quá nặng, một số khung hình sẽ bị rớt ra khỏi hoạt ảnh nhưng tốc độ vẫn giữ nguyên:

updatePosition: function() ( //Cái này thủ thuật nhỏđể tạo một biến bên ngoài vòng lặp kết xuất // Điều này đòi hỏi nhiều tài nguyên bộ nhớ bên trong vòng lặp. // Biến chỉ có sẵn cho hàm bên dưới. var moveDistance = new THREE.Vector2(); //Đây là hàm trả về thực tế function(dt) ( moveDistance.copy(this.direction); moveDistance.multiplyScalar(dt); this.position.add(moveDistance); //Lưu dấu chấm trong màn hình this.position.x = ( this.position.x + this.scene.canvas.width) % this.scene.canvas.width; this.position.y = (this.position.y + this.scene.canvas.height) % this.scene .canvas .height; ) )(), //Lưu ý rằng hàm này thực thi ngay lập tức và trả về các hàm khác nhau

Hàm này có cấu trúc hơi khó hiểu nhưng rất dễ hình dung. Nó thực sự tiêu tốn rất nhiều bộ nhớ. Biến moveDistance được đặt một lần và có thể được sử dụng lại bất cứ khi nào hàm được gọi.

Vectơ này chỉ được sử dụng để giúp tính toán vị trí mới chứ không được sử dụng bên ngoài hàm. Đây là phần tử đầu tiên của toán học vectơ mà chúng tôi sử dụng.

Bây giờ vectơ chỉ phương được nhân với mỗi thay đổi về thời gian rồi cộng vào vị trí. Cuối cùng, chúng tôi thực hiện các hành động theo mô-đun để giữ dấu chấm trong màn hình:

draw: function(dt) ( // Để thuận tiện, chúng ta nhận được tên ngắn biến var ctx = this.scene.context; ctx.beginPath(); ctx.fillStyle = this.color; ctx.fillRect(this.position.x, this.position.y, this.size, this.size); )

Sau đó mọi thứ đều đơn giản. Chúng ta lấy một bản sao của bối cảnh từ đối tượng cảnh và sau đó vẽ một hình chữ nhật ( hoặc bất cứ điều gì bạn muốn). Hình chữ nhật có lẽ là hình dạng nhanh nhất để vẽ trên màn hình.

Bây giờ tôi đang thêm một Dot mới thông qua cuộc gọi this.dot = Dấu chấm mới(x, y, this) trong hàm tạo cảnh, sau đó trong phương thức cập nhật của không gian hành động chính, tôi thêm this.dot.update(dt) và lấy điểm để chia tỷ lệ trên toàn bộ màn hình. ( Để xem tất cả mã trong ngữ cảnh, hãy xem nguồnđến bài viết).

Thật tuyệt khi chúng ta có một chút cấu trúc bên trong có mã, nhưng nó không thực sự mang lại điều gì đặc biệt thú vị. Nhưng chu kỳ thú vị hơn nhiều. Trong đối tượng không gian làm việc, chúng ta sẽ tạo một đối tượng DotManager mới.

Sẽ thuận tiện hơn nếu chúng ta thu thập chức năng này vào một đối tượng riêng biệt để mã đơn giản và rõ ràng hơn vì bản thân quy trình ngày càng trở nên phức tạp hơn:

var DotManager = function(numberOfDots, scene) ( this.dots = ; this.numberOfDots = numberOfDots; this.scene = scene; for(var i=0; i< numberOfDots; i++) { this.dots.push(new Dot(Math.random() * this.canvas.width, Math.random() * this.canvas.height, this.scene)); } }; DotManager.prototype = { update: function(dt) { for(var i=0; i < this.numberOfDots; i++) { this.dots[i].update(dt); } } };

Bây giờ, thay vì tạo và cập nhật Dot, chúng tôi sử dụng một cảnh để tạo và cập nhật DotManager. Để bắt đầu, chúng ta sẽ tạo 5000 điểm:

function Scene() ( ... this.dotManager = new DotManager(5000, this); ... ); Scene.prototype = ( ... update: function(dt) ( this.dotManager.update(dt); ) ... );

Được rồi, điều đó tốt hơn là chỉ có một điểm. Bây giờ là lúc bắt đầu thêm mã vào phương thức cập nhật cho một Dấu chấm. Mọi thứ thay đổi khi mã đối tượng tác động đến mọi điểm trên màn hình. Đó là lúc phép màu bắt đầu tác động lên mọi thứ. Bạn có nhớ hàm sin không? Bây giờ thêm một chút hiệu ứng gợn sóng thì sao?

Chúng ta sẽ tạo một biến wavePosition cho đối tượng Dot. Trong quá trình vẽ cuối cùng, chúng ta sẽ thêm biến này vào vị trí tương ứng với trục Y:

updateWave: function(dt, time) ( this.wavePosition = Math.sin(this.scene.currTime / 500 + this.position.x / this.scene.canvas.width * 4) * 20; )

Một trục trặc nhỏ ở một trong các dòng, mã bị hỏng, giống như hàm sin trước đó:

var a = 1 / 500, //Đặt hiệu ứng sóng diễn ra chậm hơn một chút x = this.scene.currTime, //Dịch chuyển nó một chút dọc theo biểu đồ, mỗi lần draw() được gọi b = this.position.x / this.scene .canvas.width * 4, //Không cần di chuyển biểu đồ lên hoặc xuống c = 20, //Đặt độ rộng sóng nhỏ hơn một nửa canvas d = 0; //Di chuyển hình chữ nhật về giữa xMovement = Math.sin(a * x + b) * c + d;

Hóa ra rất thú vị...

Thêm một mẹo nhỏ nữa. Bảng màu đơn sắc trông buồn tẻ, hãy thêm một chút màu sắc:

var Hue = this.position.x / this.scene.canvas.width * 360; this.color = Utils.hslToFillStyle(hue, 50, 50, 0.5);

Đối với mỗi Dấu chấm mới được tạo, chúng tôi lấy vị trí ban đầu của nó và đặt màu sắc của nó, tùy thuộc vào vị trí của nó dọc theo chiều rộng của khung vẽ. Utils.hslToFillStyle là một hàm trợ giúp nhỏ mà tôi đã thêm vào để biến một số biến đầu vào thành các chuỗi FillStyle được định dạng chính xác.

Bây giờ mọi thứ trông thậm chí còn thú vị hơn. Một lần nữa, đây là ví dụ về việc kiểm soát việc trực quan hóa bằng toán học hoặc các biến đầu vào. Tôi thực sự thích tạo màu bằng mô hình màu HSL hơn là RGB vì tính đơn giản của nó. RGB hơi trừu tượng.

Tương tác người dùng qua chuột

Cho đến nay chúng tôi chưa có bất kỳ tương tác thực sự nào của người dùng:

var Mouse = function(scene) ( this.scene = scene; this.position = new THREE.Vector2(-10000, -10000); $(window).mousemove(this.onMouseMove.bind(this)); ); Mouse.prototype = ( onMouseMove: function(e) ( if(typeof(e.pageX) == "number") ( this.position.x = e.pageX; this.position.y = e.pageY; ) else ( this.position.x = -100000; this.position.y = -100000; ) ) );

Đối tượng đơn giản này gói gọn logic cập nhật thông qua các thao tác chuột từ khu vực làm việc. Nó chỉ cập nhật vector vị trí khi chuột được di chuyển. Sau đó, các đối tượng khác có thể xác định vị trí của vectơ chuột nếu chúng được truyền tham chiếu đến đối tượng.

Một lưu ý. Ở đây tôi không xem xét trường hợp chiều rộng canvas không tương ứng 1 với 1 với kích thước DOM tính bằng pixel, tức là. vải thích ứng, mật độ cao pixel (võng mạc) của canvas hoặc khi canvas không bắt đầu ở góc trên cùng bên trái. Trong những trường hợp này, tọa độ chuột phải được điều chỉnh cho phù hợp:

var Scene = function() ( ... this.mouse = new Mouse(this); ... );

Điều duy nhất còn lại chúng ta phải làm là tạo một đối tượng chuột bên trong không gian làm việc. Bây giờ chúng ta đã giới thiệu tính năng tương tác với chuột, hãy tạo hiệu ứng thu hút các điểm tới nó:

function Dot(x, y, scene) ( ... this.attractSpeed ​​​= 1000 * Math.random() + 500; this.attractDistance = (150 * Math.random()) + 180; ... )

Chơi với các giá trị này để thay đổi các hiệu ứng này. Bây giờ chúng ta hãy thực hiện phương pháp thu hút điểm cho chuột. Đó không phải là nhiều mã dài với nhận xét:

thu hútMouse: function() ( //Một lần nữa, tạo các biến riêng tư cho phương thức này var vectorToMouse = new THREE.Vector2(), vectorToMove = new THREE.Vector2(); //Đây thực sự là phương pháp chung return function(dt) ( var distanceToMouse, distanceToMove; //Nhận một vectơ biểu thị khoảng cách x và y từ điểm đến chuột // Để tìm hiểu thêm về cách các vectơ này hoạt động, hãy xem tài liệu ba.js vectorToMouse .copy (this.scene.mouse.position) .sub(this.position); //Lấy khoảng cách từ chuột đến vector distanceToMouse = vectorToMouse.length(); //Sử dụng các giá trị vô hướng riêng lẻ ​​để điều chỉnh khoảng cách di chuyển moveLength = dt * (this .attractDistance - distanceToMouse) / this.attractSpeed; //Chỉ di chuyển điểm nếu nó bị thu hút if(moveLength > 0) ( //Thay đổi kích thước của vectơ chuột thành độ dài chuyển động mong muốn vectorToMove .copy (vectorToMouse) .divideScalar(distanceToMouse) .multiplyScalar (moveLength); //Hãy tiếp tục và thêm nó vào vị trí hiện tại ngay bây giờ, không phải khi gọi draw this.position.add(vectorToMove); ) ); )()

Phương pháp này có vẻ khó đối với bạn nếu bạn không rành về toán học vectơ. Các vectơ có thể giúp tạo ra biểu diễn trực quan, nếu bạn muốn tạo một cái gì đó tương tự như dấu cốc cà phê trên một tờ giấy.

Nói một cách đơn giản, hàm này lấy khoảng cách giữa chuột và một điểm. Và sau đó nó di chuyển điểm đến rất gần con chuột, tùy thuộc vào mức độ gần của nó trước đó và liệu nó có nằm trong phạm vi lực hút hay không cũng như thời gian đã trôi qua bao lâu.

Điều này được thực hiện bằng cách tính khoảng cách di chuyển ( số vô hướng thông thường) rồi nhân nó với vectơ tương ứng ( vectơ có độ dài 1), được hướng từ điểm tới chuột. Đúng, câu cuối cùng khó có thể xếp vào loại ngôn ngữ đơn giản.

Đối với tôi, bản chất của một bài thơ chương trình và sự hình thành các yếu tố nghệ thuật nằm ở việc khám phá nhiều khả năng khác nhau. Tôi khuyên bạn không nên quá chú ý đến chi tiết hoặc các dự án lớn.

Thay vì thử một vài dự án nhỏ hơn, thử nghiệm chúng và đạt được một kết quả nhất định, bạn có thể kết thúc bằng thất bại và thất vọng.

Bằng cách nào đó, khi kết thúc một tác phẩm của mình, tôi đi đến kết luận rằng mọi thứ trông giống như một mảnh rác nhiều màu. Nhưng tôi đã đặt nhiều hy vọng vào dự án này. Nhưng tôi không để thất bại làm mình gục ngã.

Đoạn mã trong bài viết này đã được viết lại nhiều lần để đạt được phong cách hướng đối tượng mà tôi thấy phù hợp nhất.

Điều chỉnh các ý tưởng ở đây cho phù hợp với quy trình làm việc và công cụ của riêng bạn. Poem không phải là một hệ thống tích hợp lớn nên rất dễ thử nghiệm mà không bị hạn chế bởi các dự án web rườm rà.

Áp dụng các bức vẽ của bạn giống như những tờ giấy mà bạn vẽ bằng bút chì. Tìm thấy ý tưởng thú vị, hãy thử nghiệm với chúng. Và đừng giới hạn chuyến bay ưa thích của bạn.

Nếu bạn đăng một bức ảnh về chú mèo Murzik yêu thích của mình trên trang web của mình nhưng bạn không muốn ai sao chép hoặc lưu nó vào ổ cứng, thì hãy đặt một đoạn script như vậy vào phần nội dung của trang web.

Công nghệ Kéo & Thả được sử dụng ở hầu hết mọi nơi chương trình ứng dụng. Đôi khi (ví dụ: khi phát triển trò chơi JS) công nghệ này là cần thiết...

Thoạt nhìn, phần tử là một phần tử HTML5 có thể được sử dụng để vẽ. Nó chỉ là một vật chứa trong đó bạn có thể vẽ...

Nếu bạn hào hứng với những cơ hội mới Microsoft Edge, nhưng bạn không muốn chuyển sang nó từ trình duyệt thông thường của mình, tôi hiểu bạn. Trong khi Edge chắc chắn nhanh hơn, quyến rũ hơn và bóng bẩy hơn trình duyệt web IE nó không có nhiều tiện ích bổ sung và tiện ích mở rộng như Chrome.


Tin vui là bạn không cần phải chuyển từ trình duyệt hiện tại của mình để tận dụng một số tính năng mới của Edge. Bạn có thể vẽ trên các trang web, xem bài viết ở chế độ đọc toàn màn hình và thậm chí tìm kiếm trên Google bằng giọng nói của mình mà không cần rời khỏi Chrome yêu thích của mình. Ngoài ra, nhóm Google không ngừng làm việc để tăng tốc và cải thiện trình duyệt của mình (ví dụ: họ đã cải thiện mức tiêu thụ pin, theo một bài đăng trên Google+ của kỹ sư phần mềm cấp cao Peter Kasting).

Được rồi, Google.

Edge cho rằng nó tốt nhất vì nó tích hợp với tìm kiếm. trợ lý giọng nói Cortana. Nhưng bạn có thể có được chức năng tương tự trong Chrome, Google có tính năng tìm kiếm bằng giọng nói "Hey Google" của riêng mình.

Để bật "Ok Google", hãy nhấp vào nút menu trong Chrome (nút "ba dòng" ở góc trên bên phải) và đi tới menu "Cài đặt". Trong phần “Tìm kiếm”, hãy chọn hộp bên cạnh “Bật tìm kiếm bằng giọng nói bằng lệnh “Ok Google”.



Giờ đây, bạn có thể kích hoạt Tìm kiếm bằng giọng nói của Google bằng cách nói "Ok Google" khi bạn đang ở trong tab mới hoặc khi bạn đang ở trên Google.com. Sau khi kích hoạt tìm kiếm bằng giọng nói, bạn chỉ cần nói ra câu hỏi của mình và Google sẽ lắng nghe, dịch từ của bạn thành văn bản và trả về kết quả tìm kiếm.

Những nét vẽ nguệch ngoạc trên các trang web.

Tính năng vẽ tích hợp của Edge rất thú vị nhưng Edge không phải là trình duyệt duy nhất có khả năng như vậy. Bạn có thể tìm thấy tính năng tương tự trong Chrome với một lượng lớn bằng cách cài đặt tiện ích mở rộng Web Paint.

Việc này rất dễ thực hiện, hãy nhấp vào liên kết ở trên và nhấp vào "Thêm vào Chrome". Sau khi tiện ích mở rộng được thêm vào, bạn sẽ thấy biểu tượng bảng màu sơn ở bên phải góc trên cùng cửa sổ. Nếu bạn muốn vẽ gì đó trên trang web, hãy nhấn vào biểu tượng này và các công cụ vẽ sẽ xuất hiện.



Sử dụng những công cụ này bạn có thể vẽ đường trên trang web, thêm văn bản, chèn các hình thức làm sẵn và tô màu các vùng đó. Nếu bạn muốn lưu tác phẩm của mình, hãy nhấp vào biểu tượng camera để chụp ảnh màn hình.

Chế độ đọc.

Chrome không được tích hợp sẵn chế độ toàn màn hình việc đọc, nhưng tiện ích mở rộng Khả năng đọc có thể xóa quảng cáo và các thành phần khác khỏi trang cản trở việc đọc thoải mái, tương tự như chế độ đọc trong Edge.



Đi tới trang Tiện ích mở rộng khả năng đọc và nhấp vào Thêm vào Chrome. Bạn sẽ thấy một biểu tượng trông giống như chiếc ghế màu đỏ ở góc trên cùng bên phải của cửa sổ trình duyệt. Nhấp vào biểu tượng này khi bạn muốn xem một trang ở định dạng dễ đọc và chọn "Đọc ngay", tiện ích mở rộng sẽ cố gắng vẽ lại các trang (cách này hoạt động tốt nhất trên các trang web có nhiều văn bản).

Bạn vẽ online đã lâu chưa kể graffiti VKontakte? Những gì tôi sắp viết khác xa với graffiti trên mạng xã hội, các lớp với chế độ hòa trộn, độ nhạy áp lực của bút, bút vẽ tiên tiến... đây là không có nghĩa là "PREVEDS" trên tường của hàng xóm )

Giới thiệu

Tôi đã từng có một ý tưởng và đã thu thập được một danh sách khổng lồ các biên tập viên trực tuyến mà ít nhất tôi có thể vẽ được thứ gì đó. Sau đó, đó là một điều mới mẻ và thật thú vị khi xem mọi người đã nghĩ ra điều gì... Nếu trí nhớ của tôi không sai thì có khoảng bốn mươi trong số đó, bao gồm nhiều công cụ vẽ hình sơn “dành cho trẻ em”. Tôi đã thu thập nó, nhưng tất cả những thứ rác rưởi trong danh sách này đều không có tác dụng thực tế gì.

Sau đó, khi tôi đang điều hành blog của mình (không còn tồn tại và sẽ không bao giờ tồn tại), tôi đã lựa chọn một số biên tập viên để có thể vẽ một tác phẩm ít nhiều đã hoàn thiện. Trong danh sách này đã có khoảng 5-7 người trong số họ (tôi không nhớ nữa).

Thật kỳ lạ, sau gần hai năm kể từ đó, tôi vẫn còn giữ một cái trong dấu trang của mình dịch vụ thú vị kể từ danh sách cuối cùng của tôi. Trải qua kiểu “chọn lọc tự nhiên” này, anh ấy đã thành công sống sót cho đến ngày nay và được tôi khá vui vẻ đến thăm… à, ít nhất mỗi tháng một lần, đó là chắc chắn: D.

Cái gì? Ở đâu?

Vậy dịch vụ này là gì? - bạn hỏi, 2draw.net - Mình sẽ trả lời :D.

Mặc dù có vẻ ngoài không hấp dẫn (theo ý kiến ​​​​của tôi), nhưng chức năng của trang này rất tốt. Có một blog, một thư viện các tác phẩm của người dùng, một diễn đàn, một wiki... và trên thực tế, một phòng vẽ.

Bây giờ điều đầu tiên chúng ta cần là cài đặt trình điều khiển máy tính bảng (bút) cho trình duyệt, để chiếc bút có thể khéo léo truyền áp lực lên ứng dụng trên trình duyệt. Tải xuống trình điều khiển cho

Viết mã đẹp- đó là một niềm vui, nhưng thật khó để chia sẻ niềm vui này với các lập trình viên khác, chứ đừng nói đến những người không phải là lập trình viên. Trong thời gian rảnh rỗi sau giờ làm và giao tiếp với gia đình, tôi nảy ra ý tưởng về cách lập trình một bài thơ bằng cách sử dụng yếu tố vảiđể vẽ trong trình duyệt.

Có rất nhiều thuật ngữ mô tả các thí nghiệm trực quan trên máy tính, sơ đồ mã, bản demo, nghệ thuật tương tác, v.v. Để mô tả quá trình này, tôi sử dụng thuật ngữ bài thơ lập trình. Bài thơ là một đoạn văn xuôi được trau chuốt cho sáng sủa, nhẹ nhàng, cô đọng và có tính thẩm mỹ. Đây không phải là một bản phác thảo ý tưởng chưa hoàn thiện trong một cuốn sổ phác thảo, mà là một thứ gì đó mạch lạc được trình bày để người xem thưởng thức. Bài thơ không phải là một nhạc cụ mà nó sống để khơi gợi cảm xúc.

Tôi đọc rất nhiều sách về toán học, công nghệ máy tính, vật lý và sinh học vì niềm vui của riêng mình. Và điều tôi nhanh chóng nhận ra là nếu tôi nói về một ý tưởng, mọi người sẽ nhanh chóng chán nó. Trên thực tế, tôi có thể đưa ra một ý tưởng mà tôi cho là vô cùng thú vị và nhanh chóng khiến ai đó cảm thấy hứng thú, ngay cả khi người đó không biết gì về mã hóa hoặc cách thức hoạt động của nó. Bạn không cần phải nắm vững một số tư tưởng triết học phức tạp hoặc các phép tính tính toán để lập trình một bài thơ. Tất cả những gì bạn cần là mong muốn được nhìn thấy thứ gì đó còn sống và đang thở trên màn hình của bạn. Các mã và ví dụ tôi để lại bên dưới sẽ giúp bạn hiểu cách thực sự thực hiện quy trình nhanh chóng và không phức tạp này.

Điểm chính là việc tạo ra một bài thơ phải đơn giản và dễ dàng. Không cần phải mất ba tháng để xây dựng một cái, mặc dù đó là một bản demo rất thú vị. Thay vào đó, hãy sáng tác 10 bài thơ sẽ giúp hiện thực hóa ý tưởng của bạn. Viết mã thú vị và đừng sợ thất bại.

Giới thiệu về Canvas

Nói tóm lại, canvas là phần tử hình ảnh bitmap 2 chiều nằm trong DOM ( mô hình đối tượng tài liệu) và có thể được vẽ ở đó. Bạn có thể vẽ cả trong ngữ cảnh 2d và ngữ cảnh WebGL. Ngữ cảnh là JavaScript mà chúng ta sử dụng để truy cập các công cụ vẽ. Các quy trình JavaScript có sẵn cho canvas rất rõ ràng, không giống như các quy trình có sẵn cho SVG. Bất kỳ quy trình nào được gọi trên toàn bộ phần tử, thay vì thứ gì đó được vẽ vào khung vẽ, đều giống hệt như phần tử hình ảnh thông thường. Đây là một ví dụ canvas cơ bản:

Var canvas = document.getElementById("example-canvas"); var context = canvas.getContext("2d"); // Vẽ một hình chữ nhật màu xanh context.fillStyle = "#91C0FF"; context.fillRect(100, // x 100, // y 400, // rộng 200 // cao); // Vẽ một số văn bản context.fillStyle = "#333"; context.font = "18px Helvetica, Arial"; bối cảnh.textAlign = "trung tâm"; context.fillText("Thế giới canvas tuyệt vời", // text 300, // x 200 // y);

Không có gì phức tạp ở đây, bạn có thể dễ dàng bắt đầu. Điều duy nhất có thể hơi khó hiểu là bối cảnh phải được cấu hình với các cài đặt như fillStyle, lineWidth, font và StrokeStyle trước khi sử dụng bản vẽ thực tế. Bạn có thể dễ dàng quên cập nhật hoặc tải lại cài đặt và nhận được kết quả không mong muốn.

Tạo một phong trào

Ví dụ đầu tiên chỉ chạy xung quanh và biến bản vẽ tĩnh thành canvas. Tất cả điều này đều ổn, nhưng niềm vui thực sự bắt đầu khi bạn đặt tốc độ thành 60 khung hình mỗi giây. bạn trình duyệt hiện đại Có một tiện ích bổ sung trong hàm requestAnimationFrame giúp đồng bộ hóa mã bản vẽ nguồn với bản vẽ di chuyển trong trình duyệt. Điều này cải thiện hiệu quả và mang lại chuyển động trơn tru. Mục tiêu kết xuất phải là mã di chuyển với tốc độ 60 khung hình mỗi giây.

var canvas = document.getElementById("example-canvas");

Var context = canvas.getContext("2d"); bộ đếm var = 0; var regWidth = 40; var regHeight = 40; var xMovement; //Đặt hình chữ nhật vào giữa màn hình var y = (canvas.height / 2) - (orthHeight / 2); context.fillStyle = "#91C0FF"; function draw() ( //Có nhiều cách thông minh hơn để tăng thời gian, nhưng đây là nhằm mục đích minh họa counter++; // Toán hay bên dưới. Giải thích thêm trong văn bản sau mã. xMovement = Math.sin(counter / 25) * canvas .width * 0.4 + canvas.width / 2 - orthWidth / 2; //Xóa kết quả bản vẽ trước đó context.clearRect(0, 0, canvas.width, canvas.height); // Thực sự vẽ trên canvas context.fillRect( xMovement, y, orthWidth, orthHeight); // Yêu cầu khi có khung hình động mới để gọi lại hàm này requestAnimationFrame(draw); ) draw();

Vẽ toán học

Bây giờ hãy cẩn thận, trước đó chúng ta đã nói về lập trình và vẽ trên màn hình, nhưng ở đây tôi đã chuẩn bị một số thứ toán học. Thú thực là tôi luôn yêu thích toán học (không giống như nhiều nghệ sĩ khác). Bất chấp tình yêu này, tôi vẫn thất vọng về cách dạy ở trường. Nó được dạy quá chính thống, điều này có thể tốt cho một giáo viên dạy toán, nhưng nó làm mất đi sự hứng thú, sự khám phá và tính thực dụng có thể được sử dụng để hoàn thành rất nhiều điều thú vị. Nhưng cũng có Tin tốt, các lập trình viên không để ý đến điều này mà tập trung vào những điều thú vị hơn.

Bây giờ tôi sẽ cố gắng giải thích nhanh cách hoạt động của hệ tọa độ. Điều này sẽ hữu ích trong việc hiểu làm thế nào hàm toán học có thể tạo ra chuyển động. Hình ảnh dưới đây cho thấy hệ tọa độ tương tác. Xin lưu ý rằng không chỉ có tọa độ x. Hàm tôi vẽ được biểu diễn dưới dạng (a*x+b)*c+d. Hãy thử sử dụng thanh trượt trên biểu đồ và bạn sẽ thấy mỗi giá trị này có thể điều chỉnh vị trí và tỷ lệ của biểu đồ như thế nào.

Bây giờ tôi sẽ viết lại công thức của mình bằng mã mẫu mà chúng ta đã có trước đây và mã này sẽ dễ đọc hơn.

Var a = 1 / 25, //Làm cho dao động diễn ra chậm hơn rất nhiều x = counter, //Di chuyển dọc theo đồ thị một chút mỗi lần draw() được gọi là b = 0, //Không cần điều chỉnh đồ thị lên hoặc down c = width * 0,4, //Tạo dao động rộng ít hơn một nửa canvas d = canvas.width / 2 - orthWidth / 2; // Tinh chỉnh vị trí của hình chữ nhật để căn giữa xMovement = Math.sin(a * x + b) * c + d;

Nhập dữ liệu

Tạm gác những gì chúng ta đã làm sang một bên, hãy dành vài phút để suy nghĩ về những gì bạn có thể làm với nhiều thiết bị khác nhau người dùng nhập để di chuyển hình vuông trong trang. Có nhiều tùy chọn có sẵn trong trình duyệt bao gồm micrô, webcam, chuột, bàn phím và gamepad. Các tùy chọn bổ sung do plugin kiểm soát có thể có sẵn, chẳng hạn như Leap Motion hoặc Kinect. Bằng cách sử dụng WebSockets và máy chủ, bạn có thể liên kết các hình ảnh trực quan với những hình ảnh được tạo tại nhà phương tiện kỹ thuật(có nghĩa là người giúp đỡ?). Kết nối micrô của bạn với API âm thanh trên web và cung cấp pixel âm thanh của bạn. Bạn thậm chí có thể chế tạo một cảm biến chuyển động từ Webcam và dọa một đàn cá ảo (lần cuối tôi làm điều đó là trong Flash khoảng năm năm trước).

Bây giờ bạn đã có ý tưởng, hãy xem thêm một số ví dụ. Một hình vuông thật nhàm chán, hãy chèn nhiều hình vuông hơn. Nhưng trước hết, hãy tạo một hàm (hệ tọa độ) sẽ hữu ích cho chúng ta về nhiều mặt. Hãy gọi nó là Điểm. Một sắc thái sẽ giúp chúng ta làm việc với các vật thể chuyển động là chúng ta cần sử dụng một vectơ khác x và y. Tôi đã biên soạn mã mẫu vào lớp Vector2 three.js. Làm việc với vectơ x và vectơ y sẽ dễ dàng hơn nhưng có nhiều tùy chọn thuận tiện hơn. Để hiểu rõ hơn những gì chúng ta đang nói đến, hãy xem ở đây. (nên có một liên kết ở đây).

Điểm toàn năng

Những ví dụ này sẽ phức tạp hơn một chút vì chúng liên quan đến các đối tượng, nhưng nó đáng giá. Hãy xem các mẫu mã để hiểu cách hoạt động của Cảnh mới, điều này sẽ giúp bạn những kiến ​​thức cơ bản về vẽ canvas. Của chúng tôi điểm mới sẽ có một điểm đánh dấu để có quyền truy cập vào bất kỳ biến nào, giống như trong ngữ cảnh canvas.

Hàm Dot(x, y, scene) ( var speed = 0,5; this.color = "#000000"; this.size = 10; this.position = new THREE.Vector2(x,y); this.direction = new BA .Vector2(tốc độ * Math.random() - tốc độ / 2, tốc độ * Math.random() - tốc độ / 2); this.scene = scene; )

Để bắt đầu làm việc với hàm tạo, cấu hình hoạt động của nó được định cấu hình cho Điểm và một số biến cần thiết cho hoạt động được đặt. Và một lần nữa chúng ta chuyển sang vector three.js. Khi đang phát lạiở tốc độ 60 khung hình/giây, điều quan trọng là phải khởi chạy các mục của bạn sớm và không tạo các mục mới trong khi phát lại. Điều này có thể ngốn hết bộ nhớ hiện có và làm cho hình ảnh của bạn bị gián đoạn. Ngoài ra, hãy chú ý cách Điểm chuyển bản sao của khung theo tham chiếu. Điều này giúp công việc rõ ràng hơn.

Dot.prototype = ( cập nhật: function() ( ... ), draw: function() ( ... ) )

Tất cả phần còn lại của mã sẽ được cài đặt trên đối tượng nguyên mẫu Point để mỗi Point mới sẽ có quyền truy cập vào các phương thức này. Tôi sẽ giải thích chức năng theo chức năng.

Cập nhật: function(dt) ( this.updatePosition(dt); this.draw(dt); ),

Tôi tách mã bản vẽ khỏi mã cập nhật. Điều này làm cho việc hỗ trợ và di chuyển đối tượng dễ dàng hơn nhiều. Giống như sơ đồ MVC phân chia của bạn kiểm soát cá nhân và cái nhìn logic. Vectơ dt là sự thay đổi về thời gian tính bằng mili giây kể từ lần cập nhật cuối cùng. Tên này thuận tiện và ngắn gọn và xuất phát từ (đừng lo lắng) các đạo hàm tính toán (đạo hàm tính toán). Nó trừ tốc độ di chuyển của bạn khỏi tốc độ khung hình. Bằng cách này, bạn sẽ không gặp phải tình trạng chậm lại kiểu NES nếu mọi việc trở nên khó khăn. Nếu tốc độ của bạn quá cao, các khung hình sẽ bị bỏ qua nhưng tốc độ vẫn giữ nguyên.

UpdatePosition: function() ( //Đây là một mẹo nhỏ để tạo một biến bên ngoài vòng lặp kết xuất // Việc phân bổ bộ nhớ bên trong vòng lặp sẽ rất tốn kém. // Biến này chỉ có thể được truy cập bởi hàm bên dưới. var moveDistance = new THREE.Vector2(); //Đây là hàm trả về thực tế function(dt) ( moveDistance.copy(this.direction); moveDistance.multiplyScalar(dt); this.position.add(moveDistance); //Giữ nguyên dấu chấm trên màn hình this.position.x = (this.position.x + this.scene.canvas.width) % this.scene.canvas.width;this.position.y = (this.position.y + this.scene .canvas.height) % this.scene.canvas.height; ) )(), //Lưu ý rằng hàm này được thực thi ngay lập tức và trả về một hàm khác

Chức năng này hơi lạ về cấu trúc nhưng dễ sử dụng. Việc phân bổ bộ nhớ trong hệ tọa độ (chức năng) thực sự rất tốn kém. MoveDistance có thể được đặt một lần và được sử dụng khi khởi động lại chức năng hệ thống khi cần.

Vectơ này chỉ được sử dụng để tính toán vị trí mới và không nhằm mục đích hoạt động bên ngoài hàm. Đây là vector toán học đầu tiên được sử dụng. Bây giờ hướng của vectơ được nhân với sự thay đổi theo thời gian và sau đó được thêm vào vị trí. Cuối cùng, mô-đun sẽ thực hiện hành động giữ điểm trên màn hình.

Draw: function(dt) ( //Lấy một tên biến ngắn để thuận tiện var ctx = this.scene.context; ctx.beginPath(); ctx.fillStyle = this.color; ctx.fillRect(this.position.x, this .position.y, this.size, this.size); )

Và cuối cùng là phần dễ nhất. Tạo một bản sao bối cảnh của đối tượng chính và vẽ một hình chữ nhật (hoặc thứ gì khác, không thành vấn đề). Chỉ là hình chữ nhật là dễ vẽ nhất trên màn hình.

Tại thời điểm này, tôi thêm một Dot mới và gọi nó là this.dot = new Dot(x, y, this) trong hàm tạo chính. Và sau đó trong phương thức cập nhật chính, tôi thêm this.dot.update(dt) và một dấu chấm xuất hiện di chuyển trên màn hình.

Thật tốt khi có thêm một chút cấu trúc trong mã, nhưng nó không làm cho nó hấp dẫn hơn chút nào. Đây là nơi chu kỳ bắt đầu. Trong đối tượng chính, chúng ta sẽ tạo một đối tượng DotManager mới. Thật thuận tiện để thu thập chức năng này trong đối tượng riêng biệt bởi vì nó dễ dàng và sạch sẽ hơn, bởi vì việc mô hình hóa ngày càng trở nên phức tạp hơn.

Var DotManager = function(numberOfDots, scene) ( this.dots = ; this.numberOfDots = numberOfDots; this.scene = scene; for(var i=0; i< numberOfDots; i++) { this.dots.push(new Dot(Math.random() * this.canvas.width, Math.random() * this.canvas.height, this.scene)); } }; DotManager.prototype = { update: function(dt) { for(var i=0; i < this.numberOfDots; i++) { this.dots[i].update(dt); } } };

Bây giờ trong mẫu, thay vì cập nhật Dot, chúng tôi tạo và cập nhật DotManager. Đầu tiên, hãy tạo 5000 điểm.

Hàm Scene() ( ... this.dotManager = new DotManager(5000, this); ... ); Scene.prototype = ( ... update: function(dt) ( this.dotManager.update(dt); ) ... );

Nó chắc chắn trông đẹp hơn rất nhiều so với một dấu chấm duy nhất. Bây giờ là lúc bắt đầu bổ sung thêm phương pháp đã cập nhật tại Điểm của bạn. Mọi thay đổi về mã đối tượng sẽ được phản ánh tại mọi điểm trên màn hình. Và đây là nơi điều kỳ diệu bắt đầu xảy ra. Bạn còn nhớ hệ tọa độ ở trên không? Làm thế nào để tạo ra hiệu ứng gợn sóng? Chúng ta sẽ tạo một biến wavePosition cho đối tượng Point. Cuối cùng, chúng ta sẽ thêm biến này vào vị trí Y.

UpdateWave: function(dt, time) ( this.wavePosition = Math.sin(this.scene.currTime / 500 + this.position.x / this.scene.canvas.width * 4) * 20; )

Vâng, hơi khó hiểu khi nó được viết trên một dòng, vì vậy tôi đính kèm một phiên bản khác, được tạo như trong hệ tọa độ.

Var a = 1 / 500, //Làm cho dao động diễn ra chậm hơn rất nhiều x = this.scene.currTime, //Di chuyển dọc theo biểu đồ một chút mỗi lần draw() được gọi là b = this.position.x / this. scene.canvas.width * 4, //Không cần điều chỉnh đồ thị lên hoặc xuống c = 20, //Tạo dao động rộng bằng một nửa canvas d = 0; // Tinh chỉnh vị trí của hình chữ nhật để căn giữa xMovement = Math.sin(a * x + b) * c + d;

Tôi lo…
Thêm một cú chạm nhỏ nữa. Đơn sắc hơi nhàm chán nên hãy thêm một chút màu sắc nhé.

Màu sắc = this.position.x / this.scene.canvas.width * 360; this.color = Utils.hslToFillStyle(hue, 50, 50, 0.5);

Đối với mỗi Điểm mới, hãy đặt vị trí ban đầu của nó và đặt bóng dọc theo khung vẽ ngang. Tôi đã thêm hàm Utils.hslToFillStyle, hàm này sẽ giúp ích một chút trong việc chuyển đổi một số biến đầu vào thành chuỗi fillStyle được định dạng chính xác. Mọi thứ đã trở nên thú vị hơn nhiều. Các chấm cuối cùng sẽ tập trung lại một chỗ và sẽ không còn hiệu ứng cầu vồng sau khi chúng bị phân tán một cách hỗn loạn. Một lần nữa, đây là một ví dụ về trực quan hóa chất lỏng với một số phép toán hoặc dữ liệu đầu vào. Tôi thích làm việc với màu sắc hơn mô hình màu HSL hơn RGB vì nó dễ sử dụng hơn. RGB hơi trừu tượng.

Sử dụng chuột

Cho đến thời điểm này không có công việc thực sự người dùng.

Var Mouse = function(scene) ( this.scene = scene; this.position = new THREE.Vector2(-10000, -10000); $(window).mousemove(this.onMouseMove.bind(this)); ); Mouse.prototype = ( onMouseMove: function(e) ( if(typeof(e.pageX) == "number") ( this.position.x = e.pageX; this.position.y = e.pageY; ) else ( this.position.x = -100000; this.position.y = -100000; ) ) );

Đối tượng đơn giản này gói gọn việc cập nhật hoạt động của chuột, trái ngược với phần còn lại của công việc. Cập nhật là vị trí của vectơ khớp với vị trí của chuột di chuyển. Các đối tượng còn lại có thể khác với vị trí vectơ chuột nếu chúng được tham chiếu trong đối tượng. Một cảnh báo tôi đã không chú ý. Nếu chiều rộng canvas không khớp với kích thước pixel DOM, tức là. để phản hồi lại việc thay đổi kích thước canvas hoặc mật độ điểm ảnh cao (võng mạc) hoặc nếu canvas không được đặt ở góc trên cùng bên trái. Tọa độ chuột phải được thay đổi cho phù hợp.

Var Scene = function() ( ... this.mouse = new Mouse(this); ... );

Tất cả những gì còn lại là tạo một đối tượng chuột bên trong sơ đồ. Bây giờ chúng ta đã có chuột, chúng ta có thể tạo các dấu chấm theo nó.

Hàm Dot(x, y, scene) ( ... this.attractSpeed ​​​​= 1000 * Math.random() + 500; this.attractDistance = (150 * Math.random()) + 180; ... )

Tôi đã thêm một số giá trị vô hướng vào điểm để mỗi giá trị hoạt động khác với các giá trị khác, làm cho quá trình trở nên thực tế hơn. Hãy chơi với những giá trị này và bạn sẽ cảm nhận được sự khác biệt. Bây giờ hãy tập trung vào phương pháp chuột. Sẽ hơi dài với các bình luận.

AttractMouse: function() ( //Một lần nữa, tạo một số biến riêng tư cho phương thức này var vectorToMouse = new THREE.Vector2(), vectorToMove = new THREE.Vector2(); //Đây là hàm trả về phương thức công khai thực tế(dt) ( var distanceToMouse, distanceToMove; //Lấy một vectơ biểu thị khoảng cách x và y từ dấu chấm đến chuột // Thủ tục thanh toán tài liệu ba.js để biết thêm thông tin về cách các vectơ này hoạt động vectorToMouse .copy(this.scene.mouse.position) .sub(this.position); //Lấy khoảng cách đến chuột từ vector distanceToMouse = vectorToMouse.length(); //Sử dụng các giá trị vô hướng riêng lẻ cho dấu chấm để điều chỉnh khoảng cách di chuyển moveLength = dt * (this.attractDistance - distanceToMouse) / this.attractSpeed; //Chỉ di chuyển dấu chấm nếu nó bị thu hút if(moveLength > 0) ( //Thay đổi kích thước vectơ của chuột theo độ dài di chuyển mong muốn vectorToMove .copy(vectorToMouse) .divideScalar(distanceToMouse) .multiplyScalar(moveLength); / /Hãy tiếp tục và thêm nó vào vị trí hiện tại, thay vì trong phần bốc thăm, hãy gọi this.position.add(vectorToMove); ) ); )()

Phương pháp này có thể hơi khó hiểu nếu bạn không giỏi toán vectơ. Các vectơ có thể được hình dung rõ ràng và có thể giúp bạn vẽ nguệch ngoạc trên giấy có vết cà phê. Nói một cách đơn giản, chức năng này hiển thị khoảng cách giữa chuột và điểm. Và khi một điểm di chuyển đến gần một điểm khác, điều này dựa trên mức độ gần của nó với một điểm khác và bao nhiêu thời gian đã trôi qua. Điều này được thực hiện bằng cách tính khoảng cách chuyển động (một hình vô hướng đều) và tăng con số này bằng cách chuẩn hóa vectơ của điểm (một vectơ có độ dài 1) trùng với chuột. Được rồi, câu cuối cùng đó không cần phải viết. bằng ngôn ngữ đơn giản, Nhưng điều này chỉ là khởi đầu.

nhất tâm điểmđối với tôi là quá trình tạo ra một bài thơ về lập trình và nghệ thuật tạo ra một cái gì đó mới mẻ. Tôi khuyên bạn không nên đi sâu vào chi tiết và dự án lớn. Thay vào đó, hãy lặp đi lặp lại, thử nghiệm, ăn mừng thành công và đôi khi thất bại. Một ngày nọ, tôi kết thúc với thứ trông giống như một mảnh cầu vồng đáng sợ. Tôi đặt nhiều hy vọng vào các vòng tròn đệ quy, nhưng tôi không để những kết quả kém cỏi cản trở con đường của mình. Cuối cùng, đoạn mã được trình bày chi tiết ở đây là một sự khám phá theo phong cách rất hướng đối tượng, đó là điều tôi thích nhất. Điều chỉnh những ý tưởng này cho phù hợp với quy trình, công cụ và kỹ thuật của riêng bạn. Bài thơ không phải là một hệ thống tích hợp lớn nên dễ dàng vẽ và thử nghiệm nó mà không cần tính đến điều kiện của các dự án lớn.

Hãy coi canvas như một cây bút chì sẽ giúp bạn đưa ra những ý tưởng tuyệt vời và để những sáng tạo của bạn bay cao.