JavaScript Canvas实现可旋转多等分圆形的频闪效应模拟

javascript canvas实现可旋转多等分圆形的频闪效应模拟

本教程旨在指导如何修改现有JavaScript Canvas代码,以实现将圆形等分为多份并进行旋转,从而更准确地模拟频闪效应。文章将详细解释如何从圆心绘制多条分割线来替代原始的直径绘制方式,并提供修改后的代码示例,帮助开发者解决特定采样频率下180度视觉偏差的问题,并为实现更多等分和自定义颜色提供基础。

引言:频闪效应与圆形分割

频闪效应(Stroboscopic Effect)是一种常见的视觉现象,当观察快速旋转的物体在间歇性光照或采样下时,物体可能看起来静止、反向旋转或以不同速度旋转。在Web前端,我们可以利用JavaScript的Canvas API来模拟这一效果。

原始的代码示例旨在展示频闪效应,但其默认的圆形分割方式是绘制一条穿过圆心的直径(即180度分割)。这种方式在某些特定采样频率下,尤其当输入频率与采样频率接近时,可能无法清晰地展示出物体在180度相位上变化的频闪特性,导致视觉上的混淆或无法观察到预期的效果。为了更灵活、更准确地观察和控制频闪效应,我们需要将圆形划分为更多等份,例如3份或更多,并确保这些分割线能够正确旋转。

核心问题分析:多等分与180°采样问题

用户提出的核心需求是:

立即学习“Java免费学习笔记(深入)”;

将圆形划分为3个或更多等份。其中一半分割线能够显示不同的颜色(尽管提供的解决方案主要侧重于分割逻辑,而非复杂的颜色区分)。解决在输入频率与采样频率相同时,采样可能出现180度偏差导致视觉效果不准确的问题。

原始代码通过绘制一个从圆周一点到其对角点的线来表示旋转物体,这实际上是将其分成了两部分。要实现多等分,并正确显示每个部分的旋转,我们需要改变绘制策略。关键在于,当绘制多条分割线时,每条线都应该从圆心出发,延伸到圆周上的一个点。

解决方案:从中心绘制多条分割线

为了将圆形分割成N个等份,并让这些分割线随着圆的旋转而移动,我们需要对 render() 函数中的绘制逻辑进行修改。原始代码的绘制方式是 moveTo 到圆周上的一点,然后 lineTo 到其对角点,这本质上是绘制一条直径。当我们需要多条分割线时,这种方法不再适用。正确的做法是:

确定圆心坐标。对于每一个分割点,从圆心 moveTo 到圆心本身。然后从圆心 lineTo 到圆周上该分割点对应的位置。

这样,每条分割线都将是半径,并且它们会以圆心为轴心旋转。对于3等分,每条分割线之间的角度差为 360 / 3 = 120 度。

uBrand Logo生成器 uBrand Logo生成器

uBrand Logo生成器是一款强大的AI智能LOGO设计工具。

uBrand Logo生成器 124 查看详情 uBrand Logo生成器

代码实现细节:render 函数的修改

以下是针对 stroboscopic_effect.js 文件中 render() 函数的关键修改部分。

