支持适配uniapp开发(直接workspace嵌入编译模式)
This commit is contained in:
@@ -3,6 +3,15 @@ import { ref, watch, nextTick, onMounted, onUnmounted } from 'vue'
|
|||||||
import type { Task } from '../models/classes/Task'
|
import type { Task } from '../models/classes/Task'
|
||||||
import { getPredecessorIds } from '../utils/predecessorUtils'
|
import { getPredecessorIds } from '../utils/predecessorUtils'
|
||||||
|
|
||||||
|
// uni-app 类型声明
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
uni?: {
|
||||||
|
createCanvasContext: (canvasId: string) => CanvasRenderingContext2D & { draw?: () => void }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 定义 TaskBar 位置信息类型
|
// 定义 TaskBar 位置信息类型
|
||||||
interface TaskBarPosition {
|
interface TaskBarPosition {
|
||||||
left: number
|
left: number
|
||||||
@@ -65,19 +74,32 @@ const drawLinks = () => {
|
|||||||
const canvas = canvasRef.value
|
const canvas = canvasRef.value
|
||||||
if (!canvas) return
|
if (!canvas) return
|
||||||
|
|
||||||
const ctx = canvas.getContext('2d', { alpha: true })
|
// 判断是否在 uni-app 环境中
|
||||||
|
const isUniApp = typeof window !== 'undefined' && window.uni
|
||||||
|
let ctx: (CanvasRenderingContext2D & { draw?: () => void }) | null = null
|
||||||
|
|
||||||
|
if (isUniApp && window.uni) {
|
||||||
|
// uni-app 环境:使用 uni.createCanvasContext
|
||||||
|
// https://uniapp.dcloud.net.cn/component/canvas.html
|
||||||
|
// 这儿存在一个问题:如果一个应用多个gantt视图会存在id冲突问题,所以后期可以加上一个配置,外部传入canvas-id
|
||||||
|
ctx = window.uni.createCanvasContext('gantt-link-canvas')
|
||||||
|
} else {
|
||||||
|
// Web 环境:使用标准 Canvas API
|
||||||
|
ctx = canvas.getContext('2d', { alpha: true })
|
||||||
|
}
|
||||||
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error('❌ Canvas context 获取失败,可能是尺寸超限')
|
console.error('❌ Canvas context 获取失败,可能是尺寸超限')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 适配高清屏(Retina)
|
|
||||||
const dpr = window.devicePixelRatio || 1
|
|
||||||
const displayWidth = props.width
|
const displayWidth = props.width
|
||||||
const displayHeight = props.height
|
const displayHeight = props.height
|
||||||
|
|
||||||
// 只在尺寸变化时更新 canvas 尺寸
|
// Web 环境才需要手动处理 DPR(uni-app 通过 hidpi 属性自动处理)
|
||||||
|
if (!isUniApp) {
|
||||||
|
const dpr = window.devicePixelRatio || 1
|
||||||
const pixelWidth = displayWidth * dpr
|
const pixelWidth = displayWidth * dpr
|
||||||
const pixelHeight = displayHeight * dpr
|
const pixelHeight = displayHeight * dpr
|
||||||
if (canvas.width !== pixelWidth || canvas.height !== pixelHeight) {
|
if (canvas.width !== pixelWidth || canvas.height !== pixelHeight) {
|
||||||
@@ -85,6 +107,7 @@ const drawLinks = () => {
|
|||||||
canvas.height = pixelHeight
|
canvas.height = pixelHeight
|
||||||
ctx.scale(dpr, dpr)
|
ctx.scale(dpr, dpr)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 清空画布(透明)
|
// 清空画布(透明)
|
||||||
ctx.clearRect(0, 0, displayWidth, displayHeight)
|
ctx.clearRect(0, 0, displayWidth, displayHeight)
|
||||||
@@ -311,6 +334,11 @@ const drawLinks = () => {
|
|||||||
// 恢复透明度
|
// 恢复透明度
|
||||||
ctx.globalAlpha = 1
|
ctx.globalAlpha = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// uni-app 环境需要调用 draw() 方法将绘制内容渲染到画布
|
||||||
|
if (isUniApp && ctx?.draw) {
|
||||||
|
ctx.draw()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -390,7 +418,7 @@ watch(
|
|||||||
// 组件挂载后初始化绘制
|
// 组件挂载后初始化绘制
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 监听主题变化
|
// 监听主题变化
|
||||||
themeObserver = new MutationObserver((mutations) => {
|
themeObserver = new MutationObserver(mutations => {
|
||||||
for (const mutation of mutations) {
|
for (const mutation of mutations) {
|
||||||
if (mutation.attributeName === 'data-theme') {
|
if (mutation.attributeName === 'data-theme') {
|
||||||
updateTheme()
|
updateTheme()
|
||||||
@@ -433,14 +461,16 @@ defineExpose({
|
|||||||
<template>
|
<template>
|
||||||
<canvas
|
<canvas
|
||||||
ref="canvasRef"
|
ref="canvasRef"
|
||||||
|
canvas-id="gantt-link-canvas"
|
||||||
class="gantt-links-canvas"
|
class="gantt-links-canvas"
|
||||||
|
type="2d"
|
||||||
|
:hidpi="true"
|
||||||
:style="{
|
:style="{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
left: 0,
|
left: `${offsetLeft}px`,
|
||||||
top: 0,
|
top: `${offsetTop}px`,
|
||||||
width: `${width}px`,
|
width: `${width}px`,
|
||||||
height: `${height}px`,
|
height: `${height}px`,
|
||||||
transform: `translate(${offsetLeft}px, ${offsetTop}px)`,
|
|
||||||
zIndex: highlightedTaskId !== null ? 1001 : 25,
|
zIndex: highlightedTaskId !== null ? 1001 : 25,
|
||||||
pointerEvents: 'none',
|
pointerEvents: 'none',
|
||||||
}"
|
}"
|
||||||
|
|||||||
Reference in New Issue
Block a user