Logo Zephyrnet

hình nền di chuyển

Ngày:

Chúng ta thường nghĩ hình nền là kết cấu hoặc thứ gì đó cung cấp độ tương phản cho nội dung dễ đọc — nói cách khác, không thực sự là nội dung. Nếu đó là nội dung, bạn có thể đạt được một <img> dù sao đi nữa, khả năng tiếp cận và không có gì.

Nhưng có những lúc khi vị trí or tỉ lệ của một hình nền có thể nằm ở đâu đó giữa các cực của nội dung và trang trí. Bối cảnh là vua, phải không? Nếu chúng tôi thay đổi vị trí của hình nền, nó có thể truyền đạt thêm một chút ngữ cảnh hoặc trải nghiệm.

Làm thế nào vậy? Hãy xem xét một vài ví dụ mà tôi đã thấy trôi nổi xung quanh.

Khi chúng ta bắt đầu, tôi sẽ lưu ý rằng có một ranh giới mong manh trong các bản trình diễn này giữa hình ảnh được sử dụng để trang trí và hình ảnh được sử dụng làm nội dung. Sự khác biệt có liên quan đến khả năng tiếp cận khi nền không được thông báo cho trình đọc màn hình. Nếu hình ảnh của bạn thực sự là một hình ảnh, sau đó có thể xem xét một <img> gắn thẻ với thích hợp alt chữ. Và trong khi chúng ta đang nói về khả năng tiếp cận, bạn nên xem xét tùy chọn chuyển động của người dùng là tốt.

Chỉ cho tôi nhiều hơn!

Chris Coyier có bản demo nhỏ này từ vài năm trước.

Bản demo cực kỳ thiết thực theo nhiều cách vì đó là một cách tiếp cận gọn gàng để hiển thị quảng cáo trong nội dung. Bạn có quảng cáo chiêu hàng và một hình ảnh hấp dẫn để bổ sung cho quảng cáo đó.

Tôi cá là hạn chế lớn nhất đối với hầu hết các quảng cáo là không gian hạn chế. Tôi không biết bạn đã bao giờ phải bỏ quảng cáo vào một trang chưa nhưng tôi đã và thường yêu cầu nhà quảng cáo cung cấp một hình ảnh đáp ứng kích thước pixel chính xác để nội dung phù hợp với không gian.

Nhưng bản demo của Chris làm giảm bớt vấn đề về không gian. Di chuột vào hình ảnh và xem cả di chuyển và tỷ lệ của nó. Người dùng thực sự nhận được chi tiết ngữ cảnh cho sản phẩm so với khi hình ảnh ở vị trí ban đầu. Đó là một đôi bên cùng có lợi, phải không? Nhà quảng cáo có thể tạo hình ảnh bắt mắt mà không ảnh hưởng đến ngữ cảnh. Trong khi đó, người dùng nhận được thêm một chút giá trị từ các phần mới được tiết lộ của hình ảnh.

Nếu bạn xem qua phần đánh dấu của bản trình diễn, bạn sẽ nhận thấy nó giống như những gì bạn mong đợi. Đây là một phiên bản rút gọn:

<div class="ad-container"> <a href="#" target="_blank" rel="noopener"> <!-- Background image container --> <div class="ad-image"></div> </a> <div class="ad-content"> <!-- Content --> </div>
</div>

Có lẽ chúng ta có thể ngụy biện về ngữ nghĩa một chút, nhưng đó không phải là vấn đề. Chúng tôi có một vùng chứa có liên kết <div> cho hình nền và một hình ảnh khác <div> để giữ nội dung.

Theo như phong cách đi, các phần quan trọng là ở đây:

.container { background-image: url("/path/to/some/image.png"); background-repeat: no-repeat; background-position: 0 0; height: 400px; width: 350px;
}

Không tệ, phải không? Chúng tôi cung cấp cho vùng chứa một số kích thước và đặt hình nền trên vùng chứa không lặp lại và được định vị bằng cạnh dưới cùng bên trái của vùng chứa.

Thủ thuật thực sự là với JavaScript. Chúng tôi sẽ sử dụng giá trị đó để lấy vị trí chuột và phần bù của vùng chứa, sau đó chuyển đổi giá trị đó thành tỷ lệ thích hợp để đặt background-position. Đầu tiên, hãy lắng nghe chuyển động của chuột trên .container thành phần:

