'构建知识图谱'

main
Your Name 9 months ago
parent 67d4922dbf
commit 306237ab56
  1. 3
      ant-design-vue-jeecg/.env.development
  2. 14094
      ant-design-vue-jeecg/package-lock.json
  3. 47
      ant-design-vue-jeecg/package.json
  4. 13499
      ant-design-vue-jeecg/pnpm-lock.yaml
  5. 1
      ant-design-vue-jeecg/public/index.html
  6. 5
      ant-design-vue-jeecg/src/config/router.config.js
  7. 152
      ant-design-vue-jeecg/src/views/seknowgroup/KnowledgeGraph copy.vue
  8. 152
      ant-design-vue-jeecg/src/views/seknowgroup/KnowledgeGraph.vue
  9. 80
      ant-design-vue-jeecg/src/views/seknowgroup/SeKnowAtlasList.vue
  10. 211
      ant-design-vue-jeecg/src/views/seknowgroup/SeKnowGroupList.vue
  11. 105
      ant-design-vue-jeecg/src/views/seknowgroup/atlas/js/bg.js
  12. 2
      ant-design-vue-jeecg/src/views/seknowgroup/atlas/js/main.js
  13. 272
      ant-design-vue-jeecg/src/views/seknowgroup/atlas/js/main1.js
  14. 5
      ant-design-vue-jeecg/src/views/seknowgroup/atlas/js/vendor.js
  15. 5
      ant-design-vue-jeecg/src/views/seknowgroup/atlas/js/vendor1.js
  16. 267
      ant-design-vue-jeecg/src/views/seknowgroup/dataJSON.js
  17. 109
      ant-design-vue-jeecg/src/views/seknowgroup/modules/SeKnowGroupForm.vue
  18. 60
      ant-design-vue-jeecg/src/views/seknowgroup/modules/SeKnowGroupModal.vue
  19. 84
      ant-design-vue-jeecg/src/views/seknowgroup/modules/SeKnowGroupModal__Style#Drawer.vue
  20. 468
      ant-design-vue-jeecg/src/views/seknowgroup/spritetext.js
  21. 3637
      ant-design-vue-jeecg/yarn.lock

@ -1,4 +1,5 @@
NODE_ENV=development NODE_ENV=development
VUE_APP_API_BASE_URL=http://localhost:8081/jeecg-boot # VUE_APP_API_BASE_URL=http://localhost:8081/jeecg-boot
VUE_APP_API_BASE_URL=http://10.115.112.52:8081/jeecg-boot
VUE_APP_CAS_BASE_URL=http://cas.example.org:8443/cas VUE_APP_CAS_BASE_URL=http://cas.example.org:8443/cas
VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview

File diff suppressed because it is too large Load Diff

@ -10,42 +10,44 @@
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint"
}, },
"dependencies": { "dependencies": {
"element-ui": "^2.15.6", "3d-force-graph": "^1.73.3",
"ant-design-vue": "^1.7.2",
"@jeecg/antd-online-mini": "2.4.5-RC",
"@antv/data-set": "^0.11.4", "@antv/data-set": "^0.11.4",
"viser-vue": "^2.4.8", "@jeecg/antd-online-mini": "2.4.5-RC",
"@tinymce/tinymce-vue": "^2.1.0",
"@toast-ui/editor": "^2.1.2",
"ant-design-vue": "^1.7.2",
"area-data": "^5.0.6",
"axios": "^0.18.0", "axios": "^0.18.0",
"clipboard": "^2.0.4",
"codemirror": "^5.46.0",
"cron-parser": "^2.10.0",
"dayjs": "^1.8.0", "dayjs": "^1.8.0",
"dom-align": "1.12.0",
"element-ui": "^2.15.6",
"enquire.js": "^2.1.6", "enquire.js": "^2.1.6",
"js-cookie": "^2.2.0", "js-cookie": "^2.2.0",
"lodash.get": "^4.4.2", "lodash.get": "^4.4.2",
"lodash.pick": "^4.4.0", "lodash.pick": "^4.4.0",
"md5": "^2.2.1", "md5": "^2.2.1",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"three": "0.163.0",
"tinymce": "^5.3.2",
"viser-vue": "^2.4.8",
"vue": "^2.6.10", "vue": "^2.6.10",
"vue-area-linkage": "^5.1.0",
"vue-cropper": "^0.5.4", "vue-cropper": "^0.5.4",
"vue-i18n": "^8.7.0", "vue-i18n": "^8.7.0",
"vue-loader": "^15.7.0", "vue-loader": "^15.7.0",
"vue-ls": "^3.2.0", "vue-ls": "^3.2.0",
"vue-router": "^3.0.1",
"vuex": "^3.1.0",
"vue-print-nb-jeecg": "^1.0.9",
"clipboard": "^2.0.4",
"vue-photo-preview": "^1.1.3", "vue-photo-preview": "^1.1.3",
"vue-print-nb-jeecg": "^1.0.9",
"vue-router": "^3.0.1",
"vue-splitpane": "^1.0.4", "vue-splitpane": "^1.0.4",
"vuedraggable": "^2.20.0", "vuedraggable": "^2.20.0",
"codemirror": "^5.46.0", "vuex": "^3.1.0",
"@tinymce/tinymce-vue": "^2.1.0",
"tinymce": "^5.3.2",
"@toast-ui/editor": "^2.1.2",
"vue-area-linkage": "^5.1.0",
"area-data": "^5.0.6",
"dom-align": "1.12.0",
"xe-utils": "2.4.8",
"vxe-table": "2.9.13", "vxe-table": "2.9.13",
"vxe-table-plugin-antd": "1.8.10", "vxe-table-plugin-antd": "1.8.10",
"cron-parser": "^2.10.0" "xe-utils": "2.4.8"
}, },
"devDependencies": { "devDependencies": {
"@babel/polyfill": "^7.2.5", "@babel/polyfill": "^7.2.5",
@ -54,13 +56,13 @@
"@vue/cli-service": "^3.3.0", "@vue/cli-service": "^3.3.0",
"@vue/eslint-config-standard": "^4.0.0", "@vue/eslint-config-standard": "^4.0.0",
"babel-eslint": "7.2.3", "babel-eslint": "7.2.3",
"compression-webpack-plugin": "^3.1.0",
"eslint": "^5.16.0", "eslint": "^5.16.0",
"eslint-plugin-vue": "^5.1.0", "eslint-plugin-vue": "^5.1.0",
"html-webpack-plugin": "^4.2.0",
"less": "^3.9.0", "less": "^3.9.0",
"less-loader": "^4.1.0", "less-loader": "^4.1.0",
"vue-template-compiler": "^2.6.10", "vue-template-compiler": "^2.6.10"
"html-webpack-plugin": "^4.2.0",
"compression-webpack-plugin": "^3.1.0"
}, },
"eslintConfig": { "eslintConfig": {
"root": true, "root": true,
@ -98,7 +100,10 @@
"vue/html-closing-bracket-newline": 0, "vue/html-closing-bracket-newline": 0,
"vue/no-parsing-error": 0, "vue/no-parsing-error": 0,
"no-tabs": 0, "no-tabs": 0,
"indent": ["off", 2], "indent": [
"off",
2
],
"no-console": 0, "no-console": 0,
"space-before-function-paren": 0 "space-before-function-paren": 0
} }

