You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js如何将指定视口设置为圆形?

实现局部圆形裁剪视口的方案

因为Canvas的setScissor()仅支持矩形区域裁剪,CSS border-radius又会影响整个画布,所以要实现指定视口的圆形裁剪,得用Canvas自身的路径裁剪(2D场景)或模板缓冲(WebGL场景)方案:

一、2D Canvas场景(使用clip()方法)

直接通过绘制圆形路径并设置裁剪区域,限制后续绘制仅在圆形范围内生效:

// 保存当前绘图状态,避免影响其他绘制
ctx.save();

// 计算圆形裁剪区域的参数(假设view1是正方形区域)
const centerX = left + width / 2;
const centerY = positiveYUpBottom + height / 2;
const radius = width / 2; // 宽高相等时取宽的一半,若为椭圆则分别设置x/y半径

// 创建圆形路径
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
ctx.closePath();

// 设置裁剪区域
ctx.clip();

// 绘制view1的内容(保留原视口设置,绘制逻辑不变)
ctx.setViewport(left, positiveYUpBottom, width, height);
// 此处替换为你绘制view1的代码...

// 恢复绘图状态,取消圆形裁剪
ctx.restore();

二、WebGL场景(使用模板缓冲)

WebGL没有直接的clip()方法,需借助模板缓冲标记圆形区域,再限制绘制范围:

const gl = renderer.getContext('webgl');

// 保存当前WebGL状态
gl.save();

// 启用模板测试
gl.enable(gl.STENCIL_TEST);
// 配置模板操作:绘制圆形时将模板值设为1
gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
gl.stencilFunc(gl.ALWAYS, 1, 0xFF);
// 临时关闭颜色和深度写入,仅更新模板缓冲
gl.colorMask(false, false, false, false);
gl.depthMask(false);

// 绘制圆形到模板缓冲(需用shader绘制圆或三角形扇形,此处假设已有drawCircle工具函数)
drawCircle(left + width/2, positiveYUpBottom + height/2, width/2);

// 恢复颜色和深度写入
gl.colorMask(true, true, true, true);
gl.depthMask(true);
// 配置模板测试:仅绘制模板值为1的区域
gl.stencilFunc(gl.EQUAL, 1, 0xFF);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);

// 绘制view1的内容
gl.viewport(left, positiveYUpBottom, width, height);
// 此处替换为你绘制view1的WebGL代码...

// 关闭模板测试,恢复状态
gl.disable(gl.STENCIL_TEST);
gl.restore();

关键说明

  • 两种方案都只会对save()和restore()之间的绘制生效,不会影响画布其他区域
  • 若view1区域不是正方形,调整arc()参数可实现椭圆形裁剪

内容的提问来源于stack exchange,提问作者javrro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 22:06:33