Share Code Button Creepy

Share Code Button Creepy
Chào mọi người, bài viết này mình chia sẽ đến mọi người một dạng button creepy khá thú vị cho người mới bắt đầu, và áp dụng code hoàn toàn đơn giản, chứ không phức tạp gì nhiều nhé mọi người.
Việc làm đẹp trang bài viết với một số biểu tương hay bố cục là điều bình thường, nhưng để làm đẹp những tiện ích như button, form...v.v là điều mọi người nên để ý, vì nó làm cho bài viết thêm sôi động và tạo tính tò mò cho người dùng khi tìm hiểu và đọc bài viết thêm sâu sắc hơn.

Chúng ta bắt đầu với mẫu button creepy này nhé.

Bước 1. Mọi người thêm đoạn mã CSS này vào giao diện của mọi người.
* {
	border: 0;
	box-sizing: border-box;
	margin: 0;
	padding: 0;
}

:root {
	--hue: 223deg;
	--gray1: hsl(var(--hue) 10% 95%);
	--gray9: hsl(var(--hue) 10% 15%);
	--black: hsl(0 0% 0%);
	--primary3: hsl(var(--hue) 90% 75%);
	--primary5: hsl(var(--hue) 90% 55%);
	--primary6: hsl(var(--hue) 90% 45%);
	--trans-dur: 0.3s;
	color-scheme: light dark;
	font-size: clamp(1.25rem, 1rem + 1.25vw, 2.5rem);
}

body,
button {
	font: 1em / 1.5 "Londrina Solid", sans-serif;
	transition:
		background-color var(--trans-dur),
		color var(--trans-dur);
}

body {
	background-color: light-dark(var(--gray1), var(--gray9));
	color: light-dark(var(--gray9), var(--gray1));
	display: grid;
	place-items: center;
	height: 100vh;
}

.creepy-btn {
	background-color: var(--black);
	border-radius: 1.25em;
	color: var(--gray1);
	cursor: pointer;
	letter-spacing: 1px;
	min-width: 9em;
	outline: 0.1875em solid transparent;
	transition: outline 0.1s linear;
	-webkit-tap-highlight-color: transparent;

	&,
	&__cover,
	&__eye {
		position: relative;
	}

	&,
	&__pupil {
		background-color: var(--black);
	}

	&__cover,
	&__pupil {
		border-radius: inherit;
		display: block;
	}

	&__cover {
		background-color: var(--primary5);
		box-shadow: 0 0 0 0.125em var(--black) inset;
		padding: 0.5em 1em;
		inset: 0;
		transform-origin: 1.25em 50%;
		transition:
			background-color var(--trans-dur),
			transform var(--trans-dur) cubic-bezier(0.65, 0, 0.35, 1);
	}

	&__eye {
		animation: eye-blink 3s infinite;
		background-color: var(--gray1);
		border-radius: 50%;
		overflow: hidden;
		width: 0.75em;
		height: 0.75em;
	}

	&__eyes,
	&__pupil {
		position: absolute;
	}

	&__eyes {
		display: flex;
		align-items: center;
		gap: 0.375em;
		right: 1em;
		bottom: 0.5em;
		height: 0.75em;
	}

	&__pupil {
		aspect-ratio: 1;
		top: 50%;
		left: 50%;
		width: 0.375em;
		transform: translate(-50%, -50%);
	}

	&:focus-visible {
		outline: 0.1875em solid var(--primary3);
	}

	&:hover &__cover {
		background-color: var(--primary6);
	}

	&:focus-visible &__cover,
	&:hover &__cover {
		transform: rotate(-12deg);
		transition-timing-function: cubic-bezier(0.65, 0, 0.35, 1.65);
	}

	&:active &__cover {
		transform: rotate(0);
		transition-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
	}
}

@keyframes eye-blink {
	0%,
	92%,
	100% {
		animation-timing-function: cubic-bezier(0.32, 0, 0.67, 0);
		height: 0.75em;
	}

	96% {
		animation-timing-function: cubic-bezier(0.33, 1, 0.68, 1);
		height: 0;
	}
}
Bước 2. Mọi người thêm đoạn mã Javascript bên dưới vào giao diện để tạo hình động khi nhấp chuột vào button.
import React, { StrictMode, useRef, useState } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";

