изменение аватарки, выбор зоны картинки, фулл рабочее
This commit is contained in:
parent
f8fa0a4f72
commit
a2fd7f7318
10 changed files with 386 additions and 75 deletions
6
package-lock.json
generated
6
package-lock.json
generated
|
@ -10,6 +10,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sveltestrap/sveltestrap": "^6.2.4",
|
"@sveltestrap/sveltestrap": "^6.2.4",
|
||||||
"@themesberg/flowbite": "^1.3.0",
|
"@themesberg/flowbite": "^1.3.0",
|
||||||
|
"cropperjs": "^1.6.2",
|
||||||
"sass": "^1.70.0",
|
"sass": "^1.70.0",
|
||||||
"socket.io": "^4.7.5",
|
"socket.io": "^4.7.5",
|
||||||
"socket.io-client": "^4.7.5",
|
"socket.io-client": "^4.7.5",
|
||||||
|
@ -1553,6 +1554,11 @@
|
||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cropperjs": {
|
||||||
|
"version": "1.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.6.2.tgz",
|
||||||
|
"integrity": "sha512-nhymn9GdnV3CqiEHJVai54TULFAE3VshJTXSqSJKa8yXAKyBKDWdhHarnlIPrshJ0WMFTGuFvG02YjLXfPiuOA=="
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sveltestrap/sveltestrap": "^6.2.4",
|
"@sveltestrap/sveltestrap": "^6.2.4",
|
||||||
"@themesberg/flowbite": "^1.3.0",
|
"@themesberg/flowbite": "^1.3.0",
|
||||||
|
"cropperjs": "^1.6.2",
|
||||||
"sass": "^1.70.0",
|
"sass": "^1.70.0",
|
||||||
"socket.io": "^4.7.5",
|
"socket.io": "^4.7.5",
|
||||||
"socket.io-client": "^4.7.5",
|
"socket.io-client": "^4.7.5",
|
||||||
|
|
13
src/app.html
13
src/app.html
|
@ -14,6 +14,19 @@
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: linear-gradient(45deg, var(--blue), var(--purple));
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-attachment: fixed;
|
||||||
|
border-radius: 15px;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Comfortaa';
|
font-family: 'Comfortaa';
|
||||||
src: url('./fonts/Comfortaa-VariableFont_wght.ttf') format('truetype');
|
src: url('./fonts/Comfortaa-VariableFont_wght.ttf') format('truetype');
|
||||||
|
|
|
@ -169,8 +169,8 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
let jopa = await response.json();
|
let data = await response.json();
|
||||||
return jopa.image_url
|
return data.image_url
|
||||||
} else {
|
} else {
|
||||||
console.log(response);
|
console.log(response);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
export async function getAvatarHistory(token){
|
export async function getAvatarHistory(token){
|
||||||
|
|
||||||
let response = fetch(`https://docs.black-phoenix.ru/api/users/avatars`,{
|
let response = await fetch(`https://docs.black-phoenix.ru/api/users/avatars`,{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
credentials:'include',
|
credentials:'include',
|
||||||
headers: {'Authorization': token },
|
headers: {'Authorization': token },
|
||||||
|
@ -8,9 +8,53 @@ export async function getAvatarHistory(token){
|
||||||
|
|
||||||
if(response.ok){
|
if(response.ok){
|
||||||
let data = await response.json();
|
let data = await response.json();
|
||||||
|
data = data.user_avatars
|
||||||
|
data.reverse();
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
console.log(response)
|
console.log(response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getConfirmationCode(token, email){
|
||||||
|
console.log(token, email, "<-- лох")
|
||||||
|
const response = await fetch(`https://docs.black-phoenix.ru/api/users/send_confirmation_code`,{
|
||||||
|
method: 'POST',
|
||||||
|
credentials:'include',
|
||||||
|
headers: {'Content-Type': 'application/json',
|
||||||
|
'Authorization': token},
|
||||||
|
body: JSON.stringify({'email': email})
|
||||||
|
})
|
||||||
|
|
||||||
|
if(response.ok){
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
console.log(response)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function changeUserData(token, username, email, password, avatar, code){
|
||||||
|
|
||||||
|
let response = await fetch(`https://docs.black-phoenix.ru/api/users/change_data`,{
|
||||||
|
|
||||||
|
method: 'POST',
|
||||||
|
credentials:'include',
|
||||||
|
headers: {'Content-Type': 'application/json',
|
||||||
|
'Authorization': token },
|
||||||
|
body: JSON.stringify({"verification_code": code,
|
||||||
|
"email": email,
|
||||||
|
"username": username,
|
||||||
|
"new_password": password,
|
||||||
|
"avatar_url": avatar})
|
||||||
|
})
|
||||||
|
|
||||||
|
if(response.ok){
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
else{
|
||||||
|
console.log(response)
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,17 +5,15 @@ export async function UserCheck(){
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
credentials:'include',
|
credentials:'include',
|
||||||
headers: {'Authorization': token },
|
headers: {'Authorization': token },
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if(!response.ok){
|
if(response.ok){
|
||||||
console.log(response)
|
const data = await response.json();
|
||||||
return(response.status)
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
else{
|
else{
|
||||||
const data = await response.json();
|
console.log(response)
|
||||||
return data
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@
|
||||||
|
|
||||||
width: 75px;
|
width: 75px;
|
||||||
height: 75px;
|
height: 75px;
|
||||||
border-radius: 50%;
|
border-radius: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown > * {
|
.dropdown > * {
|
||||||
|
|
|
@ -1,64 +1,153 @@
|
||||||
<script>
|
<script>
|
||||||
|
import Cropper from 'cropperjs';
|
||||||
|
import 'cropperjs/dist/cropper.css';
|
||||||
|
import { uploadImages } from '$lib/chat';
|
||||||
import { blur } from 'svelte/transition';
|
import { blur } from 'svelte/transition';
|
||||||
import Header from './../Header.svelte';
|
import Header from './../Header.svelte';
|
||||||
import { UserCheck } from '$lib/userFunction';
|
import { UserCheck } from '$lib/userFunction';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { getAvatarHistory } from '$lib/settings'
|
import { getAvatarHistory, changeUserData, getConfirmationCode } from '$lib/settings'
|
||||||
|
|
||||||
let userName
|
let token
|
||||||
let userEmail
|
let confCode
|
||||||
let newAvatarVisualize
|
let userData = []
|
||||||
let avatarHistory
|
let oldName
|
||||||
|
let oldEmail
|
||||||
|
|
||||||
|
let afterChanging
|
||||||
|
let newAvatarVisualize = ""
|
||||||
|
let avatars = []
|
||||||
|
|
||||||
let newName = ""
|
let newName = ""
|
||||||
let newEmail = ""
|
let newEmail = ""
|
||||||
let newPassword = ""
|
let newPassword = ""
|
||||||
let newAvatar = ""
|
let newAvatar = ""
|
||||||
|
let code = ""
|
||||||
|
|
||||||
let showSubmitFiled = false
|
let showSubmitDiv = false
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
let token = localStorage.getItem('BPChat')
|
token = localStorage.getItem('BPChat')
|
||||||
|
|
||||||
let userData = await UserCheck()
|
userData = await UserCheck()
|
||||||
//console.log(userData)
|
//console.log(userData)
|
||||||
avatarHistory = await getAvatarHistory(token)
|
avatars = await getAvatarHistory(token)
|
||||||
console.log(avatarHistory)
|
console.log(avatars)
|
||||||
userName = userData.username
|
oldName = userData.username
|
||||||
userEmail = userData.email
|
oldEmail = userData.email
|
||||||
console.log(`история аватарок ${avatarHistory}`)
|
console.log(oldEmail)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
function handleFileChange(event) {
|
async function changingData(){
|
||||||
|
|
||||||
|
if(newName == "")
|
||||||
|
newName = oldName; console.log(newName, "новое имя")
|
||||||
|
if(newEmail == "")
|
||||||
|
newEmail = oldEmail; console.log(newEmail, "новая почта")
|
||||||
|
if(newPassword == "")
|
||||||
|
newPassword = null; console.log(newPassword, " новый пароль")
|
||||||
|
if(newAvatar == "")
|
||||||
|
newAvatar = null; console.log(newAvatar, "ава")
|
||||||
|
console.log(newName, newEmail, newPassword, newAvatar, " - измененные данные")
|
||||||
|
|
||||||
|
confCode = await getConfirmationCode(token, oldEmail)
|
||||||
|
if(confCode == true)
|
||||||
|
showSubmitDiv = true
|
||||||
|
else
|
||||||
|
console.log("ну ты лошара, земля тебе пухом")
|
||||||
|
}
|
||||||
|
|
||||||
|
async function submit(){
|
||||||
|
newAvatar = await uploadImages(newAvatar)
|
||||||
|
console.log(newAvatar)
|
||||||
|
let changing = afterChanging = await changeUserData(token, newName, newEmail, newPassword, newAvatar, code)
|
||||||
|
console.log(changing)
|
||||||
|
if (changing == true){
|
||||||
|
showSubmitDiv = false
|
||||||
|
location.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancel(){
|
||||||
|
newName = ""
|
||||||
|
newEmail = ""
|
||||||
|
newPassword = ""
|
||||||
|
newAvatar = ""
|
||||||
|
newAvatarVisualize = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
let imageElement;
|
||||||
|
let cropper;
|
||||||
|
let croppedImage = "";
|
||||||
|
let showCroppingImgDiv = false
|
||||||
|
|
||||||
|
const handleFileChange = (event) => {
|
||||||
|
showCroppingImgDiv = true
|
||||||
const file = event.target.files[0];
|
const file = event.target.files[0];
|
||||||
newAvatar = file
|
|
||||||
if (file) {
|
if (file) {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onloadend = (e) => {
|
reader.onload = (e) => {
|
||||||
|
imageElement.src = e.target.result;
|
||||||
newAvatarVisualize = e.target.result;
|
if (cropper) {
|
||||||
|
cropper.destroy();
|
||||||
|
}
|
||||||
|
cropper = new Cropper(imageElement, {
|
||||||
|
aspectRatio: 1,
|
||||||
|
viewMode: 1,
|
||||||
|
autoCropArea: 0, // Начальное значение для автообрезки 0
|
||||||
|
center: true,
|
||||||
|
zoomOnTouch: false,
|
||||||
|
zoomOnWheel: false,
|
||||||
|
cropBoxMovable: true,
|
||||||
|
cropBoxResizable: true,
|
||||||
|
background: false, // Убирает сеточный фон
|
||||||
|
autoCrop: false, // Изначально не показывать зону обрезки
|
||||||
|
ready: function () {
|
||||||
|
cropper.setCropBoxData({
|
||||||
|
width: 200,
|
||||||
|
height: 200,
|
||||||
|
left: (cropper.getContainerData().width - 200) / 2,
|
||||||
|
top: (cropper.getContainerData().height - 200) / 2,
|
||||||
|
});
|
||||||
|
cropper.crop(); // Включить зону обрезки
|
||||||
|
},
|
||||||
|
});
|
||||||
};
|
};
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
async function changingData(){
|
const getCroppedImage = () => {
|
||||||
showSubmitFiled = true
|
if (cropper) {
|
||||||
}
|
croppedImage = cropper.getCroppedCanvas().toDataURL();
|
||||||
|
|
||||||
async function Submit(){
|
cropper.getCroppedCanvas().toBlob((blob) => {
|
||||||
|
newAvatar = blob;
|
||||||
|
}, 'image/jpeg');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
showCroppingImgDiv = false
|
||||||
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
{#if showSubmitFiled}
|
{#if showCroppingImgDiv}
|
||||||
|
<div class="backgroundBlur"></div>
|
||||||
|
|
||||||
|
<div class="croppingDiv">
|
||||||
|
<img class="cropAvatar" bind:this={imageElement} alt="Image to crop" />
|
||||||
|
<button class="cropButton" on:click={getCroppedImage}>Подтвердить</button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if showSubmitDiv}
|
||||||
<div class="backgroundBlur"></div>
|
<div class="backgroundBlur"></div>
|
||||||
<div class="submitPassword">
|
<div class="submitPassword">
|
||||||
<h2>Введите старый пароль</h2>
|
<h2>Подтвердите кодом из почты</h2>
|
||||||
<input type="password" id="oldPassword" placeholder="Старый пароль">
|
<input bind:value={code} type="password" id="oldPassword" placeholder="Код">
|
||||||
<button on:click={Submit}>Отправить</button>
|
<button on:click={submit}>Отправить</button>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
@ -79,9 +168,19 @@
|
||||||
<div class="avatarDiv">
|
<div class="avatarDiv">
|
||||||
<h2>изменить аватарку</h2>
|
<h2>изменить аватарку</h2>
|
||||||
<button class="changeAvatar" on:click={() => document.getElementById('fileInput').click()}>
|
<button class="changeAvatar" on:click={() => document.getElementById('fileInput').click()}>
|
||||||
|
{#if croppedImage != ""}
|
||||||
|
<img class="newAvatar" src="{croppedImage}" alt="новая ава">
|
||||||
|
{:else}
|
||||||
+
|
+
|
||||||
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<div class="avatarsHistory">
|
||||||
|
{#each avatars as avatar}
|
||||||
|
<img class="avatarHistory" src="{avatar.avatar_url}" alt="ава">
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
<input type="file" accept="image/*" id="fileInput"
|
<input type="file" accept="image/*" id="fileInput"
|
||||||
on:change={handleFileChange} style="display: none;">
|
on:change={handleFileChange} style="display: none;">
|
||||||
</div>
|
</div>
|
||||||
|
@ -89,21 +188,21 @@
|
||||||
<div class="textDiv">
|
<div class="textDiv">
|
||||||
<div>
|
<div>
|
||||||
<h3>ник</h3>
|
<h3>ник</h3>
|
||||||
<input type="text" placeholder={userName}>
|
<input bind:value={newName} type="name" placeholder={oldName}>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h3>почта</h3>
|
<h3>почта</h3>
|
||||||
<input type="text" placeholder={userEmail}>
|
<input bind:value={newEmail} type="email" placeholder={oldEmail}>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2>новый пароль</h2>
|
<h2>новый пароль</h2>
|
||||||
<input type="text" placeholder="новый пароль">
|
<input bind:value={newPassword} type="password" placeholder="новый пароль">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="finishButton">
|
<div class="finishButton">
|
||||||
<button on:click={changingData}>Подтвердить</button>
|
<button on:click={changingData}>Подтвердить</button>
|
||||||
<button>Отменить</button>
|
<button on:click={cancel}>Отменить</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -115,6 +214,84 @@
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
||||||
|
.cropper-modal {
|
||||||
|
background-color: #101010;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropButton{
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cropAvatar{
|
||||||
|
border-radius: 15px;
|
||||||
|
width: 500px;
|
||||||
|
height: 500px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.croppingDiv{
|
||||||
|
z-index: 5;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
left: 50%; top: 50%;
|
||||||
|
transform: (-50%,-50%);
|
||||||
|
transform: translate(-50%,-50%);
|
||||||
|
|
||||||
|
padding: 20px;
|
||||||
|
max-height: 90%;
|
||||||
|
max-width: 90%;
|
||||||
|
|
||||||
|
border: 1px solid transparent;
|
||||||
|
background:
|
||||||
|
linear-gradient(#101010, #101010) padding-box,
|
||||||
|
var(--gradient) border-box;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newAvatar{
|
||||||
|
width: 75px;
|
||||||
|
height: 75px;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatarsHistory{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 50%;
|
||||||
|
background-color: #FFFFFF0a;
|
||||||
|
border-radius: 15px;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatarHistory{
|
||||||
|
width: 75px;
|
||||||
|
height: 75px;
|
||||||
|
padding: 3px;
|
||||||
|
border-radius: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.changeAvatar{
|
||||||
|
width: 75px;
|
||||||
|
height: 75px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
background:
|
||||||
|
linear-gradient(#101010, #101010) padding-box,
|
||||||
|
var(--gradient) border-box;
|
||||||
|
border-radius: 15px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-attachment: fixed;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
button{
|
button{
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
}
|
}
|
||||||
|
@ -127,7 +304,7 @@ button{
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: rgba(0, 0, 0, 0.5);
|
background: rgba(0, 0, 0, 0.5);
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
z-index: 5;
|
z-index: 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
#oldPassword{
|
#oldPassword{
|
||||||
|
@ -154,30 +331,30 @@ button{
|
||||||
background:
|
background:
|
||||||
linear-gradient(#101010, #101010) padding-box,
|
linear-gradient(#101010, #101010) padding-box,
|
||||||
var(--gradient) border-box;
|
var(--gradient) border-box;
|
||||||
border-radius: 10px;
|
border-radius: 15px;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.changeAvatar{
|
.submitPassword::before{
|
||||||
width: 75px;
|
content: '';
|
||||||
height: 75px;
|
position: absolute;
|
||||||
border: 1px solid transparent;
|
background-image: url('./noise.png');
|
||||||
background:
|
background-repeat: repeat;
|
||||||
linear-gradient(#101010, #101010) padding-box,
|
width: 100%;
|
||||||
var(--gradient) border-box;
|
height: 100%;
|
||||||
border-radius: 10px;
|
border-radius: 15px;
|
||||||
background-repeat: no-repeat;
|
opacity: 0.01;
|
||||||
background-attachment: fixed;
|
pointer-events: none;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatarDiv{
|
.avatarDiv{
|
||||||
height: 60%;
|
height: 60%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
//background-color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
|
@ -216,8 +393,8 @@ input {
|
||||||
height: 60%;
|
height: 60%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-around;
|
justify-content: space-between;
|
||||||
//background-color: red;
|
//background-color: blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button{
|
.button{
|
||||||
|
@ -278,6 +455,7 @@ input {
|
||||||
.header {
|
.header {
|
||||||
height: 10%;
|
height: 10%;
|
||||||
width: 85%;
|
width: 85%;
|
||||||
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mainDiv{
|
.mainDiv{
|
||||||
|
@ -318,7 +496,7 @@ input {
|
||||||
|
|
||||||
|
|
||||||
body{
|
body{
|
||||||
display: flexbox;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
@ -515,19 +515,6 @@ function helperDivShow(event, id, text, img, username) {
|
||||||
//top: -35px;
|
//top: -35px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background: linear-gradient(45deg, var(--blue), var(--purple));
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-attachment: fixed;
|
|
||||||
border-radius: 15px;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.deleteAnswer{
|
.deleteAnswer{
|
||||||
padding: 0 0 0 10px;
|
padding: 0 0 0 10px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import Cropper from 'cropperjs';
|
||||||
|
import 'cropperjs/dist/cropper.css';
|
||||||
|
|
||||||
|
let imageElement;
|
||||||
|
let cropper;
|
||||||
|
let croppedImage;
|
||||||
|
let showCropMessage = false;
|
||||||
|
|
||||||
|
const handleFileChange = (event) => {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
imageElement.src = e.target.result;
|
||||||
|
if (cropper) {
|
||||||
|
cropper.destroy();
|
||||||
|
}
|
||||||
|
cropper = new Cropper(imageElement, {
|
||||||
|
aspectRatio: 1,
|
||||||
|
viewMode: 1,
|
||||||
|
autoCropArea: 0, // Начальное значение для автообрезки 0
|
||||||
|
center: true,
|
||||||
|
zoomOnTouch: false,
|
||||||
|
zoomOnWheel: false,
|
||||||
|
cropBoxMovable: true,
|
||||||
|
cropBoxResizable: true,
|
||||||
|
background: false, // Убирает сеточный фон
|
||||||
|
autoCrop: false, // Изначально не показывать зону обрезки
|
||||||
|
ready: function () {
|
||||||
|
cropper.setCropBoxData({
|
||||||
|
width: 200,
|
||||||
|
height: 200,
|
||||||
|
left: (cropper.getContainerData().width - 200) / 2,
|
||||||
|
top: (cropper.getContainerData().height - 200) / 2,
|
||||||
|
});
|
||||||
|
cropper.crop(); // Включить зону обрезки
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCroppedImage = () => {
|
||||||
|
if (cropper) {
|
||||||
|
croppedImage = cropper.getCroppedCanvas().toDataURL();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="crop-container">
|
||||||
|
<input type="file" accept="image/*" on:change={handleFileChange} />
|
||||||
|
<img bind:this={imageElement} alt="Image to crop" />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<button on:click={getCroppedImage}>Crop Image</button>
|
||||||
|
|
||||||
|
{#if croppedImage}
|
||||||
|
<h3>Cropped Image</h3>
|
||||||
|
<img src={croppedImage} alt="Cropped Image" />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.crop-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 80vh; /* Настройка высоты по мере необходимости */
|
||||||
|
}
|
||||||
|
.crop-message {
|
||||||
|
color: white;
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
Loading…
Add table
Reference in a new issue