Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
V
vue3-quasar-ts-study01
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
hucy
vue3-quasar-ts-study01
Commits
15a7620e
Commit
15a7620e
authored
May 12, 2023
by
hucy
☘
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix:不重要的提交
parent
b0925c4c
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
820 additions
and
58 deletions
+820
-58
index.ts
src/common/utils/index.ts
+1
-0
scale-polygon.ts
src/common/utils/scale-polygon.ts
+129
-0
config.ts
src/layouts/config.ts
+17
-2
config.ts
src/modules/page10/config.ts
+13
-13
MyPoems.vue
src/modules/page10/element/MyPoems.vue
+1
-1
IndexPage.vue
src/modules/vector/IndexPage.vue
+60
-25
utils.ts
src/modules/vector/utils.ts
+17
-0
IndexPage.vue
src/modules/vue-konva-line/IndexPage.vue
+232
-0
IndexPageTest1.vue
src/modules/vue-konva-line/IndexPageTest1.vue
+221
-0
route.ts
src/modules/vue-konva-line/route.ts
+12
-0
types.ts
src/modules/vue-konva-line/types.ts
+5
-0
IndexPage2.vue
src/modules/vue-konva/IndexPage2.vue
+4
-4
TextPage.vue
src/modules/vue-konva/TextPage.vue
+99
-0
utils.ts
src/modules/vue-konva/utils.ts
+7
-13
routes.ts
src/router/routes.ts
+2
-0
No files found.
src/common/utils/index.ts
View file @
15a7620e
...
...
@@ -12,6 +12,7 @@ export * from './get-type';
export
*
from
'./is'
;
export
*
from
'./get-angle'
;
export
*
from
'./getBoundingBox'
;
export
*
from
'./scale-polygon'
;
export
{
cloneDeep
,
orderBy
,
...
...
src/common/utils/scale-polygon.ts
0 → 100644
View file @
15a7620e
interface
Point
{
x
:
number
;
y
:
number
;
[
proppName
:
string
]:
any
;
}
/**
* 缩放多边形坐标
* https://blog.csdn.net/sun_and_breeze/article/details/107517088
* @decoration 需配合顺时针判断方法一起使用
* @param {Point[]} points 点坐标数组 [{x:0,y:0}...]
* @param {number} extra 外延大小。为正: 向外扩; 为负: 向内缩
* @return {Point[]} 扩展或缩小后的多边形点坐标数组
*/
export
function
scalePolygon
(
points
:
Point
[],
extra
:
number
)
{
if
(
!
Array
.
isArray
(
points
)
||
points
.
length
<
3
)
{
console
.
error
(
'多边形坐标集合不能少于3个'
);
return
;
}
const
ps
=
points
;
// 通过顺时针判断取正值还是负值
const
extra0
=
isClockwise
(
ps
)
?
-
extra
:
extra
;
const
norm
=
(
x
:
number
,
y
:
number
)
=>
Math
.
sqrt
(
x
*
x
+
y
*
y
);
const
len
=
ps
.
length
;
const
polygon
=
[];
for
(
let
i
=
0
;
i
<
len
;
i
++
)
{
const
point
=
ps
[
i
];
const
point1
=
ps
[
i
===
0
?
len
-
1
:
i
-
1
];
const
point2
=
ps
[
i
===
len
-
1
?
0
:
i
+
1
];
// 向量PP1
const
vectorX1
=
point1
.
x
-
point
.
x
;
// 向量PP1 横坐标
const
vectorY1
=
point1
.
y
-
point
.
y
;
// 向量PP1 纵坐标
const
n1
=
norm
(
vectorX1
,
vectorY1
);
// 向量的平方根 为了对向量PP1做单位化
let
vectorUnitX1
=
vectorX1
/
n1
;
// 向量单位化 横坐标
let
vectorUnitY1
=
vectorY1
/
n1
;
// 向量单位化 纵坐标
// 向量PP2
const
vectorX2
=
point2
.
x
-
point
.
x
;
// 向量PP2 横坐标
const
vectorY2
=
point2
.
y
-
point
.
y
;
// 向量PP2 纵坐标
const
n2
=
norm
(
vectorX2
,
vectorY2
);
// 向量的平方根 为了对向量PP1做单位化
let
vectorUnitX2
=
vectorX2
/
n2
;
// 向量单位化 横坐标
let
vectorUnitY2
=
vectorY2
/
n2
;
// 向量单位化 纵坐标
// PQ距离
const
vectorLen
=
-
extra0
/
Math
.
sqrt
(
(
1
-
(
vectorUnitX1
*
vectorUnitX2
+
vectorUnitY1
*
vectorUnitY2
))
/
2
);
// 根据向量的叉乘积来判断角是凹角还是凸角
if
(
vectorX1
*
vectorY2
+
-
1
*
vectorY1
*
vectorX2
<
0
)
{
vectorUnitX2
*=
-
1
;
vectorUnitY2
*=
-
1
;
vectorUnitX1
*=
-
1
;
vectorUnitY1
*=
-
1
;
}
// PQ的方向
const
vectorX
=
vectorUnitX1
+
vectorUnitX2
;
const
vectorY
=
vectorUnitY1
+
vectorUnitY2
;
const
n
=
vectorLen
/
norm
(
vectorX
,
vectorY
);
const
vectorUnitX
=
vectorX
*
n
;
const
vectorUnitY
=
vectorY
*
n
;
const
polygonX
=
vectorUnitX
+
point
.
x
;
const
polygonY
=
vectorUnitY
+
point
.
y
;
polygon
[
i
]
=
{
x
:
polygonX
,
y
:
polygonY
};
}
return
polygon
;
}
/**
* 判断坐标数组是否顺时针(默认为false)
* @param {Point[]} points 点坐标数组 [{x:0,y:0}...]
* @returns {boolean} 是否顺时针
*/
export
function
isClockwise
(
points
:
Point
[])
{
// 三个点可以判断矢量是顺时针旋转还是逆时针旋转的,但由于可能存在凹边,所以并不是任意三点都可以正确反映多边形的走向
// 因此需要取多边形中绝对是凸边的点来判断,
// 多边形中的极值点(x最大或x最小或y最大或y最小)它与相邻两点构成的边必然是凸边,因此我们先取出多边形中的极值点,再由极值点和其前后两点去判断矢量的走向,从而判断出多边形的走向。
if
(
!
Array
.
isArray
(
points
)
||
points
.
length
<
3
)
{
console
.
error
(
'多边形坐标集合不能少于3个'
);
return
false
;
}
let
coords
=
JSON
.
parse
(
JSON
.
stringify
(
points
));
if
(
coords
[
0
]
===
coords
[
coords
.
length
-
1
])
{
coords
=
coords
.
slice
(
0
,
coords
.
length
-
1
);
}
coords
=
coords
.
reverse
();
let
maxXIndex
=
0
;
let
maxX
=
parseFloat
(
coords
[
maxXIndex
].
x
);
let
c1
;
let
c2
;
let
c3
;
for
(
let
i
=
0
;
i
<
coords
.
length
;
i
++
)
{
if
(
parseFloat
(
coords
[
i
].
x
)
>
maxX
)
{
maxX
=
parseFloat
(
coords
[
i
].
x
);
maxXIndex
=
i
;
}
}
if
(
maxXIndex
===
0
)
{
c1
=
coords
[
coords
.
length
-
1
];
c2
=
coords
[
maxXIndex
];
c3
=
coords
[
maxXIndex
+
1
];
}
else
if
(
maxXIndex
===
coords
.
length
-
1
)
{
c1
=
coords
[
maxXIndex
-
1
];
c2
=
coords
[
maxXIndex
];
c3
=
coords
[
0
];
}
else
{
c1
=
coords
[
maxXIndex
-
1
];
c2
=
coords
[
maxXIndex
];
c3
=
coords
[
maxXIndex
+
1
];
}
const
x1
=
parseFloat
(
c1
.
x
);
const
y1
=
parseFloat
(
c1
.
y
);
const
x2
=
parseFloat
(
c2
.
x
);
const
y2
=
parseFloat
(
c2
.
y
);
const
x3
=
parseFloat
(
c3
.
x
);
const
y3
=
parseFloat
(
c3
.
y
);
const
s
=
(
x1
-
x3
)
*
(
y2
-
y3
)
-
(
x2
-
x3
)
*
(
y1
-
y3
);
return
s
<
0
;
}
src/layouts/config.ts
View file @
15a7620e
...
...
@@ -132,10 +132,25 @@ export const MenuList = [
{
title
:
'Vue Konva'
,
caption
:
'前端Canvas库-Konva'
,
icon
:
''
,
active
:
false
,
children
:
[
{
title
:
'Konva'
,
caption
:
''
,
icon
:
require
(
'./menuListIcons/amis.svg'
),
link
:
'/vue-konva'
,
active
:
false
,
},
{
title
:
'Line-多边形'
,
caption
:
''
,
icon
:
require
(
'./menuListIcons/amis.svg'
),
link
:
'/vue-konva-line'
,
active
:
false
,
},
],
},
{
title
:
'向量'
,
caption
:
'JavaScript 线性代数:向量'
,
...
...
src/modules/page10/config.ts
View file @
15a7620e
...
...
@@ -29,7 +29,7 @@ export const poems = [
},
{
key
:
'3'
,
author
:
'唐珙'
,
author
:
'唐珙
(gǒng)
'
,
content
:
[
'醉后不知天在水,满船清梦压星河'
],
style
:
{
color
:
'#4AA5DA'
,
...
...
@@ -178,7 +178,7 @@ export const poems = [
{
key
:
'18'
,
author
:
'龚自珍'
,
content
:
[
'万一禅关砉然破,美人如玉剑如虹'
],
content
:
[
'万一禅关砉
(huā)
然破,美人如玉剑如虹'
],
style
:
{
backgroundImage
:
'linear-gradient(25deg, #794a70, #8c6e90, #9e92b1, #aeb7d3)'
,
...
...
@@ -478,8 +478,8 @@ export const poems = [
},
{
key
:
'46'
,
author
:
'吴庆坻'
,
content
:
[
'须知少日拏云志,曾许人间第一流'
],
author
:
'吴庆坻
(dǐ)
'
,
content
:
[
'须知少日拏
(ná)
云志,曾许人间第一流'
],
style
:
{
backgroundColor
:
'#F5F0E9'
,
color
:
'#57A5D1'
,
...
...
@@ -509,7 +509,7 @@ export const poems = [
},
{
key
:
'49'
,
author
:
'李鼐'
,
author
:
'李鼐
(nài)
'
,
content
:
[
'从今把定春风笑,且作人间长寿仙'
],
style
:
{
backgroundImage
:
...
...
@@ -630,7 +630,7 @@ export const poems = [
},
{
key
:
'60'
,
author
:
'舒亶'
,
author
:
'舒亶
(dǎn)
'
,
content
:
[
'浮生只合尊前老,雪满长安道'
],
style
:
{
backgroundImage
:
...
...
@@ -659,7 +659,7 @@ export const poems = [
},
{
key
:
'63'
,
author
:
'钱珝'
,
author
:
'钱珝
(xǔ)
'
,
content
:
[
'莫愁千里路,自有到风来'
],
style
:
{
backgroundColor
:
'#62676C'
,
...
...
@@ -770,7 +770,7 @@ export const poems = [
},
{
key
:
'75'
,
author
:
'姚鼐'
,
author
:
'姚鼐
(nài)
'
,
content
:
[
'苍山负雪,明烛天南'
],
style
:
{
backgroundImage
:
'linear-gradient(to right, #d7d2cc 0%, #304352 100%)'
,
...
...
@@ -829,7 +829,7 @@ export const poems = [
author
:
'林清和'
,
content
:
[
'你当然不是什么惊世骇俗之物,'
,
'你只是凛冬中我愿“拥毳衣炉火”去看的白雪'
,
'你只是凛冬中我愿“拥毳
(cuì)
衣炉火”去看的白雪'
,
],
style
:
{
backgroundImage
:
'linear-gradient(-20deg, #616161 0%, #9bc5c3 100%)'
,
...
...
@@ -1069,7 +1069,7 @@ export const poems = [
{
key
:
'106'
,
author
:
'苏轼'
,
content
:
[
'粗缯大布裹生涯,腹有诗书气自华'
],
content
:
[
'粗缯
(zēng)
大布裹生涯,腹有诗书气自华'
],
style
:
{
backgroundImage
:
'linear-gradient(25deg, #1d6c99, #6d95b6, #aac1d4, #e7eff2)'
,
...
...
@@ -1137,7 +1137,7 @@ export const poems = [
{
key
:
'113'
,
author
:
'袁枚'
,
content
:
[
'学如弓弩,才如箭镞'
],
content
:
[
'学如弓弩,才如箭镞
(zú)
'
],
style
:
{
backgroundImage
:
'linear-gradient(25deg, #624365, #846e8d, #a79cb6, #cbcce2)'
,
...
...
@@ -1177,7 +1177,7 @@ export const poems = [
{
key
:
'117'
,
author
:
''
,
content
:
[
'月落星沈'
],
content
:
[
'月落星沈
(chén)
'
],
style
:
{
backgroundImage
:
'linear-gradient(25deg, #688bdd, #8392c1, #9599a5, #a1a088)'
,
...
...
@@ -1273,7 +1273,7 @@ export const poems = [
{
key
:
'128'
,
author
:
'苏轼'
,
content
:
[
'麤
(cū)
缯大布裹生涯,腹有诗书气自华'
],
content
:
[
'麤
(cū)
缯大布裹生涯,腹有诗书气自华'
],
style
:
{
backgroundColor
:
'#6A5F5C'
,
color
:
'#E18689'
,
...
...
src/modules/page10/element/MyPoems.vue
View file @
15a7620e
...
...
@@ -27,7 +27,7 @@ const { info } = useMessage();
const
source
=
ref
(
require
(
'../media/羽肿-花火が瞬く夜に.mp3'
));
const
isPlaying
=
ref
(
false
);
const
carouselRef
=
ref
<
any
>
(
null
);
const
slide
=
ref
(
'
135
'
);
const
slide
=
ref
(
'
60
'
);
onMounted
(()
=>
{
// rightClick();
...
...
src/modules/vector/IndexPage.vue
View file @
15a7620e
...
...
@@ -29,31 +29,66 @@ onMounted(() => {
drawGrid
();
const
pointO
=
{
x
:
600
,
y
:
200
,
name
:
'O'
};
const
pointA
=
{
x
:
500
,
y
:
300
,
name
:
'A'
};
const
pointB
=
{
x
:
800
,
y
:
300
,
name
:
'B'
};
drawVector
(
pointO
,
pointA
);
drawVector
(
pointO
,
pointB
);
// 加法
const
pointC
=
new
Vector
(
pointO
,
pointA
).
add
(
pointB
)
as
any
;
pointC
.
name
=
'C'
;
const
len
=
new
Vector
(
pointO
,
pointB
).
length
;
console
.
log
(
'OB向量长度'
,
len
);
const
len2
=
new
Vector
(
pointA
,
pointB
).
length
;
console
.
log
(
'AB向量的长度'
,
len2
);
drawVector
(
pointO
,
pointC
,
'#21BA45'
);
// 减
const
pointD
=
new
Vector
(
pointO
,
pointB
).
subtract
(
pointA
);
console
.
log
(
'pointD'
,
pointD
);
drawVector
(
pointO
,
pointD
,
'#FFA000'
);
// 求夹角
const
angle
=
new
Vector
(
pointO
,
pointA
).
dotProduct
(
pointB
);
console
.
log
(
'OA向量到OB向量的夹角'
,
angle
);
// const pointO = { x: 600, y: 200, name: 'O' };
// const pointA = { x: 500, y: 300, name: 'A' };
// const pointB = { x: 800, y: 300, name: 'B' };
// drawVector(pointO, pointA);
// drawVector(pointO, pointB);
// // 加法
// const pointC = new Vector(pointO, pointA).add(pointB) as any;
// pointC.name = 'C';
// const len = new Vector(pointO, pointB).length;
// console.log('OB向量长度', len);
// const len2 = new Vector(pointA, pointB).length;
// console.log('AB向量的长度', len2);
// drawVector(pointO, pointC, '#21BA45');
// // 减
// const pointD = new Vector(pointO, pointB).subtract(pointA);
// console.log('pointD', pointD);
// drawVector(pointO, pointD, '#FFA000');
// // 求夹角
// const angle = new Vector(pointO, pointA).dotProduct(pointB);
// console.log('OA向量到OB向量的夹角', angle);
const
pointP
=
{
x
:
400
,
y
:
200
,
name
:
'P'
};
const
pointP1
=
{
x
:
700
,
y
:
200
,
name
:
'P1'
};
const
pointP2
=
{
x
:
300
,
y
:
400
,
name
:
'P2'
};
drawVector
(
pointP
,
pointP1
);
drawVector
(
pointP
,
pointP2
);
// 单位化后的向量以(0,0)点为原点
// 单位化PP1向量
const
pointP1fterUnit
=
new
Vector
(
pointP
,
pointP1
).
unitization
();
// 单位化PP2向量
const
pointP2fterUnit
=
new
Vector
(
pointP
,
pointP2
).
unitization
();
const
unitP1
=
pointP1fterUnit
.
point
;
const
myUnitP1
=
{
x
:
unitP1
.
x
*
100
,
y
:
unitP1
.
y
*
100
};
const
_myUnitP1
=
{
x
:
myUnitP1
.
x
+
pointP
.
x
,
y
:
myUnitP1
.
y
+
pointP
.
y
};
drawVector
(
pointP
,
_myUnitP1
,
'pink'
);
const
unitP2
=
pointP2fterUnit
.
point
;
const
myUnitP2
=
{
x
:
unitP2
.
x
*
100
,
y
:
unitP2
.
y
*
100
};
const
_myUnitP2
=
{
x
:
myUnitP2
.
x
+
pointP
.
x
,
y
:
myUnitP2
.
y
+
pointP
.
y
};
drawVector
(
pointP
,
_myUnitP2
,
'pink'
);
// PQ的单位向量
// = 单位化PP1向量 + 单位化PP2向量
const
unitPQ
=
new
Vector
(
pointP
,
_myUnitP1
).
add
(
_myUnitP2
);
drawVector
(
pointP
,
unitPQ
,
'pink'
);
console
.
log
(
'PQ的单位向量'
,
unitPQ
);
console
.
log
(
'单位化PP1向量'
,
pointP1fterUnit
,
'单位化PP2向量'
,
pointP2fterUnit
);
});
function
drawVector
(
pointX
:
Point
,
pointY
:
Point
,
color
=
'#F44336'
)
{
...
...
src/modules/vector/utils.ts
View file @
15a7620e
...
...
@@ -102,6 +102,23 @@ export class Vector {
// c向量的模 = x1*y2 - x2*y1
// = a向量的模 * b向量的模 * sin(夹角)
// 如果以向量a和向量b边构成一个平行四边形,那么这两个向量外积的模长与这个平行四边形的面积相等。
// 向量单位化
// 单位化后的向量以(0,0)点为原点
unitization
()
{
const
pointO
=
this
.
components
[
0
];
const
pointA
=
this
.
components
[
1
];
const
norm
=
(
x
:
number
,
y
:
number
)
=>
Math
.
sqrt
(
x
*
x
+
y
*
y
);
const
vectorX1
=
pointA
.
x
-
pointO
.
x
;
// 向量OA 横坐标
const
vectorY1
=
pointA
.
y
-
pointO
.
y
;
// 向量OA 纵坐标
const
n1
=
norm
(
vectorX1
,
vectorY1
);
// 向量的平方根 为了对向量OA做单位化
const
vectorUnitX1
=
vectorX1
/
n1
;
// 向量单位化 横坐标
const
vectorUnitY1
=
vectorY1
/
n1
;
// 向量单位化 纵坐标
return
{
point
:
{
x
:
vectorUnitX1
,
y
:
vectorUnitY1
},
n
:
n1
,
};
}
}
/**
...
...
src/modules/vue-konva-line/IndexPage.vue
0 → 100644
View file @
15a7620e
<!--
* @FileDescription: vue-konva
* @Author: hcy
* @Date: 2023-03-29
-->
<
script
setup
lang=
"ts"
>
import
{
reactive
,
onMounted
}
from
'vue'
;
import
Konva
from
'konva'
;
import
{
scalePolygon
}
from
'src/common/utils'
;
import
type
{
Points
}
from
'./types'
;
const
state
=
reactive
({
stage
:
null
as
any
,
shapePath
:
[
{
name
:
'test1'
,
color
:
'pink'
,
path
:
[
{
x
:
100
,
y
:
100
},
{
x
:
200
,
y
:
100
},
{
x
:
200
,
y
:
200
},
{
x
:
0
,
y
:
300
},
],
},
]
as
any
[],
});
const
stageSize
=
reactive
({
width
:
1200
,
// 画布宽度
height
:
800
,
// 画布高度
gridGap
:
100
,
// 网格的间距
});
onMounted
(()
=>
{
drawGrid
();
handleData
();
//
initKonva
();
});
function
handleData
()
{
const
list
=
state
.
shapePath
;
for
(
const
iter
of
list
)
{
iter
.
linePath
=
[];
iter
.
scalePath
=
[];
const
path
:
Points
[]
=
iter
.
path
||
[];
const
scalePath
=
scalePolygon
(
path
,
10
)
as
Points
[];
for
(
const
ite
of
path
)
{
iter
.
linePath
.
push
(
ite
.
x
);
iter
.
linePath
.
push
(
ite
.
y
);
}
for
(
const
ite
of
scalePath
)
{
iter
.
scalePath
.
push
(
ite
.
x
);
iter
.
scalePath
.
push
(
ite
.
y
);
}
}
}
function
initKonva
()
{
const
list
=
state
.
shapePath
;
// 创建根节点(舞台)
state
.
stage
=
new
Konva
.
Stage
({
container
:
'stage-container'
,
width
:
stageSize
.
width
,
height
:
stageSize
.
height
,
});
// 创建图层
const
layer
=
new
Konva
.
Layer
({
name
:
'my-layer'
,
});
// for循环创建组
for
(
const
iter
of
list
)
{
/*
* 创建一个组,
* 将用于组合多个简单的形状。
* 变换组将变换所有的简单形状作为一个单位在一起
*/
const
group
=
new
Konva
.
Group
({
name
:
iter
.
name
,
draggable
:
true
,
});
// 创建图形1
// points: 点坐标的平面阵列。你应该定义它们为[x1, y1, x2, y2, x3, y3]。
const
poly
=
new
Konva
.
Line
({
name
:
iter
.
name
,
points
:
iter
.
linePath
,
fill
:
iter
.
color
||
'#00D2FF'
,
// 填充颜色
stroke
:
'black'
,
// 边框颜色
strokeWidth
:
0
,
// 边框宽度
closed
:
true
,
// 是否闭合路径
});
// 创建图形2-图形边框
const
polygonBorder
=
new
Konva
.
Line
({
points
:
iter
.
scalePath
,
stroke
:
'green'
,
// 边框颜色
strokeWidth
:
1
,
// 边框宽度
closed
:
true
,
// 是否闭合路径
});
// 将图形添加到组
group
.
add
(
poly
);
group
.
add
(
polygonBorder
);
// 将组添加到图层中
layer
.
add
(
group
);
}
// 将图层添加到根节点上
state
.
stage
.
add
(
layer
);
}
/**
* 绘制网格线
*/
function
drawGrid
()
{
let
canvas
:
any
=
document
.
getElementById
(
'canvas-grid'
);
let
pen
=
canvas
.
getContext
(
'2d'
);
// 绘制网格
const
step
=
stageSize
.
gridGap
;
const
h
=
stageSize
.
height
;
const
w
=
stageSize
.
width
;
const
w_l
=
w
/
step
;
const
h_l
=
h
/
step
;
// 横着的线
for
(
let
i
=
0
;
i
<=
h_l
;
i
++
)
{
pen
.
beginPath
();
pen
.
moveTo
(
0
,
i
*
step
);
pen
.
lineTo
(
w
,
i
*
step
);
pen
.
stroke
();
}
// 竖着的线
for
(
let
i
=
0
;
i
<=
w_l
;
i
++
)
{
pen
.
beginPath
();
pen
.
moveTo
(
i
*
step
,
0
);
pen
.
lineTo
(
i
*
step
,
h
);
pen
.
stroke
();
}
}
function
getAbsolutePosition
()
{
const
layerList
:
any
[]
=
state
.
stage
.
children
;
// 图层List
for
(
const
layerItem
of
layerList
)
{
dosomethingWithLayer
(
layerItem
);
}
}
/**
* Class: Layer
* https://konvajs.org/api/Konva.Layer.html
* 图层的构造函数。图层绑定到它们自己的canvas元素,并用于包含组或图形。
*/
function
dosomethingWithLayer
(
layer
:
any
)
{
// 获取图层位置
// const position = layer.absolutePosition();
// 设置图层位置
// layer.absolutePosition({
// x: 5,
// y: 10,
// });
const
groupList
:
any
[]
=
layer
.
children
;
// 组List
for
(
const
groupItem
of
groupList
)
{
dosomethingWithGroup
(
groupItem
);
}
}
/**
* Class: Group
* https://konvajs.org/api/Konva.Group.html
* 组的构造函数。组用于包含图形或其它组。
*/
function
dosomethingWithGroup
(
group
:
any
)
{
// 获取组的位置
// const position = group.absolutePosition();
// const diagramList: any[] = group.children;
const
diagramList
=
group
.
getChildren
();
// const clientRect = group.getClientRect();
for
(
const
diagramItem
of
diagramList
)
{
dosomethingWithDiagram
(
diagramItem
);
}
}
function
dosomethingWithDiagram
(
diagram
:
any
)
{
const
attrs
=
diagram
.
getAttrs
();
console
.
log
(
'attrs'
,
attrs
);
}
</
script
>
<
template
>
<div
class=
"konva-main-page container-height center"
>
<div>
<q-btn
color=
"primary"
label=
"获取坐标位置"
@
click=
"getAbsolutePosition"
/>
</div>
<div
class=
"canvas-box"
:style=
"
{
width: stageSize.width + 'px',
height: stageSize.height + 'px',
}"
>
<canvas
id=
"canvas-grid"
:width=
"stageSize.width"
:height=
"stageSize.height"
style=
"position: absolute"
></canvas>
<div
id=
"stage-container"
></div>
</div>
</div>
</
template
>
<
style
lang=
"scss"
scoped
>
.canvas-box
{
box-sizing
:
border-box
;
border
:
1px
solid
#000
;
position
:
relative
;
}
</
style
>
src/modules/vue-konva-line/IndexPageTest1.vue
0 → 100644
View file @
15a7620e
<!--
* @FileDescription: vue-konva
* @Author: hcy
* @Date: 2023-03-29
-->
<
script
setup
lang=
"ts"
>
import
{
reactive
,
onMounted
}
from
'vue'
;
import
Konva
from
'konva'
;
import
type
{
Points
}
from
'./types'
;
const
state
=
reactive
({
stage
:
null
as
any
,
shapePath
:
[
{
name
:
'test1'
,
color
:
'pink'
,
path
:
[
{
x
:
100
,
y
:
100
},
{
x
:
200
,
y
:
100
},
{
x
:
200
,
y
:
200
},
{
x
:
0
,
y
:
300
},
],
},
]
as
any
[],
});
const
stageSize
=
reactive
({
width
:
1200
,
// 画布宽度
height
:
800
,
// 画布高度
gridGap
:
100
,
// 网格的间距
});
onMounted
(()
=>
{
drawGrid
();
handleData
();
initKonva
();
});
function
handleData
()
{
const
list
=
state
.
shapePath
;
for
(
const
iter
of
list
)
{
iter
.
linePath
=
[];
const
path
:
Points
[]
=
iter
.
path
||
[];
for
(
const
ite
of
path
)
{
iter
.
linePath
.
push
(
ite
.
x
);
iter
.
linePath
.
push
(
ite
.
y
);
}
}
}
function
initKonva
()
{
const
list
=
state
.
shapePath
;
console
.
log
(
list
);
// 创建根节点(舞台)
state
.
stage
=
new
Konva
.
Stage
({
container
:
'stage-container'
,
width
:
stageSize
.
width
,
height
:
stageSize
.
height
,
});
// 创建图层
const
layer
=
new
Konva
.
Layer
({
name
:
'my-layer'
,
});
/*
* 创建一个组,
* 将用于组合多个简单的形状。
* 变换组将变换所有的简单形状作为一个单位在一起
*/
const
group
=
new
Konva
.
Group
({
name
:
'my-group'
,
draggable
:
true
,
});
// 创建图形
// points: 点坐标的平面阵列。你应该定义它们为[x1, y1, x2, y2, x3, y3]。
const
poly
=
new
Konva
.
Line
({
name
:
'my-poly'
,
points
:
[
100
,
100
,
300
,
200
,
500
,
200
,
500
,
300
,
400
,
400
,
100
,
400
],
fill
:
'#00D2FF'
,
// 填充颜色
stroke
:
'black'
,
// 边框颜色
strokeWidth
:
0
,
// 边框宽度
closed
:
true
,
// 是否闭合路径
});
// const line = new Konva.Line({
// name: 'my-line',
// x: 0,
// y: 0,
// points: [300, 100, 500, 100, 500, 200, 300, 200],
// stroke: 'red',
// closed: true,
// });
// 将图形添加到组
group
.
add
(
poly
);
// group.add(line);
// 将组添加到图层中
layer
.
add
(
group
);
// 将图层添加到根节点上
state
.
stage
.
add
(
layer
);
}
/**
* 绘制网格线
*/
function
drawGrid
()
{
let
canvas
:
any
=
document
.
getElementById
(
'canvas-grid'
);
let
pen
=
canvas
.
getContext
(
'2d'
);
// 绘制网格
const
step
=
stageSize
.
gridGap
;
const
h
=
stageSize
.
height
;
const
w
=
stageSize
.
width
;
const
w_l
=
w
/
step
;
const
h_l
=
h
/
step
;
// 横着的线
for
(
let
i
=
0
;
i
<=
h_l
;
i
++
)
{
pen
.
beginPath
();
pen
.
moveTo
(
0
,
i
*
step
);
pen
.
lineTo
(
w
,
i
*
step
);
pen
.
stroke
();
}
// 竖着的线
for
(
let
i
=
0
;
i
<=
w_l
;
i
++
)
{
pen
.
beginPath
();
pen
.
moveTo
(
i
*
step
,
0
);
pen
.
lineTo
(
i
*
step
,
h
);
pen
.
stroke
();
}
}
function
getAbsolutePosition
()
{
const
layerList
:
any
[]
=
state
.
stage
.
children
;
// 图层List
for
(
const
layerItem
of
layerList
)
{
dosomethingWithLayer
(
layerItem
);
}
}
/**
* Class: Layer
* https://konvajs.org/api/Konva.Layer.html
* 图层的构造函数。图层绑定到它们自己的canvas元素,并用于包含组或图形。
*/
function
dosomethingWithLayer
(
layer
:
any
)
{
// 获取图层位置
// const position = layer.absolutePosition();
// 设置图层位置
// layer.absolutePosition({
// x: 5,
// y: 10,
// });
const
groupList
:
any
[]
=
layer
.
children
;
// 组List
for
(
const
groupItem
of
groupList
)
{
dosomethingWithGroup
(
groupItem
);
}
}
/**
* Class: Group
* https://konvajs.org/api/Konva.Group.html
* 组的构造函数。组用于包含图形或其它组。
*/
function
dosomethingWithGroup
(
group
:
any
)
{
// 获取组的位置
// const position = group.absolutePosition();
// const diagramList: any[] = group.children;
const
diagramList
=
group
.
getChildren
();
// const clientRect = group.getClientRect();
for
(
const
diagramItem
of
diagramList
)
{
dosomethingWithDiagram
(
diagramItem
);
}
}
function
dosomethingWithDiagram
(
diagram
:
any
)
{
const
attrs
=
diagram
.
getAttrs
();
console
.
log
(
'attrs'
,
attrs
);
}
</
script
>
<
template
>
<div
class=
"konva-main-page container-height center"
>
<div>
<q-btn
color=
"primary"
label=
"获取坐标位置"
@
click=
"getAbsolutePosition"
/>
</div>
<div
class=
"canvas-box"
:style=
"
{
width: stageSize.width + 'px',
height: stageSize.height + 'px',
}"
>
<canvas
id=
"canvas-grid"
:width=
"stageSize.width"
:height=
"stageSize.height"
style=
"position: absolute"
></canvas>
<div
id=
"stage-container"
></div>
</div>
</div>
</
template
>
<
style
lang=
"scss"
scoped
>
.canvas-box
{
box-sizing
:
border-box
;
border
:
1px
solid
#000
;
position
:
relative
;
}
</
style
>
src/modules/vue-konva-line/route.ts
0 → 100644
View file @
15a7620e
export
default
[
{
path
:
'vue-konva-line'
,
name
:
'VUE_KONVA_LINE'
,
component
:
()
=>
import
(
'./IndexPage.vue'
),
meta
:
{
title
:
'Line-多边形'
,
permission
:
[
'*'
],
keepalive
:
true
,
},
},
];
src/modules/vue-konva-line/types.ts
0 → 100644
View file @
15a7620e
export
interface
Points
{
x
:
number
;
y
:
number
;
[
proppName
:
string
]:
any
;
}
src/modules/vue-konva/IndexPage2.vue
View file @
15a7620e
...
...
@@ -26,10 +26,10 @@ const state = reactive({
color
:
'#00D2FF'
,
selected
:
true
,
path
:
[
{
x
:
100
,
y
:
100
,
gap
:
10
0
},
{
x
:
200
,
y
:
100
,
gap
:
10
0
},
{
x
:
200
,
y
:
200
,
gap
:
10
0
},
{
x
:
0
,
y
:
300
,
gap
:
10
0
},
{
x
:
100
,
y
:
100
,
gap
:
10
},
{
x
:
200
,
y
:
100
,
gap
:
2
0
},
{
x
:
200
,
y
:
200
,
gap
:
3
0
},
{
x
:
0
,
y
:
300
,
gap
:
4
0
},
],
},
// {
...
...
src/modules/vue-konva/TextPage.vue
0 → 100644
View file @
15a7620e
<!--
* @FileDescription: vue-konva
* @Author: hcy
* @Date: 2023-03-29
-->
<
script
setup
lang=
"ts"
>
import
{
reactive
,
onMounted
}
from
'vue'
;
// import Konva from 'konva';
// const state = reactive({
// stage: null as any,
// layer: null as any,
// group: new Map(),
// myMap: new Map(),
// // shape: null as any,
// // boundingBox: null as any,
// // box: null as any,
// shapePath: [
// {
// name: 'test1',
// color: 'pink',
// selected: true,
// path: [
// { x: 100, y: 100 },
// { x: 200, y: 100 },
// { x: 200, y: 200 },
// { x: 0, y: 300 },
// ],
// },
// ] as any[],
// });
const
stageSize
=
reactive
({
width
:
1200
,
// 画布宽度
height
:
800
,
// 画布高度
gridGap
:
100
,
// 网格的间距
});
onMounted
(()
=>
{
drawGrid
();
});
/**
* 绘制网格线
*/
function
drawGrid
()
{
let
canvas
:
any
=
document
.
getElementById
(
'canvas-grid'
);
let
pen
=
canvas
.
getContext
(
'2d'
);
// 绘制网格
const
step
=
stageSize
.
gridGap
;
const
h
=
stageSize
.
height
;
const
w
=
stageSize
.
width
;
const
w_l
=
w
/
step
;
const
h_l
=
h
/
step
;
// 横着的线
for
(
let
i
=
0
;
i
<=
h_l
;
i
++
)
{
pen
.
beginPath
();
pen
.
moveTo
(
0
,
i
*
step
);
pen
.
lineTo
(
w
,
i
*
step
);
pen
.
stroke
();
}
// 竖着的线
for
(
let
i
=
0
;
i
<=
w_l
;
i
++
)
{
pen
.
beginPath
();
pen
.
moveTo
(
i
*
step
,
0
);
pen
.
lineTo
(
i
*
step
,
h
);
pen
.
stroke
();
}
}
</
script
>
<
template
>
<div
class=
"konva-main-page container-height center"
>
<div
class=
"canvas-box"
:style=
"
{
width: stageSize.width + 'px',
height: stageSize.height + 'px',
}"
>
<canvas
id=
"canvas-grid"
:width=
"stageSize.width"
:height=
"stageSize.height"
style=
"position: absolute"
></canvas>
<div
id=
"stage-container"
></div>
</div>
</div>
</
template
>
<
style
lang=
"scss"
scoped
>
.canvas-box
{
box-sizing
:
border-box
;
border
:
1px
solid
#000
;
position
:
relative
;
}
</
style
>
src/modules/vue-konva/utils.ts
View file @
15a7620e
...
...
@@ -3,7 +3,7 @@
* 源码Gitee:https://gitee.com/dhzx/js-polygon-algorithm
*/
import
{
toRadian
,
Vector
}
from
'src/modules/vector/utils'
;
//
import { toRadian, Vector } from 'src/modules/vector/utils';
interface
Point
{
x
:
number
;
...
...
@@ -177,6 +177,7 @@ export function scalePolygon(points: Point[]) {
const
ps
=
points
;
const
len
=
ps
.
length
;
const
polygon
:
any
[]
=
[];
const
is_clockwise
=
isClockwise
(
ps
);
for
(
let
i
=
0
;
i
<
len
;
i
++
)
{
const
pointP
=
ps
[
i
];
// 当前点
...
...
@@ -184,16 +185,10 @@ export function scalePolygon(points: Point[]) {
const
pointP2
=
ps
[
i
===
0
?
len
-
1
:
i
-
1
];
// 前一个点
// 边距
const
extraNum
=
pointP
.
gap
||
1
0
;
const
extraNum
=
2
0
;
// 通过顺时针判断取正值还是负值
const
is_clockwise
=
isClockwise
(
ps
);
const
extra0
=
is_clockwise
?
-
extraNum
:
extraNum
;
// const l1Num = pointP.gap || 10;
// const l2Num = pointP2.gap || 10;
// const L1 = is_clockwise ? -l1Num : l1Num;
// const L2 = is_clockwise ? -l2Num : l2Num;
// 向量PP1
const
vectorX1
=
pointP1
.
x
-
pointP
.
x
;
// 向量PP1 横坐标
const
vectorY1
=
pointP1
.
y
-
pointP
.
y
;
// 向量PP1 纵坐标
...
...
@@ -208,6 +203,10 @@ export function scalePolygon(points: Point[]) {
let
vectorUnitX2
=
vectorX2
/
n2
;
// 向量单位化 横坐标
let
vectorUnitY2
=
vectorY2
/
n2
;
// 向量单位化 纵坐标
const
vectorUnit1
=
{
x
:
vectorUnitX1
,
y
:
vectorUnitY1
};
const
vectorUnit2
=
{
x
:
vectorUnitX2
,
y
:
vectorUnitY2
};
console
.
log
(
'PP1的单位向量'
,
vectorUnit1
,
'PP2的单位向量'
,
vectorUnit2
);
// PQ距离
const
vectorLen
=
extra0
/
...
...
@@ -215,11 +214,6 @@ export function scalePolygon(points: Point[]) {
(
1
-
(
vectorUnitX1
*
vectorUnitX2
+
vectorUnitY1
*
vectorUnitY2
))
/
2
);
const
angle
=
new
Vector
(
pointP
,
pointP1
).
dotProduct
(
pointP2
);
const
hudu
=
toRadian
(
angle
);
const
c
=
Math
.
cos
(
hudu
);
console
.
log
(
'PQ距离'
,
vectorLen
,
'角度'
,
c
);
// 根据向量的叉乘积来判断角是凹角还是凸角
if
(
vectorX1
*
vectorY2
+
-
1
*
vectorY1
*
vectorX2
<
0
)
{
vectorUnitX2
*=
-
1
;
...
...
src/router/routes.ts
View file @
15a7620e
...
...
@@ -6,6 +6,7 @@ import AMIS from '../modules/amis/route';
import
VUE_STUDY
from
'../modules/vue-study/route'
;
import
VUE_KONVA
from
'../modules/vue-konva/route'
;
import
VECTOR
from
'../modules/vector/route'
;
import
VUE_KONVA_LINE
from
'../modules/vue-konva-line/route'
;
const
routes
:
RouteRecordRaw
[]
=
[
{
...
...
@@ -135,6 +136,7 @@ const routes: RouteRecordRaw[] = [
...
VUE_STUDY
,
...
VUE_KONVA
,
...
VECTOR
,
...
VUE_KONVA_LINE
,
],
},
],
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment