gpt4 book ai didi

javascript - 有没有办法在 CSS 中创建 canvas 元素的 3D 圆柱体?

转载 作者:太空狗 更新时间:2023-10-29 12:36:12 25 4
gpt4 key购买 nike

我想将 Canvas 呈现为圆柱形锥体,您可以像轮子一样在两个方向上旋转。这在 JS/CSS3 中完全可行吗?

最佳答案

您应该看看这个新的 CSS3 功能:自定义过滤器/CSS 着色器

这里有一些非常好的演示文稿,它们比我能做的更好地描述了整个事情(如何在 Chrome 上启用它,如何开始,它是如何工作的,等等):

基本上,如果您已经熟悉着色器和 CSS3 转换,那么一切都完成了...

优势

  • 类似 WebGl 的 GPU/3D 加速
  • 无 JS( GL 着色器和 CSS)
  • 可以将它与 CSS3 过渡结合起来

不方便

  • 新功能/仅一些浏览器的最新版本支持(有时受标志保护)
  • 着色器的独立文件(不确定 - 也许可以像使用 WebGL 一样将它们内联到 html 页面中)
  • 在实现下面描述的示例时,我遇到了一个奇怪的行为:如果 Canvas 的大小(不是 CSS 大小而是“JS”大小,定义像素密度)变得太大,着色器似乎不再应用,无论您是否在 Canvas 上进行操作。我很好奇为什么,所以我会尝试对此进行调查。

例子

为了满足您更精确的要求( Canvas 作为圆柱锥体),我做了这个小例子:http://aldream.net/various/css-shader-demo/cylindricalConeTransformDemo.html .将鼠标悬停在 Canvas 上方,使其包裹成一个圆锥体。

它不旋转,我只是应用了从上面给出的文章中的一个示例中获取的简单过渡效果,但您应该明白了。

所使用的顶点着色器和片段着色器可以在这里找到:

简化和注释代码

  • CSS
    canvas {
/* ... Prettify it as you wish */

width: 640px;
height: 560px;

-webkit-filter: custom(url(cylindricalConeTransform.vs) /* Vertex-shader */
mix(url(cylindricalConeTransform.fs) normal source-atop /* Fragment-shader and color-mixing properties */),
36 2 /* Numbers of vertices */,
/* Passing the values to the shaders uniforms: */
amount 0,
cylinderRadius 0.35,
cylinderLength 250,
transform rotateY(0deg) rotateX(0deg));

-webkit-transition: -webkit-filter linear 1s; /* Transition on the filter for animation. */

}

canvas:hover {
/* Same as above, but with different values for some uniforms. With the CSS-transition, those values will be tweened. */
filter: custom(url(cylindricalConeTransform.vs) mix(url(cylindricalConeTransform.fs) normal source-atop), 36 2,
amount 1,
cylinderRadius 0.35,
cylinderLength 250,
transform rotateY(60deg) rotateX(60deg));
}
  • 顶点着色器
precision mediump float;

// Built-in attributes
attribute vec4 a_position;
attribute vec2 a_texCoord;

// Built-in uniforms
uniform mat4 u_projectionMatrix;

// Uniforms passed in from CSS
uniform float amount;
uniform float cylinderRadius;
uniform float cylinderLength;
uniform mat4 transform;

// Constants
const float PI = 3.1415;

// Cone function
vec3 computeCylindricalConePosition( vec2 uv, float r, float l ) {
vec3 p;
float fi = uv.x * PI * 2.0;

p.x = r * cos( fi ) * uv.y;
p.y = r * sin( fi ) * uv.y;
p.z = (uv.y - 0.5) * l;
return p;
}

// Main
void main() {
vec4 position = a_position;

// Map plane to cone using UV coordinates
vec3 cone = computeCylindricalConePosition( a_texCoord, cylinderRadius, cylinderLength );

// Blend plane and cone
position.xyz = mix( position.xyz, cone, amount );

// Set vertex position
gl_Position = u_projectionMatrix * transform * position;
}
  • 片段着色器
/** spec: css */
precision mediump float;

void main() {
css_ColorMatrix = mat4(
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
);
}
  • HTML
<!doctype html>
<html>
<head>
... your meta, css, ...
<body>

<canvas></canvas>

<script>
// Draw what you want in your canvas.
</script>
</body>
</html>

编辑: 实际上我不确定您要的是圆锥体还是圆柱体,但这里的差别很小。如果你想要第二个,你可以修改顶点着色器中的 computeCylindricalConePosition() 函数,改为像这样评估 p.x 和 p.y:

p.x = r * cos( fi ) /* * uv.y */;
p.y = r * sin( fi ) /* * uv.y */;

希望对你有所帮助。一旦我澄清了一些要点,我将尝试发展我的答案。

关于javascript - 有没有办法在 CSS 中创建 canvas 元素的 3D 圆柱体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16433384/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com