توضيح:


2. تصميم اللوحة القماشية باستخدام CSS

دعونا نضيف نمطًا بسيطًا لمنح قماشنا خلفية سوداء والتأكد من إزالة جميع الحشوات والهوامش.

* {    margin: 0;    padding: 0;    box-sizing: border-box;}canvas {    background-color: black;}

توضيح:


3. فئة الجسيمات: خلق السحر

فئة الجسيمات هي المكان الذي يكمن فيه جوهر الرسوم المتحركة. يتحرك كل جسيم عبر اللوحة، تاركًا أثرًا لمواقعه السابقة، مما يخلق التأثير المتدفق.

class Particle {    constructor(effect) {        this.effect = effect;        this.x = Math.floor(Math.random() * this.effect.width);        this.y = Math.floor(Math.random() * this.effect.height);        this.speedModifier = Math.floor(Math.random() * 5   1);        this.history = [{ x: this.x, y: this.y }];        this.maxLength = Math.floor(Math.random() * 200   10);        this.timer = this.maxLength * 2;        this.colors = [\\'#4C026B\\', \\'#8E0E00\\', \\'#9D0208\\', \\'#BA1A1A\\', \\'#730D9E\\'];        this.color = this.colors[Math.floor(Math.random() * this.colors.length)];    }    draw(context) {        context.beginPath();        context.moveTo(this.history[0].x, this.history[0].y);        for (let i = 1; i < this.history.length; i  ) {            context.lineTo(this.history[i].x, this.history[i].y);        }        context.strokeStyle = this.color;        context.stroke();    }    update() {        this.timer--;        if (this.timer >= 1) {            let x = Math.floor(this.x / this.effect.cellSize);            let y = Math.floor(this.y / this.effect.cellSize);            let index = y * this.effect.cols   x;            let angle = this.effect.flowField[index];            this.speedX = Math.cos(angle);            this.speedY = Math.sin(angle);            this.x  = this.speedX * this.speedModifier;            this.y  = this.speedY * this.speedModifier;            this.history.push({ x: this.x, y: this.y });            if (this.history.length > this.maxLength) {                this.history.shift();            }        } else if (this.history.length > 1) {            this.history.shift();        } else {            this.reset();        }    }    reset() {        this.x = Math.floor(Math.random() * this.effect.width);        this.y = Math.floor(Math.random() * this.effect.height);        this.history = [{ x: this.x, y: this.y }];        this.timer = this.maxLength * 2;    }}

توضيح:


4. فئة التأثير: تنظيم الرسوم المتحركة

تتعامل فئة التأثير مع إنشاء الجسيمات ومجال التدفق نفسه، الذي يتحكم في حركة الجسيمات.

class Effect {    constructor(canvas) {        this.canvas = canvas;        this.width = this.canvas.width;        this.height = this.canvas.height;        this.particles = [];        this.numberOfParticles = 3000;        this.cellSize = 20;        this.flowField = [];        this.curve = 5;        this.zoom = 0.12;        this.debug = true;        this.init();    }    init() {        this.rows = Math.floor(this.height / this.cellSize);        this.cols = Math.floor(this.width / this.cellSize);        for (let y = 0; y < this.rows; y  ) {            for (let x = 0; x < this.cols; x  ) {                let angle = (Math.cos(x * this.zoom)   Math.sin(y * this.zoom)) * this.curve;                this.flowField.push(angle);            }        }        for (let i = 0; i < this.numberOfParticles; i  ) {            this.particles.push(new Particle(this));        }    }    drawGrid(context) {        context.save();        context.strokeStyle = \\'white\\';        context.lineWidth = 0.3;        for (let c = 0; c < this.cols; c  ) {            context.beginPath();            context.moveTo(c * this.cellSize, 0);            context.lineTo(c * this.cellSize, this.height);            context.stroke();        }        for (let r = 0; r < this.rows; r  ) {            context.beginPath();            context.moveTo(0, r * this.cellSize);            context.lineTo(this.width, r * this.cellSize);            context.stroke();        }        context.restore();    }    render(context) {        if (this.debug) this.drawGrid(context);        this.particles.forEach(particle => {            particle.draw(context);            particle.update();        });    }}

توضيح:


5. إضفاء الحيوية عليها باستخدام حلقة الرسوم المتحركة

