Commit 15a7620e authored by hucy's avatar hucy

fix:不重要的提交

parent b0925c4c
......@@ -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,
......
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;
}
......@@ -132,9 +132,24 @@ export const MenuList = [
{
title: 'Vue Konva',
caption: '前端Canvas库-Konva',
icon: require('./menuListIcons/amis.svg'),
link: '/vue-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: '向量',
......
......@@ -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',
......
......@@ -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();
......
......@@ -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') {
......
......@@ -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,
};
}
}
/**
......
<!--
* @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>
<!--
* @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>
export default [
{
path: 'vue-konva-line',
name: 'VUE_KONVA_LINE',
component: () => import('./IndexPage.vue'),
meta: {
title: 'Line-多边形',
permission: ['*'],
keepalive: true,
},
},
];
export interface Points {
x: number;
y: number;
[proppName: string]: any;
}
......@@ -26,10 +26,10 @@ const state = reactive({
color: '#00D2FF',
selected: true,
path: [
{ x: 100, y: 100, gap: 100 },
{ x: 200, y: 100, gap: 100 },
{ x: 200, y: 200, gap: 100 },
{ x: 0, y: 300, gap: 100 },
{ x: 100, y: 100, gap: 10 },
{ x: 200, y: 100, gap: 20 },
{ x: 200, y: 200, gap: 30 },
{ x: 0, y: 300, gap: 40 },
],
},
// {
......
<!--
* @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>
......@@ -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 || 10;
const extraNum = 20;
// 通过顺时针判断取正值还是负值
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;
......
......@@ -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,
],
},
],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment