Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Five-菜鸟级
NodeJS_668036
提交
51c6405e
N
NodeJS_668036
项目概览
Five-菜鸟级
/
NodeJS_668036
与 Fork 源项目一致
Fork自
inscode / NodeJS
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
N
NodeJS_668036
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
51c6405e
编写于
2月 07, 2025
作者:
Q
qq_41923622
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fri Feb 7 11:15:00 CST 2025 inscode
上级
d75f300f
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
222 addition
and
196 deletion
+222
-196
src/tiny-image-editor/src/components/Download.tsx
src/tiny-image-editor/src/components/Download.tsx
+2
-0
src/tiny-image-editor/src/components/Upload.tsx
src/tiny-image-editor/src/components/Upload.tsx
+210
-193
src/tiny-image-editor/src/components/init.tsx
src/tiny-image-editor/src/components/init.tsx
+10
-3
未找到文件。
src/tiny-image-editor/src/components/Download.tsx
浏览文件 @
51c6405e
...
@@ -110,6 +110,8 @@ const useDownload = () => {
...
@@ -110,6 +110,8 @@ const useDownload = () => {
annotations
:
annotations
,
annotations
:
annotations
,
imageWidth
:
canvas
.
backgroundImage
.
width
,
imageWidth
:
canvas
.
backgroundImage
.
width
,
imageHeight
:
canvas
.
backgroundImage
.
height
,
imageHeight
:
canvas
.
backgroundImage
.
height
,
imageLeft
:
canvas
.
backgroundImage
.
left
,
imageTop
:
canvas
.
backgroundImage
.
top
,
originalCanvasWidth
:
canvas
.
getWidth
(),
originalCanvasWidth
:
canvas
.
getWidth
(),
originalCanvasHeight
:
canvas
.
getHeight
(),
originalCanvasHeight
:
canvas
.
getHeight
(),
imgUrl
:
currentSrc
,
imgUrl
:
currentSrc
,
...
...
src/tiny-image-editor/src/components/Upload.tsx
浏览文件 @
51c6405e
...
@@ -3,220 +3,237 @@ import React, { forwardRef, useContext, useImperativeHandle } from 'react';
...
@@ -3,220 +3,237 @@ import React, { forwardRef, useContext, useImperativeHandle } from 'react';
import
{
ACTION
,
LANG
,
MENU_TYPE_ENUM
,
MENU_TYPE_TEXT
}
from
'
../constants
'
;
import
{
ACTION
,
LANG
,
MENU_TYPE_ENUM
,
MENU_TYPE_TEXT
}
from
'
../constants
'
;
import
{
EditorContext
}
from
'
../util
'
;
import
{
EditorContext
}
from
'
../util
'
;
import
Popover
from
'
./setting/Popover
'
;
import
Popover
from
'
./setting/Popover
'
;
import
{
fabric
}
from
'
fabric
'
;
import
{
fabric
}
from
'
fabric
'
;
import
ArrowClass
from
'
../helpers/Arrow
'
;
import
ArrowClass
from
'
../helpers/Arrow
'
;
function
annotationsInit
(
imgData
,
canvas
,
historyRef
,
positionInfo
){
function
annotationsInit
(
imgData
,
canvas
,
historyRef
,
positionInfo
)
{
const
{
scaleX
,
scaleY
}
=
positionInfo
const
{
scaleX
,
scaleY
,
leftOffset
,
topOffset
,
}
=
positionInfo
console
.
log
(
"
scaleX,scaleY
"
,
scaleX
,
scaleY
,
currentCanvasWidth
,
currentCanvasHeight
,
currentImageWidth
,
currentImageHeight
,
imageWidth
,
imageHeight
,
imgData
)
// 遍历标注信息,重新创建元素并添加到画布上
// 遍历标注信息,重新创建元素并添加到画布上
imgData
.
annotations
.
forEach
((
annotation
)
=>
{
imgData
.
annotations
.
forEach
((
annotation
)
=>
{
let
newObject
;
let
newObject
;
switch
(
annotation
.
type
)
{
switch
(
annotation
.
type
)
{
case
'
rect
'
:
case
'
rect
'
:
newObject
=
new
fabric
.
Rect
({
newObject
=
new
fabric
.
Rect
({
left
:
annotation
.
left
*
scaleX
,
left
:
annotation
.
left
*
scaleX
+
leftOffset
,
top
:
annotation
.
top
*
scaleY
,
top
:
annotation
.
top
*
scaleY
+
topOffset
,
originX
:
'
left
'
,
originX
:
'
left
'
,
originY
:
'
top
'
,
originY
:
'
top
'
,
width
:
annotation
.
width
*
scaleX
,
width
:
annotation
.
width
*
scaleX
,
height
:
annotation
.
height
*
scaleY
,
height
:
annotation
.
height
*
scaleY
,
angle
:
annotation
.
angle
||
0
,
angle
:
annotation
.
angle
||
0
,
fill
:
annotation
.
fill
||
'
rgba(255,0,0,0)
'
,
fill
:
annotation
.
fill
||
'
rgba(255,0,0,0)
'
,
stroke
:
annotation
.
stroke
,
stroke
:
annotation
.
stroke
,
strokeWidth
:
annotation
.
size
*
Math
.
max
(
scaleX
,
scaleY
),
strokeWidth
:
annotation
.
size
*
Math
.
max
(
scaleX
,
scaleY
),
transparentCorners
:
false
,
transparentCorners
:
false
,
opacity
:
annotation
.
opacity
||
1
opacity
:
annotation
.
opacity
||
1
});
});
break
;
break
;
case
'
textbox
'
:
case
'
textbox
'
:
case
'
i-text
'
:
case
'
i-text
'
:
case
'
text
'
:
case
'
text
'
:
newObject
=
new
fabric
.
IText
(
annotation
.
text
,
{
newObject
=
new
fabric
.
IText
(
annotation
.
text
,
{
left
:
annotation
.
left
*
scaleX
,
left
:
annotation
.
left
*
scaleX
+
leftOffset
,
top
:
annotation
.
top
*
scaleY
,
top
:
annotation
.
top
*
scaleY
+
topOffset
,
width
:
annotation
.
width
*
scaleX
,
width
:
annotation
.
width
*
scaleX
,
fontSize
:
annotation
.
fontSize
,
fontSize
:
annotation
.
fontSize
,
fill
:
annotation
.
fill
,
fill
:
annotation
.
fill
,
id
:
Math
.
random
()
*
4
+
'
_
'
+
Date
.
now
(),
id
:
Math
.
random
()
*
4
+
'
_
'
+
Date
.
now
(),
opacity
:
annotation
.
opacity
||
1
opacity
:
annotation
.
opacity
||
1
});
});
break
;
break
;
case
'
circle
'
:
case
'
circle
'
:
newObject
=
new
fabric
.
Circle
({
newObject
=
new
fabric
.
Circle
({
left
:
annotation
.
left
*
scaleX
,
left
:
annotation
.
left
*
scaleX
+
leftOffset
,
top
:
annotation
.
top
*
scaleY
,
top
:
annotation
.
top
*
scaleY
+
topOffset
,
radius
:
(
annotation
.
width
/
2
)
*
Math
.
max
(
scaleX
,
scaleY
),
radius
:
(
annotation
.
width
/
2
)
*
Math
.
max
(
scaleX
,
scaleY
),
angle
:
annotation
.
angle
||
0
,
angle
:
annotation
.
angle
||
0
,
fill
:
annotation
.
fill
||
''
,
fill
:
annotation
.
fill
||
''
,
originX
:
'
left
'
,
originX
:
'
left
'
,
originY
:
'
top
'
,
originY
:
'
top
'
,
stroke
:
annotation
.
stroke
,
stroke
:
annotation
.
stroke
,
strokeWidth
:
annotation
.
size
*
Math
.
max
(
scaleX
,
scaleY
),
strokeWidth
:
annotation
.
size
*
Math
.
max
(
scaleX
,
scaleY
),
opacity
:
annotation
.
opacity
||
1
opacity
:
annotation
.
opacity
||
1
});
});
break
;
break
;
case
'
arrow
'
:
case
'
arrow
'
:
let
pointList
=
annotation
.
pointList
||
[
annotation
.
left
,
annotation
.
top
,
annotation
.
left
,
annotation
.
top
]
let
pointList
=
annotation
.
pointList
||
[
annotation
.
left
,
annotation
.
top
,
annotation
.
left
,
annotation
.
top
]
pointList
[
0
]
=
pointList
[
0
]
*
scaleX
;
pointList
[
0
]
=
pointList
[
0
]
*
scaleX
+
leftOffset
;
pointList
[
1
]
=
pointList
[
1
]
*
scaleY
;
pointList
[
1
]
=
pointList
[
1
]
*
scaleY
+
topOffset
;
pointList
[
2
]
=
pointList
[
2
]
*
scaleX
;
pointList
[
2
]
=
pointList
[
2
]
*
scaleX
+
leftOffset
;
pointList
[
3
]
=
pointList
[
3
]
*
scaleY
;
pointList
[
3
]
=
pointList
[
3
]
*
scaleY
+
topOffset
;
newObject
=
new
ArrowClass
(
pointList
,
{
newObject
=
new
ArrowClass
(
pointList
,
{
strokeWidth
:
annotation
.
size
*
Math
.
max
(
scaleX
,
scaleY
),
strokeWidth
:
annotation
.
size
*
Math
.
max
(
scaleX
,
scaleY
),
stroke
:
annotation
.
stroke
,
stroke
:
annotation
.
stroke
,
id
:
new
Date
().
valueOf
()
+
'
_
'
+
Math
.
random
()
*
4
,
id
:
new
Date
().
valueOf
()
+
'
_
'
+
Math
.
random
()
*
4
,
});
});
newObject
.
strokeUniform
=
true
;
newObject
.
strokeUniform
=
true
;
break
;
break
;
case
'
path
'
:
case
'
path
'
:
const
adjustedPath
=
annotation
.
path
.
map
((
segment
)
=>
{
const
adjustedPath
=
annotation
.
path
.
map
((
segment
)
=>
{
const
newSegment
=
[...
segment
];
const
newSegment
=
[...
segment
];
for
(
let
i
=
1
;
i
<
newSegment
.
length
;
i
++
)
{
for
(
let
i
=
1
;
i
<
newSegment
.
length
;
i
++
)
{
if
(
typeof
newSegment
[
i
]
===
'
number
'
)
{
if
(
typeof
newSegment
[
i
]
===
'
number
'
)
{
if
(
i
%
2
===
1
)
{
if
(
i
%
2
===
1
)
{
newSegment
[
i
]
*=
scaleX
;
newSegment
[
i
]
=
newSegment
[
i
]
*
scaleX
+
leftOffset
;
}
else
{
}
else
{
newSegment
[
i
]
*=
scaleY
;
newSegment
[
i
]
=
newSegment
[
i
]
*
scaleY
+
topOffset
;
}
}
}
}
}
return
newSegment
;
});
newObject
=
new
fabric
.
Path
(
adjustedPath
,
{
fill
:
annotation
.
fill
,
stroke
:
annotation
.
stroke
,
strokeWidth
:
annotation
.
size
*
Math
.
max
(
scaleX
,
scaleY
),
opacity
:
annotation
.
opacity
||
1
});
break
;
// 可以根据需要添加更多元素类型的处理
}
if
(
newObject
)
{
console
.
log
(
`annotation`
,
newObject
,
annotation
,
canvas
)
canvas
.
add
(
newObject
)
canvas
.
setActiveObject
(
newObject
);
historyRef
.
current
.
updateCanvasState
(
ACTION
.
add
,
true
,
true
);
// canvas.setActiveObject(newObject);
}
}
return
newSegment
;
});
newObject
=
new
fabric
.
Path
(
adjustedPath
,
{
fill
:
annotation
.
fill
,
stroke
:
annotation
.
stroke
,
strokeWidth
:
annotation
.
size
*
Math
.
max
(
scaleX
,
scaleY
),
opacity
:
annotation
.
opacity
||
1
});
});
break
;
// 可以根据需要添加更多元素类型的处理
}
if
(
newObject
)
{
console
.
log
(
`annotation`
,
newObject
,
annotation
,
canvas
)
canvas
.
add
(
newObject
)
canvas
.
setActiveObject
(
newObject
);
historyRef
.
current
.
updateCanvasState
(
ACTION
.
add
,
true
,
true
);
// canvas.setActiveObject(newObject);
}
});
}
}
export
const
useUpload
=
()
=>
{
export
const
useUpload
=
()
=>
{
const
{
const
{
canvasInstanceRef
,
canvasInstanceRef
,
canvasEl
,
canvasEl
,
currentMenuRef
,
currentMenuRef
,
historyRef
,
historyRef
,
setCurrentMenu
,
setCurrentMenu
,
initBackGroundImage
,
initBackGroundImage
,
}
=
useContext
(
EditorContext
);
}
=
useContext
(
EditorContext
);
const
handleUpload
=
(
e
:
any
,
imgData
?:
any
)
=>
{
const
handleUpload
=
(
e
:
any
,
imgData
?:
any
)
=>
{
console
.
log
(
`e`
,
e
,
imgData
)
console
.
log
(
`e`
,
e
,
imgData
)
const
canvas
=
canvasInstanceRef
.
current
;
const
canvas
=
canvasInstanceRef
.
current
;
if
(
canvasEl
?.
current
&&
typeof
e
===
'
string
'
)
{
if
(
canvasEl
?.
current
&&
typeof
e
===
'
string
'
)
{
let
imgObj
=
new
Image
();
let
imgObj
=
new
Image
();
if
(
imgData
)
{
if
(
imgData
)
{
// 获取当前图片和画布尺寸
// 获取当前图片和画布尺寸
const
currentImageWidth
=
canvas
.
backgroundImage
.
width
;
const
currentImageWidth
=
canvas
.
backgroundImage
.
width
;
const
currentImageHeight
=
canvas
.
backgroundImage
.
height
;
const
currentImageHeight
=
canvas
.
backgroundImage
.
height
;
const
currentCanvasWidth
=
canvas
.
getWidth
();
const
currentCanvasWidth
=
canvas
.
getWidth
();
const
currentCanvasHeight
=
canvas
.
getHeight
();
const
currentCanvasHeight
=
canvas
.
getHeight
();
let
imageWidth
=
imgData
.
imageWidth
||
imgData
.
imgWidth
;
let
imageWidth
=
imgData
.
imageWidth
||
imgData
.
imgWidth
;
let
imageHeight
=
imgData
.
imageHeight
||
imgData
.
imgHeight
;
let
imageHeight
=
imgData
.
imageHeight
||
imgData
.
imgHeight
;
// 计算缩放比例
// 计算缩放比例
const
originalScaleX
=
imgData
.
originalCanvasWidth
/
imageWidth
;
const
originalScaleX
=
imgData
.
originalCanvasWidth
/
imageWidth
;
const
originalScaleY
=
imgData
.
originalCanvasHeight
/
imageHeight
;
const
originalScaleY
=
imgData
.
originalCanvasHeight
/
imageHeight
;
const
currentScaleX
=
currentCanvasWidth
/
currentImageWidth
;
const
currentScaleX
=
currentCanvasWidth
/
currentImageWidth
;
const
currentScaleY
=
currentCanvasHeight
/
currentImageHeight
;
const
currentScaleY
=
currentCanvasHeight
/
currentImageHeight
;
const
scaleX
=
currentScaleX
/
originalScaleX
;
const
scaleX
=
currentScaleX
/
originalScaleX
;
const
scaleY
=
currentScaleY
/
originalScaleY
;
const
scaleY
=
currentScaleY
/
originalScaleY
;
const
newScaleFactor
=
Math
.
min
(
currentCanvasWidth
/
imageWidth
,
currentCanvasHeight
/
imageHeight
);
const
newScaleFactor
=
Math
.
min
(
currentCanvasWidth
/
imageWidth
,
currentCanvasHeight
/
imageHeight
);
const
newLeft
=
(
currentCanvasWidth
-
imageWidth
*
newScaleFactor
)
/
2
;
const
newTop
=
(
currentCanvasHeight
-
imageHeight
*
newScaleFactor
)
/
2
;
annotationsInit
(
imgData
,
canvas
,
historyRef
,{
const
leftOffset
=
newLeft
-
imgData
.
imageLeft
*
scaleX
;
scaleX
,
const
topOffset
=
newTop
-
imgData
.
imageTop
*
scaleY
;
scaleY
,
imgObj
.
src
=
e
as
string
;
});
initBackGroundImage
(
e
as
string
,
true
,
()
=>
{
}
historyRef
.
current
.
updateCanvasState
(
ACTION
.
add
);
})
annotationsInit
(
imgData
,
canvas
,
historyRef
,
{
scaleX
,
}
else
{
scaleY
,
newLeft
,
}
newTop
,
imgObj
.
src
=
e
as
string
;
leftOffset
,
initBackGroundImage
(
e
as
string
,
true
,
()
=>
{
topOffset
,
historyRef
.
current
.
updateCanvasState
(
ACTION
.
add
);
});
return
;
return
;
},
{
}
newLeft
,
if
(
newTop
,
!
canvas
||
newScaleFactor
,
!
canvasEl
.
current
||
})
!
e
.
target
.
files
.
length
||
!
e
.
target
.
files
[
0
]?.
type
?.
includes
(
'
image
'
)
}
else
{
imgObj
.
src
=
e
as
string
;
initBackGroundImage
(
e
as
string
,
true
,
()
=>
{
historyRef
.
current
.
updateCanvasState
(
ACTION
.
add
);
return
;
})
}
return
;
}
if
(
!
canvas
||
!
canvasEl
.
current
||
!
e
.
target
.
files
.
length
||
!
e
.
target
.
files
[
0
]
?.
type
?.
includes
(
'
image
'
)
)
{
)
{
return
;
return
;
}
}
if
(
currentMenuRef
.
current
!==
MENU_TYPE_ENUM
.
upload
)
{
if
(
currentMenuRef
.
current
!==
MENU_TYPE_ENUM
.
upload
)
{
setCurrentMenu
(
MENU_TYPE_ENUM
.
upload
);
setCurrentMenu
(
MENU_TYPE_ENUM
.
upload
);
}
}
const
reader
=
new
FileReader
();
const
reader
=
new
FileReader
();
reader
.
onload
=
function
(
event
)
{
reader
.
onload
=
function
(
event
)
{
if
(
!
event
||
!
event
.
target
)
{
if
(
!
event
||
!
event
.
target
)
{
return
;
return
;
}
}
let
imgObj
=
new
Image
();
let
imgObj
=
new
Image
();
imgObj
.
src
=
event
.
target
.
result
as
string
;
imgObj
.
src
=
event
.
target
.
result
as
string
;
initBackGroundImage
(
event
.
target
.
result
as
string
,
true
,
()
=>
{
initBackGroundImage
(
event
.
target
.
result
as
string
,
true
,
()
=>
{
historyRef
.
current
.
updateCanvasState
(
ACTION
.
add
);
historyRef
.
current
.
updateCanvasState
(
ACTION
.
add
);
});
});
};
reader
.
readAsDataURL
(
e
.
target
.
files
[
0
]);
};
};
reader
.
readAsDataURL
(
e
.
target
.
files
[
0
]);
};
return
{
handleUpload
};
return
{
handleUpload
};
};
};
/** 上传 */
/** 上传 */
export
const
Upload
=
forwardRef
((
props
,
ref
)
=>
{
export
const
Upload
=
forwardRef
((
props
,
ref
)
=>
{
const
{
const
{
lang
=
LANG
.
en
lang
=
LANG
.
en
}
=
useContext
(
EditorContext
);
}
=
useContext
(
EditorContext
);
const
{
handleUpload
}
=
useUpload
();
const
{
handleUpload
}
=
useUpload
();
useImperativeHandle
(
useImperativeHandle
(
ref
,
ref
,
()
=>
({
()
=>
({
handleUpload
:
handleUpload
,
handleUpload
:
handleUpload
,
}),
}),
[
handleUpload
],
[
handleUpload
],
);
);
return
(
return
(
<>
<>
{
/* <div className="tie-image-editor_tool-item tie-image-editor_tool-upload"> */
}
{
/* <div className="tie-image-editor_tool-item tie-image-editor_tool-upload"> */
}
{
/* <Popover content={MENU_TYPE_TEXT.upload[lang]} placement="top"> */
}
{
/* <Popover content={MENU_TYPE_TEXT.upload[lang]} placement="top"> */
}
{
/* <i className="tie-image-editor_icon"> */
}
{
/* <i className="tie-image-editor_icon"> */
}
{
/* <input
{
/* <input
onChange={handleUpload}
onChange={handleUpload}
type="file"
type="file"
className="tie-image-editor_tool-upload-input"
className="tie-image-editor_tool-upload-input"
accept="image/*"
accept="image/*"
/> */
}
/> */
}
{
/* </i> */
}
{
/* </i> */
}
{
/* </Popover> */
}
{
/* </Popover> */
}
{
/* </div> */
}
{
/* </div> */
}
</>
</>
);
);
})
})
src/tiny-image-editor/src/components/init.tsx
浏览文件 @
51c6405e
...
@@ -142,12 +142,19 @@ export const useInit = ({ url }: IProps) => {
...
@@ -142,12 +142,19 @@ export const useInit = ({ url }: IProps) => {
(
oImg
:
any
)
=>
{
(
oImg
:
any
)
=>
{
const
center
=
canvas
.
getCenter
();
const
center
=
canvas
.
getCenter
();
const
imgHeight
=
oImg
.
height
;
const
imgHeight
=
oImg
.
height
;
/** 图片过大,使其大小正好跟容器一致 */
oImg
.
scale
(
height
/
imgHeight
);
if
(
annotationsData
){
if
(
annotationsData
){
let
imgScaleFactor
=
height
/
imgHeight
let
newScaleFactor
=
imgScaleFactor
/
annotationsData
.
newScaleFactor
oImg
.
scale
(
imgScaleFactor
);
oImg
.
set
({
left
:
annotationsData
.
newLeft
*
newScaleFactor
,
top
:
annotationsData
.
newTop
*
newScaleFactor
,
});
}
else
{
}
else
{
/** 图片过大,使其大小正好跟容器一致 */
oImg
.
scale
(
height
/
imgHeight
);
/** 使得图片在canvas中间 */
/** 使得图片在canvas中间 */
oImg
.
set
({
oImg
.
set
({
left
:
center
.
left
-
(
oImg
.
width
*
(
height
/
imgHeight
))
/
2
,
left
:
center
.
left
-
(
oImg
.
width
*
(
height
/
imgHeight
))
/
2
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录