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

如何将HTML5中SCSS实现的球体精准复刻到SpriteKit?

如何在SpriteKit中精准复刻HTML5实现的球体效果

一、原HTML5实现(SCSS代码)

通过SCSS径向渐变和阴影实现目标球体:

$color-green-dark: #226f54;

$color-cream: #f4f0bb;
$color-coffee: #7b4b39;
$color-brown: #43291f;

.ballType1 {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;

  &::after {
    content: '';
    width: 60%;
    height: 60%;
    border-radius: 50%;

    box-shadow: 2px 2px 5px #00000030;

    background-image: radial-gradient(
      circle at 40% 40%,
      mix($color-cream, $color-coffee, 90%) 5%,
      mix($color-cream, $color-coffee, 40%) 50%,
      mix($color-cream, $color-brown, 10%) 80%
    );
  }
}

二、效果对比

  • HTML5预期效果:
    HTML5渲染效果
  • SpriteKit当前实现效果:
    SpriteKit渲染效果

三、当前SpriteKit尝试代码

使用SKShapeNode+Shader方案,但小半径(如20)时效果混乱:

override func didMove(to view: SKView) {
    super.didMove(to: view)
    
    // Setup your scene initial state here
    self.backgroundColor = SKColor.greenDark
    
    addBall()
}

func addBall() {
    let ballRadius = 100.0
    let ball = SKShapeNode(circleOfRadius: ballRadius)
    ball.position = CGPoint(x: 40, y: 70)
    
    let shader = SKShader(source: """
        void main() {
            float dist = distance(v_tex_coord, vec2(0.4, 0.4));
            vec3 color = mix(vec3(0.957, 0.941, 0.733), vec3(0.482, 0.294, 0.224), smoothstep(0.05, 0.5, dist));
            color = mix(color, vec3(0.259, 0.161, 0.122), smoothstep(0.5, 0.8, dist));
            gl_FragColor = vec4(color, 1.0);
        }
    """)
    
    ball.fillShader = shader
    ball.strokeColor = SKColor.clear
    
    let shadowNode = SKShapeNode(circleOfRadius: ballRadius)
    shadowNode.fillColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.19)
    shadowNode.strokeColor = SKColor.clear
    shadowNode.position = CGPoint(x: 2, y: -2)
    shadowNode.zPosition = -1
    
    let shadowBlurNode = SKEffectNode()
    shadowBlurNode.shouldRasterize = true
    shadowBlurNode.filter = CIFilter(name: "CIGaussianBlur", parameters: ["inputRadius": 5])
    shadowBlurNode.addChild(shadowNode)
    
    ball.addChild(shadowBlurNode)
    
    addChild(ball)
}

可行解决方案

1. SVG导入方案(推荐)

完全匹配原效果,无需Shader,适配任意尺寸:

  • 步骤1:生成匹配的SVG
    用Figma、Illustrator或在线SVG编辑器复刻效果:
    1. 绘制圆形,添加径向渐变:
      • 渐变中心:相对于圆心偏移至40%x40%位置
      • 颜色节点:
        • 5%位置:mix(#f4f0bb, #7b4b39, 90%)(近似#f2edb9)
        • 50%位置:mix(#f4f0bb, #7b4b39, 40%)(近似#c9b59a)
        • 80%位置:mix(#f4f0bb, #43291f, 10%)(近似#5a3b2f)
    2. 添加阴影:偏移(2px, 2px)、模糊5px、透明度0.19的黑色阴影
  • 步骤2:导入SpriteKit
    将SVG文件添加到Xcode项目,直接用SKSpriteNode加载:
    func addBall() {
        guard let ballTexture = SKTexture(imageNamed: "ball.svg") else { return }
        let ball = SKSpriteNode(texture: ballTexture, size: CGSize(width: 200, height: 200))
        ball.position = CGPoint(x: 40, y: 70)
        addChild(ball)
    }
    
    Xcode默认支持SVG矢量渲染,缩放时不会失真,小尺寸下效果稳定。

2. 修复现有Shader方案

针对SpriteKit纹理坐标特性调整Shader,解决小半径问题:

  • 修改Shader代码,基于圆形边界计算坐标,避免方形拉伸:
    void main() {
        // 转换为圆心在(0.5,0.5)的坐标系
        vec2 center = vec2(0.5, 0.5);
        vec2 pos = v_tex_coord - center;
        // 计算圆形相对半径(0=圆心,1=边缘)
        float circleDist = length(pos) * 2.0; 
        // 渐变中心偏移到原40%位置(相对于圆心左移10%、上移10%)
        vec2 gradientCenter = center + vec2(-0.1, -0.1);
        float gradientDist = distance(v_tex_coord, gradientCenter) * 2.0;
    
        vec3 color1 = vec3(0.957, 0.941, 0.733); // #f4f0bb
        vec3 color2 = vec3(0.482, 0.294, 0.224); // #7b4b39
        vec3 color3 = vec3(0.259, 0.161, 0.122); // #43291f
    
        vec3 color = mix(color1, color2, smoothstep(0.05, 0.5, gradientDist));
        color = mix(color, color3, smoothstep(0.5, 0.8, gradientDist));
    
        // 只渲染圆形区域,隐藏方形边界
        if(circleDist > 1.0) {
            gl_FragColor = vec4(0.0);
        } else {
            gl_FragColor = vec4(color, 1.0);
        }
    }
    
  • 同时调整阴影节点尺寸:shadowNode.radius = ballRadius + 5,避免模糊后边缘缺失。

3. 预渲染PNG方案

快速实现,无需复杂操作:

  • 用浏览器渲染原HTML5球体,截图保存为高分辨率PNG(如400x400)
  • 导入Xcode项目,用SKSpriteNode加载,适合对缩放要求不高的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 09:32:02