Merge branch 'master' into online

This commit is contained in:
hawk86104 2024-08-14 11:55:34 +08:00
commit 12e0743860
48 changed files with 899 additions and 258 deletions

38
.fes.js
View File

@ -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]

View File

@ -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
View File

@ -18,3 +18,4 @@
yarn.lock
yarn-error.log
package-lock.json
src/plugins/resourceManager

View File

@ -105,11 +105,6 @@
</script>
```
- 🧩 丰富的插件应用市场<br/>
插件中心包含各式各样的项目场景和功能。插件是 ICE 社区生态中重要的一环,在应用市场中完整应用和普通插件统一称为插件。
### 我们将会逐一把落地的项目以插件的形式加入到此开源框中...
### 敬请右上角一键三连: 关注 💛 点赞 ⭐ fork👣
# ✅ 快速开始
@ -144,6 +139,12 @@
![展示](./public/plugins/goView/preview/goViewPlugin.png)
# 🧩 丰富的[插件应用市场🌏tvtstore](https://www.icegl.cn/tvtstore)
插件中心 [🌏www.icegl.cn/tvtstore](https://www.icegl.cn/tvtstore) 包含各式各样的项目场景和功能。插件是 ICE 社区生态中重要的一环,在应用市场中完整应用和普通插件统一称为插件。<br/>
[![tvt.js插件市场](https://icegl-1314935952.cos.ap-beijing.myqcloud.com/uploads/20240814/5b370fdeb9e9817c4b78cd919da74d8a.png)](https://www.icegl.cn/tvtstore)
### 我们将会逐一把落地的项目以插件的形式加入到此开源框中...
[![加入我们](https://icegl-1314935952.cos.ap-beijing.myqcloud.com/uploads/20240712/bd350b8cb5bc46d4b7a05b903cf787b4.png)](https://www.icegl.cn/p/tvtdeveloper.html)
# ❓ 问题反馈
在使用中有任何问题,请使用以下联系方式联系我们

View File

@ -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",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 KiB

View File

@ -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: [

View File

@ -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) {

View File

@ -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)">
点击查看演示

View File

@ -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&amp;query=data.follower&amp;color=282c34&amp;label=B%E7%AB%99&amp;labelColor=FE7398&amp;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&amp;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">

View File

@ -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, '请连接网络,获得样例的更新')
})
}

View File

@ -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">

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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">

View File

@ -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>

View File

@ -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: '建筑物' },

View File

@ -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>

View File

@ -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>

View File

@ -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 => margin1em
// class:mt-1 => margin-top1em
// 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;
}
}

View 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>

View 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>

View 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": "绘制箭头" },
]
}

View 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>

View 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>

View 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>

View 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.);
}
}

View 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.);
}

View 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 }
})

View File

@ -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