لجعل كل شيء يعمل، نحتاج إلى حلقة رسوم متحركة تمسح اللوحة القماشية باستمرار وتعيد عرض الجزيئات:

const effect = new Effect(canvas);function animate() {    ctx.clearRect(0, 0, canvas.width, canvas.height);    effect.render(ctx);    requestAnimationFrame(animate);}animate();

توضيح:


خاتمة

من خلال تقسيم فئات الجسيمات والتأثيرات، قمنا بإنشاء رسوم متحركة سلسة وديناميكية لحقل التدفق باستخدام JavaScript الفانيليا فقط. إن بساطة لوحة HTML، جنبًا إلى جنب مع وظائف جافا سكريبت المثلثية، تسمح لنا ببناء هذه التأثيرات المرئية المذهلة.

لا تتردد في تجربة عدد الجسيمات أو الألوان أو صيغة مجال التدفق لإنشاء تأثيرات فريدة خاصة بك!

","image":"http://www.luping.net/uploads/20241022/17296041676717aa472ee02.jpg","datePublished":"2024-11-09T01:12:23+08:00","dateModified":"2024-11-09T01:12:23+08:00","author":{"@type":"Person","name":"luping.net","url":"https://www.luping.net/articlelist/0_1.html"}}
"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > شاشة مجال التدفق

شاشة مجال التدفق

تم النشر بتاريخ 2024-11-09
تصفح:699

Flow Field Screen

حقول التدفق الديناميكي مع Vanilla JS وHTML Canvas

هل سبق لك أن فتنت بالرسوم المتحركة للجسيمات المجردة؟ يمكن تحقيق هذه المرئيات الديناميكية المتدفقة باستخدام تقنيات بسيطة بشكل مدهش باستخدام JavaScript عادي وعنصر قماش HTML. في هذه المقالة، سنشرح عملية إنشاء حقل تدفق يحرك آلاف الجزيئات، مما يمنحها حركة طبيعية.

1. إعداد المشروع

للبدء، نحتاج إلى ثلاثة ملفات: ملف HTML لإعداد اللوحة، وملف CSS للتصميم، وملف JavaScript للتعامل مع المنطق.



    Flow Fields

توضيح:

  • نحدد عنصر حيث ستحدث جميع الرسوم المتحركة لدينا.
  • سيتم ربط ملف style.css بتصميم اللوحة القماشية.
  • منطق الرسوم المتحركة الرئيسي موجود في script.js.

2. تصميم اللوحة القماشية باستخدام CSS

دعونا نضيف نمطًا بسيطًا لمنح قماشنا خلفية سوداء والتأكد من إزالة جميع الحشوات والهوامش.

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

canvas {
    background-color: black;
}

توضيح:

  • يضمن ضبط الهامش والحشوة على الصفر أن اللوحة القماشية تملأ الشاشة بأكملها.
  • توفر الخلفية السوداء تباينًا لطيفًا للجزيئات البيضاء.

3. فئة الجسيمات: خلق السحر

فئة الجسيمات هي المكان الذي يكمن فيه جوهر الرسوم المتحركة. يتحرك كل جسيم عبر اللوحة، تاركًا أثرًا لمواقعه السابقة، مما يخلق التأثير المتدفق.

class Particle {
    constructor(effect) {
        this.effect = effect;
        this.x = Math.floor(Math.random() * this.effect.width);
        this.y = Math.floor(Math.random() * this.effect.height);
        this.speedModifier = Math.floor(Math.random() * 5   1);
        this.history = [{ x: this.x, y: this.y }];
        this.maxLength = Math.floor(Math.random() * 200   10);
        this.timer = this.maxLength * 2;
        this.colors = ['#4C026B', '#8E0E00', '#9D0208', '#BA1A1A', '#730D9E'];
        this.color = this.colors[Math.floor(Math.random() * this.colors.length)];
    }

