Merge branch 'master' into online
38
.fes.js
@ -4,7 +4,7 @@
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2023-10-16 10:53:09
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-06-15 11:17:09
|
||||
* @LastEditTime: 2024-08-11 18:22:40
|
||||
*/
|
||||
// import { resolve } from 'path';
|
||||
import { join } from 'path'
|
||||
@ -17,9 +17,7 @@ import glsl from 'vite-plugin-glsl'
|
||||
import obfuscatorPlugin from 'vite-plugin-javascript-obfuscator'
|
||||
|
||||
const timeStamp = new Date().getTime()
|
||||
const combinedIsCustomElement = (tag) => {
|
||||
return tag.startsWith('iconify-icon') || templateCompilerOptions.template.compilerOptions.isCustomElement(tag)
|
||||
}
|
||||
const combinedIsCustomElement = (tag) => tag.startsWith('iconify-icon') || templateCompilerOptions.template.compilerOptions.isCustomElement(tag)
|
||||
|
||||
export default defineBuildConfig({
|
||||
title: 'TvT.js',
|
||||
@ -55,27 +53,27 @@ export default defineBuildConfig({
|
||||
}),
|
||||
glsl(),
|
||||
process.env.NODE_ENV === 'production' &&
|
||||
obfuscatorPlugin({
|
||||
debugger: false,
|
||||
// include: ['src/plugins/'],
|
||||
// exclude: ['/node_modules/', '/src/.fes/', '/src/app.jsx', /index.jsx$/],
|
||||
// apply: 'build',
|
||||
options: {
|
||||
// 配置项,根据需要进行调整
|
||||
optionsPreset: 'default',
|
||||
// identifierNamesGenerator: 'mangled',
|
||||
debugProtection: true,
|
||||
disableConsoleOutput: true,
|
||||
reservedStrings: ['suspenseLayout.vue', '/plugins'],
|
||||
// ... [See more options](https://github.com/javascript-obfuscator/javascript-obfuscator)
|
||||
},
|
||||
}),
|
||||
obfuscatorPlugin({
|
||||
debugger: false,
|
||||
// include: ['src/plugins/'],
|
||||
// exclude: ['/node_modules/', '/src/.fes/', '/src/app.jsx', /index.jsx$/],
|
||||
// apply: 'build',
|
||||
options: {
|
||||
// 配置项,根据需要进行调整
|
||||
optionsPreset: 'default',
|
||||
// identifierNamesGenerator: 'mangled',
|
||||
debugProtection: true,
|
||||
disableConsoleOutput: true,
|
||||
reservedStrings: ['suspenseLayout.vue', '/plugins'],
|
||||
// ... [See more options](https://github.com/javascript-obfuscator/javascript-obfuscator)
|
||||
},
|
||||
}),
|
||||
],
|
||||
build: {
|
||||
chunkSizeWarningLimit: 1000, // 单位为KB
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks(id) {
|
||||
manualChunks (id) {
|
||||
// 自定义拆分策略,例如将特定的第三方库拆分为单独的 chunk
|
||||
if (id.includes('node_modules')) {
|
||||
return id.toString().split('node_modules/')[1].split('/')[0]
|
||||
|
@ -4,7 +4,7 @@
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2023-10-16 10:53:09
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-05-31 11:45:17
|
||||
* @LastEditTime: 2024-08-14 10:58:20
|
||||
*/
|
||||
import { defineBuildConfig } from '@fesjs/fes'
|
||||
import addExtraScriptPlugin from './src/common/addExtraScriptPlugin'
|
||||
@ -48,12 +48,16 @@ export default defineBuildConfig({
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'https://icegl.cn/',
|
||||
title: '🧊 ICEGL官网',
|
||||
path: 'https://www.bilibili.com/video/BV1LH4y1p7Yn',
|
||||
title: '📀 TvT视频教程',
|
||||
},
|
||||
{
|
||||
path: 'https://space.bilibili.com/410503457',
|
||||
title: '🅱️ B站主页',
|
||||
path: 'https://www.icegl.cn/tvtstore',
|
||||
title: '🧩 插件市场',
|
||||
},
|
||||
{
|
||||
path: 'https://icegl.cn/',
|
||||
title: '🧊 ICEGL官网',
|
||||
},
|
||||
{
|
||||
title: '👨🏫 课程中心',
|
||||
|
1
.gitignore
vendored
@ -18,3 +18,4 @@
|
||||
yarn.lock
|
||||
yarn-error.log
|
||||
package-lock.json
|
||||
src/plugins/resourceManager
|
||||
|
11
README.md
@ -105,11 +105,6 @@
|
||||
</script>
|
||||
```
|
||||
|
||||
- 🧩 丰富的插件应用市场<br/>
|
||||
插件中心包含各式各样的项目场景和功能。插件是 ICE 社区生态中重要的一环,在应用市场中完整应用和普通插件统一称为插件。
|
||||
|
||||
### 我们将会逐一把落地的项目以插件的形式加入到此开源框中...
|
||||
|
||||
### 敬请右上角一键三连: 关注 💛 点赞 ⭐ fork👣
|
||||
|
||||
# ✅ 快速开始
|
||||
@ -144,6 +139,12 @@
|
||||
|
||||

|
||||
|
||||
# 🧩 丰富的[插件应用市场🌏tvtstore](https://www.icegl.cn/tvtstore)
|
||||
插件中心 [🌏www.icegl.cn/tvtstore](https://www.icegl.cn/tvtstore) 包含各式各样的项目场景和功能。插件是 ICE 社区生态中重要的一环,在应用市场中完整应用和普通插件统一称为插件。<br/>
|
||||
[](https://www.icegl.cn/tvtstore)
|
||||
### 我们将会逐一把落地的项目以插件的形式加入到此开源框中...
|
||||
[](https://www.icegl.cn/p/tvtdeveloper.html)
|
||||
|
||||
# ❓ 问题反馈
|
||||
|
||||
在使用中有任何问题,请使用以下联系方式联系我们
|
||||
|
@ -58,6 +58,7 @@
|
||||
"@tresjs/cientos": "3.8.0",
|
||||
"@tresjs/core": "4.2.1",
|
||||
"@tresjs/leches": "^0.14.0",
|
||||
"@turf/turf": "^7.0.0",
|
||||
"@tweenjs/tween.js": "^23.1.2",
|
||||
"@vicons/carbon": "^0.12.0",
|
||||
"@vicons/ionicons5": "^0.12.0",
|
||||
@ -82,6 +83,7 @@
|
||||
"iconify-icon": "^2.1.0",
|
||||
"jszip": "^3.10.1",
|
||||
"lamina": "^1.1.23",
|
||||
"lodash": "^4.17.21",
|
||||
"lygia": "^1.1.3",
|
||||
"naive-ui": "^2.39.0",
|
||||
"oimophysics": "^1.2.2",
|
||||
@ -97,6 +99,7 @@
|
||||
"three-subdivide": "^1.1.5",
|
||||
"three.quarks": "^0.15.0",
|
||||
"tilebelt-wgs84": "^1.0.4",
|
||||
"turf": "^3.0.14",
|
||||
"tweakpane": "4.0.4",
|
||||
"unocss": "^0.58.9",
|
||||
"vite-plugin-javascript-obfuscator": "^3.1.0",
|
||||
|
Before Width: | Height: | Size: 113 KiB |
Before Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 110 KiB |
BIN
public/plugins/operationTool/model/湖中小亭/BS_F_491.jpg
Normal file
After Width: | Height: | Size: 207 KiB |
BIN
public/plugins/operationTool/model/湖中小亭/BS_T_306.jpg
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
public/plugins/operationTool/model/湖中小亭/BS_T_445_01.png
Normal file
After Width: | Height: | Size: 303 KiB |
BIN
public/plugins/operationTool/model/湖中小亭/BS_tree_48.png
Normal file
After Width: | Height: | Size: 424 KiB |
BIN
public/plugins/operationTool/model/湖中小亭/GRS_10245.jpg
Normal file
After Width: | Height: | Size: 307 KiB |
BIN
public/plugins/operationTool/model/湖中小亭/clay23M.jpg
Normal file
After Width: | Height: | Size: 136 KiB |
BIN
public/plugins/operationTool/model/湖中小亭/dmzs070.jpg
Normal file
After Width: | Height: | Size: 152 KiB |
BIN
public/plugins/operationTool/model/湖中小亭/dx030.jpg
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
public/plugins/operationTool/model/湖中小亭/scltdfx_100.png
Normal file
After Width: | Height: | Size: 293 KiB |
1
public/plugins/operationTool/model/湖中小亭/湖中小亭.gltf
Normal file
BIN
public/plugins/operationTool/preview/框选.png
Normal file
After Width: | Height: | Size: 164 KiB |
BIN
public/plugins/operationTool/preview/炸开.png
Normal file
After Width: | Height: | Size: 340 KiB |
30
src/app.jsx
@ -4,14 +4,12 @@
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2023-10-16 10:53:09
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-05-31 11:46:51
|
||||
* @LastEditTime: 2024-08-11 18:02:39
|
||||
*/
|
||||
import { defineRuntimeConfig, useModel } from '@fesjs/fes'
|
||||
import { FMenu } from '@fesjs/fes-design'
|
||||
import Tres from '@tresjs/core'
|
||||
import chalk from 'chalk'
|
||||
import PageLoading from '@/components/pageLoading.vue'
|
||||
import UserCenter from '@/components/forPreview/userCenter.vue'
|
||||
|
||||
// add by 地虎降天龙
|
||||
import 'uno.css'
|
||||
@ -22,6 +20,9 @@ import { addCollection } from 'iconify-icon'
|
||||
import uimIcons from '@iconify/json/json/uim.json'
|
||||
import lineMdIcons from '@iconify/json/json/line-md.json'
|
||||
import wiIcons from '@iconify/json/json/wi.json'
|
||||
import UserCenter from '@/components/forPreview/userCenter.vue'
|
||||
import PageLoading from '@/components/pageLoading.vue'
|
||||
|
||||
addCollection(uimIcons)
|
||||
addCollection(lineMdIcons)
|
||||
addCollection(wiIcons)
|
||||
@ -30,9 +31,9 @@ export default defineRuntimeConfig({
|
||||
beforeRender: {
|
||||
loading: <PageLoading />,
|
||||
action () {
|
||||
const { signin,getMenu } = useModel('forPreview')
|
||||
const { signin, getMenu } = useModel('forPreview')
|
||||
signin()
|
||||
if (process.env.FES_APP_PLUGINS === 'true') {
|
||||
if (process.env.FES_APP_PLUGINS === 'true') {
|
||||
getMenu()
|
||||
}
|
||||
// return new Promise((resolve) => {
|
||||
@ -51,7 +52,7 @@ export default defineRuntimeConfig({
|
||||
// },
|
||||
})
|
||||
|
||||
export function layout(layoutConfig) {
|
||||
export function layout (layoutConfig) {
|
||||
return {
|
||||
renderCustom: () => <UserCenter />,
|
||||
...layoutConfig,
|
||||
@ -66,9 +67,9 @@ export function onAppCreated ({ app }) {
|
||||
app.use(FMenu)
|
||||
app.use(Tres)
|
||||
|
||||
window['$vue'] = app
|
||||
window.$vue = app
|
||||
// if (process.env.FES_APP_PLUGINS === 'true') {
|
||||
console.log(chalk.hex('#1c86e5')(`
|
||||
console.log(chalk.hex('#1c86e5')(`
|
||||
░▒▓████████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓████████▓▒░ ░▒▓█▓▒░ ░▒▓███████▓▒░
|
||||
░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░
|
||||
░▒▓█▓▒░ ░▒▓█▓▒▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░ ░▒▓█▓▒░
|
||||
@ -77,16 +78,16 @@ export function onAppCreated ({ app }) {
|
||||
░▒▓█▓▒░ ░▒▓█▓▓█▓▒░ ░▒▓█▓▒░ ░▒▓██▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
|
||||
░▒▓█▓▒░ ░▒▓██▓▒░ ░▒▓█▓▒░ ░▒▓██▓▒░ ░▒▓██████▓▒░ ░▒▓███████▓▒░
|
||||
`))
|
||||
console.log(chalk.hex('#5384ff').bold('· 二次开发如用于商业性质或开源竞品请不要删除和修改 TvT.js 源码头部的版权与作者声明及出处。'))
|
||||
console.log(chalk.hex('#5384ff').bold('· 本项目遵循 Apache2 开源协议发布,并提供永久免费使用以及商用,但是不允许二次开源出来并进行收费。'))
|
||||
console.log(chalk.hex('#1c86e5').bold('版权所有 Copyright © 2022-2025 by 🧊icegl (https://www.icegl.cn)'))
|
||||
console.log(chalk.hex('#5384ff').bold('· 二次开发如用于商业性质或开源竞品请不要删除和修改 TvT.js 源码头部的版权与作者声明及出处。'))
|
||||
console.log(chalk.hex('#5384ff').bold('· 本项目遵循 Apache2 开源协议发布,并提供永久免费使用以及商用,但是不允许二次开源出来并进行收费。'))
|
||||
console.log(chalk.hex('#1c86e5').bold('版权所有 Copyright © 2022-2025 by 🧊icegl (https://www.icegl.cn)'))
|
||||
// }
|
||||
}
|
||||
const findStringBetween = (str) => {
|
||||
const regex = /plugins\/([^/]+)\/pages\//;
|
||||
const match = str.match(regex);
|
||||
const regex = /plugins\/([^/]+)\/pages\//
|
||||
const match = str.match(regex)
|
||||
if (match && match[1]) {
|
||||
return match[1];
|
||||
return match[1]
|
||||
}
|
||||
return null
|
||||
}
|
||||
@ -148,6 +149,7 @@ export function modifyRoute (memo) {
|
||||
indexRoute.component = null
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...memo,
|
||||
routes: [
|
||||
|
@ -4,7 +4,7 @@
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2023-10-16 10:53:09
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-05-24 09:52:10
|
||||
* @LastEditTime: 2024-08-12 16:33:18
|
||||
*/
|
||||
// 放工具函数
|
||||
import { request } from '@fesjs/fes'
|
||||
@ -21,20 +21,49 @@ const findStringBetween = (str) => {
|
||||
|
||||
export const getPluginsConfig = () => {
|
||||
// 获得插件列表 根据插件目录
|
||||
const modulePaths = import.meta.glob('PLS/*/config.js', { eager: true })
|
||||
const config = {}
|
||||
for (const path of Object.keys(modulePaths)) {
|
||||
const name = findStringBetween(path)
|
||||
if (!name) {
|
||||
continue
|
||||
if (!window.pluginsConfig) {
|
||||
const modulePaths = import.meta.glob('PLS/*/config.js', { eager: true })
|
||||
const config = {}
|
||||
for (const path of Object.keys(modulePaths)) {
|
||||
const name = findStringBetween(path)
|
||||
if (!name) {
|
||||
continue
|
||||
}
|
||||
config[name] = modulePaths[path].default
|
||||
}
|
||||
config[name] = modulePaths[path].default
|
||||
window.pluginsConfig = config
|
||||
}
|
||||
return config
|
||||
//检查插件依赖关系
|
||||
for (const name of Object.keys(window.pluginsConfig)) {
|
||||
if (window.pluginsConfig[name].require) {
|
||||
window.pluginsConfig[name].require.forEach((req) => {
|
||||
// eslint-disable-next-line no-undefined
|
||||
const re = window.pluginsConfig[req] !== undefined
|
||||
if (!re) {
|
||||
console.error(`${req}插件_未安装,请到插件市场下载安装:https://icegl.cn/tvtstore/${req}`)
|
||||
// window.open(`https://icegl.cn/tvtstore/${req}`, '_blank')
|
||||
const features = 'width=600,height=350'
|
||||
window.open(`https://icegl.cn/tvtstore/${req}`, req, features)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
return window.pluginsConfig
|
||||
}
|
||||
|
||||
export const hasPlugin = (ename, cname) => {
|
||||
const config = getPluginsConfig()
|
||||
// eslint-disable-next-line no-undefined
|
||||
const re = config[ename] !== undefined
|
||||
if (!re) {
|
||||
console.error(`${cname}_未安装,请到插件市场下载安装:https://icegl.cn/tvtstore/${cname}`)
|
||||
window.open(`https://icegl.cn/tvtstore/${cname}`, '_blank')
|
||||
}
|
||||
return re
|
||||
}
|
||||
|
||||
// 警告函数
|
||||
function showWarning() {
|
||||
function showWarning () {
|
||||
FMessage.warning?.({
|
||||
content: '官网已经更新的插件功能,请git 更新代码!',
|
||||
colorful: true,
|
||||
@ -94,11 +123,11 @@ export const getOnlinePluginConfig = (plConfig) => {
|
||||
}
|
||||
|
||||
// 通过名称查找预览配置
|
||||
function findPreviewByName(previews, name) {
|
||||
function findPreviewByName (previews, name) {
|
||||
return previews.find((preview) => preview.name === name)
|
||||
}
|
||||
// 在子配置中查找预览配置
|
||||
function findChildPreviewByName(children, childName, previewName) {
|
||||
function findChildPreviewByName (children, childName, previewName) {
|
||||
const child = children.find((chi) => chi.name === childName)
|
||||
if (child && child.preview) {
|
||||
return child.preview.find((preview) => preview.name === previewName)
|
||||
@ -119,7 +148,7 @@ export const getOnePluginConfig = (pName, oName, cName) => {
|
||||
// 根据页面参数名查找预览配置
|
||||
if (oName && config.preview) {
|
||||
const preview = findPreviewByName(config.preview, oName)
|
||||
if (preview) return { config, preview: preview }
|
||||
if (preview) return { config, preview }
|
||||
}
|
||||
// 根据子页面参数名查找子配置
|
||||
else if (cName && config.child) {
|
||||
|
@ -28,7 +28,7 @@
|
||||
class="w-full h-48 text-5 line-height-1.5em text-left mb-2 text-#5384ff"
|
||||
style="background-color: rgb(55 56 61); overflow: hidden; border-radius: 10px"
|
||||
>
|
||||
<div class="p-2">官网已经更新的插件功能,请git 更新代码!</div>
|
||||
<div class="p-2">官网已经更新样例功能,请git 更新代码!</div>
|
||||
</div>
|
||||
<div class="cursor-pointer text-right" style="margin-top: 6px; margin-bottom: -8px" @click="toPage(props.onePlugin, onePreview, true)">
|
||||
点击查看演示
|
||||
|
@ -30,10 +30,9 @@
|
||||
<a target="_black" href="https://gitee.com/ice-gl/icegl-three-vue-tres">
|
||||
<img src="https://gitee.com/ice-gl/icegl-three-vue-tres/badge/star.svg?theme=dark" alt="gitee-starts">
|
||||
</a>
|
||||
<a target="_black" href="https://space.bilibili.com/410503457" style="top: -1px;">
|
||||
<img alt="bilibili"
|
||||
src="https://img.shields.io/badge/dynamic/json?url=https://api.bilibili.com/x/relation/stat?vmid=410503457&query=data.follower&color=282c34&label=B%E7%AB%99&labelColor=FE7398&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAD7ElEQVR4nO2dW9WrMBCFK6ESkFAJSKiESqgEHCABCZWAhEpAAhL2ecik5dDc%2FpXLBDLfWnlqy0xmJ5BMQnq5CIIgCIIgCIIgCIIgCEIBAHQAemYfrgCunD6wAKAHsEKxALgx+bCQD8%2FS9tmgVqeDr1lLigDgZvDhXso+K9TyTBQRwRJ8AHjntl0Flh5QRAQK%2FmKxPeayWx2OXpBNBKiHvi34b7T2MC4pAvW6twR%2FRwkRKPizBN8CgEcuESj4Lwm+BwBjahEk+H8EwJRKhOaCDzW8e1JLfkUUH1NgmR3XmHffHR1l+72BSs8d7w8U+JDAnZERQMcV+CtUi7dNqFqibB4J7vtrq7xKCuAasbTMXCL4T+5aVk6+2xHUrWdhruAR6HIJcOeu2UHI8zyAe2ytWfEdWz9PVvQ8YAmIQ5dDAB9LFsMVAv8oMO2zAGrC5WNIarRiAuKR9jYEd9pY08aa6uUzIHGRdkgKd8pY0yc1WjEBAqypDYoAG0QAZkQAZkQAZkQAZk4vANQenjsSzS3I%2FwcSbXU5jQBUkRtdf4Rar90v8kSv3+I3ffCCSpk8I%2Fw+lgDkdI%2Fv2rEp2CaiWm1AsDQLlDAD+dlFXLMeAaCSeLZdaSFE5VUQNot38cKuEeBgAsSuG0flVZBmEanbXfNQAsS0fgBYIn2fIu3%2FBBMHEyBmDXlFfA8IzeHb+Ems4WAChKykrVA9ZfsQTL57jXzRg4A5wC%2FA8N4ADiZAZwm2XjW75Qh2KOTfA0p4kygPw28OJcCVgn3nDnYo2EwEYRgGH0qAMyICMCMCMCMCMCMCMCMCMCMCfP3qwHDOQ4AAUekTk8FaBRihJnZdYbvtCGC7LvmkM63GjVDINPFrQgCq5ETXfmMzI90FXzPvfqt7x4rEu%2FZaEcCUxFvgz2zO+BUn6UkoaEEAsptiMSX5e8FoRYCN7cVgb4Vq7U%2FH50Pq4JNP7Qiw8UFnJwcK+tXy+Wj6PLEvPgHSHv5UgwA1IQIwwyFAyLJin9RoxYgAzAQIkPwNmf26busC+OIx5TDqo5nDT+F%2FSS%2F9CYzwb+No49zNy2evkYv0LywGGAXUvp6eSneycqOic0w20k7CNgKE7jJunSGLACTCxF27ylmQc98T5MQUH49swd+I0HPXslLKnT0N+wnkrTKi9JZL%2FL9i1SorMmdeQ4TQQ7OFMxIMzGD45w8nUL1im7efENZLJpgPSw0pfz0cdt4U3230Td%2FTvx2R6d2FrHhEWLkq5PELOMsRPHCPnAZGv1xJteL7jbJiaW3sB2nDvPC%2FosSYvjRQz4cJ6n7KO3rYQL7M+L6nVtfDVRAEQRAEQRAEQRAEIZ5%2FSAXmdfXaoQsAAAAASUVORK5CYII%3D&cacheSeconds=3600">
|
||||
</a>
|
||||
<a target="_black" href="https://space.bilibili.com/410503457">
|
||||
<img alt="bilibili" src="https://img.shields.io/badge/dynamic/json?url=https://api.bilibili.com/x/relation/stat?vmid=410503457&query=data.follower&color=282c34&label=冰哥B站&labelColor=FE7398&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAD7ElEQVR4nO2dW9WrMBCFK6ESkFAJSKiESqgEHCABCZWAhEpAAhL2ecik5dDc%2FpXLBDLfWnlqy0xmJ5BMQnq5CIIgCIIgCIIgCIIgCEIBAHQAemYfrgCunD6wAKAHsEKxALgx+bCQD8%2FS9tmgVqeDr1lLigDgZvDhXso+K9TyTBQRwRJ8AHjntl0Flh5QRAQK%2FmKxPeayWx2OXpBNBKiHvi34b7T2MC4pAvW6twR%2FRwkRKPizBN8CgEcuESj4Lwm+BwBjahEk+H8EwJRKhOaCDzW8e1JLfkUUH1NgmR3XmHffHR1l+72BSs8d7w8U+JDAnZERQMcV+CtUi7dNqFqibB4J7vtrq7xKCuAasbTMXCL4T+5aVk6+2xHUrWdhruAR6HIJcOeu2UHI8zyAe2ytWfEdWz9PVvQ8YAmIQ5dDAB9LFsMVAv8oMO2zAGrC5WNIarRiAuKR9jYEd9pY08aa6uUzIHGRdkgKd8pY0yc1WjEBAqypDYoAG0QAZkQAZkQAZkQAZk4vANQenjsSzS3I%2FwcSbXU5jQBUkRtdf4Rar90v8kSv3+I3ffCCSpk8I%2Fw+lgDkdI%2Fv2rEp2CaiWm1AsDQLlDAD+dlFXLMeAaCSeLZdaSFE5VUQNot38cKuEeBgAsSuG0flVZBmEanbXfNQAsS0fgBYIn2fIu3%2FBBMHEyBmDXlFfA8IzeHb+Ems4WAChKykrVA9ZfsQTL57jXzRg4A5wC%2FA8N4ADiZAZwm2XjW75Qh2KOTfA0p4kygPw28OJcCVgn3nDnYo2EwEYRgGH0qAMyICMCMCMCMCMCMCMCMCMCMCfP3qwHDOQ4AAUekTk8FaBRihJnZdYbvtCGC7LvmkM63GjVDINPFrQgCq5ETXfmMzI90FXzPvfqt7x4rEu%2FZaEcCUxFvgz2zO+BUn6UkoaEEAsptiMSX5e8FoRYCN7cVgb4Vq7U%2FH50Pq4JNP7Qiw8UFnJwcK+tXy+Wj6PLEvPgHSHv5UgwA1IQIwwyFAyLJin9RoxYgAzAQIkPwNmf26busC+OIx5TDqo5nDT+F%2FSS%2F9CYzwb+No49zNy2evkYv0LywGGAXUvp6eSneycqOic0w20k7CNgKE7jJunSGLACTCxF27ylmQc98T5MQUH49swd+I0HPXslLKnT0N+wnkrTKi9JZL%2FL9i1SorMmdeQ4TQQ7OFMxIMzGD45w8nUL1im7efENZLJpgPSw0pfz0cdt4U3230Td%2FTvx2R6d2FrHhEWLkq5PELOMsRPHCPnAZGv1xJteL7jbJiaW3sB2nDvPC%2FosSYvjRQz4cJ6n7KO3rYQL7M+L6nVtfDVRAEQRAEQRAEQRAEIZ5%2FSAXmdfXaoQsAAAAASUVORK5CYII%3D&cacheSeconds=3600">
|
||||
</a>
|
||||
<a href="https://github.com/hawk86104/icegl-three-vue-tres" target="_blank">
|
||||
<img src="https://img.shields.io/github/stars/hawk86104/icegl-three-vue-tres" />
|
||||
</a>
|
||||
@ -43,6 +42,9 @@
|
||||
<a href="https://github.com/hawk86104/icegl-three-vue-tres" target="_blank">
|
||||
<img src="https://img.shields.io/github/license/hawk86104/icegl-three-vue-tres" />
|
||||
</a>
|
||||
<a target="_black" href="https://space.bilibili.com/384558900">
|
||||
<img alt="bilibili" src="https://img.shields.io/badge/dynamic/json?url=https://api.bilibili.com/x/relation/stat?vmid=384558900&query=data.follower&color=282c34&label=地虎B站&labelColor=FE7398&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAD7ElEQVR4nO2dW9WrMBCFK6ESkFAJSKiESqgEHCABCZWAhEpAAhL2ecik5dDc%2FpXLBDLfWnlqy0xmJ5BMQnq5CIIgCIIgCIIgCIIgCEIBAHQAemYfrgCunD6wAKAHsEKxALgx+bCQD8%2FS9tmgVqeDr1lLigDgZvDhXso+K9TyTBQRwRJ8AHjntl0Flh5QRAQK%2FmKxPeayWx2OXpBNBKiHvi34b7T2MC4pAvW6twR%2FRwkRKPizBN8CgEcuESj4Lwm+BwBjahEk+H8EwJRKhOaCDzW8e1JLfkUUH1NgmR3XmHffHR1l+72BSs8d7w8U+JDAnZERQMcV+CtUi7dNqFqibB4J7vtrq7xKCuAasbTMXCL4T+5aVk6+2xHUrWdhruAR6HIJcOeu2UHI8zyAe2ytWfEdWz9PVvQ8YAmIQ5dDAB9LFsMVAv8oMO2zAGrC5WNIarRiAuKR9jYEd9pY08aa6uUzIHGRdkgKd8pY0yc1WjEBAqypDYoAG0QAZkQAZkQAZkQAZk4vANQenjsSzS3I%2FwcSbXU5jQBUkRtdf4Rar90v8kSv3+I3ffCCSpk8I%2Fw+lgDkdI%2Fv2rEp2CaiWm1AsDQLlDAD+dlFXLMeAaCSeLZdaSFE5VUQNot38cKuEeBgAsSuG0flVZBmEanbXfNQAsS0fgBYIn2fIu3%2FBBMHEyBmDXlFfA8IzeHb+Ems4WAChKykrVA9ZfsQTL57jXzRg4A5wC%2FA8N4ADiZAZwm2XjW75Qh2KOTfA0p4kygPw28OJcCVgn3nDnYo2EwEYRgGH0qAMyICMCMCMCMCMCMCMCMCMCMCfP3qwHDOQ4AAUekTk8FaBRihJnZdYbvtCGC7LvmkM63GjVDINPFrQgCq5ETXfmMzI90FXzPvfqt7x4rEu%2FZaEcCUxFvgz2zO+BUn6UkoaEEAsptiMSX5e8FoRYCN7cVgb4Vq7U%2FH50Pq4JNP7Qiw8UFnJwcK+tXy+Wj6PLEvPgHSHv5UgwA1IQIwwyFAyLJin9RoxYgAzAQIkPwNmf26busC+OIx5TDqo5nDT+F%2FSS%2F9CYzwb+No49zNy2evkYv0LywGGAXUvp6eSneycqOic0w20k7CNgKE7jJunSGLACTCxF27ylmQc98T5MQUH49swd+I0HPXslLKnT0N+wnkrTKi9JZL%2FL9i1SorMmdeQ4TQQ7OFMxIMzGD45w8nUL1im7efENZLJpgPSw0pfz0cdt4U3230Td%2FTvx2R6d2FrHhEWLkq5PELOMsRPHCPnAZGv1xJteL7jbJiaW3sB2nDvPC%2FosSYvjRQz4cJ6n7KO3rYQL7M+L6nVtfDVRAEQRAEQRAEQRAEIZ5%2FSAXmdfXaoQsAAAAASUVORK5CYII%3D&cacheSeconds=3600">
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
@ -4,7 +4,7 @@
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2023-10-21 15:34:19
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-03-26 17:20:38
|
||||
* @LastEditTime: 2024-08-14 09:41:19
|
||||
*/
|
||||
import { reactive } from 'vue'
|
||||
import { access, request } from '@fesjs/fes'
|
||||
@ -43,7 +43,7 @@ export default function userModel () {
|
||||
})
|
||||
.catch((err) => {
|
||||
// 处理异常
|
||||
console.log(err, '请连接网络,获得插件的更新')
|
||||
console.log(err, '请连接网络,获得样例的更新')
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
<TresGridHelper :position-y="0.1" />
|
||||
</TresCanvas>
|
||||
<h1 class="text-center text-white w-full absolute">若需查看插件中心,请运行:npm run pre.dev</h1>
|
||||
<h1 class="text-center text-white w-full absolute">若需查看样例中心,请运行:npm run pre.dev</h1>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
@ -4,7 +4,7 @@
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2024-03-13 15:00:34
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-03-14 08:12:03
|
||||
* @LastEditTime: 2024-08-12 16:19:33
|
||||
-->
|
||||
<template>
|
||||
<div v-if="!hasFinishLoading" class="absolute bg-grey-600 t-0 l-0 w-full h-full z-99999999 flex justify-center items-center text-black font-mono bg-black">
|
||||
@ -21,19 +21,37 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { hasPlugin } from '@/common/utils'
|
||||
import { useProgress } from '@tresjs/cientos'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
isDemo?: boolean
|
||||
showProgress?: boolean
|
||||
useResourceManager?: boolean
|
||||
}>(),
|
||||
{
|
||||
isDemo: false,
|
||||
showProgress: true,
|
||||
useResourceManager: false,
|
||||
},
|
||||
)
|
||||
const { hasFinishLoading, progress } = await useProgress()
|
||||
|
||||
let progress = null as any
|
||||
let hasFinishLoading = null as any
|
||||
|
||||
if (props.useResourceManager) {
|
||||
if (hasPlugin('resourceManager', '资源管理器插件')) {
|
||||
const modules = import.meta.glob('PLS/resourceManager/index.js')
|
||||
const { Resource } = await modules['/src/plugins/resourceManager/index.js']()
|
||||
progress = Resource.progress
|
||||
hasFinishLoading = Resource.hasAllFinished
|
||||
}
|
||||
} else {
|
||||
const uP = await useProgress()
|
||||
progress = uP.progress
|
||||
hasFinishLoading = uP.hasFinishLoading
|
||||
}
|
||||
|
||||
const animloop = () => {
|
||||
if (progress.value++ > 100) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2024-03-12 21:53:22
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-05-30 17:51:33
|
||||
* @LastEditTime: 2024-08-12 11:10:25
|
||||
-->
|
||||
<template>
|
||||
<div v-if="!hasFinishLoading" class="absolute bg-grey-600 t-0 l-0 w-full h-full z-99999999 flex justify-center items-center text-black font-mono bg-black">
|
||||
@ -23,6 +23,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { hasPlugin } from '@/common/utils'
|
||||
import { useProgress } from '@tresjs/cientos'
|
||||
|
||||
const props = withDefaults(
|
||||
@ -30,15 +31,31 @@ const props = withDefaults(
|
||||
styleNum?: number
|
||||
isDemo?: boolean
|
||||
showProgress?: boolean
|
||||
useResourceManager?: boolean
|
||||
}>(),
|
||||
{
|
||||
styleNum: 0,
|
||||
isDemo: false,
|
||||
showProgress: true,
|
||||
useResourceManager: false,
|
||||
},
|
||||
)
|
||||
|
||||
const { hasFinishLoading, progress } = await useProgress()
|
||||
let progress = null as any
|
||||
let hasFinishLoading = null as any
|
||||
|
||||
if (props.useResourceManager) {
|
||||
if (hasPlugin('resourceManager', '资源管理器插件')) {
|
||||
const modules = import.meta.glob('PLS/resourceManager/index.js')
|
||||
const { Resource } = await modules['/src/plugins/resourceManager/index.js']()
|
||||
progress = Resource.progress
|
||||
hasFinishLoading = Resource.hasAllFinished
|
||||
}
|
||||
} else {
|
||||
const uP = await useProgress()
|
||||
progress = uP.progress
|
||||
hasFinishLoading = uP.hasFinishLoading
|
||||
}
|
||||
|
||||
const animloop = () => {
|
||||
if (progress.value++ > 100) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2024-03-12 19:56:21
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-06-11 18:06:21
|
||||
* @LastEditTime: 2024-08-12 11:11:20
|
||||
-->
|
||||
<template>
|
||||
<div v-if="!hasFinishLoading" class="absolute bg-grey-600 t-0 l-0 w-full h-full z-99999999 flex justify-center items-center text-black font-mono bg-black">
|
||||
@ -79,6 +79,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { hasPlugin } from '@/common/utils'
|
||||
import { useProgress } from '@tresjs/cientos'
|
||||
|
||||
const props = withDefaults(
|
||||
@ -86,14 +87,30 @@ const props = withDefaults(
|
||||
styleNum?: number
|
||||
isDemo?: boolean
|
||||
showProgress?: boolean
|
||||
useResourceManager?: boolean
|
||||
}>(),
|
||||
{
|
||||
styleNum: 0,
|
||||
isDemo: false,
|
||||
showProgress: true,
|
||||
useResourceManager: false,
|
||||
},
|
||||
)
|
||||
const { hasFinishLoading, progress } = await useProgress()
|
||||
let progress = null as any
|
||||
let hasFinishLoading = null as any
|
||||
|
||||
if (props.useResourceManager) {
|
||||
if (hasPlugin('resourceManager', '资源管理器插件')) {
|
||||
const modules = import.meta.glob('PLS/resourceManager/index.js')
|
||||
const { Resource } = await modules['/src/plugins/resourceManager/index.js']()
|
||||
progress = Resource.progress
|
||||
hasFinishLoading = Resource.hasAllFinished
|
||||
}
|
||||
} else {
|
||||
const uP = await useProgress()
|
||||
progress = uP.progress
|
||||
hasFinishLoading = uP.hasFinishLoading
|
||||
}
|
||||
|
||||
const animloop = () => {
|
||||
if (progress.value++ > 100) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2024-03-13 18:46:19
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-03-20 10:14:37
|
||||
* @LastEditTime: 2024-08-12 11:05:50
|
||||
-->
|
||||
<template>
|
||||
<div v-if="!hasFinishLoading" class="absolute bg-grey-600 t-0 l-0 w-full h-full z-99999999 flex justify-center items-center text-black font-mono bg-black">
|
||||
@ -20,19 +20,36 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { hasPlugin } from '@/common/utils'
|
||||
import { useProgress } from '@tresjs/cientos'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
isDemo?: boolean
|
||||
showProgress?: boolean
|
||||
useResourceManager?: boolean
|
||||
}>(),
|
||||
{
|
||||
isDemo: false,
|
||||
showProgress: true,
|
||||
useResourceManager: false,
|
||||
},
|
||||
)
|
||||
const { hasFinishLoading, progress } = await useProgress()
|
||||
let progress = null as any
|
||||
let hasFinishLoading = null as any
|
||||
|
||||
if (props.useResourceManager) {
|
||||
if (hasPlugin('resourceManager', '资源管理器插件')) {
|
||||
const modules = import.meta.glob('PLS/resourceManager/index.js')
|
||||
const { Resource } = await modules['/src/plugins/resourceManager/index.js']()
|
||||
progress = Resource.progress
|
||||
hasFinishLoading = Resource.hasAllFinished
|
||||
}
|
||||
} else {
|
||||
const uP = await useProgress()
|
||||
progress = uP.progress
|
||||
hasFinishLoading = uP.hasFinishLoading
|
||||
}
|
||||
|
||||
const animloop = () => {
|
||||
if (progress.value++ > 100) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2024-03-13 17:14:11
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-03-13 17:22:47
|
||||
* @LastEditTime: 2024-08-12 11:09:17
|
||||
-->
|
||||
<template>
|
||||
<div
|
||||
@ -31,19 +31,36 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { hasPlugin } from '@/common/utils'
|
||||
import { useProgress } from '@tresjs/cientos'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
isDemo?: boolean
|
||||
showProgress?: boolean
|
||||
useResourceManager?: boolean
|
||||
}>(),
|
||||
{
|
||||
isDemo: false,
|
||||
showProgress: true,
|
||||
useResourceManager: false,
|
||||
},
|
||||
)
|
||||
const { hasFinishLoading, progress } = await useProgress()
|
||||
let progress = null as any
|
||||
let hasFinishLoading = null as any
|
||||
|
||||
if (props.useResourceManager) {
|
||||
if (hasPlugin('resourceManager', '资源管理器插件')) {
|
||||
const modules = import.meta.glob('PLS/resourceManager/index.js')
|
||||
const { Resource } = await modules['/src/plugins/resourceManager/index.js']()
|
||||
progress = Resource.progress
|
||||
hasFinishLoading = Resource.hasAllFinished
|
||||
}
|
||||
} else {
|
||||
const uP = await useProgress()
|
||||
progress = uP.progress
|
||||
hasFinishLoading = uP.hasFinishLoading
|
||||
}
|
||||
|
||||
const animloop = () => {
|
||||
if (progress.value++ > 100) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2024-03-13 17:14:11
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-03-14 08:13:11
|
||||
* @LastEditTime: 2024-08-12 11:06:13
|
||||
-->
|
||||
<template>
|
||||
<div v-if="!hasFinishLoading" class="absolute bg-grey-600 t-0 l-0 w-full h-full z-99999999 flex justify-center items-center text-black font-mono bg-black">
|
||||
@ -28,19 +28,37 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { hasPlugin } from '@/common/utils'
|
||||
import { useProgress } from '@tresjs/cientos'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
isDemo?: boolean
|
||||
showProgress?: boolean
|
||||
useResourceManager?: boolean
|
||||
}>(),
|
||||
{
|
||||
isDemo: false,
|
||||
showProgress: true,
|
||||
useResourceManager: false,
|
||||
},
|
||||
)
|
||||
const { hasFinishLoading, progress } = await useProgress()
|
||||
|
||||
let progress = null as any
|
||||
let hasFinishLoading = null as any
|
||||
|
||||
if (props.useResourceManager) {
|
||||
if (hasPlugin('resourceManager', '资源管理器插件')) {
|
||||
const modules = import.meta.glob('PLS/resourceManager/index.js')
|
||||
const { Resource } = await modules['/src/plugins/resourceManager/index.js']()
|
||||
progress = Resource.progress
|
||||
hasFinishLoading = Resource.hasAllFinished
|
||||
}
|
||||
} else {
|
||||
const uP = await useProgress()
|
||||
progress = uP.progress
|
||||
hasFinishLoading = uP.hasFinishLoading
|
||||
}
|
||||
|
||||
const animloop = () => {
|
||||
if (progress.value++ > 100) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2024-03-12 21:53:22
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-03-13 20:54:42
|
||||
* @LastEditTime: 2024-08-12 11:07:20
|
||||
-->
|
||||
|
||||
<script setup lang="ts">
|
||||
|
@ -1,32 +0,0 @@
|
||||
<!--
|
||||
* @Description:
|
||||
* @Version: 1.668
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2024-01-09 15:02:26
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-07-18 10:38:20
|
||||
-->
|
||||
|
||||
<template>
|
||||
<TresCanvas renderMode="manual" window-size ref="tcRef">
|
||||
<TresPerspectiveCamera :position="[10, 10, 10]" />
|
||||
<TresAmbientLight :intensity="1" />
|
||||
<OrbitControls />
|
||||
<TresGridHelper :args="[10, 10]" />
|
||||
<ecLayerShaderPass />
|
||||
</TresCanvas>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { OrbitControls } from '@tresjs/cientos'
|
||||
import ecLayerShaderPass from '../../components/ecLayerShaderPass.vue'
|
||||
import { watchEffect, ref } from 'vue'
|
||||
|
||||
const tcRef = ref()
|
||||
watchEffect(() => {
|
||||
if (tcRef.value) {
|
||||
let renderer = tcRef.value.context.renderer.value
|
||||
renderer.autoClear = false
|
||||
}
|
||||
})
|
||||
</script>
|
@ -4,7 +4,7 @@
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2023-10-26 09:20:42
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-07-26 10:13:13
|
||||
* @LastEditTime: 2024-08-12 16:18:13
|
||||
*/
|
||||
export default {
|
||||
name: 'digitalCity',
|
||||
@ -14,7 +14,7 @@ export default {
|
||||
author: '地虎降天龙',
|
||||
website: 'https://gitee.com/hawk86104',
|
||||
state: 'active',
|
||||
require: ['cannon-es'],
|
||||
require: [],
|
||||
preview: [
|
||||
// { "src": "plugins/digitalCity/preview/buildings.mp4", "type": "video", "name": "buildings", "title": "建筑物" },
|
||||
{ src: 'plugins/digitalCity/preview/buildings.png', type: 'img', name: 'buildings', title: '建筑物' },
|
||||
|
@ -1,47 +0,0 @@
|
||||
<!--
|
||||
* @Description:
|
||||
* @Version: 1.668
|
||||
* @Autor: Hawk
|
||||
* @Date: 2023-10-13 09:04:49
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-03-12 19:54:32
|
||||
-->
|
||||
<script setup lang="ts">
|
||||
import { useRenderLoop } from '@tresjs/core'
|
||||
import { OrbitControls, Stars } from '@tresjs/cientos'
|
||||
import { PCFSoftShadowMap, SRGBColorSpace } from 'three'
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
import loading from 'PLS/UIdemo/components/loading/default.vue'
|
||||
import Planet from '../components/lowpolyPlanet/planet.vue'
|
||||
|
||||
const gl = {
|
||||
clearColor: '#11101B',
|
||||
shadows: true,
|
||||
alpha: false,
|
||||
outputColorSpace: SRGBColorSpace,
|
||||
shadowMapType: PCFSoftShadowMap,
|
||||
useLegacyLights: true,
|
||||
}
|
||||
const yRotation = shallowRef(0)
|
||||
useRenderLoop().onLoop(({ delta }) => {
|
||||
yRotation.value += 0.02 * delta
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<loading />
|
||||
<TresCanvas v-bind="gl" window-size>
|
||||
<TresPerspectiveCamera :position="[0, 1, 5]" :fov="75" :near="0.1" :far="1000" />
|
||||
<OrbitControls />
|
||||
|
||||
<TresAmbientLight color="#484068" :intensity="1" />
|
||||
<Suspense>
|
||||
<Planet />
|
||||
</Suspense>
|
||||
<Stars :rotation="[0, yRotation, 0]" :radius="50" :depth="50" :count="5000" :size="0.3" :size-attenuation="true" />
|
||||
<TresPointLight color="#1BFFEF" :position="[0, 0, -8]" :intensity="80" cast-shadow />
|
||||
<TresDirectionalLight :position="[0, 2, 4]" :intensity="3" cast-shadow :shadow-mapSize-width="2048"
|
||||
:shadow-mapSize-height="2048" />
|
||||
</TresCanvas>
|
||||
</template>
|
@ -1,39 +1,41 @@
|
||||
<template>
|
||||
<div v-show="load" class="go-skeleton">
|
||||
<div v-show="repeat == 1">
|
||||
<n-skeleton class="item" v-bind="$attrs"></n-skeleton>
|
||||
</div>
|
||||
<div v-show="repeat == 2">
|
||||
<n-skeleton class="item" v-bind="$attrs"></n-skeleton>
|
||||
<n-skeleton class="item" v-bind="$attrs" style="width: 60%;"></n-skeleton>
|
||||
</div>
|
||||
<div v-show="repeat > 2">
|
||||
<n-skeleton class="item" v-bind="$attrs" :repeat="repeat - 2"></n-skeleton>
|
||||
<n-skeleton class="item" v-bind="$attrs" style="width: 60%;"></n-skeleton>
|
||||
<n-skeleton class="item" v-bind="$attrs" style="width: 50%;"></n-skeleton>
|
||||
</div>
|
||||
<div v-show="repeat == 1">
|
||||
<n-skeleton class="item" v-bind="$attrs"></n-skeleton>
|
||||
</div>
|
||||
<div v-show="repeat == 2">
|
||||
<n-skeleton class="item" v-bind="$attrs"></n-skeleton>
|
||||
<n-skeleton class="item" v-bind="$attrs" style="width: 60%"></n-skeleton>
|
||||
</div>
|
||||
<div v-show="repeat > 2">
|
||||
<n-skeleton class="item" v-bind="$attrs" :repeat="repeat - 2"></n-skeleton>
|
||||
<n-skeleton class="item" v-bind="$attrs" style="width: 60%"></n-skeleton>
|
||||
<n-skeleton class="item" v-bind="$attrs" style="width: 50%"></n-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
defineProps({
|
||||
repeat: {
|
||||
type: Number,
|
||||
default: 1
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
load: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@include go("skeleton") {
|
||||
@include go('skeleton') {
|
||||
.item {
|
||||
margin-top: 5px;
|
||||
margin-left: 5px;
|
||||
margin-top: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
& {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -13,16 +13,16 @@
|
||||
}
|
||||
|
||||
.go-flex-center {
|
||||
display: flex;
|
||||
display : flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
align-items : center;
|
||||
text-align : center;
|
||||
}
|
||||
|
||||
.go-flex-items-center {
|
||||
display: flex;
|
||||
display : flex;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
text-align : center;
|
||||
}
|
||||
|
||||
.go-flex-no-wrap {
|
||||
@ -30,9 +30,9 @@
|
||||
}
|
||||
|
||||
.go-absolute-center {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
position : absolute;
|
||||
top : 50%;
|
||||
left : 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@ -50,64 +50,80 @@
|
||||
.go-background-filter {
|
||||
backdrop-filter: $--filter-blur-base;
|
||||
@include fetch-bg-color("filter-color");
|
||||
box-shadow: $--border-shadow;
|
||||
|
||||
& {
|
||||
box-shadow: $--border-shadow;
|
||||
}
|
||||
}
|
||||
|
||||
// 毛玻璃
|
||||
.go-background-filter-shallow {
|
||||
backdrop-filter: $--filter-blur-base;
|
||||
@include fetch-bg-color("filter-color-shallow");
|
||||
box-shadow: $--border-shadow;
|
||||
|
||||
& {
|
||||
box-shadow: $--border-shadow;
|
||||
}
|
||||
}
|
||||
|
||||
// 边框圆角
|
||||
.go-border-radius {
|
||||
border-radius: $--border-radius-base;
|
||||
overflow: hidden;
|
||||
overflow : hidden;
|
||||
}
|
||||
|
||||
// 背景斑点需配合 @mixin background-image 使用
|
||||
.go-point-bg {
|
||||
@include fetch-theme-custom("background-color", "background-color1");
|
||||
background-size: 15px 15px, 15px 15px;
|
||||
|
||||
& {
|
||||
background-size: 15px 15px, 15px 15px;
|
||||
}
|
||||
}
|
||||
|
||||
// 省略号
|
||||
.go-ellipsis-1 {
|
||||
overflow: hidden;
|
||||
overflow : hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
word-break: break-all;
|
||||
white-space : nowrap;
|
||||
word-break : break-all;
|
||||
}
|
||||
|
||||
// class:m-1 => margin:1em
|
||||
// class:mt-1 => margin-top:1em
|
||||
// m-0|mt-0|mx-0|my-0|p-0|pt-0|...
|
||||
|
||||
@each $typekey, $type in $spacing-types {
|
||||
@each $typekey,
|
||||
$type in $spacing-types {
|
||||
|
||||
//.m-1
|
||||
@each $sizekey, $size in $spacing-sizes {
|
||||
@each $sizekey,
|
||||
$size in $spacing-sizes {
|
||||
.go-#{$typekey}-#{$sizekey} {
|
||||
#{$type}: $size * $spacing-base-size;
|
||||
}
|
||||
}
|
||||
|
||||
//.mx-1
|
||||
@each $sizekey, $size in $spacing-sizes {
|
||||
@each $sizekey,
|
||||
$size in $spacing-sizes {
|
||||
.go-#{$typekey}x-#{$sizekey} {
|
||||
#{$type}-left: $size * $spacing-base-size;
|
||||
#{$type}-left : $size * $spacing-base-size;
|
||||
#{$type}-right: $size * $spacing-base-size;
|
||||
}
|
||||
|
||||
.go-#{$typekey}y-#{$sizekey} {
|
||||
#{$type}-top: $size * $spacing-base-size;
|
||||
#{$type}-top : $size * $spacing-base-size;
|
||||
#{$type}-bottom: $size * $spacing-base-size;
|
||||
}
|
||||
}
|
||||
|
||||
//.mt-1
|
||||
@each $directionkey, $direction in $spacing-directions {
|
||||
@each $sizekey, $size in $spacing-sizes {
|
||||
@each $directionkey,
|
||||
$direction in $spacing-directions {
|
||||
|
||||
@each $sizekey,
|
||||
$size in $spacing-sizes {
|
||||
.go-#{$typekey}#{$directionkey}-#{$sizekey} {
|
||||
#{$type}-#{$direction}: $size * $spacing-base-size;
|
||||
}
|
||||
@ -122,6 +138,7 @@
|
||||
.go-d-inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.go-d-block {
|
||||
display: block;
|
||||
}
|
||||
}
|
70
src/plugins/operationTool/components/drawArrows.vue
Normal file
@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<primitive :object="model" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, watchEffect } from 'vue'
|
||||
import * as THREE from 'three'
|
||||
import { SelectionBox } from 'three/examples/jsm/interactive/SelectionBox.js'
|
||||
import { SelectionHelper } from 'three/examples/jsm/interactive/SelectionHelper'
|
||||
import { useTresContext, useRenderLoop } from '@tresjs/core'
|
||||
import { useGLTF } from '@tresjs/cientos'
|
||||
|
||||
const { scene: model, nodes } = await useGLTF('/plugins/operationTool/model/湖中小亭/湖中小亭.gltf')
|
||||
const { camera, renderer, scene, sizes, raycaster, controls } = useTresContext()
|
||||
|
||||
let mouse = new THREE.Vector2()
|
||||
let points = []
|
||||
let polygonMesh = null
|
||||
const planeGeometry = new THREE.PlaneGeometry(100, 100)
|
||||
const planeMaterial = new THREE.MeshBasicMaterial({ visible: false })
|
||||
const plane = new THREE.Mesh(planeGeometry, planeMaterial)
|
||||
scene.value.add(plane)
|
||||
let init = function () {
|
||||
window.addEventListener('click', onMouseClick, false)
|
||||
}
|
||||
|
||||
let onMouseClick = function (event) {
|
||||
// 将鼠标坐标转换到[-1, 1]范围
|
||||
mouse.x = (event.clientX / window.innerWidth) * 2 - 1
|
||||
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
|
||||
|
||||
// 使用raycaster检测鼠标点击的位置
|
||||
raycaster.value.setFromCamera(mouse, camera.value)
|
||||
|
||||
// 默认点击在Z=0的平面上
|
||||
const intersects = raycaster.value.intersectObject(plane)
|
||||
if (intersects.length > 0) {
|
||||
const point = intersects[0].point
|
||||
points.push(new THREE.Vector3(point.x, point.y, 0))
|
||||
updatePolygon()
|
||||
}
|
||||
}
|
||||
|
||||
let updatePolygon = function () {
|
||||
debugger
|
||||
if (polygonMesh != null) {
|
||||
scene.value.remove(polygonMesh)
|
||||
}
|
||||
|
||||
if (points.length > 2) {
|
||||
const shape = new THREE.Shape()
|
||||
shape.moveTo(points[0].x, points[0].y)
|
||||
for (let i = 1; i < points.length; i++) {
|
||||
shape.lineTo(points[i].x, points[i].y)
|
||||
}
|
||||
shape.lineTo(points[0].x, points[0].y) // 闭合多边形
|
||||
const geometry = new THREE.ShapeGeometry(shape)
|
||||
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, side: THREE.DoubleSide })
|
||||
polygonMesh = new THREE.Mesh(geometry, material)
|
||||
scene.value.add(polygonMesh)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
watchEffect(() => {})
|
||||
</script>
|
||||
<style>
|
||||
</style>
|
73
src/plugins/operationTool/components/frameSelect.vue
Normal file
@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<primitive :object="model" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, watchEffect } from 'vue'
|
||||
import * as THREE from 'three'
|
||||
import { SelectionBox } from 'three/examples/jsm/interactive/SelectionBox.js'
|
||||
import { SelectionHelper } from 'three/examples/jsm/interactive/SelectionHelper'
|
||||
import { useTresContext, useRenderLoop} from '@tresjs/core'
|
||||
import { useGLTF} from '@tresjs/cientos'
|
||||
const { scene: model, nodes } = await useGLTF('/plugins/operationTool/model/湖中小亭/湖中小亭.gltf')
|
||||
const { camera, renderer, scene, sizes, raycaster, controls } = useTresContext()
|
||||
|
||||
let selectionBox = new SelectionBox(camera.value, scene.value)
|
||||
let helper = new SelectionHelper(renderer.value, 'selectBox')
|
||||
let init = function () {
|
||||
document.addEventListener('mousedown', onMouseDown, false)
|
||||
document.addEventListener('mousemove', onMouseMove, false)
|
||||
document.addEventListener('mouseup', onMouseUp, false)
|
||||
}
|
||||
|
||||
let onMouseDown = function (event) {
|
||||
|
||||
console.log(controls.value);
|
||||
|
||||
for (const item of selectionBox.collection) {
|
||||
if (item instanceof THREE.Mesh) {
|
||||
item.material.emissive.set(0x000000)
|
||||
}
|
||||
}
|
||||
selectionBox.collection.length = 0
|
||||
selectionBox.startPoint.set((event.clientX / sizes.width.value) * 2 - 1, -(event.clientY / sizes.height.value) * 2 + 1, 0.5)
|
||||
}
|
||||
|
||||
let onMouseMove = function (event) {
|
||||
if (helper.isDown) {
|
||||
|
||||
selectionBox.endPoint.set((event.clientX / sizes.width.value) * 2 - 1, -(event.clientY / sizes.height.value) * 2 + 1, 0.5)
|
||||
const allSelected = selectionBox.select()
|
||||
console.log("allSelected",allSelected);
|
||||
|
||||
for (let i = 0; i < allSelected.length; i++) {
|
||||
let item = allSelected[i]
|
||||
if (item instanceof THREE.Mesh) {
|
||||
item.material.emissive.set(0xf80000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let onMouseUp = function (event) {
|
||||
const allSelected = selectionBox.select()
|
||||
selectionBox.endPoint.set((event.clientX / sizes.width.value) * 2 - 1, -(event.clientY / sizes.height.value) * 2 + 1, 0.5)
|
||||
for (let i = 0; i < allSelected.length; i++) {
|
||||
let item = allSelected[i]
|
||||
if (item instanceof THREE.Mesh) {
|
||||
item.material.emissive.set(0x000000)
|
||||
}
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
watchEffect(() => {})
|
||||
</script>
|
||||
<style>
|
||||
.selectBox {
|
||||
border: 1px solid #55aaff;
|
||||
background-color: rgba(75, 160, 255, 0.3);
|
||||
position: fixed;
|
||||
}
|
||||
</style>
|
15
src/plugins/operationTool/config.js
Normal file
@ -0,0 +1,15 @@
|
||||
export default {
|
||||
"name": "operationTool",
|
||||
"title": "THREE操作工具",
|
||||
"intro": "THREE操作工具",
|
||||
"version": "0.0.1",
|
||||
"author": "Jsonco",
|
||||
"website": "icegl.cn",
|
||||
"state": "active",
|
||||
"require": [],
|
||||
"preview": [
|
||||
{ "src": "plugins/operationTool/preview/炸开.png", "type": "img", "name": "explode", "title": "炸开与还原" },
|
||||
{ "src": "plugins/operationTool/preview/框选.png", "type": "img", "name": "frameSelect", "title": "框选实例" },
|
||||
// { "src": "plugins/AMapGIS/preview/cubeMesh.png", "type": "img", "name": "drawArrows", "title": "绘制箭头" },
|
||||
]
|
||||
}
|
38
src/plugins/operationTool/pages/drawArrows.vue
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
<template>
|
||||
<TresCanvas clearColor="#201919" window-size v-bind="state">
|
||||
<TresPerspectiveCamera :fov="60" :near="0.1" :far="2000" :position="[0, 10, -28]" />
|
||||
<TresAmbientLight :intensity="1" />
|
||||
<OrbitControls v-bind="controlsState" />
|
||||
<Suspense>
|
||||
<drawArrows />
|
||||
</Suspense>
|
||||
</TresCanvas>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted, ref } from 'vue'
|
||||
import { OrbitControls, useGLTF } from '@tresjs/cientos'
|
||||
import { useRenderLoop, useTexture } from '@tresjs/core'
|
||||
import { Pane } from 'tweakpane'
|
||||
import drawArrows from "../components/drawArrows.vue"
|
||||
|
||||
const state = reactive({
|
||||
// windowSize: true,
|
||||
alpha: true,
|
||||
antialias: true,
|
||||
autoClear: false,
|
||||
disableRender: true,
|
||||
})
|
||||
const controlsState = reactive({
|
||||
enableDamping: false,
|
||||
enableZoom: false,
|
||||
autoRotate: false,
|
||||
enablePan: false,
|
||||
enableRotate: false,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style >
|
||||
|
||||
</style>
|
114
src/plugins/operationTool/pages/explode.vue
Normal file
@ -0,0 +1,114 @@
|
||||
|
||||
<template>
|
||||
<TresCanvas clearColor="#201919" window-size v-bind="state">
|
||||
<TresPerspectiveCamera :fov="60" :near="0.1" :far="2000" :position="[0, 10, -28]" />
|
||||
<TresAmbientLight :intensity="1" />
|
||||
<OrbitControls />
|
||||
<Suspense>
|
||||
<primitive :object="model" />
|
||||
</Suspense>
|
||||
</TresCanvas>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted, ref } from 'vue'
|
||||
import { OrbitControls, useGLTF } from '@tresjs/cientos'
|
||||
import { useRenderLoop, useTexture } from '@tresjs/core'
|
||||
import { Pane } from 'tweakpane'
|
||||
import * as TWEEN from '@tweenjs/tween.js'
|
||||
import _ from 'Lodash'
|
||||
import * as THREE from 'three'
|
||||
|
||||
const { scene: model, nodes } = await useGLTF('/plugins/operationTool/model/湖中小亭/湖中小亭.gltf')
|
||||
model.updateMatrixWorld(true) // 强制更新
|
||||
let ifExplode = false
|
||||
const state = reactive({
|
||||
// windowSize: true,
|
||||
alpha: true,
|
||||
antialias: true,
|
||||
autoClear: false,
|
||||
disableRender: true,
|
||||
})
|
||||
const buildingsLinesState = reactive({
|
||||
width: 1.0,
|
||||
color: '#000',
|
||||
opacity: 1.0,
|
||||
show: true,
|
||||
})
|
||||
const disintegrate = function () {
|
||||
model.children.forEach((child, index) => {
|
||||
if (child.isMesh) {
|
||||
const boundingBox = new THREE.Box3().setFromObject(child)
|
||||
const childCenter = new THREE.Vector3()
|
||||
boundingBox.getCenter(childCenter)
|
||||
// let pos = childCenter.multiplyScalar(2);
|
||||
new TWEEN.Tween(childCenter)
|
||||
.to(new THREE.Vector3(0,0,0), 3000)
|
||||
.onUpdate((val) => {
|
||||
child.position.copy(val)
|
||||
})
|
||||
.start()
|
||||
.onComplete((val) => {
|
||||
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
const explode = function () {
|
||||
model.children.forEach((child, index) => {
|
||||
let origin = _.cloneDeep(child.position)
|
||||
child.userData.explode = {
|
||||
state: false,
|
||||
explode: origin,
|
||||
}
|
||||
if (child.isMesh) {
|
||||
const boundingBox = new THREE.Box3().setFromObject(child)
|
||||
const childCenter = new THREE.Vector3()
|
||||
boundingBox.getCenter(childCenter)
|
||||
let pos = childCenter.multiplyScalar(2);
|
||||
new TWEEN.Tween(origin)
|
||||
.to(pos, 3000)
|
||||
.onUpdate((val) => {
|
||||
child.position.copy(val)
|
||||
})
|
||||
.start()
|
||||
.onComplete((val) => {
|
||||
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
|
||||
const paneControl = new Pane({
|
||||
title: '炸开与还原',
|
||||
expanded: true,
|
||||
})
|
||||
// paneControl.containerElem_.style.top = '54px'
|
||||
|
||||
const f1 = paneControl.addFolder({
|
||||
title: '参数',
|
||||
})
|
||||
|
||||
f1.addButton({
|
||||
title: '炸开',
|
||||
label: '炸开', // optional
|
||||
}).on('click', () => {
|
||||
explode()
|
||||
})
|
||||
f1.addButton({
|
||||
title: '还原',
|
||||
label: '还原', // optional
|
||||
}).on('click', () => {
|
||||
disintegrate()
|
||||
})
|
||||
})
|
||||
const { onLoop } = useRenderLoop()
|
||||
onLoop(({ delta }) => {
|
||||
TWEEN.update()
|
||||
//循环render
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
39
src/plugins/operationTool/pages/frameSelect.vue
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
<template>
|
||||
<TresCanvas clearColor="#201919" window-size v-bind="state">
|
||||
<TresPerspectiveCamera :fov="60" :near="0.1" :far="2000" :position="[0, 10, -28]" />
|
||||
<TresAmbientLight :intensity="1" />
|
||||
<OrbitControls v-bind="controlsState" />
|
||||
<Suspense>
|
||||
<FrameSelect/>
|
||||
</Suspense>
|
||||
</TresCanvas>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted, ref } from 'vue'
|
||||
import { OrbitControls } from '@tresjs/cientos'
|
||||
import FrameSelect from "../components/frameSelect.vue"
|
||||
let ifExplode = false
|
||||
const state = reactive({
|
||||
// windowSize: true,
|
||||
alpha: true,
|
||||
antialias: true,
|
||||
autoClear: false,
|
||||
|
||||
})
|
||||
const controlsState = reactive({
|
||||
enableDamping: false,
|
||||
enableZoom: false,
|
||||
autoRotate: false,
|
||||
enablePan: false,
|
||||
enableRotate: false,
|
||||
makeDefault: true,
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style >
|
||||
|
||||
</style>
|
119
src/plugins/operationTool/shaders/buildingModels.frag
Normal file
@ -0,0 +1,119 @@
|
||||
precision highp float;
|
||||
uniform float u_opacity;
|
||||
uniform vec4 u_baseColor;
|
||||
uniform vec4 u_color;
|
||||
uniform vec4 u_brightColor;
|
||||
uniform vec4 u_windowColor;
|
||||
|
||||
uniform float u_zoom;
|
||||
uniform float u_time;
|
||||
uniform float u_near;
|
||||
uniform float u_far;
|
||||
varying vec2 v_texCoord;
|
||||
varying vec4 v_color;
|
||||
varying float v_lightWeight;
|
||||
|
||||
vec3 getWindowColor(float n,float hot,vec3 brightColor,vec3 darkColor){
|
||||
float s=step(hot,n);
|
||||
vec3 color=mix(brightColor,vec3(1.,1.,1.),n);
|
||||
return mix(darkColor,color,s);
|
||||
}
|
||||
|
||||
float random(vec2 st){
|
||||
return fract(sin(dot(st.xy,vec2(12.9898,78.233)))*43758.5453123);
|
||||
}
|
||||
|
||||
float LinearizeDepth()
|
||||
{
|
||||
float z=gl_FragCoord.z*2.-1.;
|
||||
return(2.*u_near*u_far)/(u_far+u_near-z*(u_far-u_near));
|
||||
}
|
||||
|
||||
vec3 fog(vec3 color,vec3 fogColor,float depth){
|
||||
float fogFactor=clamp(depth,0.,1.);
|
||||
vec3 output_color=mix(fogColor,color,fogFactor);
|
||||
return output_color;
|
||||
}
|
||||
|
||||
float sdRect(vec2 p,vec2 sz){
|
||||
vec2 d=abs(p)-sz;
|
||||
float outside=length(max(d,0.));
|
||||
float inside=min(max(d.x,d.y),0.);
|
||||
return outside+inside;
|
||||
}
|
||||
|
||||
void main(){
|
||||
if(v_color.w==0.){
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
vec3 baseColor=u_color.xyz;
|
||||
vec3 brightColor=u_brightColor.xyz;
|
||||
vec3 windowColor=u_windowColor.xyz;
|
||||
float targetColId=5.;
|
||||
float depth=1.-LinearizeDepth()/u_far*u_zoom;// 深度,调节明暗,远的颜色暗,近的颜色亮
|
||||
vec3 fogColor=vec3(23./255.,31./255.,51./255.);
|
||||
|
||||
if(v_texCoord.x<0.){//顶部颜色
|
||||
vec3 foggedColor=fog(baseColor.xyz+vec3(.12*.9,.2*.9,.3*.9),fogColor,depth);
|
||||
gl_FragColor=vec4(foggedColor,v_color.w*u_opacity);
|
||||
}else{// 侧面颜色
|
||||
|
||||
if(u_zoom<14.){
|
||||
gl_FragColor=v_color;
|
||||
return;
|
||||
}
|
||||
|
||||
if(v_texCoord.x<.01||v_texCoord.x>.99||v_texCoord.y<.01){
|
||||
gl_FragColor=vec4(1.,.7,.25,.5);
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 st=v_texCoord;
|
||||
vec2 UvScale=v_texCoord;
|
||||
vec2 tStep=vec2(.05,.125);
|
||||
vec2 tStart=vec2(tStep.x*.25,tStep.y*.25);
|
||||
vec2 tEnd=vec2(tStep.x*.75,tStep.y*.75);
|
||||
|
||||
float u=mod(UvScale.x,tStep.x);
|
||||
float v=mod(UvScale.y,tStep.y);
|
||||
float ux=floor(UvScale.x/tStep.x);
|
||||
float uy=floor(UvScale.y/tStep.y);
|
||||
float n=random(vec2(ux,uy));
|
||||
float lightP=u_time;
|
||||
float head=1.-step(.005,st.y);
|
||||
/*step3*/
|
||||
// 将窗户颜色和墙面颜色区别开来
|
||||
float sU=step(tStart.x,u)-step(tEnd.x,u);
|
||||
float sV=step(tStart.y,v)-step(tEnd.y,v);
|
||||
vec2 windowSize=vec2(abs(tEnd.x-tStart.x),abs(tEnd.y-tStart.y));
|
||||
float dist=sdRect(vec2(u,v),windowSize);
|
||||
float s=sU*sV;
|
||||
|
||||
float curColId=ux;// floor(UvScale.x / tStep.x);
|
||||
float sCol=step(targetColId-.2,curColId)-step(targetColId+.2,curColId);
|
||||
|
||||
float mLightP=mod(lightP,2.);
|
||||
float sRow=step(mLightP-.2,st.y)-step(mLightP,st.y);
|
||||
if(ux==targetColId){
|
||||
n=0.;
|
||||
}
|
||||
// float hot = min(1.0, abs (sin(u_time/6.0) ) );
|
||||
// float hot = smoothstep(1.0,0.0,timeP);
|
||||
//hot = clamp(hot,0.2,0.8);
|
||||
vec3 color=mix(baseColor,getWindowColor(n,u_time,brightColor,windowColor),s);
|
||||
|
||||
float sFinal=s*sCol*sRow;
|
||||
color+=mix(baseColor,brightColor,sFinal*n);
|
||||
|
||||
if(head==1.){// 顶部亮线
|
||||
color=brightColor;
|
||||
}
|
||||
color=color*v_lightWeight;
|
||||
|
||||
vec3 foggedColor=fog(color,fogColor,depth);
|
||||
|
||||
gl_FragColor=vec4(foggedColor,1.);
|
||||
}
|
||||
|
||||
}
|
47
src/plugins/operationTool/shaders/buildingModels.vert
Normal file
@ -0,0 +1,47 @@
|
||||
precision highp float;
|
||||
#define ambientRatio .5
|
||||
#define diffuseRatio .4
|
||||
#define specularRatio .1
|
||||
|
||||
attribute vec2 faceUv;
|
||||
uniform vec4 u_color;
|
||||
varying vec2 v_texCoord;
|
||||
varying vec4 v_color;
|
||||
varying float v_lightWeight;
|
||||
|
||||
void main(){
|
||||
|
||||
mat4 matModelViewProjection=projectionMatrix*modelViewMatrix;
|
||||
|
||||
v_texCoord=faceUv;
|
||||
|
||||
if(normal==vec3(0.,0.,1.)){
|
||||
v_color=u_color;
|
||||
gl_Position=matModelViewProjection*vec4(position,1.);
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 worldPos=vec3(vec4(position,1.)*modelMatrix);
|
||||
vec3 worldNormal=vec3(vec4(normal,1.)*modelMatrix);// N
|
||||
// //cal light weight 光亮度的权重
|
||||
vec3 viewDir=normalize(cameraPosition-worldPos);// V
|
||||
// 光照的方向, 前上方 Ild = k*I*(N·L)
|
||||
vec3 lightDir=normalize(vec3(0.,-10.,1.));// L
|
||||
vec3 halfDir=normalize(viewDir+lightDir);
|
||||
// //lambert
|
||||
float lambert=dot(worldNormal,lightDir);
|
||||
//specular //反射
|
||||
float specular=pow(max(0.,dot(worldNormal,halfDir)),32.);
|
||||
//sum to light weight (lambert + 环境光) Idiff = Iad + Ild = k*Ia + k*Il*(N·L)
|
||||
float lightWeight=ambientRatio+diffuseRatio*lambert+specularRatio*specular;
|
||||
v_texCoord=faceUv;
|
||||
v_lightWeight=lightWeight;
|
||||
|
||||
// 根据光照方向,调整光线明暗
|
||||
|
||||
// v_lightWeight = pow( 0.0 + 1.0 * abs(dot(worldNormal, worldPos)), 2.0);
|
||||
|
||||
v_color=vec4(u_color.rgb*v_lightWeight,u_color.w);
|
||||
|
||||
gl_Position=matModelViewProjection*vec4(position,1.);
|
||||
}
|
19
src/plugins/operationTool/stores/mapStore.js
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* @Description:
|
||||
* @Version: 1.668
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2024-02-21 14:31:55
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-02-22 10:11:00
|
||||
*/
|
||||
import { defineStore } from 'pinia'
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
export const useMapStore = defineStore('mapStore', () => {
|
||||
const aMap = shallowRef(null)
|
||||
const mapHandle = shallowRef(null)
|
||||
const cameraState = shallowRef(null)
|
||||
|
||||
//导出参数
|
||||
return { aMap, mapHandle, cameraState }
|
||||
})
|
@ -4,7 +4,7 @@
|
||||
* @Autor: 地虎降天龙
|
||||
* @Date: 2023-11-18 22:17:49
|
||||
* @LastEditors: 地虎降天龙
|
||||
* @LastEditTime: 2024-06-12 09:12:11
|
||||
* @LastEditTime: 2024-08-14 11:41:43
|
||||
-->
|
||||
<template>
|
||||
<div class="absolute menuSelf">
|
||||
@ -42,7 +42,7 @@
|
||||
<AppstoreOutlined />
|
||||
</template>
|
||||
<template #label
|
||||
>基础功能 <FBadge :max="999" :value="getMenusCount(true)" class="count-fbdge big-cf" type="primary" size="small"
|
||||
>基础功能 <FBadge :max="999" :value="getMenusCount().basic" class="count-fbdge big-cf" type="primary" size="small"
|
||||
/></template>
|
||||
<template v-for="(bP, pkey) in filteredData">
|
||||
<f-menu-item v-if="pkey === 'basic'" v-for="(onePlugin, okey) in bP.child" :value="onePlugin.name">
|
||||
@ -62,9 +62,36 @@
|
||||
<template #icon>
|
||||
<PictureOutlined />
|
||||
</template>
|
||||
<template #label>插件中心 <FBadge :max="999" :value="getMenusCount()" class="count-fbdge big-cf" type="primary" size="small" /></template>
|
||||
<template #label>样例中心 <FBadge :max="999" :value="getMenusCount().case" class="count-fbdge big-cf" type="primary" size="small" /></template>
|
||||
<template v-for="(onePlugin, pkey) in filteredData">
|
||||
<f-menu-item v-if="pkey !== 'basic'" :value="pkey">
|
||||
<f-menu-item v-if="pkey !== 'basic' && !isTvtstore(onePlugin)" :value="pkey">
|
||||
<template #label>
|
||||
<div class="flex absolute" style="left: 1px; flex-direction: column; top: 2px">
|
||||
<template v-for="(lbItem, lbKey) in getleftMenuBadge(onePlugin.name)">
|
||||
<f-badge v-if="lbItem.show" :value="lbItem.text" class="tag-fbdge" type="primary" size="small" />
|
||||
</template>
|
||||
</div>
|
||||
<span class="left-m-text">{{ onePlugin.title }}</span>
|
||||
<FBadge :value="onePlugin.preview.length" class="count-fbdge" type="primary" size="small" />
|
||||
</template>
|
||||
</f-menu-item>
|
||||
</template>
|
||||
</f-sub-menu>
|
||||
<f-sub-menu value="3">
|
||||
<template #icon>
|
||||
<ClusterOutlined />
|
||||
</template>
|
||||
<template #label>插件应用管理 <FBadge :max="999" :value="getMenusCount().tvtstore" class="count-fbdge big-cf" type="primary" size="small" /></template>
|
||||
<f-menu-item value="tvtPluginUrl">
|
||||
<template #label>
|
||||
<div class="flex absolute" style="left: 1px; flex-direction: column; top: 2px">
|
||||
<f-badge value="tvtstore" class="tag-fbdge" type="danger" size="small" />
|
||||
</div>
|
||||
<span class="left-m-text">插件应用市场</span>
|
||||
</template>
|
||||
</f-menu-item>
|
||||
<template v-for="(onePlugin, pkey) in filteredData">
|
||||
<f-menu-item v-if="pkey !== 'basic' && isTvtstore(onePlugin)" :value="pkey">
|
||||
<template #label>
|
||||
<div class="flex absolute" style="left: 1px; flex-direction: column; top: 2px">
|
||||
<template v-for="(lbItem, lbKey) in getleftMenuBadge(onePlugin.name)">
|
||||
@ -93,7 +120,12 @@
|
||||
</template>
|
||||
</template>
|
||||
<template v-for="(onePlugin, pkey) in filteredData" :key="pkey">
|
||||
<div style="background-color: #f1f1f2" v-if="pkey !== 'basic'" :ref="(el) => (tabListRef[pkey] = el)">
|
||||
<div style="background-color: #f1f1f2" v-if="pkey !== 'basic' && !isTvtstore(onePlugin)" :ref="(el) => (tabListRef[pkey] = el)">
|
||||
<cardList :onePlugin="onePlugin" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-for="(onePlugin, pkey) in filteredData" :key="pkey">
|
||||
<div style="background-color: #f1f1f2" v-if="pkey !== 'basic' && isTvtstore(onePlugin)" :ref="(el) => (tabListRef[pkey] = el)">
|
||||
<cardList :onePlugin="onePlugin" />
|
||||
</div>
|
||||
</template>
|
||||
@ -106,7 +138,7 @@
|
||||
import { ref, provide, watch } from 'vue'
|
||||
import { defineRouteMeta, useModel } from '@fesjs/fes'
|
||||
import { FBadge, FDrawer, FMenu, FSubMenu, FMenuItem } from '@fesjs/fes-design'
|
||||
import { AppstoreOutlined, PictureOutlined, UpCircleOutlined, MoreCircleOutlined } from '@fesjs/fes-design/icon'
|
||||
import { AppstoreOutlined, PictureOutlined, UpCircleOutlined, MoreCircleOutlined, ClusterOutlined } from '@fesjs/fes-design/icon'
|
||||
import { getPluginsConfig, getOnlinePluginConfig } from '../common/utils'
|
||||
import cardList from '../components/forPreview/cardList.vue'
|
||||
import filterComFixed from '../components/forPreview/filterComFixed.vue'
|
||||
@ -116,7 +148,6 @@ defineRouteMeta({
|
||||
title: '开源框架展示',
|
||||
})
|
||||
|
||||
// console.log(window.layoutConfig)
|
||||
const layoutConfigMenus = window.layoutConfig.menus
|
||||
const menuGoto = (value: any) => {
|
||||
console.log(value)
|
||||
@ -134,29 +165,18 @@ const pluginsConfig = ref({})
|
||||
pluginsConfig.value = getPluginsConfig() as any
|
||||
getOnlinePluginConfig(pluginsConfig)
|
||||
const goto = (value: string) => {
|
||||
tabListRef.value[value.value]?.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' })
|
||||
if (value.value === 'tvtPluginUrl') {
|
||||
window.open('https://www.icegl.cn/tvtstore', '_blank')
|
||||
} else {
|
||||
tabListRef.value[value.value]?.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' })
|
||||
}
|
||||
}
|
||||
// const isNew = ((time: string) => {
|
||||
// if (time) {
|
||||
// const targetDate = new Date(time)
|
||||
// const currentDate = new Date()
|
||||
// const targetTimestamp = targetDate.getTime()
|
||||
// const currentTimestamp = currentDate.getTime()
|
||||
// const timeDifference = currentTimestamp - targetTimestamp
|
||||
// const millisecondsPerDay = 1000 * 60 * 60 * 24 // 每天的毫秒数
|
||||
// const daysDifference = Math.floor(timeDifference / millisecondsPerDay)
|
||||
// if (daysDifference < 7) { //小于七天 算新插件
|
||||
// return true
|
||||
// }
|
||||
// }
|
||||
// return false
|
||||
// })
|
||||
|
||||
const scrollToTop = () => {
|
||||
document.querySelector('.right-page-list')?.scrollTo({ top: 0, behavior: 'smooth' })
|
||||
}
|
||||
|
||||
const expandedKeys = ref(['1', '2'])
|
||||
// const expandedKeys = ref(['1','2','3'])
|
||||
|
||||
const filterFixedInputValue = ref('')
|
||||
provide('filterFixedInputValue', filterFixedInputValue)
|
||||
@ -199,14 +219,9 @@ const filterObjects = (obj: any, searchString: string): any => {
|
||||
}
|
||||
return result
|
||||
}
|
||||
let filteredData = ref(pluginsConfig.value)
|
||||
|
||||
let filteredData = ref(pluginsConfig.value) as any
|
||||
watch(filterFixedInputValue, (newValue: any) => {
|
||||
filteredData.value = filterObjects(pluginsConfig.value, newValue.toLocaleLowerCase())
|
||||
if (!newValue) {
|
||||
expandedKeys.value = ['1', '2']
|
||||
}
|
||||
// console.log('filterFixedInputValue filteredData', filteredData.value)
|
||||
})
|
||||
|
||||
const { menuSetup } = useModel('forPreview')
|
||||
@ -214,7 +229,6 @@ const { menuSetup } = useModel('forPreview')
|
||||
function filterMenuSetup(msFilter: any) {
|
||||
if (msFilter.length === 0) {
|
||||
return pluginsConfig.value
|
||||
// return filterObjects(pluginsConfig.value, filterFixedInputValue.value.toLocaleLowerCase())
|
||||
}
|
||||
const result = {} as any
|
||||
msFilter.forEach((tag: any) => {
|
||||
@ -248,29 +262,8 @@ const menuSetupFilter = ref([])
|
||||
provide('menuSetupFilter', menuSetupFilter)
|
||||
watch(menuSetupFilter, (newValue: any) => {
|
||||
filteredData.value = filterMenuSetup(newValue)
|
||||
// console.log('menuSetupFilter filteredData', filteredData.value)
|
||||
})
|
||||
|
||||
const getMenusCount = (isBasic = false) => {
|
||||
let count = 0
|
||||
for (const key in filteredData.value) {
|
||||
if (filteredData.value.hasOwnProperty(key)) {
|
||||
if ((key === 'basic') === isBasic) {
|
||||
if (isBasic) {
|
||||
for (const key2 in filteredData.value[key].child) {
|
||||
if (filteredData.value[key].child.hasOwnProperty(key2)) {
|
||||
count += filteredData.value[key].child[key2].preview.length
|
||||
}
|
||||
}
|
||||
} else {
|
||||
count += filteredData.value[key].preview.length
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
const getleftMenuBadge = (name: string) => {
|
||||
const tagOne = {
|
||||
recommend: { show: false, text: '荐' },
|
||||
@ -283,9 +276,10 @@ const getleftMenuBadge = (name: string) => {
|
||||
tagOne[tmpOne[key].taglist].show = true
|
||||
}
|
||||
}
|
||||
// console.log(tagOne)
|
||||
return tagOne
|
||||
}
|
||||
|
||||
//获取设备类型
|
||||
function detectDeviceType() {
|
||||
const ua = navigator.userAgent
|
||||
const width = window.innerWidth
|
||||
@ -307,7 +301,35 @@ function detectDeviceType() {
|
||||
}
|
||||
}
|
||||
}
|
||||
// console.log(detectDeviceType())
|
||||
// 区分是否是案例中心的 还是 插件市场的
|
||||
const isTvtstore = (onePlugin: any) => {
|
||||
return typeof onePlugin.tvtstore !== 'undefined'
|
||||
}
|
||||
const getMenusCount = () => {
|
||||
const reCount = {
|
||||
basic: 0,
|
||||
case: 0,
|
||||
tvtstore: 0,
|
||||
}
|
||||
for (const key in filteredData.value) {
|
||||
if (filteredData.value.hasOwnProperty(key)) {
|
||||
if (key === 'basic') {
|
||||
for (const key2 in filteredData.value[key].child) {
|
||||
if (filteredData.value[key].child.hasOwnProperty(key2)) {
|
||||
reCount.basic += filteredData.value[key].child[key2].preview.length
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isTvtstore(filteredData.value[key])) {
|
||||
reCount.tvtstore += filteredData.value[key].preview.length
|
||||
} else {
|
||||
reCount.case += filteredData.value[key].preview.length
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return reCount
|
||||
}
|
||||
const showTopMune = ref(false)
|
||||
const openTopMune = () => {
|
||||
showTopMune.value = true
|
||||
|