createRoot(document.getElementById("root")!).render(
	<StrictMode>
		<CreepyButton>Button</CreepyButton>
	</StrictMode>
);

function CreepyButton({
	onClick,
	children
}: Readonly<CreepyButtonProps>) {
	const eyesRef = useRef<HTMLSpanElement>(null);
	const [eyeCoords, setEyeCoords] = useState<Coords>({ x: 0, y: 0 })
	const translateX = `${-50 + eyeCoords.x * 50}%`;
	const translateY = `${-50 + eyeCoords.y * 50}%`;
	const eyeStyle: React.CSSProperties = {
		"transform": `translate(${translateX}, ${translateY})`
	};
	const updateEyes = (
		e: React.MouseEvent<HTMLButtonElement> | React.TouchEvent<HTMLButtonElement>
	) => {
		const userEvent = "touches" in e ? e.touches[0] : e;
		// get the center of the eyes container and cursor location
		const eyesRect = eyesRef.current?.getBoundingClientRect() as DOMRect;
		const eyes: Coords = {
			x: eyesRect.left + eyesRect.width / 2,
			y: eyesRect.top + eyesRect.height / 2
		};
		const cursor: Coords = {
			x: userEvent.clientX,
			y: userEvent.clientY
		};
		// calculate the eye angle
		const dx = cursor.x - eyes.x;
		const dy = cursor.y - eyes.y;
		const angle = Math.atan2(-dy, dx) + Math.PI / 2;
		// then the pupil distance from the eye center
		const visionRangeX = 180;
		const visionRangeY = 75;
		const distance = Math.hypot(dx, dy);
		const x = Math.sin(angle) * distance / visionRangeX;
		const y = Math.cos(angle) * distance / visionRangeY;

		setEyeCoords({ x, y });
	};

	return (
		<button
			className="creepy-btn"
			type="button"
			onClick={onClick}
			onMouseMove={updateEyes}
			onTouchMove={updateEyes}
		>
			<span className="creepy-btn__eyes" ref={eyesRef}>
				<span className="creepy-btn__eye">
					<span className="creepy-btn__pupil" style={eyeStyle}></span>
				</span>
				<span className="creepy-btn__eye">
					<span className="creepy-btn__pupil" style={eyeStyle}></span>
				</span>
			</span>
			<span className="creepy-btn__cover">{children}</span>
		</button>
	);
}

interface CreepyButtonProps {
	onClick?: () => void;
	children?: React.ReactNode;
}

type Coords = {
	x: number;
	y: number;
}
Bước 3. Mọi người thêm đoạn code sau vào nới bạn muốn hiển thị.
<div id="root"></div>
Tôi Hùng, Một Công Nhân Điện Lực Lệ Thủy, Thuộc Công Ty Điện Lực Quảng Trị, Chi nhánh Tổng công ty Điện Lực Miền Trung, Trực thuộc Tổng Công Ty Điện Lực Việt Nam. Tôi có đam mê với lập trình website/…

Post a Comment

👉 Nội dung liên quan: Nhận xét cần tập trung vào chủ đề của bài viết hoặc giao diện đang chia sẻ.

👉 Văn hóa ứng xử: Không sử dụng ngôn từ tục tĩu, xúc phạm, phân biệt chủng tộc hoặc kích động.

👉 Không Spam/Quảng cáo: Nghiêm cấm chèn link spam, quảng cáo dịch vụ/sản phẩm không liên quan hoặc rác điện tử.

👉 Tôn trọng quyền riêng tư: Không chia sẻ thông tin cá nhân của người khác (doxxing).
Ngôn ngữ: Khuyến khích tiếng Việt có dấu, rõ ràng.

👉 Quyền quản trị: Quản trị viên có quyền xóa hoặc chỉnh sửa bình luận vi phạm mà không cần báo trước.
Hung Pro VN © 2015
Tôi Lê Hùng, chia sẽ kiến thức và tư duy sáng tạo của bản thân mỗi ngày cho cộng đồng Internet Việt Nam hiện tại.
Developed by Jago Desain