    draw(context) {
        context.beginPath();
        context.moveTo(this.history[0].x, this.history[0].y);
        for (let i = 1; i = 1) {
            let x = Math.floor(this.x / this.effect.cellSize);
            let y = Math.floor(this.y / this.effect.cellSize);
            let index = y * this.effect.cols   x;
            let angle = this.effect.flowField[index];

            this.speedX = Math.cos(angle);
            this.speedY = Math.sin(angle);
            this.x  = this.speedX * this.speedModifier;
            this.y  = this.speedY * this.speedModifier;

            this.history.push({ x: this.x, y: this.y });
            if (this.history.length > this.maxLength) {
                this.history.shift();
            }
        } else if (this.history.length > 1) {
            this.history.shift();
        } else {
            this.reset();
        }
    }

    reset() {
        this.x = Math.floor(Math.random() * this.effect.width);
        this.y = Math.floor(Math.random() * this.effect.height);
        this.history = [{ x: this.x, y: this.y }];
        this.timer = this.maxLength * 2;
    }
}

توضيح:

  • المُنشئ: تتم تهيئة كل جسيم بموضع عشوائي وسرعة حركة. تقوم مصفوفة السجل بتتبع المواضع السابقة لإنشاء مسارات.
  • draw(): ترسم هذه الوظيفة مسار الجسيم بناءً على تاريخه. يترك الجسيم أثرًا ملونًا يضيف إلى التأثير البصري.
  • update(): هنا، يتم تحديث موضع الجسيم عن طريق حساب الزاوية من مجال التدفق. يتم التحكم في السرعة والاتجاه عن طريق الدوال المثلثية.
  • reset(): عندما ينتهي الجسيم من مساره، تتم إعادة تعيينه إلى موقع عشوائي جديد.

4. فئة التأثير: تنظيم الرسوم المتحركة

تتعامل فئة التأثير مع إنشاء الجسيمات ومجال التدفق نفسه، الذي يتحكم في حركة الجسيمات.

class Effect {
    constructor(canvas) {
        this.canvas = canvas;
        this.width = this.canvas.width;
        this.height = this.canvas.height;
        this.particles = [];
        this.numberOfParticles = 3000;
        this.cellSize = 20;
        this.flowField = [];
        this.curve = 5;
        this.zoom = 0.12;
        this.debug = true;
        this.init();
    }

    init() {
        this.rows = Math.floor(this.height / this.cellSize);
        this.cols = Math.floor(this.width / this.cellSize);
        for (let y = 0; y  {
            particle.draw(context);
            particle.update();
        });
    }
}

توضيح:

  • المنشئ: تهيئة أبعاد اللوحة القماشية وعدد الجزيئات ومجال التدفق.
  • init(): لحساب زوايا مجال التدفق من خلال الجمع بين الدوال المثلثية لكل خلية في الشبكة. يؤثر هذا المجال على كيفية تحرك الجزيئات.
  • drawGrid(): يرسم الشبكة التي تقسم اللوحة القماشية إلى خلايا، وتستخدم عند تصحيح الأخطاء.
  • render(): يستدعي طرق الرسم والتحديث لكل جسيم لتحريك الجسيمات عبر اللوحة القماشية.

5. إضفاء الحيوية عليها باستخدام حلقة الرسوم المتحركة

لجعل كل شيء يعمل، نحتاج إلى حلقة رسوم متحركة تمسح اللوحة القماشية باستمرار وتعيد عرض الجزيئات:

const effect = new Effect(canvas);

function animate() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    effect.render(ctx);
    requestAnimationFrame(animate);
}
animate();

توضيح:

  • clearRect(): لمسح اللوحة القماشية الموجودة على كل إطار لتجنب الرسم على الإطارات السابقة.
  • requestAnimationFrame: يحافظ على سلاسة الرسوم المتحركة عن طريق استدعاء وظيفة animate() بشكل متكرر.

خاتمة

من خلال تقسيم فئات الجسيمات والتأثيرات، قمنا بإنشاء رسوم متحركة سلسة وديناميكية لحقل التدفق باستخدام JavaScript الفانيليا فقط. إن بساطة لوحة HTML، جنبًا إلى جنب مع وظائف جافا سكريبت المثلثية، تسمح لنا ببناء هذه التأثيرات المرئية المذهلة.

لا تتردد في تجربة عدد الجسيمات أو الألوان أو صيغة مجال التدفق لإنشاء تأثيرات فريدة خاصة بك!

بيان الافراج تم نشر هذه المقالة على: https://dev.to/ibra-kdbra/flow-field-screen-567c?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ [email protected] لحذفه
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3