Merge pull request #1 from anatolykopyl/vite

Vite
This commit is contained in:
Anatoly Kopyl
2022-07-24 14:43:08 +03:00
committed by GitHub
23 changed files with 22355 additions and 29029 deletions

View File

@@ -1,18 +1,12 @@
module.exports = { module.exports = {
root: true, root: true,
env: { env: {
node: true, es2021: true,
}, },
extends: [ extends: [
'plugin:vue/vue3-essential', 'plugin:vue/vue3-essential',
'@vue/airbnb', '@vue/airbnb',
], ],
parserOptions: {
parser: 'babel-eslint',
},
ignorePatterns: [
'bundle/*'
],
rules: { rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',

2
.gitignore vendored
View File

@@ -1,7 +1,5 @@
.DS_Store .DS_Store
node_modules node_modules
/dist
# local env files # local env files
.env.local .env.local

File diff suppressed because one or more lines are too long

16799
dist/vue-three-d-mockup.js vendored Normal file

File diff suppressed because one or more lines are too long

3018
dist/vue-three-d-mockup.umd.cjs vendored Normal file

File diff suppressed because one or more lines are too long

15
docs/.vitepress/config.js Normal file
View File

@@ -0,0 +1,15 @@
import { defineConfig } from 'vitepress'
export default defineConfig({
title: 'Vue 3D Mockup',
description: '📱 A 3D phone mockup component to showcase your apps',
themeConfig: {
nav: [
{ text: 'Guide', link: '/guide' },
{ text: 'Github', link: 'https://github.com/anatolykopyl/vue-three-d-mockup' }
],
footer: {
message: 'Released under the GPL-3.0 license.',
}
}
})

BIN
docs/assets/screen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

191
docs/guide.md Normal file
View File

@@ -0,0 +1,191 @@
# Guide
## Installation
```bash
npm install vue-three-d-mockup
```
## Usage
<script setup>
import { ref } from 'vue';
import Mockup from '../src/Mockup.vue'
import screenImage from './assets/screen.png';
import screenVideo from './assets/screen.mp4';
const videoElement = ref(null);
const vidReady = ref(false);
</script>
<Mockup
style="width: 100%; height: 400px;"
:screen="screenImage"
/>
### Simple example
`screen.png` is a static asset in the public folder.
```vue
<template>
<Mockup screen="screen.png" />
</template>
<script setup>
import Mockup from 'vue-three-d-mockup';
</script>
```
### Using assets as the screen
- #### In vite powered projects
```vue
<template>
<Mockup :screen="screenImage" />
</template>
<script setup>
import Mockup from 'vue-three-d-mockup';
import screenImage from './assets/screen.png';
</script>
```
- #### In vue-cli powered projects
```vue
<template>
<Mockup :screen="require('./assets/screen.png')" />
</template>
<script setup>
import Mockup from 'vue-three-d-mockup';
</script>
```
### Multiple phones
<Mockup
style="width: 100%; height: 400px;"
:screen="[screenImage, screenImage]"
:position="[
{
x: -50
},
{
x: 50
},
]"
:rotation="[{}, {
y: -0.3,
z: -0.06,
}]"
/>
```vue
<template>
<Mockup
:screen="[screenImage, screenImage]"
:position="[
{
x: -50
},
{
x: 50
},
]"
:rotation="[{}, {
y: -0.3,
z: -0.06,
}]"
/>
</template>
<script setup>
import Mockup from 'vue-three-d-mockup';
import screenImage from './assets/screen.png';
</script>
```
### Video
<Mockup
v-if="vidReady"
style="width: 100%; height: 400px;"
:screen="videoElement"
/>
<div>
<video
:src="screenVideo"
ref="videoElement"
@canplay="vidReady = true"
muted
autoplay
loop
style="
position: fixed;
top: 0;
left: 0;
visibility: hidden;
"
></video>
</div>
```vue
<template>
<Mockup
v-if="vidReady"
:screen="videoElement"
/>
<video
:src="screenVideo"
ref="videoElement"
@canplay="vidReady = true"
muted
autoplay
loop
style="
position: fixed;
top: 0;
left: 0;
visibility: hidden;
"
></video>
</template>
<script setup>
import { ref } from 'vue';
import Mockup from 'vue-three-d-mockup';
import screenVideo from './assets/screen.mp4';
const videoElement = ref(null);
const vidReady = ref(false);
</script>
```
## Avaliable props
| Prop | Type | Required | Default | Description |
| ---------- | -------------------------- | -------- | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `screen` | String \| Element \| Array | `true` | none | Path to an image that will be displayed on the phones screen or the `<video>` element displayed on the phones screen. When using the latter there are [caveats](#caveats). Can also be an array of any of the options above. |
| `lightClr` | String | `false` | `"white"` | Color of the light as a CSS-style string. |
| `phoneClr` | String | `false` | `"white"` | Color of the phone as a CSS-style string. |
| `position` | Object \| Array | `false` | `{ x: 0, y: 0, z: 0 }` | The position of the phone. Can also be an array if multiple screens specified. | |
| `rotation` | Object \| Array | `false` | `{ x: -0.2, y: 0.3, z: 0.06 }` | The orientation of the phone described in rotation values arround the 3 axes. Can also be an array if multiple screens specified. |
## Caveats
- The `screen` prop is unreactive, so when using it as a video
it's important to only render the `Mockup` element when the video
is loaded. Check out the examples above to see how
to do this.
- The video on the model will not be shown if the original `<video>`
element is hidden with `display: none`, so use `visibility: hidden`
instead.
- The video may not be autoplaying if the original `<video>` element
is scrolled off screen.
- Even with the mentioned above workarounds, the video may not be
working in Safari.

84
docs/index.md Normal file
View File

@@ -0,0 +1,84 @@
---
layout: home
---
<script setup>
import Mockup from '../src/Mockup.vue'
import screenImage from './assets/screen.png';
</script>
<main>
<Mockup
class="mockup"
:screen="screenImage"
/>
<h1 class="heading">
Vue 3D Mockup
</h1>
<p class="tagline">
Create interactive 3D mockups with ease.
</p>
<div class="buttons">
<a
href="/guide"
class="buttons__button"
>
Guide
</a>
<a
href="https://github.com/anatolykopyl/vue-three-d-mockup"
class="buttons__button buttons__button--secondary"
>
Github
</a>
</div>
</main>
<style scoped>
main {
text-align: center;
}
.mockup {
max-width: 600px;
height: 500px;
margin: auto;
}
.heading {
font-size: 42px;
line-height: 1.2;
padding: 32px;
font-weight: bold;
color: var(--vp-c-brand);
}
.tagline {
font-size: 24px;
padding: 16px;
}
.buttons {
padding: 32px;
}
.buttons__button {
display: inline-block;
padding: 8px 16px;
border-radius: 4px;
background-color: var(--vp-c-brand);
border: 1px solid var(--vp-c-brand);
color: var(--vp-c-white);
text-decoration: none;
font-size: 16px;
margin: 0 8px;
}
.buttons__button--secondary {
background-color: var(--vp-c-gray-light-4);
color: var(--vp-c-black);
border: 1px solid var(--vp-c-divider-light-2);
}
</style>

16
index.html Normal file
View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>vue-three-d-mockup</title>
</head>
<body>
<noscript>
<strong>We're sorry but vue-three-d-mockup doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

28572
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,46 +1,58 @@
{ {
"name": "vue-three-d-mockup", "name": "vue-three-d-mockup",
"version": "0.2.2", "version": "1.0.0",
"description": "📱 A 3D phone mockup component to showcase your apps", "description": "📱 A 3D phone mockup component to showcase your apps",
"author": "Anatoly Kopyl <akopyl@radner.ru>", "author": "Anatoly Kopyl <akopyl@radner.ru>",
"keywords": ["vue", "mockup-generator", "threejs", "design", "mockup"], "keywords": [
"vue",
"mockup-generator",
"threejs",
"design",
"mockup"
],
"license": "GPL-3.0", "license": "GPL-3.0",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/anatolykopyl/vue-three-d-mockup.git" "url": "https://github.com/anatolykopyl/vue-three-d-mockup.git"
}, },
"main": "bundle/vue-three-d-mockup.esm.js", "type": "module",
"browser": { "browser": {
"./sfc": "src/Mockup.vue" "./sfc": "src/Mockup.vue"
}, },
"files": [
"dist"
],
"main": "./dist/my-lib.umd.cjs",
"module": "./dist/my-lib.js",
"exports": {
".": {
"import": "./dist/my-lib.js",
"require": "./dist/my-lib.umd.cjs"
}
},
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "dev": "vite",
"build": "vue-cli-service build", "build": "vite build",
"build-bundle": "rollup -c", "serve": "vite preview",
"lint": "vue-cli-service lint" "docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:serve": "vitepress serve docs"
}, },
"pre-commit": [ "pre-commit": [
"build-bundle" "build"
], ],
"dependencies": { "dependencies": {
"core-js": "^3.6.5", "@vitejs/plugin-vue": "^3.0.1",
"three": "^0.137.5", "three": "^0.137.5",
"vite": "^3.0.2",
"vue": "^3.0.0" "vue": "^3.0.0"
}, },
"devDependencies": { "devDependencies": {
"@rollup/plugin-commonjs": "^21.0.1",
"@rollup/plugin-url": "^6.1.0",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0",
"@vue/eslint-config-airbnb": "^5.0.2", "@vue/eslint-config-airbnb": "^5.0.2",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2", "eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.2", "eslint-plugin-import": "^2.20.2",
"eslint-plugin-vue": "^7.0.0", "eslint-plugin-vue": "^7.0.0",
"file-loader": "^6.2.0",
"pre-commit": "^1.2.2", "pre-commit": "^1.2.2",
"rollup-plugin-vue": "^6.0.0" "vitepress": "^1.0.0-alpha.4"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@@ -1,20 +0,0 @@
import vue from 'rollup-plugin-vue';
import url from '@rollup/plugin-url';
import packageJson from './package.json';
export default {
input: 'src/Mockup.vue',
output: [
{
format: 'esm',
file: packageJson.main,
},
],
plugins: [
vue(),
url({
limit: 3000000,
include: ['**/*.obj'],
}),
],
};

View File

@@ -7,7 +7,7 @@
<Mockup <Mockup
v-if="vidReady" v-if="vidReady"
class="mockup" class="mockup"
:screen="[$refs.video, require('./assets/screen.png')]" :screen="[$refs.video, screenImage]"
:position="[ :position="[
{ {
x: -50 x: -50
@@ -27,7 +27,7 @@
/> --> /> -->
<video <video
src="@/assets/screen.mp4" :src="screenVideo"
ref="video" ref="video"
@canplay="vidReady = true" @canplay="vidReady = true"
muted muted
@@ -39,6 +39,8 @@
<script> <script>
import { defineAsyncComponent } from 'vue'; import { defineAsyncComponent } from 'vue';
import screenImage from './assets/screen.png';
import screenVideo from './assets/screen.mp4';
export default { export default {
data() { data() {
@@ -49,6 +51,12 @@ export default {
components: { components: {
Mockup: defineAsyncComponent(() => import('./Mockup.vue')), Mockup: defineAsyncComponent(() => import('./Mockup.vue')),
}, },
setup() {
return {
screenImage,
screenVideo,
};
}
}; };
</script> </script>

View File

@@ -18,7 +18,7 @@ import * as THREE from 'three';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'; import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
import MockupModel from './MockupModel'; import MockupModel from './MockupModel';
import roundedPlane from './utils/roundedPlane'; import roundedPlane from './utils/roundedPlane';
import phoneObj from './assets/iphone.obj'; const phoneObj = new URL('./assets/iphone.obj', import.meta.url).href;
export default { export default {
name: 'Mockup', name: 'Mockup',

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

View File

@@ -1,4 +0,0 @@
import { createApp } from 'vue';
import App from './Demo.vue';
createApp(App).mount('#app');

23
vite.config.js Normal file
View File

@@ -0,0 +1,23 @@
import { defineConfig } from 'vite'
import { resolve } from 'path'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
assetsInclude: ['**/*.obj'],
build: {
lib: {
entry: resolve(__dirname, 'src/Mockup.vue'),
name: 'vue-three-d-mockup',
fileName: 'vue-three-d-mockup'
},
rollupOptions: {
external: ['vue'],
output: {
globals: {
vue: 'Vue'
}
}
}
}
});

View File

@@ -1,11 +0,0 @@
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/vue-three-d-mockup/' : '/',
chainWebpack: (config) => {
config.module
.rule('file-loader')
.test(/\.obj$/)
.use('file-loader')
.loader('file-loader')
.end();
},
};

2167
yarn.lock Normal file

File diff suppressed because it is too large Load Diff