let container = document.querySelector(".container");
container.addEventListener("mousemove", function(e) { // Our function }
);

Từ đây, chúng ta có thể sử dụng container offsetXoffsetY của cải. Nhưng chúng tôi sẽ không sử dụng trực tiếp các giá trị này vì giá trị cho tọa độ X nhỏ hơn giá trị chúng tôi cần và tọa độ Y lớn hơn. Chúng ta sẽ phải chơi xung quanh một chút để tìm một hằng số mà chúng ta có thể sử dụng làm hệ số nhân.

Đó là một chút cảm ứng, nhưng tôi thấy rằng 1.320.455 hoạt động hoàn hảo cho các tọa độ X và Y tương ứng. Chúng tôi nhân các giá trị bù đắp với các giá trị đó, nối thêm một px đơn vị trên kết quả, sau đó áp dụng nó cho background-position các giá trị.

let container = document.querySelector(".container");
container.addEventListener("mousemove", function(e) { container.style.backgroundPositionX = -e.offsetX * 1.32 + "px"; container.style.backgroundPositionY = -e.offsetY * 0.455 + "px"; }
);

Cuối cùng, chúng ta cũng có thể đặt lại các vị trí nền về vị trí ban đầu nếu người dùng rời khỏi vùng chứa hình ảnh.

container.addEventListener("mouseleave", function() { container.style.backgroundPosition = "0px 0px"; }
);

Vì chúng ta đang sử dụng Thủ thuật CSS, tôi xin đề nghị rằng chúng ta có thể thực hiện phiên bản này rẻ hơn nhiều với một chút chuyển đổi di chuột trong CSS gốc:

Vẽ một bức tranh lớn hơn

Chắc chắn bạn đã từng đến một số cửa hàng quần áo trực tuyến hoặc bất cứ thứ gì và bắt gặp tính năng phóng to khi di chuột.

Mô hình này đã tồn tại mãi mãi (Dylan Winn-Brown đã chia sẻ cách tiếp cận của mình trong 2016), nhưng đó chỉ là một minh chứng (tôi hy vọng) về tính hữu dụng của nó. Người dùng nhận được nhiều ngữ cảnh hơn khi họ phóng to và hiểu rõ hơn về đường khâu của áo len hoặc những gì bạn có.

Có hai mảnh này: chứakiếng hiển vi. Vùng chứa là thứ duy nhất chúng tôi cần trong phần đánh dấu, vì chúng tôi sẽ thêm phần tử kính lúp trong quá trình tương tác của người dùng. Vì vậy, hãy xem HTML của chúng tôi!

<div class="container"></div>

Trong CSS, chúng ta sẽ tạo widthheight các biến để lưu trữ kích thước của chính kính lúp. Sau đó, chúng tôi sẽ cung cấp cho rằng .containermột số hình dạng và một background-image:

​​:root {
​​ --magnifer-width: 85;
​​ --magnifer-height: 85;
​​} .container { width: 500px; height: 400px; background-size: cover; background-image: url("/path/to/image.png"); background-repeat: no-repeat; position: relative;
}

Có một số điều chúng ta đã biết về kính lúp trước khi nhìn thấy nó và chúng ta có thể xác định trước các kiểu đó, cụ thể là các biến đã xác định trước đó cho .maginifier'S widthheight:

.magnifier { position: absolute; width: calc(var(--magnifer-width) * 1px);
​​ height: calc(var(--magnifer-height) * 1px);
​​ border: 3px solid #000;
​​ cursor: none;
​​ background-image: url("/path/to/image.png");
​​ background-repeat: no-repeat;
}

Đó là một hình vuông nhỏ được định vị tuyệt đối sử dụng tương tự tập tin hình nền dưới dạng .container. Xin lưu ý rằng hàm calc chỉ được sử dụng ở đây để chuyển đổi giá trị không có đơn vị trong biến thành pixel. Vui lòng sắp xếp điều đó theo cách bạn thấy phù hợp miễn là loại bỏ sự lặp lại trong mã của bạn.

Bây giờ, hãy chuyển sang JavaScript kết hợp tất cả những thứ này lại với nhau. Trước tiên, chúng ta cần truy cập vào biến CSS được xác định trước đó. Chúng tôi sẽ sử dụng điều này ở nhiều nơi sau này. Sau đó, chúng tôi cần lấy vị trí chuột trong vùng chứa vì đó là giá trị chúng tôi sẽ sử dụng cho vị trí nền của kính lúp.

​​// Get the css variables
​​let root = window.getComputedStyle(document.documentElement);
​​let magnifier_width = root.getPropertyValue("--magnifer-width");
​​let magnifier_height = root.getPropertyValue("--magnifer-height"); let container = document.querySelector(".container");
let rect = container.getBoundingClientRect();
let x = (e.pageX - rect.left);
let y = (e.pageY - rect.top); // Take page scrolling into account
x = x - window.pageXOffset;
y = y - window.pageYOffset;

Những gì chúng ta cần về cơ bản là một mousemove người nghe sự kiện trên .container. Sau đó, chúng tôi sẽ sử dụng event.pageX or event.pageY thuộc tính để lấy tọa độ X hoặc Y của chuột. Nhưng để có được chính xác vị trí tương đối của chuột trên một phần tử, chúng ta cần trừ vị trí của phần tử cha khỏi vị trí chuột mà chúng ta nhận được từ JavaScript ở trên. Một cách "đơn giản" để làm điều này là sử dụng getBoundingClientRect(), trả về kích thước của một phần tử và vị trí của nó so với khung nhìn.

Lưu ý cách tôi đang tính đến việc cuộn vào tài khoản. Nếu có tràn, trừ cửa sổ pageXpageY offsets sẽ đảm bảo hiệu ứng chạy như mong đợi.

Đầu tiên chúng ta sẽ tạo div kính lúp. Tiếp theo, chúng ta sẽ tạo một mousemove chức năng và thêm nó vào vùng chứa hình ảnh. Trong chức năng này, chúng tôi sẽ cung cấp cho kính lúp một thuộc tính lớp. Chúng tôi cũng sẽ tính toán vị trí chuột và cung cấp cho kính lúp các giá trị bên trái và trên cùng mà chúng tôi đã tính toán trước đó.

Hãy tiếp tục và xây dựng magnifier khi chúng ta nghe thấy một mousemove sự kiện trên .container:

// create the magnifier
let magnifier = document.createElement("div");
container.append(magnifier);

Bây giờ chúng ta cần đảm bảo rằng nó có một tên lớp mà chúng ta có thể đặt trong phạm vi CSS:

// run the function on `mousemove`
container.addEventListener("mousemove", (e) => { magnifier.setAttribute("class", "magnifier");
}

Video ví dụ tôi đã trình bày trước đó định vị kính lúp bên ngoài hộp chứa. Thay vào đó, chúng ta sẽ giữ cái này đơn giản và phủ nó lên trên hộp chứa khi chuột di chuyển. Chúng tôi sẽ sử dụng if các câu lệnh để đặt vị trí của kính lúp chỉ khi các giá trị X và Y là lớn hơn or như nhau về XNUMX, và ít hơn chiều rộng hoặc chiều cao của vùng chứa. Điều đó sẽ giữ nó trong giới hạn. Chỉ cần đảm bảo trừ chiều rộng và chiều cao của kính lúp khỏi các giá trị X và Y.

// Run the function on mouse move.
container.addEventListener("mousemove", (e) => { magnifier.setAttribute("class", "magnifier"); // Get mouse position let rect = container.getBoundingClientRect(); let x = (e.pageX - rect.left); let y = (e.pageY - rect.top); // Take page scrolling into account x = x - window.pageXOffset; y = y - window.pageYOffset; // Prevent magnifier from exiting the container // Then set top and left values of magnifier if (x >= 0 && x <= container.clientWidth - magnifier_width) { magnifier.style.left = x + "px"; } if (y >= 0 && y <= container.clientHeight - magnifier_height) { magnifier.style.top = y + "px"; }
});

Cuối cùng, nhưng không kém phần quan trọng… chúng ta cần chơi với hình nền của kính lúp một chút. Toàn bộ vấn đề là người dùng có được chế độ xem LỚN HƠN về hình nền dựa trên vị trí di chuột đang diễn ra. Vì vậy, hãy xác định một kính lúp mà chúng ta có thể sử dụng để mở rộng mọi thứ. Sau đó, chúng tôi sẽ xác định các biến cho chiều rộng và chiều cao của hình nền để chúng tôi có thứ gì đó làm cơ sở cho tỷ lệ đó và đặt tất cả các giá trị đó trên .magnifier phong cách:

// Magnifier image configurations
let magnify = 2;
let imgWidth = 500;
let imgHeight = 400; magnifier.style.backgroundSize = imgWidth * magnify + "px " + imgHeight * magnify + "px";

Hãy lấy tọa độ X và Y của hình ảnh của kính lúp và áp dụng chúng cho .magnifierphần tử background-position​. Như trước đây với vị trí kính lúp, chúng ta cần trừ chiều rộng và chiều cao của kính lúp khỏi các giá trị X và Y bằng cách sử dụng các biến CSS.

// the x and y positions of the magnifier image
let magnify_x = x * magnify + 15;
let magnify_y = y * magnify + 15; // set backgroundPosition for magnifier if it is within image
if ( x <= container.clientWidth - magnifier_width && y <= container.clientHeight - magnifier_height
) { magnifier.style.backgroundPosition = -magnify_x + "px " + -magnify_y + "px";
}

Sau đó!

Làm cho nó điện ảnh

Bạn đã thấy Hiệu ứng Ken Burns? Đó là điều cổ điển và vượt thời gian khi một hình ảnh lớn hơn vùng chứa chứa nó, sau đó sắp xếp các trang trình bày và chia tỷ lệ chậm như một con sên. Gần như mọi bộ phim tài liệu trên thế giới dường như sử dụng nó cho ảnh tĩnh. Nếu bạn có Apple TV, thì chắc chắn bạn đã thấy nó trên trình bảo vệ màn hình.

nhiều of các ví dụ tại CodePen nếu bạn muốn có một ý tưởng tốt hơn.

Bạn sẽ thấy rằng có một số cách để tiếp cận điều này. Một số sử dụng JavaScript. Những người khác là 100% CSS. Tôi chắc chắn rằng các phương pháp JavaScript phù hợp với một số trường hợp sử dụng, nhưng nếu mục tiêu chỉ đơn giản là thu nhỏ hình ảnh một cách tinh vi, thì CSS hoàn toàn phù hợp.

Chúng tôi có thể cải thiện mọi thứ một chút bằng cách sử dụng nhiều hình nền thay vì một hình nền. Hoặc, tốt hơn nữa, nếu chúng ta mở rộng các quy tắc để sử dụng các phần tử thay vì hình nền, chúng ta có thể áp dụng cùng một hoạt ảnh cho tất cả các hình nền và sử dụng một dấu gạch ngang animation-delay để làm xáo trộn hiệu ứng.

Rất nhiều cách để làm điều này, tất nhiên! Nó chắc chắn có thể được tối ưu hóa với các biến Sass và/hoặc CSS. Heck, có lẽ bạn có thể kéo nó ra với một đĩa đơn <div> Nếu vậy, chia sẻ nó trong các ý kiến!

Tiền thưởng: Làm cho nó đắm chìm

Tôi không biết liệu có thứ gì ngầu hơn của Sarah Drasner không Bút “Halloween vui vẻ”… và đó là từ năm 2016! Đó là một ví dụ tuyệt vời khi tạo lớp nền và di chuyển chúng ở các tốc độ khác nhau để tạo ra trải nghiệm gần như điện ảnh. Trời ơi hay quá!

GSAP là trình điều khiển chính ở đó, nhưng tôi tưởng tượng chúng ta có thể tạo một phiên bản rút gọn chỉ đơn giản là dịch từng lớp nền từ trái sang phải ở các tốc độ khác nhau. Tất nhiên, không thú vị bằng, nhưng chắc chắn là trải nghiệm cơ bản. Phải đảm bảo phần đầu và phần cuối của mỗi hình nền nhất quán để nó lặp lại liền mạch khi hoạt ảnh lặp lại.


Đó là nó cho bây giờ! Khá gọn gàng khi chúng ta có thể sử dụng hình nền cho nhiều thứ hơn ngoài kết cấu và độ tương phản. Tôi hoàn toàn khẳng định rằng có rất nhiều tương tác thông minh khác mà chúng ta có thể áp dụng cho nền. Temani Afif đã làm chính xác điều đó với một loạt các hiệu ứng di chuột gọn gàng cho các liên kết. Bạn đang nghĩ gì vậy? Chia sẻ nó với tôi trong các ý kiến!

tại chỗ_img

Tin tức mới nhất

tại chỗ_img