使用JavaScript在水效果中创建动画粒子

2023-11-07

Water simulation with javascript. Today we continue JavaScript lessons, and our article will about using js in modeling of water effects. Sometimes we can create very interesting solutions using ordinary Javascript.

用javascript进行水模拟。 今天,我们继续JavaScript课程,并且我们的文章将介绍在水效果建模中使用js。 有时我们可以使用普通Javascript创建非常有趣的解决方案。

Here are sample and downloadable package:

以下是示例和可下载的软件包:

现场演示

步骤1. HTML (Step 1. HTML)

As usual, we start with the HTML.

和往常一样,我们从HTML开始。

This is our main page code with all samples.

这是我们所有示例的主页代码。

index.html (index.html)


<link rel="stylesheet" href="css/main.css" type="text/css" media="all" />
<script src="js/main.js" type="text/javascript"></script>
<div class="example">
    <img id="unit" src="unit.png" style="visibility:hidden" >
    <div id="main"></div>
    <div id="fps"></div>
</div>

<link rel="stylesheet" href="css/main.css" type="text/css" media="all" />
<script src="js/main.js" type="text/javascript"></script>
<div class="example">
    <img id="unit" src="unit.png" style="visibility:hidden" >
    <div id="main"></div>
    <div id="fps"></div>
</div>

步骤2. CSS (Step 2. CSS)

Here are used CSS styles.

这是使用CSS样式。

css / main.css (css/main.css)


