Open In App

Scratch Card Using React js

In this article, we will build a scratch card using ReactJS. A scratch card contains a reward; when the user scratches that card, the color present on the card will start erasing. And after erasing, the color content (reward) will be visible.

Preview:



Prerequisite

Steps to Create the project:

npx create-react-app random-meal-generator

cd random-meal-generator

Project Structure

Package.json

"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}

Approach

Example:




import React, { useEffect, useState } from "react";
import "./App.css";
 
const App = () => {
    const [prizeValue, setPrizeValue] = useState("$10"); // Default value
 
    useEffect(() => {
        const canvasElement = document.getElementById("scratch");
        const canvasContext = canvasElement.getContext("2d");
 
        const initializeCanvas = () => {
            const gradient = canvasContext
                .createLinearGradient(0, 0, 135, 135);
            gradient.addColorStop(0, "#d63031");
            gradient.addColorStop(1, "#fdcb6e");
            canvasContext.fillStyle = gradient;
            canvasContext.fillRect(0, 0, 200, 200);
 
            // Generate a random prize value
            //from the available options
            const prizeOptions = [
                "$1",
                "$5",
                "$10",
                "$20",
                "$25",
                "$30",
                "$35",
                "$40",
                "$45",
                "$50"
            ];
            const randomPrize =
            prizeOptions[Math.floor(Math.random() * prizeOptions.length)];
            setPrizeValue(randomPrize);
        };
 
        let mouseX = 0;
        let mouseY = 0;
        let isDragging = false;
 
        const eventTypes = {
            mouse: {
                down: "mousedown",
                move: "mousemove",
                up: "mouseup"
            },
            touch: {
                down: "touchstart",
                move: "touchmove",
                up: "touchend"
            }
        };
 
        let deviceType = "";
 
        const checkIfTouchDevice = () => {
            try {
                document.createEvent("TouchEvent");
                deviceType = "touch";
                return true;
            } catch (e) {
                deviceType = "mouse";
                return false;
            }
        };
 
        const getMouseCoordinates = (event) => {
            mouseX =
                (!checkIfTouchDevice() ? event.pageX :
                 event.touches[0].pageX) -
                canvasElement.getBoundingClientRect().left;
            mouseY =
                (!checkIfTouchDevice() ? event.pageY :
                 event.touches[0].pageY) -
                canvasElement.getBoundingClientRect().top;
        };
 
        checkIfTouchDevice();
 
        canvasElement.addEventListener(eventTypes[deviceType]
            .down, (event) => {
            isDragging = true;
            getMouseCoordinates(event);
            scratch(mouseX, mouseY);
        });
 
        canvasElement.addEventListener(eventTypes[deviceType]
            .move, (event) => {
            if (!checkIfTouchDevice()) {
                event.preventDefault();
            }
            if (isDragging) {
                getMouseCoordinates(event);
                scratch(mouseX, mouseY);
            }
        });
 
        canvasElement.addEventListener(eventTypes[deviceType]
            .up, () => {
            isDragging = false;
        });
 
        canvasElement.addEventListener("mouseleave", () => {
            isDragging = false;
        });
 
        const scratch = (x, y) => {
            canvasContext
            .globalCompositeOperation = "destination-out";
            canvasContext.beginPath();
            canvasContext.arc(x, y, 12, 0, 2 * Math.PI);
            canvasContext.fill();
        };
 
        initializeCanvas();
    }, []);
 
    return (
        <div className="container">
            <div className="base">
                <h4>You Won</h4>
                <h3>{prizeValue}</h3>
            </div>
            <canvas
                id="scratch"
                width="200"
                height="200"
                style={{
                    cursor:
                }}
            ></canvas>
        </div>
    );
};
 
export default App;




* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}
 
body {
    height: 100vh;
    background: #eee;
}
 
.container {
    position: absolute;
    transform: translate(-50%, -50%);
    top: 50%;
    left: 50%;
    border-radius: 0.6em;
}
 
.base,
#scratch {
    height: 200px;
    width: 200px;
    position: absolute;
    transform: translate(-50%, -50%);
    top: 50%;
    left: 50%;
    text-align: center;
    cursor: grabbing;
    border-radius: 2em;
}
 
.base {
    background-color: #ffffff;
    font-family: 'Poppins', sans-serif;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    box-shadow: 0 1.2em 2.5em rgba(16, 2, 96, 0.15);
}
 
.base h3 {
    font-weight: 600;
    font-size: 1.5em;
    color: #17013b;
}
 
.base h4 {
    font-weight: 400;
    color: #746e7e;
}
 
#scratch {
    -webkit-tap-highlight-color: transparent;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
}

npm start
 http://localhost:3000/

Output:




Article Tags :