File diff suppressed because it is too large Load Diff

@ -8,6 +8,7 @@
<title>JeecgBoot 企业级低代码平台</title> <title>JeecgBoot 企业级低代码平台</title>
<link rel="icon" href="<%= BASE_URL %>logo.png"> <link rel="icon" href="<%= BASE_URL %>logo.png">
<script src="<%= BASE_URL %>cdn/babel-polyfill/polyfill_7_2_5.js"></script> <script src="<%= BASE_URL %>cdn/babel-polyfill/polyfill_7_2_5.js"></script>
<script src="https://unpkg.com/3d-force-graph@1.73.3/dist/3d-force-graph.min.js"></script>
<style> <style>
html, html,
body, body,

@ -322,6 +322,11 @@ export const constantRouterMap = [
}, },
] ]
}, },
{
path:'/atlas',
name:'Atlas',
component: () => import('@/views/seknowgroup/KnowledgeGraph')
},
// { // {
// path: '/', // path: '/',

@ -0,0 +1,152 @@
<template>
<div id="3d-graph"></div>
</template>
<script>
// import ForceGraph3D from '3d-force-graph'
import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js'
import SpriteText from './spritetext.js'
import data from './dataJSON'
export default {
name: 'ThreeDForceGraph',
props: {
width: {
type: Number,
default: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
},
height: {
type: Number,
default: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
}
},
data() {
return {
Graph: {},
data: {
nodes: [
{ id: 'node1', label: '计算机' },
{ id: 'node2', label: 'java' },
{ id: 'node3', label: '前端' },
{ id: 'node4', label: '数据库' },
{ id: 'node5', label: 'mysql' }
],
edges: [
{ source: 'node1', target: 'node2', label: '' },
{ source: 'node1', target: 'node3', label: '' },
{ source: 'node1', target: 'node4', label: '' },
{ source: 'node4', target: 'node5', label: '' }
]
}
}
},
mounted() {
this.initGraph()
},
methods: {
initGraph() {
let dom = null
this.Graph = ForceGraph3D({
extraRenderers: [new CSS2DRenderer()]
})(document.getElementById('3d-graph'))
.graphData(JSON.parse(data))
// .nodeAutoColorBy('group')
.nodeThreeObject(node => {
const nodeEl = document.createElement('div')
nodeEl.textContent = node.label
nodeEl.style.color = '#333333'
nodeEl.style.borderRadius = '50%'
return new CSS2DObject(nodeEl)
})
.linkLabel(link => link.label) //
.linkWidth(0.8)
.linkHoverPrecision(0.5) //
.linkColor(() => '#dd92fd') // 线
.backgroundColor('#f5f6fd')
.width(window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth)
.height(window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight)
.linkThreeObjectExtend(true)
.nodeColor(node => {
return node.color
})
.nodeRelSize(7) // 4
.nodeResolution(20)
.linkDirectionalArrowLength(3) // 线3
.linkDirectionalArrowRelPos(1) // 线线
.nodeThreeObjectExtend(true)
.onNodeClick(node => {
// Aim at node from outside it
//
const targetDistance = 200 //
//
const distRatio = 1 + targetDistance / Math.hypot(node.x, node.y, node.z)
const newPos = {
x: node.x * distRatio,
y: node.y * distRatio,
z: node.z * distRatio
}
//
if (node.x === 0 && node.y === 0 && node.z === 0) {
newPos.z = targetDistance // z
}
//
//@ts-ignore
this.Graph.cameraPosition(
newPos, //
node, //
3000 //
)
//
//@ts-ignore
const graphData = this.Graph.graphData()
// 线
graphData.links.forEach(link => {
if (link.source.id === node.id || link.target.id === node.id) {
this.setLabel()
// 线
// link.color = '#FF0000' // 线
//@ts-ignore
this.Graph.linkColor(item => {
if (item.source.id === node.id || item.target.id === node.id) {
return 'red'
} else {
return '#dd92fd'
}
})
} else {
// Graph.linkColor(() => '#a4c7fe') // 线
}
})
//
//@ts-ignore
Graph.graphData(graphData)
})
dom = document.querySelector('canvas')
},
setLabel() {
this.Graph.linkThreeObject(link => {
// extend link with text sprite
const sprite = new SpriteText(`${link.label}`)
sprite.color = '#ccc'
sprite.textHeight = 1.5
return sprite
})
this.Graph.linkPositionUpdate((sprite, { start, end }) => {
const middlePos = Object.assign(
...['x', 'y', 'z'].map(c => ({
[c]: start[c] + (end[c] - start[c]) / 2 // calc middle point
}))
)
Object.assign(sprite.position, middlePos)
})
this.Graph.d3Force('charge').strength(-120)
}
}
}
</script>

@ -0,0 +1,152 @@
<template>
<div id="3d-graph"></div>
</template>
<script>
// import ForceGraph3D from '3d-force-graph'
import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js'
import SpriteText from './spritetext.js'
import data from './dataJSON'
export default {
name: 'ThreeDForceGraph',
props: {
width: {
type: Number,
default: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
},
height: {
type: Number,
default: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
}
},
data() {
return {
Graph: {},
data: {
nodes: [
{ id: 'node1', label: '计算机' },
{ id: 'node2', label: 'java' },
{ id: 'node3', label: '前端' },
{ id: 'node4', label: '数据库' },
{ id: 'node5', label: 'mysql' }
],
edges: [
{ source: 'node1', target: 'node2', label: '' },
{ source: 'node1', target: 'node3', label: '' },
{ source: 'node1', target: 'node4', label: '' },
{ source: 'node4', target: 'node5', label: '' }
]
}
}
},
mounted() {
this.initGraph()
},
methods: {
initGraph() {
let dom = null
this.Graph = ForceGraph3D({
extraRenderers: [new CSS2DRenderer()]
})(document.getElementById('3d-graph'))
.graphData(JSON.parse(data))
// .nodeAutoColorBy('group')
.nodeThreeObject(node => {
const nodeEl = document.createElement('div')
nodeEl.textContent = node.label
nodeEl.style.color = '#333333'
nodeEl.style.borderRadius = '50%'
return new CSS2DObject(nodeEl)
})
.linkLabel(link => link.label) //
.linkWidth(0.8)
.linkHoverPrecision(0.5) //
.linkColor(() => '#dd92fd') // 线
.backgroundColor('#f5f6fd')
.width(window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth)
.height(window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight)
.linkThreeObjectExtend(true)
.nodeColor(node => {
return node.color
})
.nodeRelSize(7) // 4
.nodeResolution(20)
.linkDirectionalArrowLength(3) // 线3
.linkDirectionalArrowRelPos(1) // 线线
.nodeThreeObjectExtend(true)
.onNodeClick(node => {
// Aim at node from outside it
//
const targetDistance = 200 //
//
const distRatio = 1 + targetDistance / Math.hypot(node.x, node.y, node.z)
const newPos = {
x: node.x * distRatio,
y: node.y * distRatio,
z: node.z * distRatio
}
//
if (node.x === 0 && node.y === 0 && node.z === 0) {
newPos.z = targetDistance // z
}
//
//@ts-ignore
this.Graph.cameraPosition(
newPos, //
node, //
3000 //
)
//
//@ts-ignore
const graphData = this.Graph.graphData()
// 线
graphData.links.forEach(link => {
if (link.source.id === node.id || link.target.id === node.id) {
this.setLabel()
// 线
// link.color = '#FF0000' // 线
//@ts-ignore
this.Graph.linkColor(item => {
if (item.source.id === node.id || item.target.id === node.id) {
return 'red'
} else {
return '#dd92fd'
}
})
} else {
// Graph.linkColor(() => '#a4c7fe') // 线
}
})
//
//@ts-ignore
Graph.graphData(graphData)
})
dom = document.querySelector('canvas')
},
setLabel() {
this.Graph.linkThreeObject(link => {
// extend link with text sprite
const sprite = new SpriteText(`${link.label}`)
sprite.color = '#ccc'
sprite.textHeight = 1.5
return sprite
})
this.Graph.linkPositionUpdate((sprite, { start, end }) => {
const middlePos = Object.assign(
...['x', 'y', 'z'].map(c => ({
[c]: start[c] + (end[c] - start[c]) / 2 // calc middle point
}))
)
Object.assign(sprite.position, middlePos)
})
this.Graph.d3Force('charge').strength(-120)
}
}
}
</script>