function render() {    context.fillStyle = "#000000";    context.fillRect(0, 0, canvas_width, canvas_height);    context.strokeStyle = "#ffffff";    context.beginPath();    context.moveTo(canvas_width / 2, 0);    context.lineTo(canvas_width / 2, canvas_height);    context.stroke();    context.strokeStyle = "#ff51ff";    context.beginPath();    /* 左侧旋转圆的绘制逻辑修改 */    const x1 = canvas_width / 4, y1 = canvas_height / 2 + y_offset; // 左侧圆的圆心    context.moveTo(x1, y1); // 移动到圆心    // 绘制第一条分割线    context.lineTo(x1 + wheel_radius * Math.cos(toRadian(wheel_angle)), y1 - wheel_radius * Math.sin(toRadian(wheel_angle)));    context.moveTo(x1, y1); // 移动回圆心    // 绘制第二条分割线 (120度偏移)    context.lineTo(x1 + wheel_radius * Math.cos(toRadian(wheel_angle + 120)), y1 - wheel_radius * Math.sin(toRadian(wheel_angle + 120)));    context.moveTo(x1, y1); // 移动回圆心    // 绘制第三条分割线 (240度偏移)    context.lineTo(x1 + wheel_radius * Math.cos(toRadian(wheel_angle + 240)), y1 - wheel_radius * Math.sin(toRadian(wheel_angle + 240)));    context.stroke(); // 提交绘制    context.beginPath();    context.arc(canvas_width / 4, canvas_height / 2 + y_offset, wheel_radius, 0, 2 * Math.PI);    context.stroke();    /* 右侧采样圆的绘制逻辑修改 */    context.strokeStyle = "#00ff00";    context.beginPath();    const x2 = 3 * canvas_width / 4, y2 = y1; // 右侧圆的圆心,与左侧圆y坐标相同    context.moveTo(x2, y2); // 移动到圆心    // 绘制第一条分割线    context.lineTo(x2 + wheel_radius * Math.cos(toRadian(camera_angle)), y1 - wheel_radius * Math.sin(toRadian(camera_angle)));    context.moveTo(x2, y2); // 移动回圆心    // 绘制第二条分割线 (120度偏移)    context.lineTo(x2 + wheel_radius * Math.cos(toRadian(camera_angle + 120)), y2 - wheel_radius * Math.sin(toRadian(camera_angle + 120)));    context.moveTo(x2, y2); // 移动回圆心    // 绘制第三条分割线 (240度偏移)    context.lineTo(x2 + wheel_radius * Math.cos(toRadian(camera_angle + 240)), y2 - wheel_radius * Math.sin(toRadian(camera_angle + 240)));    context.stroke(); // 提交绘制    context.beginPath();    context.arc(3 * canvas_width / 4, canvas_height / 2 + y_offset, wheel_radius, 0, 2 * Math.PI);    context.stroke();    // ... (其他文本和Canvas设置保持不变)}

修改说明:

定义圆心: 首先,我们为左右两个圆分别定义了圆心坐标 (x1, y1) 和 (x2, y2)。context.moveTo(x, y) 到圆心: 在绘制每条分割线之前,都使用 context.moveTo(x, y) 将画笔移动到当前圆的圆心。这是实现从中心向外绘制的关键。context.lineTo(x, y) 到圆周: 接着,使用 context.lineTo(x, y) 绘制一条从圆心到圆周上特定角度点的线。wheel_angle 或 camera_angle 代表当前旋转角度。wheel_angle + 120 和 wheel_angle + 240 分别表示相对于当前角度偏移120度和240度的位置,从而实现3等分。toRadian() 函数将角度转换为弧度,因为 Math.cos() 和 Math.sin() 接受弧度作为参数。重复绘制: 对于每个分割线,都需要重复 moveTo 到圆心,然后 lineTo 到新的圆周点。

通用化与扩展:N等分与颜色定制

N等分

要将圆形分割成 N 个等份,只需将 120 和 240 等固定角度替换为基于 N 的计算:

// 假设 divisions 是你想要分割的份数 (例如 3, 4, 6 等)const divisions = 3; // 可以是任何大于2的整数const angleIncrement = 360 / divisions;for (let i = 0; i < divisions; i++) {    const currentAngle = wheel_angle + i * angleIncrement;    context.moveTo(x1, y1);    context.lineTo(x1 + wheel_radius * Math.cos(toRadian(currentAngle)), y1 - wheel_radius * Math.sin(toRadian(currentAngle)));}

通过这种循环结构,你可以轻松地将圆分割成任意数量的等份,使其更具通用性。

颜色定制

如果需要实现“一半分割线是不同颜色”的需求,则需要更精细的绘制控制。例如,如果想让某个扇形区域或某条分割线具有不同颜色,可以这样做:

绘制不同颜色的分割线: 在循环中,根据 i 的值判断是否更改 context.strokeStyle。绘制不同颜色的扇形区域: 如果目标是让分割出的“扇形”区域具有不同颜色,则需要使用 context.arc() 结合 context.lineTo() 和 context.fill() 来绘制和填充扇形,而不是简单地绘制线。这会比仅仅绘制分割线复杂一些,需要计算每个扇形的起始和结束角度。

例如,绘制一个特定颜色的扇形:

// 假设要绘制第一个120度扇形为红色context.fillStyle = "red";context.beginPath();context.moveTo(x1, y1);context.arc(x1, y1, wheel_radius, toRadian(wheel_angle), toRadian(wheel_angle + angleIncrement));context.closePath();context.fill();// 其他扇形或线条继续绘制

完整代码示例

为了提供一个完整的可运行示例,下面将整合修改后的JavaScript代码。HTML部分保持不变,因为它主要负责设置Canvas元素和用户交互控件。

stroboscopic_effect.js (修改后)

let wheel_angle, camera_angle;let wheel_rpm, angular_speed;let wheel_radius;let frames_skip, cooldown, sampling_rate, frame_no;let is_paused, direction;/* original code from  *//* https://visualize-it.github.io/stroboscopic_effect/simulation.html */function update() {    wheel_angle += direction * angular_speed;    if (wheel_angle > 360) {        wheel_angle -= 360;    }    else if (wheel_angle < 0) {        wheel_angle += 360;    }    if (frame_no == 0) {        camera_angle = wheel_angle;        frame_no = frames_skip;    }    else {        frame_no -= 1;    }}function render() {    context.fillStyle = "#000000";    context.fillRect(0, 0, canvas_width, canvas_height);    context.strokeStyle = "#ffffff";    context.beginPath();    context.moveTo(canvas_width / 2, 0);    context.lineTo(canvas_width / 2, canvas_height);    context.stroke();    context.strokeStyle = "#ff51ff";    context.beginPath();    /* 左侧旋转圆的绘制逻辑修改 */    const x1 = canvas_width / 4, y1 = canvas_height / 2 + y_offset; // 左侧圆的圆心    context.moveTo(x1, y1); // 移动到圆心    // 绘制第一条分割线    context.lineTo(x1 + wheel_radius * Math.cos(toRadian(wheel_angle)), y1 - wheel_radius * Math.sin(toRadian(wheel_angle)));    context.moveTo(x1, y1); // 移动回圆心    // 绘制第二条分割线 (120度偏移)    context.lineTo(x1 + wheel_radius * Math.cos(toRadian(wheel_angle + 120)), y1 - wheel_radius * Math.sin(toRadian(wheel_angle + 120)));    context.moveTo(x1, y1); // 移动回圆心    // 绘制第三条分割线 (240度偏移)    context.lineTo(x1 + wheel_radius * Math.cos(toRadian(wheel_angle + 240)), y1 - wheel_radius * Math.sin(toRadian(wheel_angle + 240)));    context.stroke(); // 提交绘制    context.beginPath();    context.arc(canvas_width / 4, canvas_height / 2 + y_offset, wheel_radius, 0, 2 * Math.PI);    context.stroke();    /* 右侧采样圆的绘制逻辑修改 */    context.strokeStyle = "#00ff00";    context.beginPath();    const x2 = 3 * canvas_width / 4, y2 = y1; // 右侧圆的圆心,与左侧圆y坐标相同    context.moveTo(x2, y2); // 移动到圆心    // 绘制第一条分割线    context.lineTo(x2 + wheel_radius * Math.cos(toRadian(camera_angle)), y1 - wheel_radius * Math.sin(toRadian(camera_angle)));    context.moveTo(x2, y2); // 移动回圆心    // 绘制第二条分割线 (120度偏移)    context.lineTo(x2 + wheel_radius * Math.cos(toRadian(camera_angle + 120)), y2 - wheel_radius * Math.sin(toRadian(camera_angle + 120)));    context.moveTo(x2, y2); // 移动回圆心    // 绘制第三条分割线 (240度偏移)    context.lineTo(x2 + wheel_radius * Math.cos(toRadian(camera_angle + 240)), y2 - wheel_radius * Math.sin(toRadian(camera_angle + 240)));    context.stroke(); // 提交绘制    context.beginPath();    context.arc(3 * canvas_width / 4, canvas_height / 2 + y_offset, wheel_radius, 0, 2 * Math.PI);    context.stroke();    if (mobile) {        context.font = "15px Arial";    }    else {        context.font = "30px Arial";    }    context.textAlign = "center";    context.fillStyle = "#ffffff";    context.fillText("Base", canvas_width / 4, 30);    context.fillText("Teste Aliasing", 3 * canvas_width / 4, 30);}function initParams() {    wheel_angle = Math.random() * 360;    wheel_rpm = 60;    rpm_slider.value = wheel_rpm;    calcSpeed();    //rpm_display.innerHTML = `Wheel speed: ${wheel_rpm} RPM or ${(angular_speed * fps / 360).toFixed(2)} revolution(s) per second`;    rpm_display.innerHTML = `Frequência do cículo base: ${(angular_speed * fps / 360).toFixed(2)} Hz (Hertz)`;    frames_skip = 26;    calcCooldown();    fps_slider.value = 60 - frames_skip;    //fps_display.innerHTML = `Sampling rate: ${sampling_rate.toFixed(2)} Hz; Sampling Time: ${cooldown.toFixed(2)} seconds`;    fps_display.innerHTML = `Frequência de Amostragem: ${sampling_rate.toFixed(2)} Hz;`;    wheel_radius = (canvas_width / 4) - 20;    frame_no = 0;    paused = false;    direction = -1;}function updateParams(variable) {    if (variable == 'rpm') {        wheel_rpm = rpm_slider.value;        calcSpeed();        //rpm_display.innerHTML = `Wheel speed: ${wheel_rpm} RPM or ${(angular_speed * fps / 360).toFixed(2)} revolution(s) per second`;        rpm_display.innerHTML = `Frequência do cículo base: ${(angular_speed * fps / 360).toFixed(2)} Hz (Hertz)`;    }    else if (variable == 'fps') {        frames_skip = 60 - fps_slider.value;        calcCooldown();        //fps_display.innerHTML = `Sampling rate: ${sampling_rate.toFixed(2)} Hz; Sampling Time: ${cooldown.toFixed(2)} seconds`;        fps_display.innerHTML = `Frequência de Amostragem: ${sampling_rate.toFixed(2)} Hz;`;    }    else if (variable == 'pause') {        if (is_paused) {            is_paused = false;            pause_button.innerHTML = "Parar";        }        else {            is_paused = true;            pause_button.innerHTML = "Continuar";        }    }    else if (variable == 'dir') {        direction *= (-1);    }}function simulate(number) {    if (number == 1) {        rpm_slider.value = 80;        fps_slider.value = 59;    }    else if (number == 2) {

以上就是JavaScript Canvas实现可旋转多等分圆形的频闪效应模拟的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/910215.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月29日 01:59:31
下一篇 2025年11月29日 01:59:53

相关推荐

  • 雪崩价格预测:灰度提升信号潜在集会到50美元?

    雪崩(avax)因其不断增强的链上活跃度与机构关注度正逐步升温,其价格是否有望冲高至50美元?我们来看看最新的价格预测和市场动向。 雪崩价格展望:灰度背书预示或将冲击50美元? 雪崩(AVAX)展现出强劲的韧性,吸引了越来越多机构的关注,并在链上活动方面表现突出。这是否意味着一场大规模上涨即将到来?…

    2025年12月8日
    000
  • Cosmos(ATOM)跨链枢纽价值被低估?生态爆发前夜信号显现

    本文将围绕Cosmos(ATOM)作为跨链枢纽的价值进行探讨,分析其当前可能被市场低估的原因,并通过解读其核心技术、经济模型演进以及生态发展的关键信号,阐述为何Cosmos生态可能正处于爆发的前夜。文章将深入讲解其底层协议与新功能,帮助理解其价值捕获能力的提升过程。 2025主流加密货币交易所官网注…

    2025年12月8日
    000
  • Blockdag,Cosmos和Algorand:在2025年浏览加密货币景观

    在2025年,加密货币的格局正在被重塑,blockdag、cosmos和algorand以其独特的创新能力和市场定位脱颖而出。 Blockdag,Cosmos和Algorand:2025年加密市场的关键参与者 加密世界从不停歇,进入2025年,Blockdag、Cosmos与Algorand正逐渐成…

    2025年12月8日
    000
  • 加密货币,Web3和AI:绘制趋势并发现宝石

    探索加密货币、web3 与人工智能的最新动向与深度见解,聚焦这一快速演进领域中的核心参与者和新兴机遇。 加密货币、Web3 与 AI 的交汇正在重塑数字世界格局,带来挑战的同时也开启了前所未有的机会。让我们深入探讨这一活跃领域的最新动态、发展趋势以及关键洞见。 崭露头角的加密项目 加密市场虽经历波动…

    2025年12月8日
    000
  • BlockDag:这是增长最快的加密货币,准备爆炸吗?

    blockdag凭借其创新技术与亮眼的预售表现吸引了众多关注。但这是否真的是目前发展最快的加密货币呢? BlockDag正在引发热议!该项目设定了6亿美元的融资目标,并以实际进展支撑其计划。但它真的能够兑现承诺吗? Blockdag:只是炒作还是真有实力? 在加密领域,炒作层出不穷,但一些项目确实在…

    2025年12月8日
    000
  • 波卡(DOT)平行链插槽拍卖遇冷,跨链叙事已经过时了吗?

    本文将围绕波卡(DOT)平行链插槽拍卖热度下降的现象,探讨其背后的深层原因,并进一步分析这是否意味着“跨链”这一核心叙事已经过时。我们将通过剖析当前的市场环境、技术发展以及叙事演变,来解答标题中的疑问。文章会提供一个分析框架,帮助您理解如何从现象看本质,并客观看待技术叙事的生命周期。 2025主流加…

    2025年12月8日
    000
  • 改变游戏规则的山寨币:在风格中导航加密货币景观

    带着纽约人的优势进入altcoins的世界。发现改变游戏规则的加密货币(例如qubetics($ tics),宇宙等等),这些加密货币正在激动市场。 好吧,听!加密场景正在嗡嗡作响,如果您不关注Altcoins,您会错过一些严肃的行动。从分散的金融到革新连通性,这些数字资产不仅是投资;他们是对未来的…

    2025年12月8日
    000
  • Blockdag,Presale Projects,Crypto实用程序:在2024年找到宝石

    探索blockdag的6亿美元目标以及其他具备真实加密货币效用的预售项目,在2024年寻找稳定投资机会时,去除了市场炒作,聚焦真正价值。 加密领域不断涌现新的机遇,但关键在于辨别哪些项目具备实质内容。让我们深入了解BlockDag及其他预售项目,关注它们的实际用途与长期增长潜力。 BlockDag:…

    2025年12月8日
    000
  • SUI,HEDERA和UNSTAKED:导航加密货币景观

    探索sui与hedera(hbar)的市场动态,同时关注未固定项目的独特表现。 加密货币领域始终处于不断变化之中,当前,Sui、Hedera(HBAR)以及Unstaked等项目正成为市场的焦点。在Sui展现出平稳的价格走势时,Hedera则显示出回升迹象,而Unstaked则凭借其独特的参与机制吸…

    2025年12月8日
    000
  • 加密买家指南:最佳加密和投资项目,您不会错过

    导航加密货币未来?探索qubetics、cardano、litecoin、cosmos、sui与astra等潜力项目,把握下一轮牛市机遇。 加密投资指南:精选高潜力币种与项目推荐 随着加密市场逐步回暖,越来越多投资者开始寻找下一个爆发点。从去中心化金融到网络扩展方案,各类创新山寨币不断涌现。以下是一…

    2025年12月8日
    000
  • 区块链趋势2025:Altcoins和最佳观看项目(也许可以购买!)

    潜入2025年区块链景观:探索顶级山寨币趋势,涵盖现实世界资产代币化和跨链互操作性。 加密爱好者们,让我们一起踏上旅程。2025年的区块链世界已经不再只是关于炒作。它更注重实际功能、稳定的技术以及真正能带来改变的项目。那么,目前哪些领域最值得关注?哪些山寨币值得追踪?我们一起来看看。 区块链格局:2…

    2025年12月8日
    100
  • 锚地,稳定币和脱口秀:加密戏剧中的纽约分钟

    anchorage digital的stablecoin剔除举动引发争议。是出于监管审慎,还是背后隐藏自我利益?我们深入解析锚地、稳定币以及下架风波。 锚地、稳定币与退市风波:加密世界的一出大戏 Anchorage Digital决定剔除部分Stablecoin,此举在加密圈掀起了轩然大波,不仅引发…

    2025年12月8日
    000
  • Litecoin Price,2030 Prediction,LTC预测:LTC可以恢复其荣耀吗?

    litecoin(ltc)是否具备卷土重来的潜力?查看2030年及以后的最新价格预测,以及影响ltc未来走势的关键因素。 Litecoin Price,2030 Prediction,LTC预测:LTC能否重现辉煌? Litecoin(LTC)这一曾被誉为比特币黄金搭档的加密货币再次引发关注。随着整…

    2025年12月8日
    000
  • 锚固,稳定和法规:纽约的潮汐视角

    安克雷奇(Anchorage)摆脱了有关Stablecoin安全,监管和市场机会的辩论。这是监管的必要性还是战略性游戏? Stablecoins的世界总是在嗡嗡作响,最近,Anchorage Digital逐步支持USDC的决定确实引起了锅的刺激。此举提出了一些有关Stablecoin安全性,不断发…

    2025年12月8日
    000
  • Cosmos(ATOM)跨链枢纽价值凸显,生态项目谁最有潜力?

    本文旨在阐述Cosmos作为“区块链互联网”的核心价值,并针对标题中提出的“生态项目谁最有潜力”这一问题,提供一个系统性的评估框架。文章将首先解析Cosmos通过其核心技术实现的跨链功能,随后通过分步骤讲解,帮助您学习如何从技术、社区、经济模型等多个维度去分析和判断其生态内项目的潜在价值,从而形成自…

    2025年12月8日
    000
  • 狗狗币(DOGE)还能再创奇迹吗?Meme币的未来走势分析

    本文将围绕“狗狗币能否再创奇迹”这一问题展开探讨,通过分析Meme币市场的核心驱动力、未来走势的关键影响因素,以及狗狗币自身面临的机遇与挑战,为读者提供一个理解和判断其未来潜力的分析框架。我们将通过分步讲解的方式,阐述如何观察和分析这些因素,帮助您更好地理解Meme币的波动逻辑。 Meme币的核心驱…

    2025年12月8日
    000
  • Qubetics,Cosmos,Cardano:解码当今的加密嗡嗡声

    深入探索qubetics预售热潮、cosmos技术实力及cardano可扩展性蓝图。 加密市场正掀起新一轮热议!我们来看看Qubetics、Cosmos与Cardano的最新动态。Qubetics预售持续升温,Cosmos展现强劲技术面,而Cardano则在可扩展性方面稳步推进。 Qubetics:…

    2025年12月8日
    000
  • 云采矿:您获得财务自由和加密奖励的门票?

    探索hashj与miningtoken等云采矿平台如何通过加密货币奖励实现财务自由。这些机会是否真实可行? 云采矿:通往财务自由与加密奖励的途径? 云挖矿正变得炙手可热,承诺通过加密货币奖励实现财务自由。Hashj和MiningToken等平台正迅速崛起,但它们真的可靠吗?我们来深入了解。 云采矿的…

    2025年12月8日
    000
  • 加密股票激增:硬币,Mara,clsk和Altcoin国库革命

    coin、mara与clsk等美国加密资产正吸引着投资者的目光。一些公司开始多元化布局山寨币,引发了“美国上市altcoin热潮”。 加密股票飙升:Coin、Mara、clsk与Altcoin国库革新 加密市场正在升温,相关的数字资产也在同步上涨!像Coinbase(Coin)、Marathon D…

    2025年12月8日
    000
  • 7月要观看的十大加密投资:超越通常的嫌疑人

    探索7月有潜力的加密投资,超越sol和xrp等主流币种,寻找潜在的高增长机会。 7月值得关注的十大加密投资:不止于主流币种 随着7月的到来,加密市场正蓄势待发。虽然主流币种依然稳健,但精明的投资者正在挖掘那些被低估的代币,以寻求更高的回报。今年7月,关键在于跳出常规思维,发现具备不对称收益潜力的项目…

    2025年12月8日
    000

发表回复

登录后才能评论
关注微信