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

如何让RN Skia中的Path围绕自身中心点旋转?

问题:React Native Skia 中让图形绕自身中心点旋转

当前我的图形是绕下图中的点旋转,想调整为围绕图形自身的中心点旋转。

图形当前旋转中心点

我的代码如下:

import {
  Path,
  Skia,
  useClockValue,
  useComputedValue,
  Canvas,
  vec

} from '@shopify/react-native-skia'
import React, { useEffect } from 'react'
import { Dimensions } from 'react-native'

import PathCommands from '../PathCommands'

const { width, height } = Dimensions.get('window')
const c = vec(width / 2, height / 2)

export const Headspace = () => {
  const clock = useClockValue()
  useEffect(() => {
    clock.start()
  }, [])

  const path = useComputedValue(() => {
    const p = Skia.Path.Make()

    for (const command of PathCommands.commands) {
      p[command.type](...command.args)
    }

    const m = Skia.Matrix()
    m.translate(c.x, c.y)
    m.rotate(clock.current / 2000)
    p.transform(m)

    return p
  }, [clock])

  return (
    <Canvas style={{ flex: 1 }}>
      <Path
        path={path}
        style='stroke'
        strokeWidth={1}
        antiAlias
      />
    </Canvas>
  )
}

该图形的SVG路径表示如下(图形宽约173单位,高约172单位):

M154.031 57.526l-.065.327.277.185c11.309 7.571 16.908 17.778 16.908 27.93 0 10.153-5.599 20.359-16.908 27.93l-.277.186.065.327c2.642 13.35-.616 24.525-7.794 31.703-7.178 7.178-18.353 10.436-31.704 7.794l-.327-.065-.185.277c-7.571 11.31-17.778 16.909-27.93 16.909-10.153 0-20.36-5.599-27.93-16.909l-.186-.277-.327.065c-13.35 2.642-24.526-.616-31.704-7.794-7.177-7.178-10.435-18.353-7.793-31.703l.064-.327-.277-.186C6.63 106.327 1.03 96.121 1.03 85.968c0-10.152 5.599-20.359 16.908-27.93l.277-.185-.064-.327c-2.642-13.35.616-24.526 7.794-31.704 7.178-7.178 18.352-10.436 31.703-7.794l.327.065.186-.277C65.735 6.506 75.942.908 86.094.908c10.151 0 20.356 5.599 27.927 16.908l.185.277.327-.065c13.351-2.642 24.526.616 31.704 7.794 7.178 7.178 10.436 18.353 7.794 31.704z

解决方案

要实现图形绕自身中心点旋转,核心是调整矩阵变换的顺序:先将图形平移至自身中心与原点重合,再执行旋转,最后平移到画布中心。具体修改如下:

修改后的核心代码

const path = useComputedValue(() => {
  const p = Skia.Path.Make()

  for (const command of PathCommands.commands) {
    p[command.type](...command.args)
  }

  // 获取图形的边界框,计算自身中心点
  const bounds = p.getBounds();
  const pathCenter = vec(
    bounds.left + bounds.width / 2,
    bounds.top + bounds.height / 2
  );

  const m = Skia.Matrix()
  // 1. 平移图形,让自身中心对齐坐标原点
  m.translate(-pathCenter.x, -pathCenter.y);
  // 2. 绕原点(即图形原中心)旋转
  m.rotate(clock.current / 2000);
  // 3. 将旋转后的图形平移到画布中心
  m.translate(c.x, c.y);
  
  p.transform(m)

  return p
}, [clock])

逻辑说明

原代码先平移到画布中心再旋转,导致图形绕画布中心转动。调整顺序后:

  1. 第一步平移抵消图形自身的偏移,让中心落到原点,此时旋转就会围绕图形自身中心进行
  2. 旋转完成后,再将图形整体移到画布中心,最终呈现出绕自身中心旋转且居中显示的效果

如果不想通过getBounds()计算,也可以用你提供的图形尺寸(宽173、高172)直接计算中心,但getBounds()的方式更通用,适配任意路径图形。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 09:14:54