@ -0,0 +1,80 @@
<template>
</template>
<script>
import { threeMainFunction } from "./atlas/js/main1.js";
import { threeVendorFunction } from "./atlas/js/vendor1.js";
export default {
name: 'SeKnowGroupList',
mixins:[ ],
components: {
threeMainFunction,
threeVendorFunction
},
mounted() {
threeVendorFunction;
threeMainFunction;
},
data () {
return {
description: '知识图谱表管理页面',
dictOptions:{},
loadRouteType:false,
parameterId:"",
}
},
created() {
this.loadParameter();
this.initLoad();
// console.log(document.getElementById('app').style.height)
},
computed: {
},
methods: {
initDictConfig(){
},
initLoad(){
let that = this;
this.timer = setInterval(function () {
that.newDate = new Date().toLocaleString();
});
let canvas = document.body.querySelector("canvas");
canvas.style.position = "absolute";
canvas.style.top = "0";
},
//
loadParameter() {
if(this.loadRouteType==false)
{
// this.id = this.$route.query.name
// console.log(id);
this.loadRouteType=true;
}
},
}
}
</script>
<style scoped>
html,
body,
#app {
height: 0px;
margin: 0px;
padding: 0px;
}
</style>

@ -0,0 +1,211 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
</a-row>
</a-form>
</div>
<!-- 查询区域-END -->
<!-- 操作按钮区域 -->
<!-- <div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button type="primary" icon="download" @click="handleExportXls('知识图谱表')">导出</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
</a-upload>
&lt;!&ndash; 高级查询区域 &ndash;&gt;
<j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
</a-dropdown>
</div>-->
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table
ref="table"
size="middle"
:scroll="{x:true}"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
class="j-table-force-nowrap"
@change="handleTableChange">
<template slot="htmlSlot" slot-scope="text">
<div v-html="text"></div>
</template>
<template slot="imgSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
<img v-else :src="getImgView(text)" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
</template>
<template slot="fileSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
<a-button
v-else
:ghost="true"
type="primary"
icon="download"
size="small"
@click="downloadFile(text)">
下载
</a-button>
</template>
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" />
<a @click="zsAtlsa(record)">知识图谱</a>
<a-divider type="vertical" />
<a @click="updatetp(record)">更新图谱</a>
<a-divider type="vertical" />
<a-dropdown>
<a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
<a-menu slot="overlay">
<a-menu-item>
<a @click="handleDetail(record)">详情</a>
</a-menu-item>
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
</a-table>
</div>
<se-know-group-modal ref="modalForm" @ok="modalFormOk"></se-know-group-modal>
</a-card>
</template>
<script>
import '@/assets/less/TableExpand.less'
import { mixinDevice } from '@/utils/mixin'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import SeKnowGroupModal from './modules/SeKnowGroupModal'
import { getAction } from '@api/manage'
export default {
name: 'SeKnowGroupList',
mixins:[JeecgListMixin, mixinDevice],
components: {
SeKnowGroupModal,
},
data () {
return {
description: '知识图谱表管理页面',
//
columns: [
{
title: '#',
dataIndex: '',
key:'rowIndex',
width:60,
align:"center",
customRender:function (t,r,index) {
return parseInt(index)+1;
}
},
{
title:'图谱名称',
align:"center",
dataIndex: 'name'
},
{
title:'中心知识点',
align:"center",
dataIndex: 'knowPoint'
},
{
title: '操作',
dataIndex: 'action',
align:"center",
fixed:"right",
width:147,
scopedSlots: { customRender: 'action' }
}
],
url: {
list: "/seknowgroup/seKnowGroup/list",
delete: "/seknowgroup/seKnowGroup/delete",
deleteBatch: "/seknowgroup/seKnowGroup/deleteBatch",
exportXlsUrl: "/seknowgroup/seKnowGroup/exportXls",
importExcelUrl: "seknowgroup/seKnowGroup/importExcel",
updatetp: "seknowgroup/seKnowGroup/updatetp",
},
dictOptions:{},
superFieldList:[],
queryParams:{
id:'',
},
}
},
created() {
this.getSuperFieldList();
},
computed: {
importExcelUrl: function(){
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
},
},
methods: {
zsAtlsa(record) {
let routeData = this.$router.resolve({ path: '/atlas', query: { id: record.id } });
window.open(routeData.href, '_blank');
},
updatetp(record) {
getAction(this.url.updatetp, { cid: record.courseid,id: record.id }).then((res) => {
if (res.success) {
this.$message.success(res.message)
this.loadData()
} else {
this.$message.warning(res.message)
}
})
},
initDictConfig(){
},
getSuperFieldList(){
let fieldList=[];
fieldList.push({type:'string',value:'name',text:'图谱名称',dictCode:''})
fieldList.push({type:'string',value:'knowPoint',text:'中心知识点',dictCode:'se_konw,name,id'})
this.superFieldList = fieldList
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>

@ -0,0 +1,105 @@
//宇宙特效
"use strict";
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
w = canvas.width = window.innerWidth,
h = canvas.height = window.innerHeight,
hue = 217,
stars = [],
count = 0,
maxStars = 1300;//星星数量
var canvas2 = document.createElement('canvas'),
ctx2 = canvas2.getContext('2d');
canvas2.width = 100;
canvas2.height = 100;
var half = canvas2.width / 2,
gradient2 = ctx2.createRadialGradient(half, half, 0, half, half, half);
gradient2.addColorStop(0.025, '#CCC');
gradient2.addColorStop(0.1, 'hsl(' + hue + ', 61%, 33%)');
gradient2.addColorStop(0.25, 'hsl(' + hue + ', 64%, 6%)');
gradient2.addColorStop(1, 'transparent');
ctx2.fillStyle = gradient2;
ctx2.beginPath();
ctx2.arc(half, half, half, 0, Math.PI * 2);
ctx2.fill();
// End cache
function random(min, max) {
if (arguments.length < 2) {
max = min;
min = 0;
}
if (min > max) {
var hold = max;
max = min;
min = hold;
}
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function maxOrbit(x, y) {
var max = Math.max(x, y),
diameter = Math.round(Math.sqrt(max * max + max * max));
return diameter / 2;
//星星移动范围,值越大范围越小,
}
var Star = function() {
this.orbitRadius = random(maxOrbit(w, h));
this.radius = random(60, this.orbitRadius) / 8;
//星星大小
this.orbitX = w / 2;
this.orbitY = h / 2;
this.timePassed = random(0, maxStars);
this.speed = random(this.orbitRadius) / 1000000;
//星星移动速度
this.alpha = random(2, 10)/1000;
count++;
stars[count] = this;
}
Star.prototype.draw = function() {
var x = Math.sin(this.timePassed) * this.orbitRadius + this.orbitX,
y = Math.cos(this.timePassed) * this.orbitRadius + this.orbitY,
twinkle = random(10);
if (twinkle === 1 && this.alpha > 0) {
this.alpha -= 0.05;
} else if (twinkle === 2 && this.alpha < 1) {
this.alpha += 0.05;
}
ctx.globalAlpha = this.alpha;
ctx.drawImage(canvas2, x - this.radius / 2, y - this.radius / 2, this.radius, this.radius);
this.timePassed += this.speed;
}
for (var i = 0; i < maxStars; i++) {
new Star();
}
function animation() {
ctx.globalCompositeOperation = 'source-over';
ctx.globalAlpha = 0.5; //尾巴
ctx.fillStyle = 'hsla(' + hue + ', 64%, 6%, 2)';
ctx.fillRect(0, 0, w, h)
ctx.globalCompositeOperation = 'lighter';
for (var i = 1, l = stars.length; i < l; i++) {
stars[i].draw();
};
window.requestAnimationFrame(animation);
}
animation();

File diff suppressed because one or more lines are too long

@ -0,0 +1,272 @@
export let threeMainFunction = function(e) {
function t(t) {
for (var a, u, s = t[0], i = t[1], c = t[2], d = 0, p = []; d < s.length; d++) u = s[d], r[u] && p.push(r[u][0]), r[u] = 0;
for (a in i) Object.prototype.hasOwnProperty.call(i, a) && (e[a] = i[a]);
for (l && l(t); p.length;) p.shift()();
return n.push.apply(n, c || []), o()
}
function o() {
for (var e, t = 0; t < n.length; t++) {
for (var o = n[t], a = !0, s = 1; s < o.length; s++) {
var i = o[s];
0 !== r[i] && (a = !1)
}
a && (n.splice(t--, 1), e = u(u.s = o[0]))
}
return e
}
var a = {},
r = {
0: 0
},
n = [];
function u(t) {
if (a[t]) return a[t].exports;
var o = a[t] = {
i: t,
l: !1,
exports: {}
};
return e[t].call(o.exports, o, o.exports, u), o.l = !0, o.exports
}
u.m = e, u.c = a, u.d = function(e, t, o) {
u.o(e, t) || Object.defineProperty(e, t, {
enumerable: !0,
get: o
})
},
u.r = function(e) {
"undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
value: "Module"
}), Object.defineProperty(e, "__esModule", {
value: !0
})
},
u.t = function(e, t) {
if (1 & t && (e = u(e)), 8 & t) return e;
if (4 & t && "object" == typeof e && e && e.__esModule) return e;
var o = Object.create(null);
if (u.r(o), Object.defineProperty(o, "default", {
enumerable: !0,
value: e
}), 2 & t && "string" != typeof e)
for (var a in e) u.d(o, a, function(t) {
return e[t]
}.bind(null, a));
return o
},
u.n = function(e) {
var t = e && e.__esModule ? function() {
return e.default
} : function() {
return e
};
return u.d(t, "a", t), t
},
u.o = function(e, t) {
return Object.prototype.hasOwnProperty.call(e, t)
},
u.p = "";
var s = window.webpackJsonp = window.webpackJsonp || [],
i = s.push.bind(s);
s.push = t, s = s.slice();
for (var c = 0; c < s.length; c++) t(s[c]);
var l = i;
n.push([4, 1]), o()
}
([, , , , function(e, t, o)
{
e.exports = o(5)
},
function(e, t, o) {
"use strict";
o.r(t);
var a = o(2),
r = o(0),
n = o(1),
u = o(3);
let s = o(6);
const i = o(7);
window.top.forceBallBackground = 16777215, (async() => {
let e = window.innerWidth,
t = window.innerHeight,
o = a.b(a.c);
new Map;
(() => {
let e = new Map,
t = 0;
s.nodes.forEach(o => {
e.set(o.name, t++)
}), s.nodes[0].level = 0, s.edges = s.links.map(o => {
let a = e.get(o.source);
return void 0 === a && (s.nodes.push({
name: o.source
}), e.set(o.source, t++), console.log(a)), void 0 === e.get(o.target) && (s.nodes.push({
name: o.target
}), e.set(o.target, t++)), s.nodes[e.get(o.target)].level = s.nodes[e.get(o.source)].level + 1, {
source: e.get(o.source),
target: e.get(o.target)
}
}), s.nodes.forEach(e => {
e.color = (e => a.a(o(e)).brighter(1.7).toString())(e.level)
})
})();
let c = s.nodes,
l = s.edges,
d = new n.World;
d.gravity.set(0, 0, 0), d.solver.iterations = 20;
let p = new r.Scene,
g = new r.WebGLRenderer({
antialias: !0
});
g.setSize(e, t), g.shadowMap.enabled = !0, g.setClearColor(window.top.forceBallBackground, 1), document.body.appendChild(g.domElement);
let v = new r.PerspectiveCamera(45, e / t, 1, 1e4);
v.position.set(0, -300, 300), v.lookAt(0, 0, 0), window.onresize = (() => {
v.aspect = window.innerWidth / window.innerHeight, v.updateProjectionMatrix(), g.setSize(window.innerWidth, window.innerHeight)
});
let m = [];
c.forEach((e, t) => {
! function() {
let t = document.createElement("canvas");
t.width = 512, t.height = 512;
let o = t.getContext("2d");
o.fillStyle = "#000000", o.font = "75px Yahei", o.textAlign = "center", o.textBaseline = "middle", o.fillText(e.name, 256, 256, 512);
let a = new r.CanvasTexture(t);
a.needsUpdate = !0;
let n = new r.SpriteMaterial({
map: a
}),
u = new r.Sprite(n);
u.scale.set(30, 30, 1), u.castShadow = !0, u.receiveShadow = !0, p.add(u), e.text = u, u.data = e
}();
let o = function() {
let o = new r.SphereGeometry(10, 32, 32),
a = new r.MeshPhongMaterial({
color: e.color
}),
n = new r.Mesh(o, a);
n.castShadow = !0, n.receiveShadow = !0, n.frustumCulled = !1; {
let e = c.length,
o = 50 * e / 2 / Math.PI;
n.position.set(Math.cos(2 * Math.PI / e * t) * o, Math.sin(2 * Math.PI / e * t) * o, 0)
}
return p.add(n), m.push(n), e.body = n, n.data = e, n
}(),
a = new n.Body({
mass: 1,
shape: new n.Sphere(10),
linearDamping: .9,
angularDamping: .9
});
a.position.copy(o.position), a.fixedRotation = !0, d.addBody(a), e.pbody = a
}), l.forEach(e => {
let t = new r.LineBasicMaterial({
vertexColors: !0,
side: r.DoubleSide
}),
o = new r.Geometry;
o.vertices.push(c[e.source].body.position), o.vertices.push(c[e.target].body.position), o.colors.push(c[e.source].body.material.color, c[e.target].body.material.color);
let a = new r.Line(o, t);
a.castShadow = !0, a.receiveShadow = !0, a.frustumCulled = !1, p.add(a), e.body = a;
let u = c[e.source].pbody,
s = c[e.target].pbody,
i = new n.DistanceConstraint(u, s, 50, 10);
d.addConstraint(i)
}),
function() {
let e = new r.AmbientLight(16777215, .5);
e.position.set(0, 10, 0), p.add(e), (e = new r.SpotLight(16777215, .4)).position.set(0, 0, 300), e.castShadow = !0, e.shadow.mapSize.width = 4096, e.shadow.mapSize.height = 4096, p.add(e), (e = new r.SpotLight(16777215, .4)).position.set(0, 0, -300), e.castShadow = !0, e.shadow.mapSize.width = 4096, e.shadow.mapSize.height = 4096, p.add(e)
}();
const h = new i(v, g.domElement);
let f = !1,
w = !1;
const y = new u.a(m, v, g.domElement);
function b() {
if (!f) {
let e = new r.Vector3(0, 0, 0);
c.forEach(t => {
e.add(t.pbody.position)
}), e.divideScalar(c.length);
let t = 10 * e.sub(new r.Vector3(0, 0, 0)).length(),
o = e.negate().clampLength(t, Math.ceil(t));
c.forEach(e => {
e.pbody.force.copy(e.pbody.force.vadd(o))
})
}
c.forEach(e => {
e.body.position.copy(e.pbody.position), e.body.quaternion.copy(e.pbody.quaternion);
let t = v.position.clone().sub(e.pbody.position).clampLength(11, 12).add(e.pbody.position);
e.text.position.copy(t), c.forEach(t => {
if (t !== e && t.pbody.type === n.Body.DYNAMIC) {
let o = (new r.Vector3).copy(t.pbody.position).distanceTo(e.pbody.position),
a = 1e5,
n = (new r.Vector3).copy(t.pbody.position).sub(e.pbody.position).clampLength(a / o ** 2, Math.ceil(a / o ** 2));
t.pbody.force.copy(t.pbody.force.vadd(n))
}
})
}), l.forEach(e => {
e.body.geometry.verticesNeedUpdate = !0
})
}
y.addEventListener("hoveron", function(e) {
h.enabled = !1
}), y.addEventListener("hoveroff", function(e) {
h.enabled = !0
}), y.addEventListener("dragstart", function(e) {
e.object.data.pbody.type = n.Body.KINEMATIC, e.object.data.pbody.updateMassProperties(), f = !0
}), y.addEventListener("drag", function(e) {
e.object.data.pbody.position.copy(e.object.position), w = !0
}), y.addEventListener("dragend", function(e) {
e.object.data.pbody.type = n.Body.DYNAMIC, e.object.data.pbody.updateMassProperties(), f = !1, !w && e.object.data.url && "" !== e.object.data.url && window.top.open(e.object.data.url), w = !1
});
console.time();
for (let e = 0; e < 250; e++) d.step(.02), b();
console.timeEnd();
let S = performance.now(),
M = function(e) {
let t = e - S;
S = e, t > 0 && (d.step(Math.min(t, 100) / 1e3), b()), g.render(p, v), h.update(), requestAnimationFrame(M)
};
M(S)
})()
},
function (e) {
var nodestemp = []
var linkstemp = []
var id = window.location.href;
var ids = id.indexOf('=')
var idsur = id.substring(ids + 1)
var xhr = new XMLHttpRequest();
var url=process.env.VUE_APP_API_BASE_URL+'/seknowgroup/seKnowGroup/zzzztp?id='+idsur;
xhr.open('GET', url, false);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200 || xhr.status == 304) {
console.log(2222);
// 从服务器获得数据
var jsonObj = JSON.parse(xhr.responseText)
// 获取 nodes 数组和 links 数组
nodestemp = jsonObj.nodes;
linkstemp = jsonObj.links;
// 输出结果
console.log(nodestemp);
console.log(linkstemp);
/* var stemp= xhr.responseText;
console.log(stemp);
console.log('aaaa',stemp.nodes)
console.log('bbbb',stemp.links)*/
}
};
xhr.send();
e.exports = {
nodes: nodestemp,
links: linkstemp
}
console.log(3333);
}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,267 @@
const data = {
nodes: [
{ id: 'node1', label: '计算机', color: '#4682B4', classID: 0 },
{
id: 'node2',
label: '前端',
color: 'rgba(254, 241, 0, 1)',
classID: 1
},
{
id: 'node3',
label: 'js',
color: 'rgba(239, 242, 18, 1)',
classID: 2
},
{
id: 'node4',
label: 'html',
color: 'rgba(230, 234, 10, 1)',
classID: 3
},
{
id: 'node5',
label: 'css',
color: 'rgba(244, 231, 0, 1)',
classID: 4
},
{
id: 'node6',
label: 'less',
color: 'rgba(15, 245, 57, 1)',
classID: 5
},
{
id: 'node7',
label: 'scss',
color: 'rgba(133, 255, 11, 1)',
classID: 6
},
{
id: 'node8',
label: 'VUE',
color: 'rgba(42, 255, 0, 1)',
classID: 7
},
{
id: 'node9',
label: 'React',
color: 'rgba(76, 73, 245, 1)',
classID: 8
},
{ id: 'node10', label: '模块化', color: '#4682B4', classID: 9 },
{ id: 'node11', label: 'webpack', color: '#4682B4', classID: 10 },
{ id: 'node12', label: 'vite', color: '#4682B4', classID: 11 },
{
id: 'node13',
label: 'uniapp',
color: 'rgba(77, 255, 0, 1)',
classID: 12
},
{
id: 'node14',
label: 'element',
color: 'rgba(33, 162, 255, 1)',
classID: 13
},
{
id: 'node15',
label: 'web3',
color: 'rgba(255, 0, 251, 1)',
classID: 14
},
{
id: 'node16',
label: 'webGl',
color: 'rgba(208, 0, 249, 1)',
classID: 15
},
{
id: 'node17',
label: 'three',
color: 'rgba(225, 0, 255, 1)',
classID: 16
},
{
id: 'node18',
label: '后端',
color: 'rgba(0, 229, 255, 1)',
classID: 17
},
{
id: 'node19',
label: 'java',
color: 'rgba(237, 229, 85, 1)',
classID: 18
},
{
id: 'node20',
label: 'PHP',
color: 'rgba(195, 206, 215, 1)',
classID: 19
},
{
id: 'node21',
label: 'Go',
color: 'rgba(255, 0, 0, 1)',
classID: 20
},
{
id: 'node22',
label: 'Python',
color: 'rgba(109, 238, 180, 1)',
classID: 21
},
{ id: 'node23', label: 'MySQL', color: '#4682B4', classID: 22 },
{
id: 'node24',
label: '人工智能',
color: 'rgba(180, 5, 255, 1)',
classID: 23
},
{
id: 'node25',
label: 'python',
color: 'rgba(255, 8, 8, 1)',
classID: 24
},
{
id: 'node26',
label: 'AI模型',
color: 'rgba(10, 138, 244, 1)',
classID: 25
},
{
id: 'node27',
label: 'Spring Framework',
color: 'rgba(242, 238, 14, 1)',
classID: 26
},
{
id: 'node28',
label: 'Hibernate',
color: 'rgba(242, 238, 14, 1)',
classID: 27
},
{
id: 'node29',
label: 'Spring MVC',
color: 'rgba(242, 238, 14, 1)',
classID: 28
},
{
id: 'node30',
label: 'Gin',
color: 'rgba(255, 0, 0, 1)',
classID: 29
},
{
id: 'node31',
label: 'Echo',
color: 'rgba(255, 0, 0, 1)',
classID: 30
},
{
id: 'node32',
label: 'Beego',
color: 'rgba(255, 8, 0, 1)',
classID: 31
},
{
id: 'node33',
label: 'Laravel',
color: 'rgba(200, 209, 217, 1)',
classID: 32
},
{
id: 'node34',
label: 'Symfony',
color: 'rgba(182, 194, 204, 1)',
classID: 33
},
{
id: 'node35',
label: 'CodeIgniter',
color: 'rgba(188, 197, 204, 1)',
classID: 34
},
{
id: 'node36',
label: 'Django',
color: 'rgba(36, 245, 144, 1)',
classID: 35
},
{
id: 'node37',
label: 'Flask',
color: 'rgba(41, 244, 176, 1)',
classID: 36
},
{
id: 'node38',
label: 'FastAPI',
color: 'rgba(58, 244, 142, 1)',
classID: 37
}
],
links: [
{ source: 'node2', target: 'node3', label: '', classID: 0 },
{ source: 'node2', target: 'node5', label: '', classID: 1 },
{ source: 'node2', target: 'node4', label: '', classID: 2 },
{ source: 'node1', target: 'node2', label: '前端方向', classID: 3 },
{ source: 'node5', target: 'node6', label: '', classID: 4 },
{ source: 'node5', target: 'node7', label: '', classID: 5 },
{ source: 'node3', target: 'node8', label: '', classID: 6 },
{ source: 'node3', target: 'node9', label: '', classID: 7 },
{ source: 'node3', target: 'node10', label: '', classID: 8 },
{ source: 'node10', target: 'node11', label: '', classID: 9 },
{ source: 'node10', target: 'node12', label: '', classID: 10 },
{ source: 'node11', target: 'node9', label: '', classID: 11 },
{ source: 'node11', target: 'node8', label: '', classID: 12 },
{ source: 'node12', target: 'node8', label: '', classID: 13 },
{ source: 'node8', target: 'node13', label: '', classID: 14 },
{ source: 'node8', target: 'node14', label: '', classID: 15 },
{ source: 'node11', target: 'node13', label: '', classID: 16 },
{ source: 'node12', target: 'node13', label: '', classID: 17 },
{ source: 'node2', target: 'node15', label: '', classID: 18 },
{ source: 'node15', target: 'node16', label: '', classID: 19 },
{ source: 'node16', target: 'node17', label: '', classID: 20 },
{ source: 'node1', target: 'node1', label: '', classID: 21 },
{
source: 'node1',
target: 'node18',
label: '后端方向',
classID: 22
},
{ source: 'node18', target: 'node21', label: '', classID: 23 },
{ source: 'node18', target: 'node20', label: '', classID: 24 },
{ source: 'node18', target: 'node19', label: '', classID: 25 },
{ source: 'node18', target: 'node22', label: '', classID: 26 },
{ source: 'node22', target: 'node23', label: '', classID: 27 },
{ source: 'node19', target: 'node23', label: '', classID: 28 },
{ source: 'node20', target: 'node23', label: '', classID: 29 },
{ source: 'node21', target: 'node23', label: '', classID: 30 },
{
source: 'node1',
target: 'node24',
label: '人工智能方向',
classID: 31
},
{ source: 'node24', target: 'node25', label: '', classID: 32 },
{ source: 'node24', target: 'node26', label: '', classID: 33 },
{ source: 'node12', target: 'node9', label: '', classID: 34 },
{ source: 'node19', target: 'node27', label: '', classID: 35 },
{ source: 'node19', target: 'node28', label: '', classID: 36 },
{ source: 'node19', target: 'node29', label: '', classID: 37 },
{ source: 'node21', target: 'node30', label: '', classID: 38 },
{ source: 'node21', target: 'node31', label: '', classID: 39 },
{ source: 'node21', target: 'node32', label: '', classID: 40 },
{ source: 'node20', target: 'node33', label: '', classID: 41 },
{ source: 'node20', target: 'node34', label: '', classID: 42 },
{ source: 'node20', target: 'node35', label: '', classID: 43 },
{ source: 'node22', target: 'node36', label: '', classID: 44 },
{ source: 'node22', target: 'node37', label: '', classID: 45 },
{ source: 'node22', target: 'node38', label: '', classID: 46 }
]
}
export default JSON.stringify(data)

@ -0,0 +1,109 @@
<template>
<a-spin :spinning="confirmLoading">
<j-form-container :disabled="formDisabled">
<a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
<a-row>
<a-col :span="24">
<a-form-model-item label="图谱名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="name">
<a-input v-model="model.name" placeholder="请输入图谱名称" ></a-input>
</a-form-model-item>
</a-col>
<a-col :span="24">
<a-form-model-item label="中心知识点" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="knowPoint">
<j-dict-select-tag type="list" v-model="model.knowPoint" dictCode="se_konw,name,id" placeholder="请选择中心知识点" />
</a-form-model-item>
</a-col>
</a-row>
</a-form-model>
</j-form-container>
</a-spin>
</template>
<script>
import { httpAction, getAction } from '@/api/manage'
import { validateDuplicateValue } from '@/utils/util'
export default {
name: 'SeKnowGroupForm',
components: {
},
props: {
//
disabled: {
type: Boolean,
default: false,
required: false
}
},
data () {
return {
model:{
},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
confirmLoading: false,
validatorRules: {
},
url: {
add: "/seknowgroup/seKnowGroup/add",
edit: "/seknowgroup/seKnowGroup/edit",
queryById: "/seknowgroup/seKnowGroup/queryById"
}
}
},
computed: {
formDisabled(){
return this.disabled
},
},
created () {
//model
this.modelDefault = JSON.parse(JSON.stringify(this.model));
},
methods: {
add () {
this.edit(this.modelDefault);
},
edit (record) {
this.model = Object.assign({}, record);
this.visible = true;
},
submitForm () {
const that = this;
//
this.$refs.form.validate(valid => {
if (valid) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
if(!this.model.id){
httpurl+=this.url.add;
method = 'post';
}else{
httpurl+=this.url.edit;
method = 'put';
}
httpAction(httpurl,this.model,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
}else{
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
})
}
})
},
}
}
</script>