body{background:#eee;font-family:Verdana, Helvetica, Arial, sans-serif;margin:0;padding:0}
.example{position:relative;background:#FFF;width:600px;height:600px;border:1px #000 solid;margin:20px auto;padding:20px;-moz-border-radius:3px;-webkit-border-radius:3px}
#main{position:absolute;width:520px;height:520px;background:#000;outline:#f0f solid 3px;overflow:hidden;cursor:pointer}
#fps{position:absolute;right:20px;top:20px}

body{background:#eee;font-family:Verdana, Helvetica, Arial, sans-serif;margin:0;padding:0}
.example{position:relative;background:#FFF;width:600px;height:600px;border:1px #000 solid;margin:20px auto;padding:20px;-moz-border-radius:3px;-webkit-border-radius:3px}
#main{position:absolute;width:520px;height:520px;background:#000;outline:#f0f solid 3px;overflow:hidden;cursor:pointer}
#fps{position:absolute;right:20px;top:20px}

步骤3. JS (Step 3. JS)

Here are our main control JS file.

这是我们的主要控制JS文件。

js / main.js (js/main.js)


var wp = function () {
    // variables
    var scr, grid, npart, diam, nx, ny, nw, nh, gw, gh;
    var xm = 0;
    var ym = 0;
    var obj = new Array(npart);
    var down = false;
    var fps = 0;
    // add listeners
    var addEvent = function  (o, e, f) {
        if (window.addEventListener) o.addEventListener(e, f, false);
        else if (window.attachEvent) r = o.attachEvent('on' + e, f);
    }
    // resize function
    var resize = function () {
        nw = scr.offsetWidth;
        nh = scr.offsetHeight;
        var o = scr;
        for (nx = 0, ny = 0; o != null; o = o.offsetParent) {
            nx += o.offsetLeft;
            ny += o.offsetTop;
        }
        gw = Math.round(nw / pdiam);
        gh = Math.round(nh / pdiam);
    }
    // particle constructor
    var Particle = function (img) {
        this.x = Math.random() * nw;
        this.y = Math.random() * nh;
        this.vx = 0;
        this.vy = 0;
        this.dx = 0;
        this.dy = 0;
        this.wi = img.width * .5;
        this.hi = img.height * .5;
        // new html elements
        var d = document.createElement('img');
        d.style.position = "absolute";
        d.style.left = "-1000px";
        d.src = img.src;
        scr.appendChild(d);
        this.plo = d.style;
    }
    // move particle
    Particle.prototype.move = function () {
        this.x  += this.dx;
        this.y  += this.dy;
        this.vx += this.dx;
        this.vy += this.dy;
        this.dx  = 0;
        this.dy  = 0;
        // DOM
        this.plo.left = Math.round(this.x - this.wi) + 'px';
        this.plo.top  = Math.round(this.y - this.hi) + 'px';
    }
    // water simulation
    Particle.prototype.physics = function () {
        // mouse influence
        if (down) {
            var dx = this.x - xm;
            var dy = this.y - ym;
            var d = Math.sqrt(dx * dx + dy * dy);
            if (d < pdiam * 2) {
                this.dx += dx / d;
                this.dy += dy / d;
            }
        }
        // gravity and acceleration
        this.vy += .2;
        this.x += this.vx;
        this.y += this.vy;
        // screens limits
        if (this.x < pdiam * .5) this.dx += (pdiam * .5 - this.x);
        else if (this.x > nw - pdiam * .5) this.dx -= (this.x - nw + pdiam * .5);
        if (this.y < pdiam * .5) this.dy += (pdiam * .5 - this.y);
        else if (this.y > nh - pdiam * .5) this.dy -= (this.y - nh + pdiam * .5);
        // grid coordinates
        var gx = Math.round(this.x / pdiam);
        var gy = Math.round(this.y / pdiam);
        // neightbors constraints
        for (var ix = gx - 1; ix <= gx + 1; ix++) {
            for (var iy = gy - 1; iy <= gy + 1; iy++) {
                var g = grid[iy * gw + ix] || [];
                for (j = 0, l = g.length; j < l; j++) {
                    var that = g[j];
                    var dx = that.x - this.x;
                    var dy = that.y - this.y;
                    var d = Math.sqrt(dx * dx + dy * dy);
                    if (d < pdiam && d > 0) {
                        dx = (dx / d) * (pdiam - d) * .25;
                        dy = (dy / d) * (pdiam - d) * .25;
                        this.dx -= dx;
                        this.dy -= dy;
                        that.dx += dx;
                        that.dy += dy;
                    }
                }
            }
        }
        // update neighbors array
        if (!grid[gy * gw + gx]) grid[gy * gw + gx] = [this];
        else grid[gy * gw + gx].push(this);
    }
    // loop
    var run = function () {
        fps++;
        grid = new Array(gw * gh);
        for(var i = 0; i < npart; i++) obj[i].physics();
        for(var i = 0; i < npart; i++) obj[i].move();
        setTimeout(run, 1);
    }
    return {
        // initialization
        init : function (n, d) {
            scr = document.getElementById('main');
            npart = n;
            pdiam = d;
            // subscribing to events
            addEvent(document, 'mousemove', function (e) {
                if (window.event) e = window.event;
                xm = e.clientX - nx;
                ym = e.clientY - ny;
            });
            addEvent(window, 'resize', resize);
            addEvent(document, 'mousedown', function(e) {if (e.preventDefault) e.preventDefault(); down = true;return false;});
            addEvent(document, 'mouseup', function() { down = false;return false;});
            document.onselectstart = function () { return false; }
            scr.ondrag = function () { return false; }
            // fps countrt
            setInterval(function() {
                document.getElementById('fps').innerHTML = fps + ' FPS';
                fps = 0;
            }, 1000);
            // starting
            resize();
            for (var i = 0; i < npart; i++) obj[i] = new Particle(document.getElementById('unit'));
            run();
        }
    }
}();
window.onload = function() {
  wp.init(50, 45);
}

var wp = function () {
    // variables
    var scr, grid, npart, diam, nx, ny, nw, nh, gw, gh;
    var xm = 0;
    var ym = 0;
    var obj = new Array(npart);
    var down = false;
    var fps = 0;
    // add listeners
    var addEvent = function  (o, e, f) {
        if (window.addEventListener) o.addEventListener(e, f, false);
        else if (window.attachEvent) r = o.attachEvent('on' + e, f);
    }
    // resize function
    var resize = function () {
        nw = scr.offsetWidth;
        nh = scr.offsetHeight;
        var o = scr;
        for (nx = 0, ny = 0; o != null; o = o.offsetParent) {
            nx += o.offsetLeft;
            ny += o.offsetTop;
        }
        gw = Math.round(nw / pdiam);
        gh = Math.round(nh / pdiam);
    }
    // particle constructor
    var Particle = function (img) {
        this.x = Math.random() * nw;
        this.y = Math.random() * nh;
        this.vx = 0;
        this.vy = 0;
        this.dx = 0;
        this.dy = 0;
        this.wi = img.width * .5;
        this.hi = img.height * .5;
        // new html elements
        var d = document.createElement('img');
        d.style.position = "absolute";
        d.style.left = "-1000px";
        d.src = img.src;
        scr.appendChild(d);
        this.plo = d.style;
    }
    // move particle
    Particle.prototype.move = function () {
        this.x  += this.dx;
        this.y  += this.dy;
        this.vx += this.dx;
        this.vy += this.dy;
        this.dx  = 0;
        this.dy  = 0;
        // DOM
        this.plo.left = Math.round(this.x - this.wi) + 'px';
        this.plo.top  = Math.round(this.y - this.hi) + 'px';
    }
    // water simulation
    Particle.prototype.physics = function () {
        // mouse influence
        if (down) {
            var dx = this.x - xm;
            var dy = this.y - ym;
            var d = Math.sqrt(dx * dx + dy * dy);
            if (d < pdiam * 2) {
                this.dx += dx / d;
                this.dy += dy / d;
            }
        }
        // gravity and acceleration
        this.vy += .2;
        this.x += this.vx;
        this.y += this.vy;
        // screens limits
        if (this.x < pdiam * .5) this.dx += (pdiam * .5 - this.x);
        else if (this.x > nw - pdiam * .5) this.dx -= (this.x - nw + pdiam * .5);
        if (this.y < pdiam * .5) this.dy += (pdiam * .5 - this.y);
        else if (this.y > nh - pdiam * .5) this.dy -= (this.y - nh + pdiam * .5);
        // grid coordinates
        var gx = Math.round(this.x / pdiam);
        var gy = Math.round(this.y / pdiam);
        // neightbors constraints
        for (var ix = gx - 1; ix <= gx + 1; ix++) {
            for (var iy = gy - 1; iy <= gy + 1; iy++) {
                var g = grid[iy * gw + ix] || [];
                for (j = 0, l = g.length; j < l; j++) {
                    var that = g[j];
                    var dx = that.x - this.x;
                    var dy = that.y - this.y;
                    var d = Math.sqrt(dx * dx + dy * dy);
                    if (d < pdiam && d > 0) {
                        dx = (dx / d) * (pdiam - d) * .25;
                        dy = (dy / d) * (pdiam - d) * .25;
                        this.dx -= dx;
                        this.dy -= dy;
                        that.dx += dx;
                        that.dy += dy;
                    }
                }
            }
        }
        // update neighbors array
        if (!grid[gy * gw + gx]) grid[gy * gw + gx] = [this];
        else grid[gy * gw + gx].push(this);
    }
    // loop
    var run = function () {
        fps++;
        grid = new Array(gw * gh);
        for(var i = 0; i < npart; i++) obj[i].physics();
        for(var i = 0; i < npart; i++) obj[i].move();
        setTimeout(run, 1);
    }
    return {
        // initialization
        init : function (n, d) {
            scr = document.getElementById('main');
            npart = n;
            pdiam = d;
            // subscribing to events
            addEvent(document, 'mousemove', function (e) {
                if (window.event) e = window.event;
                xm = e.clientX - nx;
                ym = e.clientY - ny;
            });
            addEvent(window, 'resize', resize);
            addEvent(document, 'mousedown', function(e) {if (e.preventDefault) e.preventDefault(); down = true;return false;});
            addEvent(document, 'mouseup', function() { down = false;return false;});
            document.onselectstart = function () { return false; }
            scr.ondrag = function () { return false; }
            // fps countrt
            setInterval(function() {
                document.getElementById('fps').innerHTML = fps + ' FPS';
                fps = 0;
            }, 1000);
            // starting
            resize();
            for (var i = 0; i < npart; i++) obj[i] = new Particle(document.getElementById('unit'));
            run();
        }
    }
}();
window.onload = function() {
  wp.init(50, 45);
}

This is most interesting and important part of our article. Here we creating our main object – scene, and adding particle to it. Also added several events (mainly for mouse). All this looks like low level coding, but don`t worry – this is mainly mathematics.

这是我们文章中最有趣,最重要的部分。 在这里,我们创建主要对象–场景,并向其中添加粒子。 还添加了几个事件(主要用于鼠标)。 所有这些看起来都像是低级编码,但是不用担心–这主要是数学。

现场演示

[sociallocker]

[社交储物柜]

打包下载

[/sociallocker]

[/ sociallocker]

结论 (Conclusion)

Hope that you was happy to play with thas robo-water :) If is you were wondering – do not forget to thank. I would be grateful for your interesting comments. Good luck!

希望您很高兴与thas robo-water一起玩:)如果您想知道–别忘了感谢。 谢谢您提出的宝贵意见。 祝好运!

翻译自: https://www.script-tutorials.com/particles-in-water/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用JavaScript在水效果中创建动画粒子 的相关文章

  • ElectronJS ReferenceError:导航器未定义

    我正在尝试在电子上制作自定义标题栏 但是当我启动我的应用程序时 我遇到了 ReferenceError 导航器未定义 问题 请帮忙 这是我的 main js 中的代码片段 My Codes https i stack imgur com c
  • html5 输入模式属性在表单之外不起作用?

    这把小提琴 http jsfiddle net 2gaw3 按预期工作 当用户输入无效的国家 地区代码时 它会显示警告 这另一个小提琴 http jsfiddle net y66vH 4 没有form元素 不起作用 看来输入的pattern
  • 如何在CSS3媒体查询中使主体宽度自动等于设备宽度?

    我现在正在做一个移动网站 并尝试使用 CSS3 媒体查询来定位不同的设备 我的部分代码如下 media screen and max width 320px body width 320px some other style 正如您所看到的
  • Ember.JS - 如何在同一页面中使用多个模型、控制器和视图?

    我主要了解 Ember JS 的基础知识 大多数示例实际上只处理单个控制器和模型以在页面上显示某些内容 我真的很想用 Ember 构建一个完整的 Web 应用程序 所以有人能告诉我如何组织和连接多个控制器 模型和视图到一个页面中吗 例如 如
  • JavaScript 动画平滑滚动

    默认情况下 当您有这样的片段链接时 a href some url some fragment some text a 浏览器立即向下滚动到该片段 我该如何编程才能使用标准 JS 顺利地向下移动到该片段 这是一个例子 Example htt
  • 如何在 WordPress HTML 中包含“onclick”对象

    我正在尝试将 onclick 对象添加到触发事件的单站点 即而不是多站点 WordPress 中的页面 代码是 a href Send a voice message a 当尝试保存代码时 WordPress 会删除 onclick 对象
  • v-file-input .click() 不是函数

    我试图以编程方式触发 v file input 的 click 事件 因为它在 Vuetify 的文档中 但它显示一个错误this refs imagePicker click is not a function我在这里错过了什么吗 代码重
  • 选中复选框时提交表单

    有没有办法在选中复选框时提交表单
  • 是否可以使用打字稿映射类型来创建接口的非函数属性类型?

    所以我正在研究 Typescript 的映射类型 是否可以创建一个接口来包装另一种类型 从而从原始类型中删除函数 例如 interface Person name string age number speak void type Data
  • 如何使 jQuery 向上动画

    我有一些 jquery 运行得相当好 但是当我将鼠标悬停在有问题的元素上时 底部向下扩展 这并不意外 但不是所需的效果 我希望元素的底部保持静止 而元素的顶部向上扩展 如果您想查看我目前拥有的内容 您可以导航至http demo ivann
  • 一旦 webapp 添加到主屏幕,是否可以强制 iphone/ipod 更新 apple-touch-icon?

    我使用 safari 的所有推荐链接和元标记创建了一个网络应用程序 例如
  • 从多维无穷大数组中删除数组元素

    我想删除一个特定元素 例如 我想删除元素id 76在下面的数组中 而且 数组可以无限地组合在一起 这里的问题是我无法刷新页面 因为我使用 Vue js 进行即时操作 如果我能做到这一点 我的下一个问题可能是如何在我现在想要的地方添加一个元素
  • 加载另一个 JS 脚本后加载

    这是我的代码 very big js file lots of html stuff 问题是 这些是异步加载的 有没有办法等待第二个脚本直到第一个脚本加载 如果您使用 jQuery 有一个非常简单的方法可以通过获取脚本 https api
  • React Native - 跨屏幕传递数据

    我遇到了一些麻烦react native应用程序 我不知道如何跨屏幕传递数据 我意识到还有其他类似的问题在 SO 上得到了回答 但是这些解决方案对我来说不起作用 我正在使用StackNavigator 这是我的设置App js file e
  • 在javascript中动态生成行?

    我是 javascript 新手 我想在按下 Tab 时动态生成行 并希望获取在动态生成的行中输入的值 以便我可以在 servlet 代码中使用这些值 这是我的html
  • 当选择下拉列表中的某些值时,取消选中复选框

    当我从下拉列表中选择某个值或用户未从下拉列表中选择任何值时 我需要取消选中复选框 我现在正在使用 Jquery 这是我现在使用的代码 但它不起作用 Script
  • CSS - 第一个没有特定类别的孩子

    是否可以编写一个 CSS 规则来选择没有特定类的元素的第一个子元素 example div span class common class ignore span span class common class ignore span sp
  • Django 与谷歌图表

    我试图让谷歌图表显示在我的页面上 但我不知道如何将值从 django 视图传递到 javascript 以便我可以绘制图表 姜戈代码 array Year Sales Expenses 2004 1000 400 2005 1170 460
  • 如何更改订阅值?使用 rxJS

    我正在创建一个计时器 需要你的帮助 我刚刚学习 Angular 和 rxJS 对此我有一些疑问 我正在创建一个具有启动 停止 暂停 重置功能的计时器 并且 btn Reset 必须将我的计时器 暂停 到 300 毫秒 怎么做 D 我的启动定
  • 在 javascript 中使用 xPath 解析具有默认命名空间的 XML

    我需要创建一个 XML xPath 解析器 所有解析都必须在客户端进行 使用 JavaScript 我创建了一个 javascript 来执行此操作 在默认名称空间发挥作用之前 一切看起来都正常 我根本无法查询具有默认命名空间的 XML 我

随机推荐

  • 前言-如何学习区块链

    最新内容会更新在主站深入浅出区块链社区 原文链接 前言 如何学习区块链 摘要 区块链未来3到5年应该会出现行业井喷式发展 相应所需的人才必定水涨船高 每一个开发人员都不应该错过这样的机会 区块链涉及的技术很多 很多开发人员看了一些资料后 感
  • C语言常见问题(10):Sections of code should not be commented out

    注释掉的代码及时清理掉 让函数的body干净清洁 不要杂草丛生
  • clang: error: no such file or directory:xxx的处理方法

    经常会遇到这个问题 后来看了一下 大概是在编程的适合改变了工程目录结构 在编译的时候无法找到相应的文件结构 说句话白话 编译器是傻的 你小心或者不小心 结果文件的结果和以前不一样了 编译器是不知情的 还按照之前的方式进行文件之间的链接 所以
  • JavaScript面试题看这一篇就够了,简单全面一发入魂(持续更新 step1)

    目录 1 BOM DOM有什么区别 1 DOM 2 BOM 2 JavaScript中代码后加不加分号 有什么区别 3 var与let const有什么区别 4 原始值和引用值有什么区别 5 什么是执行上下文 6 解释一下JavaScrip
  • hive的高级分组

    1 with cube 2的n次方 使用场景 维度字段之间无关系 底层分组实现 可以实现hive多个任意维度的查询 cube a b c 则首先会对 a b c 进行group by 然后依次是 a b a c a b c b c 最后在对
  • 「已解决」 iTunes 由于卸载 Apple Software Upadate 失败的问题。

    已解决 iTunes 由于卸载 Apple Software Upadate 失败的问题 官方给出的解决方案是 相信大家都会卡在第 2 个步骤上面 卸载 Apple Software Update 时发生出错 这里给出几个方案 方案 1 将
  • 广电大数据用户画像及营销推荐策略(四)——Python实现

    本次大数据项目数据及分析均做脱敏化和保密化 主要分享思路体系 全程用Python实现 数据和代码均不提供 如有建议欢迎讨论 4 模型构建 在实际应用中 构造推荐系统时 并不是采用单一的某种推荐方法进行推荐 为了实现较好的推荐效果 大部分都将
  • 读书思考:步步惊心的《技术陷阱》

    技术陷阱 这本书450页 43万字之巨 信息量密密麻麻 采集的资料极其丰富 复习了一遍大停滞 大分流 大平衡 大逆转时代 并展望未来 看完了有很多想法 随手写了下来 希望不是蹭热点 一 时间折半加速 忽略人类起源到中世纪的万年大停滞 175
  • unity 调用 .dll 或 .so时遇到的问题

    1 32位的 dll 无法在64位的unity编辑器下运行 System DllNotFoundException xxx 64位的程序运行32位的dll是会报这种错 2 Failed to load Assets Plugins xxx
  • 个人网站实现微信扫码登录

    个人网站实现微信扫码登录 效果图 外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直接上传 img kzSrNgiv 1685034480658 https img ggball top picGo 动画 gif 开发背景 为什么
  • javascript canvas 模拟mac最小化

    文章是别人写的 不是我自己的 链接忘记了
  • 【用JS自制表格软件玩数据】4. 行列计数器的实现

    渲染单元格 列计数器 原理 步进器 字符的运算表 源码 当写完本系列后 我会把源代码分享出来给大家 本课程也会持续更新与矫正 欢迎留言指正 前面已经设计了一个底层渲染类 现在准备在这个底层类的基础上 构建一个渲染单元格的模块 列计数器 通常
  • 去中心化时代的创作者经济

    所谓创作者经济 具体是指利用各种互联网工具 由个人或团体进行内容创作 分发及一系列与创作者相关服务下产生的经济收益 这一概念也主要在当前的 web2互联网时代 并且有很多鲜明的案例凸显出了创作者经济的强大潜力 像我们熟知的抖音 哔哩哔哩等都
  • android后台获取当前屏幕截图(screencap.cpp修改)

    本文基于android6 0 首先找到screencap在Android源码中的位置 若不清楚 可以通过在android目录下通过命令find namescreencap cpp 本文直接给出路径 android frameworks ba
  • 开源的C++静态分析工具

    开源的C 静态分析工具 Java有一些非常好的 开源的静态分析工具 如FindBugs Checkstyle和PMD 这些工具易于使用 有益于开发 能运行于多种操作系统而且还免费 商业级的C 静态分析工具产品有Klocwork Gimpel
  • Anaconda命令总结

    Anaconda搭建python学习环境 由于最近打算入坑机器学习 发现很多项目都会用到一些相同的包 每次都要到导入太麻烦了 而Anconda中的conda包管理工具可以提供一套通用的环境 可以极大地提高开发效率 本文主要介绍Anacond
  • idea使用sonarqube对项目代码检测

    idea使用sonarqube对项目代码检测 1 sonarqube的安装 参考网上教程安装即可 2 在本地maven配置文件中配置上安装好的sonarqube相关信息
  • linux学习文档

    汇总 链接 http pan baidu com s 1pLk8SSr 密码 p6b6 如有帮助 还请不吝 推荐 1 1 2序和硬件基础 pdf 链接 http pan baidu com s 1kVFjoTh 密码 powh 2 3中断机
  • Ubuntu安装NVIDIA 显卡驱动

    文章目录 前言 一 基本概念 二 操作步骤 1 显卡硬件型号 2 安装驱动 总结 前言 NVIDIA Nvidia Corporation n v di 港称乎为NVIDIA 台湾与香港译为辉达 中国大陆译为英伟达 创立于1993年1月 是
  • 使用JavaScript在水效果中创建动画粒子

    Water simulation with javascript Today we continue JavaScript lessons and our article will about using js in modeling of