OHIF Viewer (3.9版本最新版) 适配移动端——最后一篇

根据一些调用资料和尝试,OHIF 的底层用的是Cornerstonejs ,这个是基于web端写的,如果说写在微信小程序里,确实有很多报错,

第一个问题就是 npm下载的依赖,

一、运行环境差异

微信小程序的运行环境与传统的 Node.js 环境有很大不同。小程序在微信客户端中运行,有严格的安全限制和性能要求。而 npm 包通常是为 Node.js 环境设计的,其中可能包含一些在小程序环境中不被支持的代码或依赖项。

二、构建机制不同

  1. 小程序有自己特定的构建体系。微信小程序使用自己的开发工具进行构建和打包,这个过程与基于 npm 和 Webpack 等工具的传统前端构建流程不同。小程序的构建工具主要针对小程序的特定结构和需求进行优化,不一定能直接处理 npm 包的复杂依赖关系。
  2. 小程序的代码结构通常是由多个页面和组件组成,每个页面和组件都有自己独立的代码文件。这种结构与传统的基于模块的前端项目有所不同,也使得直接引入 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
  • 13
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值