@ -0,0 +1,60 @@
<template>
<j-modal
:title="title"
:width="width"
:visible="visible"
switchFullscreen
@ok="handleOk"
:okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
@cancel="handleCancel"
cancelText="关闭">
<se-know-group-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></se-know-group-form>
</j-modal>
</template>
<script>
import SeKnowGroupForm from './SeKnowGroupForm'
export default {
name: 'SeKnowGroupModal',
components: {
SeKnowGroupForm
},
data () {
return {
title:'',
width:800,
visible: false,
disableSubmit: false
}
},
methods: {
add () {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.add();
})
},
edit (record) {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.edit(record);
})
},
close () {
this.$emit('close');
this.visible = false;
},
handleOk () {
this.$refs.realForm.submitForm();
},
submitCallback(){
this.$emit('ok');
this.visible = false;
},
handleCancel () {
this.close()
}
}
}
</script>

@ -0,0 +1,84 @@
<template>
<a-drawer
:title="title"
:width="width"
placement="right"
:closable="false"
@close="close"
destroyOnClose
:visible="visible">
<se-know-group-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></se-know-group-form>
<div class="drawer-footer">
<a-button @click="handleCancel" style="margin-bottom: 0;">关闭</a-button>
<a-button v-if="!disableSubmit" @click="handleOk" type="primary" style="margin-bottom: 0;">提交</a-button>
</div>
</a-drawer>
</template>
<script>
import SeKnowGroupForm from './SeKnowGroupForm'
export default {
name: 'SeKnowGroupModal',
components: {
SeKnowGroupForm
},
data () {
return {
title:"操作",
width:800,
visible: false,
disableSubmit: false
}
},
methods: {
add () {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.add();
})
},
edit (record) {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.edit(record);
});
},
close () {
this.$emit('close');
this.visible = false;
},
submitCallback(){
this.$emit('ok');
this.visible = false;
},
handleOk () {
this.$refs.realForm.submitForm();
},
handleCancel () {
this.close()
}
}
}
</script>
<style lang="less" scoped>
/** Button按钮间距 */
.ant-btn {
margin-left: 30px;
margin-bottom: 30px;
float: right;
}
.drawer-footer{
position: absolute;
bottom: -8px;
width: 100%;
border-top: 1px solid #e8e8e8;
padding: 10px 16px;
text-align: right;
left: 0;
background: #fff;
border-radius: 0 0 2px 2px;
}
</style>

