码农笔录博客源码
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 

287 linhas
11 KiB

{{template "header" .}}
<meta name="keywords" content="码农随笔,个人随笔,博客,个人博客,个人笔记,技术博客,免费云笔记,云笔记,随笔,IT博客,谷歌地图,码农笔录,aiprose">
<script src="https://cdn.bootcdn.net/ajax/libs/three.js/r128/three.min.js"></script>
<title>登录 - 码农随笔</title>
<style>
.login-form {
background: #55555555;
padding: 18px;
border-radius: 8px;
position: fixed;
left: 25%;
top: 20%;
width: 350px;
margin: auto;
}
</style>
</head>
<body>
<div class="root-container">
{{template "nav" .}}
<div class="login-root">
<script type="x-shader/x-vertex" id="vertexshader">
attribute float scale;
void main() {
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_PointSize = scale * ( 300.0 / - mvPosition.z );
gl_Position = projectionMatrix * mvPosition;
}
</script>
<script type="x-shader/x-fragment" id="fragmentshader">
uniform vec3 color;
void main() {
if ( length( gl_PointCoord - vec2( 0.5, 0.5 ) ) > 0.475 ) discard;
gl_FragColor = vec4( color, 1.0 );
}
</script>
<div id="threeContainer" class="threeContainer" ref="threeContainer"></div>
<div class="login-form" :style="mstyle">
<el-form :model="loginForm" :rules="rules" ref="loginForm" label-width="0px" class="loginForm">
<el-form-item prop="username">
<el-input v-model="loginForm.username" placeholder="请输入用户名">
<i slot="prefix" class="el-input__icon el-icon-user-solid"></i>
</el-input>
</el-form-item>
<el-form-item prop="userpwd">
<el-input type="password" v-model="loginForm.userpwd" placeholder="请输入密码" show-password>
<i slot="prefix" class="el-input__icon el-icon-user-solid"></i>
</el-input>
</el-form-item>
<el-form-item prop="captcha">
<div style="display: flex">
<el-input v-model="loginForm.captcha" placeholder="请输入验证码">
<i slot="prefix" class="el-input__icon el-icon-user-solid"></i>
</el-input>
<img :src="captcha" width="150px" @click="getCaptcha"/>
</div>
</el-form-item>
<div>
<el-button type="primary" @click="loginHandler" :loading="loading" style="width: 48%">登陆</el-button>
<el-button type="primary" @click="registHandler" :loading="loading" style="width: 48%">注册
</el-button>
</div>
</el-form>
</div>
</div>
</div>
</body>
<script>
var windowHalfX = 0
var windowHalfY = 0
var camera = null
var renderer = null
var scene = null
var count = 0
var mouseX = 145
var mouseY = -322
var particles = null
var AMOUNTX = 50
var AMOUNTY = 50
var app = new Vue({
el: ".root-container",
delimiters: ['${', '}'],
data: {
captcha: '',
loading: false,
loginForm: {
username: '',
userpwd: '',
captchaId: ''
},
rules: {
username: [
{
required: true,
message: '请输入用户名',
trigger: 'blur'
},
{
min: 5,
message: '长度最少5个字符',
trigger: 'blur'
}
],
userpwd: [
{
required: true,
message: '请输入密码',
trigger: 'blur'
},
{
min: 6,
message: '长度最少6个字符',
trigger: 'blur'
}
],
captcha: [
{
required: true,
message: '请输入验证码',
trigger: 'blur'
}
]
},
mstyle: {
left: window.innerWidth / 2 - 175 + 'px'
}
},
created() {
this.getCaptcha()
},
mounted() {
const SEPARATION = 100
windowHalfX = window.innerWidth / 2
windowHalfY = window.innerHeight / 2
const container = this.$refs.threeContainer
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000)
camera.position.z = 1000
scene = new THREE.Scene()
const numParticles = AMOUNTX * AMOUNTY
const positions = new Float32Array(numParticles * 3)
const scales = new Float32Array(numParticles)
let i = 0;
let j = 0
for (let ix = 0; ix < AMOUNTX; ix++) {
for (let iy = 0; iy < AMOUNTY; iy++) {
positions[i] = ix * SEPARATION - ((AMOUNTX * SEPARATION) / 2) // x
positions[i + 1] = 0 // y
positions[i + 2] = iy * SEPARATION - ((AMOUNTY * SEPARATION) / 2) // z
scales[j] = 1
i += 3
j++
}
}
const geometry = new THREE.BufferGeometry()
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))
geometry.setAttribute('scale', new THREE.BufferAttribute(scales, 1))
const material = new THREE.ShaderMaterial({
uniforms: {
color: {value: new THREE.Color(0.0, 1.0, 1.0, 1.0)}
},
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent
})
particles = new THREE.Points(geometry, material)
scene.add(particles)
renderer = new THREE.WebGLRenderer({antialias: true})
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
container.appendChild(renderer.domElement)
// containerParent.append(container)
container.style.touchAction = 'none'
container.addEventListener('pointermove', this.onPointerMove)
window.addEventListener('resize', this.onWindowResize)
this.animate()
},
methods: {
animate() {
requestAnimationFrame(this.animate)
this.render()
},
getCaptcha() {
const _this = this
$.get('/api/authc/captcha',
function (resp) {
if (resp.Status === 0) {
_this.loginForm.captchaId = resp.Data.captchaId
_this.captcha = resp.Data.img
}
}, 'json')
},
render() {
camera.position.x += (mouseX - camera.position.x) * 0.05
camera.position.y += (-mouseY - camera.position.y) * 0.05
camera.lookAt(scene.position)
const positions = particles.geometry.attributes.position.array
const scales = particles.geometry.attributes.scale.array
let i = 0;
let j = 0
for (let ix = 0; ix < AMOUNTX; ix++) {
for (let iy = 0; iy < AMOUNTY; iy++) {
positions[i + 1] = (Math.sin((ix + count) * 0.3) * 50) +
(Math.sin((iy + count) * 0.5) * 50)
scales[j] = (Math.sin((ix + count) * 0.3) + 1) * 5 +
(Math.sin((iy + count) * 0.5) + 1) * 5
i += 3
j++
}
}
particles.geometry.attributes.position.needsUpdate = true
particles.geometry.attributes.scale.needsUpdate = true
renderer.render(scene, camera)
count += 0.08
},
onWindowResize() {
this.mstyle.left = window.innerWidth / 2 - 175 + 'px'
windowHalfX = window.innerWidth / 2
windowHalfY = window.innerHeight / 2
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
},
onPointerMove(event) {
if (event.isPrimary === false) return
mouseX = event.clientX - windowHalfX
// mouseY = event.clientY - windowHalfY
},
loginHandler() {
const _this = this
this.loading = true
this.$refs.loginForm.validate(valid => {
if (valid) {
$.post('/api/login', this.loginForm,
function (data) {
_this.loading = false
if (data.Status == 1) {
_this.getCaptcha()
_this.$message.warning(data.Msg);
} else {
_this.$message.success("登录成功");
window.location.href = "/"
}
}, 'json')
} else {
this.loading = false
}
})
},
registHandler() {
const _this = this
this.loading = true
this.$refs.loginForm.validate(valid => {
if (valid) {
$.post('/api/regist', this.loginForm,
function (data) {
_this.loading = false
_this.getCaptcha()
if (data.Status == 1) {
_this.$message.warning(data.Msg);
} else {
_this.$message.success("注册成功,请登陆");
}
}, 'json')
} else {
this.loading = false
}
})
}
}
})
</script>
<script type="text/javascript" src="/static/js/seo.js"></script>
</html>