根据一些调用资料和尝试,OHIF 的底层用的是Cornerstonejs ,这个是基于web端写的,如果说写在微信小程序里,确实有很多报错,
第一个问题就是 npm下载的依赖,
一、运行环境差异
微信小程序的运行环境与传统的 Node.js 环境有很大不同。小程序在微信客户端中运行,有严格的安全限制和性能要求。而 npm 包通常是为 Node.js 环境设计的,其中可能包含一些在小程序环境中不被支持的代码或依赖项。
二、构建机制不同
- 小程序有自己特定的构建体系。微信小程序使用自己的开发工具进行构建和打包,这个过程与基于 npm 和 Webpack 等工具的传统前端构建流程不同。小程序的构建工具主要针对小程序的特定结构和需求进行优化,不一定能直接处理 npm 包的复杂依赖关系。
- 小程序的代码结构通常是由多个页面和组件组成,每个页面和组件都有自己独立的代码文件。这种结构与传统的基于模块的前端项目有所不同,也使得直接引入 npm 包变得更加困难。
第二个 修改的话很考验技术,得修改js文件,而且不保证是否能运行起来
第三个 ohif 最新版用的react+ hooks 框架写的,很多组件都是已经封装好,要是另外写的话 ,也很考研技术
现在是用手机模式写的适配移动端
第一个:
platform\app\src\utils\isMobile.ts
创建一个ts文件 用来判断现在是否处于移动端模式
export default function isMobile(): boolean {
const pattern: RegExp = new RegExp(
'Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini'
);
return pattern.test(navigator.userAgent);
}
第二个:
extensions\default\src\ViewerLayout\index.tsx
在这个里面是基础查看器的布局位置,我们先通过这个文件来找到 导航栏、左侧面板、右侧面板、·中间影像的查看器、以及工具栏的工具们的组件位置
导航栏 的移动端改造
原来的导航栏的组件组件 是
extensions\default\src\ViewerLayout\ViewerHeader.tsx
这个里面的 Header
platform\ui\src\components\Header\Header.tsx
里面有个NavBar
platform\ui\src\components\NavBar\NavBar.tsx
这个是控制外面那个容器的
我把它改成 没有下拉菜单的 ,都横着展示出来,所以要自己写一套组件组件出来或者直接判断 写两个return也可以
组件们都在
platform\ui\src\components 这个下面,如果想要自己新建一个组件的话,就来这里,记得导出,建完文件夹以后,还得导出
有两个index.js里面 写上新建的组件
platform\ui\src\components\index.js
platform\ui\src\index.js
这两个里面都得加上,不然你的组件没有办法使用
里面图标的具体 控制
extensions\default\src\Toolbar\ToolbarSplitButtonWithServices.tsx
这个里面的
<SplitButton
primary={primary}
secondary={secondary}
items={getSplitButtonItems(items)}
groupId={groupId}
renderer={listItemRenderer}
onInteraction={onInteraction}
Component={props => (
<PrimaryButtonComponent
{...props}
servicesManager={servicesManager}
/>
)}
/>
我先建了一个SplitButtonAPP的组件,在新的组件里面的把按钮拆成一长条,具体代码
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import OutsideClickHandler from 'react-outside-click-handler';
import { useTranslation } from 'react-i18next';
import Icon from '../Icon';
import Tooltip from '../Tooltip';
import ListMenu from '../ListMenu';
const baseClasses = {
Button: 'flex flex-col items-center rounded-md border-transparent group/button',
Primary: 'flex flex-col items-center text-center',
Content: 'flex flex-row space-x-4',
};
const classes = {
Button: () => classNames(baseClasses.Button, 'hover:!bg-primary-dark hover:border-primary-dark'),
Primary: ({ isActive }) =>
classNames(
baseClasses.Primary,
isActive
? 'border-primary-light bg-primary-light rounded-md'
: 'border-secondary-dark bg-secondary-dark group-hover/button:border-primary-dark group-hover/button:text-primary-light hover:!bg-primary-dark hover:border-primary-dark'
),
Content: () => classNames(baseClasses.Content),
};
const DefaultListItemRenderer = props => {
const { t, icon, label, className, isActive } = props;
return (
<div
className={classNames(
'flex h-8 w-full select-none flex-row items-center p-3',
'whitespace-pre text-base',
className,
`${isActive ? 'hover:opacity-80' : 'hover:bg-primary-dark'}`
)}
>
{icon && (
<span className="mr-4">
<Icon
name={icon}
className="h-[28px] w-[28px]"
/>
</span>
)}
<span className="mr-5">{t?.(label)}</span>
</div>
);
};
/**
* SplitButton 组件是一个更通用的拆分按钮实现,没有isActive和其他交互属性
* 它提供了一种在主按钮和次按钮之间切换,并展示相关选项列表的功能
*
* @param {object} props - 组件的属性对象
* @param {string} props.groupId - 按钮组的ID,用于数据追踪
* @param {object} props.primary - 主按钮的配置对象
* @param {object} props.secondary - 次按钮的配置对象
* @param {array} props.items - 列表菜单项的数组
* @param {function} props.renderer - 渲染列表项的自定义函数
* @param {function} props.onInteraction - 交互时触发的回调函数
* @param {React.Component} props.Component - 渲染图标使用的组件,默认为Icon
* @returns {JSX.Element} - 拆分按钮的JSX实现
*/
const SplitButtonAPP = ({
groupId,
primary,
secondary,
items,
renderer = null,
onInteraction,
Component = Icon,
}) => {
// 使用useTranslation钩子管理翻译
const { t } = useTranslation('Buttons');
// 渲染函数,如果未提供renderer则使用默认渲染函数
const listItemRenderer = renderer || DefaultListItemRenderer;
return (
<div
id="SplitButtonAPP"
className={classes.Content()}
>
{items.map((item, index) => {
const primaryClassNames = classNames(
classes.Primary({
isActive: item.isActive,
}),
item.className
);
return (
<div
key={item.id}
className="flex flex-col items-center"
>
<Tooltip
content={item.label}
className="h-full"
>
<Component