@ -0,0 +1,468 @@
import { LinearFilter, Sprite, SpriteMaterial, SRGBColorSpace, Texture } from 'three';
function _callSuper(t, o, e) {
return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
}
function _isNativeReflectConstruct() {
try {
var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
} catch (t) {}
return (_isNativeReflectConstruct = function () {
return !!t;
})();
}
function _iterableToArrayLimit(r, l) {
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (null != t) {
var e,
n,
i,
u,
a = [],
f = !0,
o = !1;
try {
if (i = (t = t.call(r)).next, 0 === l) {
if (Object(t) !== t) return;
f = !1;
} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
} catch (r) {
o = !0, n = r;
} finally {
try {
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
} finally {
if (o) throw n;
}
}
return a;
}
}
function _toPrimitive(t, r) {
if ("object" != typeof t || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != typeof i) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == typeof i ? i : String(i);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
Object.defineProperty(Constructor, "prototype", {
writable: false
});
return Constructor;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
Object.defineProperty(subClass, "prototype", {
writable: false
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
} else if (call !== void 0) {
throw new TypeError("Derived constructors may only return object or undefined");
}
return _assertThisInitialized(self);
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var three = typeof window !== 'undefined' && window.THREE ? window.THREE // Prefer consumption from global THREE, if exists
: {
LinearFilter: LinearFilter,
Sprite: Sprite,
SpriteMaterial: SpriteMaterial,
SRGBColorSpace: SRGBColorSpace,
Texture: Texture
};
var _default = /*#__PURE__*/function (_three$Sprite) {
_inherits(_default, _three$Sprite);
function _default() {
var _this;
var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var textHeight = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10;
var color = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'rgba(255, 255, 255, 1)';
_classCallCheck(this, _default);
_this = _callSuper(this, _default, [new three.SpriteMaterial()]);
_this._text = "".concat(text);
_this._textHeight = textHeight;
_this._color = color;
_this._backgroundColor = false; // no background color
_this._padding = 0;
_this._borderWidth = 0;
_this._borderRadius = 0;
_this._borderColor = 'white';
_this._strokeWidth = 0;
_this._strokeColor = 'white';
_this._fontFace = 'system-ui';
_this._fontSize = 90; // defines text resolution
_this._fontWeight = 'normal';
_this._canvas = document.createElement('canvas');
_this._genCanvas();
return _this;
}
_createClass(_default, [{
key: "text",
get: function get() {
return this._text;
},
set: function set(text) {
this._text = text;
this._genCanvas();
}
}, {
key: "textHeight",
get: function get() {
return this._textHeight;
},
set: function set(textHeight) {
this._textHeight = textHeight;
this._genCanvas();
}
}, {
key: "color",
get: function get() {
return this._color;
},
set: function set(color) {
this._color = color;
this._genCanvas();
}
}, {
key: "backgroundColor",
get: function get() {
return this._backgroundColor;
},
set: function set(color) {
this._backgroundColor = color;
this._genCanvas();
}
}, {
key: "padding",
get: function get() {
return this._padding;
},
set: function set(padding) {
this._padding = padding;
this._genCanvas();
}
}, {
key: "borderWidth",
get: function get() {
return this._borderWidth;
},
set: function set(borderWidth) {
this._borderWidth = borderWidth;
this._genCanvas();
}
}, {
key: "borderRadius",
get: function get() {
return this._borderRadius;
},
set: function set(borderRadius) {
this._borderRadius = borderRadius;
this._genCanvas();
}
}, {
key: "borderColor",
get: function get() {
return this._borderColor;
},
set: function set(borderColor) {
this._borderColor = borderColor;
this._genCanvas();
}
}, {
key: "fontFace",
get: function get() {
return this._fontFace;
},
set: function set(fontFace) {
this._fontFace = fontFace;
this._genCanvas();
}
}, {
key: "fontSize",
get: function get() {
return this._fontSize;
},
set: function set(fontSize) {
this._fontSize = fontSize;
this._genCanvas();
}
}, {
key: "fontWeight",
get: function get() {
return this._fontWeight;
},
set: function set(fontWeight) {
this._fontWeight = fontWeight;
this._genCanvas();
}
}, {
key: "strokeWidth",
get: function get() {
return this._strokeWidth;
},
set: function set(strokeWidth) {
this._strokeWidth = strokeWidth;
this._genCanvas();
}
}, {
key: "strokeColor",
get: function get() {
return this._strokeColor;
},
set: function set(strokeColor) {
this._strokeColor = strokeColor;
this._genCanvas();
}
}, {
key: "_genCanvas",
value: function _genCanvas() {
var _this2 = this;
var canvas = this._canvas;
var ctx = canvas.getContext('2d');
var border = Array.isArray(this.borderWidth) ? this.borderWidth : [this.borderWidth, this.borderWidth]; // x,y border
var relBorder = border.map(function (b) {
return b * _this2.fontSize * 0.1;
}); // border in canvas units
var borderRadius = Array.isArray(this.borderRadius) ? this.borderRadius : [this.borderRadius, this.borderRadius, this.borderRadius, this.borderRadius]; // tl tr br bl corners
var relBorderRadius = borderRadius.map(function (b) {
return b * _this2.fontSize * 0.1;
}); // border radius in canvas units
var padding = Array.isArray(this.padding) ? this.padding : [this.padding, this.padding]; // x,y padding
var relPadding = padding.map(function (p) {
return p * _this2.fontSize * 0.1;
}); // padding in canvas units
var lines = this.text.split('\n');
var font = "".concat(this.fontWeight, " ").concat(this.fontSize, "px ").concat(this.fontFace);
ctx.font = font; // measure canvas with appropriate font
var innerWidth = Math.max.apply(Math, _toConsumableArray(lines.map(function (line) {
return ctx.measureText(line).width;
})));
var innerHeight = this.fontSize * lines.length;
canvas.width = innerWidth + relBorder[0] * 2 + relPadding[0] * 2;
canvas.height = innerHeight + relBorder[1] * 2 + relPadding[1] * 2;
// paint border
if (this.borderWidth) {
ctx.strokeStyle = this.borderColor;
if (relBorder[0]) {
// left + right borders
var hb = relBorder[0] / 2;
ctx.lineWidth = relBorder[0];
ctx.beginPath();
ctx.moveTo(hb, relBorderRadius[0]);
ctx.lineTo(hb, canvas.height - relBorderRadius[3]);
ctx.moveTo(canvas.width - hb, relBorderRadius[1]);
ctx.lineTo(canvas.width - hb, canvas.height - relBorderRadius[2]);
ctx.stroke();
}
if (relBorder[1]) {
// top + bottom borders
var _hb = relBorder[1] / 2;
ctx.lineWidth = relBorder[1];
ctx.beginPath();
ctx.moveTo(Math.max(relBorder[0], relBorderRadius[0]), _hb);
ctx.lineTo(canvas.width - Math.max(relBorder[0], relBorderRadius[1]), _hb);
ctx.moveTo(Math.max(relBorder[0], relBorderRadius[3]), canvas.height - _hb);
ctx.lineTo(canvas.width - Math.max(relBorder[0], relBorderRadius[2]), canvas.height - _hb);
ctx.stroke();
}
if (this.borderRadius) {
// strike rounded corners
var cornerWidth = Math.max.apply(Math, _toConsumableArray(relBorder));
var _hb2 = cornerWidth / 2;
ctx.lineWidth = cornerWidth;
ctx.beginPath();
[!!relBorderRadius[0] && [relBorderRadius[0], _hb2, _hb2, relBorderRadius[0]], !!relBorderRadius[1] && [canvas.width - relBorderRadius[1], canvas.width - _hb2, _hb2, relBorderRadius[1]], !!relBorderRadius[2] && [canvas.width - relBorderRadius[2], canvas.width - _hb2, canvas.height - _hb2, canvas.height - relBorderRadius[2]], !!relBorderRadius[3] && [relBorderRadius[3], _hb2, canvas.height - _hb2, canvas.height - relBorderRadius[3]]].filter(function (d) {
return d;
}).forEach(function (_ref) {
var _ref2 = _slicedToArray(_ref, 4),
x0 = _ref2[0],
x1 = _ref2[1],
y0 = _ref2[2],
y1 = _ref2[3];
ctx.moveTo(x0, y0);
ctx.quadraticCurveTo(x1, y0, x1, y1);
});
ctx.stroke();
}
}
// paint background
if (this.backgroundColor) {
ctx.fillStyle = this.backgroundColor;
if (!this.borderRadius) {
ctx.fillRect(relBorder[0], relBorder[1], canvas.width - relBorder[0] * 2, canvas.height - relBorder[1] * 2);
} else {
// fill with rounded corners
ctx.beginPath();
ctx.moveTo(relBorder[0], relBorderRadius[0]);
[[relBorder[0], relBorderRadius[0], canvas.width - relBorderRadius[1], relBorder[1], relBorder[1], relBorder[1]],
// t
[canvas.width - relBorder[0], canvas.width - relBorder[0], canvas.width - relBorder[0], relBorder[1], relBorderRadius[1], canvas.height - relBorderRadius[2]],
// r
[canvas.width - relBorder[0], canvas.width - relBorderRadius[2], relBorderRadius[3], canvas.height - relBorder[1], canvas.height - relBorder[1], canvas.height - relBorder[1]],
// b
[relBorder[0], relBorder[0], relBorder[0], canvas.height - relBorder[1], canvas.height - relBorderRadius[3], relBorderRadius[0]] // t
].forEach(function (_ref3) {
var _ref4 = _slicedToArray(_ref3, 6),
x0 = _ref4[0],
x1 = _ref4[1],
x2 = _ref4[2],
y0 = _ref4[3],
y1 = _ref4[4],
y2 = _ref4[5];
ctx.quadraticCurveTo(x0, y0, x1, y1);
ctx.lineTo(x2, y2);
});
ctx.closePath();
ctx.fill();
}
}
ctx.translate.apply(ctx, _toConsumableArray(relBorder));
ctx.translate.apply(ctx, _toConsumableArray(relPadding));
// paint text
ctx.font = font; // Set font again after canvas is resized, as context properties are reset
ctx.fillStyle = this.color;
ctx.textBaseline = 'bottom';
var drawTextStroke = this.strokeWidth > 0;
if (drawTextStroke) {
ctx.lineWidth = this.strokeWidth * this.fontSize / 10;
ctx.strokeStyle = this.strokeColor;
}
lines.forEach(function (line, index) {
var lineX = (innerWidth - ctx.measureText(line).width) / 2;
var lineY = (index + 1) * _this2.fontSize;
drawTextStroke && ctx.strokeText(line, lineX, lineY);
ctx.fillText(line, lineX, lineY);
});
// Inject canvas into sprite
if (this.material.map) this.material.map.dispose(); // gc previous texture
var texture = this.material.map = new three.Texture(canvas);
texture.minFilter = three.LinearFilter;
texture.colorSpace = three.SRGBColorSpace;
texture.needsUpdate = true;
var yScale = this.textHeight * lines.length + border[1] * 2 + padding[1] * 2;
this.scale.set(yScale * canvas.width / canvas.height, yScale, 0);
}
}, {
key: "clone",
value: function clone() {
return new this.constructor(this.text, this.textHeight, this.color).copy(this);
}
}, {
key: "copy",
value: function copy(source) {
three.Sprite.prototype.copy.call(this, source);
this.color = source.color;
this.backgroundColor = source.backgroundColor;
this.padding = source.padding;
this.borderWidth = source.borderWidth;
this.borderColor = source.borderColor;
this.fontFace = source.fontFace;
this.fontSize = source.fontSize;
this.fontWeight = source.fontWeight;
this.strokeWidth = source.strokeWidth;
this.strokeColor = source.strokeColor;
return this;
}
}]);
return _default;
}(three.Sprite);
export { _default as default };

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save