Spaces:
Running
Running
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> | |
<title>蒙版王</title> | |
<style> | |
/* 适用于手机的样式 */ | |
@media (max-width: 767px) { | |
body { | |
--bg-color: var(--tg-theme-bg-color); | |
font: 12px/18px "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, Verdana, sans-serif; | |
background-color: var(--bg-color); | |
color: var(--tg-theme-text-color); | |
width: 350; | |
margin: 0 auto; /* 水平居中 */ | |
} | |
#canvas { | |
border: 1px solid #000; | |
width: 100%; | |
height: auto; | |
} | |
html, body { | |
overflow-x: hidden; | |
} | |
#uploadButton{ | |
width: 80%; | |
} | |
#save{ | |
width: 20%; | |
} | |
.myDiv { | |
width: 98%; | |
display: flex; | |
flex-direction: row; | |
justify-content: flex-start; | |
margin: 0px 1%; | |
flex-wrap: wrap; | |
} | |
.myDiv1 { | |
width: 98%; | |
display: flex; | |
flex-direction: row; | |
justify-content: flex-start; | |
margin: 0px 1%; | |
} | |
.overlay { | |
left: 20px; | |
} | |
} | |
/* 适用于电脑的样式 */ | |
@media (min-width: 768px) { | |
#canvas { | |
border: 1px solid #000; | |
width: auto; | |
height: auto; | |
} | |
.myDiv { | |
display: flex; | |
flex-direction: row; | |
justify-content: center; | |
margin: 0 100px; | |
width: 512px; | |
flex-wrap: wrap; | |
} | |
.myDiv1 { | |
display: flex; | |
flex-direction: row; | |
justify-content: center; | |
margin: 0 100px; | |
width: 512px; | |
} | |
.overlay { | |
left: 100px; | |
} | |
} | |
#circle { | |
position: absolute; | |
width: 10px; | |
height: 10px; | |
border-radius: 50%; | |
border: 2px solid red; | |
background-color: transparent; | |
transition: opacity 1s; | |
pointer-events: none; | |
} | |
.show { | |
opacity: 1; | |
} | |
.hide { | |
opacity: 0; | |
} | |
.overlay { | |
position: absolute; | |
top: 82px; | |
z-index: 10; | |
/* 设置悬浮控件的样式和尺寸 */ | |
/* 可以使用 z-index 属性来控制层叠顺序 */ | |
} | |
</style> | |
</head> | |
<body> | |
<div class="myDiv1"> | |
<button id="uploadButton" style="display: None;"> | |
选择图片 | |
<input type="file" id="upload" accept="image/*" style="position: absolute; top: 0; left: 0; width: 98%; height: 100%; opacity: 0; cursor: pointer;"> | |
</button> | |
<button id="save" style="height: 50px;display: None">保存蒙版</button> | |
<button id="saveToClipboard" style="height: 50px;box-sizing: border-box; padding: 10px; width: 98%; font-size: 16px; height: 50px; | |
line-height: 30px; overflow: hidden; position: relative;">上传蒙版 Upload mask</button> | |
</div> | |
<div class="myDiv" id="tools"> | |
<input type="range" id="brushSizeSlider" style="width: 100%" value="40" min="1" max="150" step="1" > | |
</div> | |
<br> | |
<br> | |
<div class="myDiv" id="myImg1"> | |
<canvas id="canvas"></canvas> | |
<br> | |
<img id="outputImg" ></img> | |
</div> | |
<div class="overlay" style="display: flex; flex-direction: row; align-items: flex-start;"> | |
<label style="margin-bottom: 10px;"> | |
<input type="radio" name="editMode" value="draw" checked> 画笔模式 | |
</label> | |
<label style="margin-bottom: 10px;"> | |
<input type="radio" name="editMode" value="erase"> 擦除模式 | |
</label> | |
<label> | |
<input type="radio" name="editMode" value="select"> 不编辑 | |
</label> | |
</div> | |
<div id="circle" style="width: 20px; height: 20px; border-radius: 50%; border: 2px solid red;"></div> | |
<!-- <script src="https://telegram.org/js/telegram-web-app.js"></script> --> | |
<script> | |
// Init TWA | |
//Telegram.WebApp.ready(); | |
//Telegram.WebApp.expand(); | |
//Telegram.WebApp.enableClosingConfirmation() | |
//Telegram.WebApp.HapticFeedback.impactOccurred("medium"); | |
// Event occurs whenever theme settings are changed in the user's Telegram app (including switching to night mode). | |
//Telegram.WebApp.onEvent('themeChanged', function() { | |
// document.documentElement.className = Telegram.WebApp.colorScheme; | |
//}); | |
function getQueryParameter(name) { | |
const urlParams = new URLSearchParams(window.location.search); | |
return urlParams.get(name); | |
} | |
async function uploadMask(base64String) { | |
const response = await fetch('https://api.imgur.com/3/image', { | |
method: 'POST', | |
headers: { | |
'Authorization': 'Client-ID 955c061744537ff', | |
'Content-Type': 'application/json', | |
}, | |
body: JSON.stringify({ image: base64String }), | |
}); | |
const r = await response.json() | |
return r.data.link; | |
} | |
window.onerror = function (message, source, lineno, colno, error) { | |
const errorData = { | |
message: message, | |
source: source, | |
lineno: lineno, | |
colno: colno, | |
stack: error ? error.stack : null | |
}; | |
console.error("JavaScript Error:", errorData); | |
// 使用 Fetch API 上传错误信息 | |
fetch('https://u7leyomozktm-5527.shanghai-01.dayunet.com/log-error', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json' | |
}, | |
body: JSON.stringify(errorData) | |
}); | |
}; | |
window.onload = function() { | |
var canvas = document.getElementById('canvas'); | |
var context = canvas.getContext('2d'); | |
var image = document.getElementById('outputImg'); | |
var imageMask = new Image(); | |
var maskData = null; | |
var isDrawing = false; | |
var brushSize = 40; | |
var intervalHandel = null; | |
var brushSizeSlider = document.getElementById('brushSizeSlider'); | |
var editModeRadios = document.getElementsByName('editMode'); | |
var selectedMode = "draw"; | |
var isRotate = false; | |
function isMobile() { | |
return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)); | |
} | |
for (var i = 0; i < editModeRadios.length; i++) { | |
editModeRadios[i].addEventListener('change', function() { | |
// 获取选中的编辑模式值 | |
selectedMode = this.value; | |
drawImagesInterval(100); | |
}); | |
} | |
brushSizeSlider.addEventListener('input', function() { | |
brushSize = parseInt(this.value); | |
setCircleSize(brushSize); | |
if (isMobile()){ | |
var canvasRect = canvas.getBoundingClientRect(); | |
var scaleX = canvas.width / canvasRect.width; | |
showCircle(175 + window.scrollX, 200 + window.scrollY, scaleX); | |
} | |
}); | |
function resizeImage(img,s,resizedImage) { | |
var maxWidth = s; // 最大宽度 | |
var maxHeight = s; // 最大高度 | |
var width = img.width; | |
var height = img.height; | |
if (width/height < 4/3 && width <= maxWidth && height <= maxHeight) { | |
return false; | |
} | |
if (!isMobile() && width <= maxWidth && height <= maxHeight) { | |
return false; | |
} | |
if (width > maxWidth || height > maxHeight || width/height >= 4/3) { | |
var ratio = Math.max(maxWidth / width, maxHeight / height); | |
if (width <= maxWidth && height <= maxHeight){ | |
ratio = 1; | |
} | |
width = Math.floor(width * ratio); | |
height = Math.floor(height * ratio); | |
var tempCanvas = document.createElement('canvas'); | |
tempCanvas.width = width; | |
tempCanvas.height = height; | |
var ctx = tempCanvas.getContext('2d'); | |
isRotate = false; | |
if (width/height >= 4/3 && isMobile()){ | |
tempCanvas.height = width; | |
tempCanvas.width = height; | |
ctx.clearRect(0, 0, tempCanvas.width, tempCanvas.height); | |
ctx.save(); | |
ctx.translate(tempCanvas.width / 2, tempCanvas.height / 2); | |
ctx.rotate(Math.PI / 2); | |
ctx.drawImage(img, -img.width / 2, -img.height / 2); | |
ctx.restore(); | |
isRotate = true; | |
} | |
else { | |
ctx.drawImage(img, 0, 0, width, height); | |
} | |
resizedImage.src = tempCanvas.toDataURL(); | |
return true; | |
} | |
return false; | |
} | |
function drawImages() { | |
context.clearRect(0, 0, canvas.width, canvas.height); | |
context.putImageData(maskData,0,0); | |
if (selectedMode == "select") { | |
return; | |
} | |
context.globalAlpha = 0.75; // 设置透明度为0.5 | |
context.drawImage(image, 0, 0); | |
//context.drawImage(imageMask, 0, 0); | |
context.globalAlpha = 1; // 恢复透明度为1 | |
} | |
function drawImagesInterval(t) { | |
if (intervalHandel != null){ | |
drawImagesTimeOut(100); | |
window.clearInterval(intervalHandel); | |
intervalHandel = null; | |
} | |
intervalHandel = window.setInterval(function() {drawImages();}, t); | |
} | |
window.addEventListener('scroll', function(event) { | |
var scrollTop = window.pageYOffset || document.documentElement.scrollTop; | |
var overlay = document.querySelector(".overlay"); | |
overlay.style.top = (scrollTop + 82) + "px"; | |
}); | |
function stopDrawImagesInterval() { | |
if (intervalHandel != null){ | |
drawImagesTimeOut(100); | |
window.clearInterval(intervalHandel); | |
intervalHandel = null; | |
} | |
} | |
function drawImagesTimeOut(t) { | |
window.setTimeout(function() {drawImages();}, t); | |
} | |
function getImageDataB(img) { | |
context.clearRect(0, 0, canvas.width, canvas.height); | |
var width = image.width; | |
var height = image.height; | |
canvas.width = width; | |
canvas.height = height; | |
context.drawImage(img, 0, 0); | |
var imageData = context.getImageData(0, 0, width, height); | |
return imageData; | |
} | |
function getImageData(img) { | |
var tempCanvas = document.createElement('canvas'); | |
tempCanvas.width = canvas.width; | |
tempCanvas.height = canvas.height; | |
var tempContext = tempCanvas.getContext('2d'); | |
var width = image.width; | |
var height = image.height; | |
tempCanvas.width = width; | |
tempCanvas.height = height; | |
tempContext.drawImage(img, 0, 0); | |
var imageData = tempContext.getImageData(0, 0, width, height); | |
return imageData; | |
} | |
function createMaskImageData(width, height) { | |
// 创建一个新的ImageData对象 | |
var imageData = new ImageData(width, height); | |
// 获取像素数据 | |
var data = imageData.data; | |
// 将每个像素设置为黑色 | |
for (var i = 0; i < data.length; i += 4) { | |
data[i] = 0; // 设置红色通道 | |
data[i + 1] = 0; // 设置绿色通道 | |
data[i + 2] = 0; // 设置蓝色通道 | |
data[i + 3] = 255; // 设置透明度通道(不透明) | |
} | |
return imageData; | |
} | |
function getImageDataUrl(imageData) { | |
var tempCanvas = document.createElement('canvas'); | |
tempCanvas.width = canvas.width; | |
tempCanvas.height = canvas.height; | |
var tempContext = tempCanvas.getContext('2d'); | |
tempContext.putImageData(imageData, 0, 0); | |
return tempCanvas.toDataURL(); | |
} | |
async function loadImageFromUrl0(imageUrl) { | |
const dataUrl = await convertImageUrlToDataUrl(imageUrl); | |
await loadImageFromUrl(dataUrl); | |
} | |
async function loadImageFromUrl(dataUrl) { | |
image.crossOrigin='anonymous'; | |
image.onload = function() { | |
var resizedImage = new Image(); | |
resizedImage.onload = _ok; | |
function _ok(event){ | |
image = resizedImage; | |
canvas.width = resizedImage.width; | |
canvas.height = resizedImage.height; | |
maskData = createMaskImageData(image.width,image.height); | |
imageMask.src = getImageDataUrl(maskData); | |
drawImagesTimeOut(100); | |
} | |
if (!resizeImage(image,512,resizedImage)) { | |
canvas.width = image.width; | |
canvas.height = image.height; | |
maskData = createMaskImageData(image.width,image.height); | |
imageMask.src = getImageDataUrl(maskData); | |
drawImagesTimeOut(100); | |
} | |
} | |
image.src = dataUrl; | |
} | |
/* | |
function handleImageLoad(image) { | |
var resizedImage = new Image(); | |
resizedImage.onload = function() { | |
image = resizedImage; | |
canvas.width = resizedImage.width; | |
canvas.height = resizedImage.height; | |
maskData = createMaskImageData(image.width, image.height); | |
imageMask.src = getImageDataUrl(maskData); | |
drawImagesTimeOut(100); | |
} | |
if (!resizeImage(image, 512, resizedImage)) { | |
canvas.width = image.width; | |
canvas.height = image.height; | |
maskData = createMaskImageData(image.width, image.height); | |
imageMask.src = getImageDataUrl(maskData); | |
drawImagesTimeOut(100); | |
} | |
} | |
// 监听文件选择 | |
function handleFile(file) { | |
var reader = new FileReader(); | |
reader.onload = function(event) { | |
var image = new Image(); | |
image.onload = function() { | |
handleImageLoad(image); | |
} | |
image.src = event.target.result; | |
} | |
reader.readAsDataURL(file); | |
} | |
*/ | |
function handleFile(file) { | |
var reader = new FileReader(); | |
reader.onload = function(event) { | |
image.onload = function() { | |
var resizedImage = new Image(); | |
resizedImage.onload = _ok; | |
function _ok(event){ | |
image = resizedImage; | |
canvas.width = resizedImage.width; | |
canvas.height = resizedImage.height; | |
maskData = createMaskImageData(image.width,image.height); | |
imageMask.src = getImageDataUrl(maskData); | |
drawImagesTimeOut(100); | |
} | |
if (!resizeImage(image,512,resizedImage)) { | |
canvas.width = image.width; | |
canvas.height = image.height; | |
maskData = createMaskImageData(image.width,image.height); | |
imageMask.src = getImageDataUrl(maskData); | |
drawImagesTimeOut(100); | |
} | |
} | |
image.src = event.target.result; | |
console.log(image.src); | |
} | |
reader.readAsDataURL(file); | |
} | |
// 上传图片 | |
document.getElementById("upload").addEventListener('change', function(e) { | |
var file = e.target.files[0]; | |
handleFile(file); | |
}); | |
// 添加拖拽文件事件监听 | |
document.addEventListener('dragover', function(e) { | |
e.preventDefault(); | |
}); | |
document.addEventListener('drop', function(e) { | |
e.preventDefault(); | |
// 获取拖拽事件中的文件对象 | |
var file = e.dataTransfer.files[0]; | |
// 执行与文件上传按钮相同的操作 | |
handleFile(file); | |
}); | |
function inRect(x,y,rect){ | |
return ( | |
x >= rect.left && | |
x <= rect.right && | |
y >= rect.top && | |
y <= rect.bottom | |
); | |
} | |
function calcCanvasOffset(e,canvas) { | |
var canvasRect = canvas.getBoundingClientRect(); | |
var scaleX = canvas.width / canvasRect.width; | |
var scaleY = canvas.height / canvasRect.height; | |
var offsetX = (e.clientX - canvasRect.left) * scaleX; | |
var offsetY = (e.clientY - canvasRect.top) * scaleY; | |
return [offsetX,offsetY,scaleX,scaleY]; | |
} | |
// 开始绘制 | |
function onTouchDown(e) { | |
if (selectedMode == "select") { | |
return; | |
} | |
var canvasRect = canvas.getBoundingClientRect(); | |
var [offsetX,offsetY,scaleX,scaleY] = calcCanvasOffset(e,canvas); | |
//console.log([offsetX,offsetY,scaleX,scaleY]); | |
if (!inRect(e.clientX,e.clientY,canvasRect)){ | |
return; | |
} | |
if (draw(offsetX, offsetY)) { | |
isDrawing = true; | |
drawImagesInterval(100); | |
} | |
} | |
document.addEventListener('touchstart', function(event) { | |
var touch = event.touches[0]; | |
onTouchDown(touch); | |
}); | |
document.addEventListener('mousedown',function(event){ | |
onTouchDown(event); | |
} ); | |
// 结束绘制 | |
document.addEventListener('mouseup', function() { | |
isDrawing = false; | |
stopDrawImagesInterval(); | |
}); | |
// 绘制中 | |
function onMove(e) { | |
var [offsetX,offsetY,scaleX,scaleY] = calcCanvasOffset(e,canvas); | |
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { | |
showCircle(e.clientX + window.scrollX, e.clientY + window.scrollY, scaleX); | |
} else { | |
showCircle(e.clientX + window.scrollX, e.clientY + window.scrollY, scaleX); | |
} | |
var canvasRect = canvas.getBoundingClientRect(); | |
if (isDrawing) { | |
//console.log('onMove1'); | |
if (!inRect(e.clientX,e.clientY,canvasRect)){ | |
return; | |
} | |
draw(offsetX, offsetY); | |
} | |
} | |
canvas.addEventListener('touchmove', function(event) { | |
if (selectedMode == "select") { | |
return; | |
} | |
event.preventDefault(); | |
var touch = event.touches[0]; | |
onMove(touch); | |
}, { passive: false }); | |
if (!isMobile()) { | |
document.addEventListener('mousemove', function(event){ | |
onMove(event); | |
}); | |
} | |
// 绘制函数 | |
function draw(x, y) { | |
if (selectedMode == "selected") { | |
return false; | |
} | |
if (maskData == null) { | |
return false; | |
} | |
var data = maskData.data; | |
var brushRadius = brushSize / 2; | |
for (var i = -brushRadius; i <= brushRadius; i++) { | |
for (var j = -brushRadius; j <= brushRadius; j++) { | |
var pixelX = Math.round(x + i); | |
var pixelY = Math.round(y + j); | |
if (pixelX < 0 || pixelX >= canvas.width || pixelY < 0 || pixelY >= canvas.height) { | |
continue; | |
} | |
var distance = Math.sqrt((pixelX - x) * (pixelX - x) + (pixelY - y) * (pixelY - y)); | |
if (distance > brushRadius) { | |
continue; | |
} | |
var index = (pixelY * canvas.width + pixelX) * 4; | |
if (selectedMode == "draw"){ | |
data[index] = 255; // 设置红色通道为最大值,即白色 | |
data[index + 1] = 255; // 设置绿色通道为最大值,即白色 | |
data[index + 2] = 255; | |
} | |
else { | |
data[index] = 0; // 设置红色通道为最大值,即白色 | |
data[index + 1] = 0; // 设置绿色通道为最大值,即白色 | |
data[index + 2] = 0; | |
} | |
//data[index + 3] = 128; | |
} | |
} | |
//imageMask.src = getImageDataUrl(maskData); | |
return true; | |
} | |
function generateRandomFileName() { | |
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; | |
var length = 10; // 文件名长度 | |
var fileName = ''; | |
for (var i = 0; i < length; i++) { | |
var randomIndex = Math.floor(Math.random() * characters.length); | |
fileName += characters.charAt(randomIndex); | |
} | |
return fileName; | |
} | |
function rotateImageData(imageData) { | |
const { width, height } = imageData; | |
const rotatedData = new Uint8ClampedArray(width * height * 4); | |
for (let y = 0; y < height; y++) { | |
for (let x = 0; x < width; x++) { | |
const srcIndex = (x + y * width) * 4; | |
const destIndex = ((width - x - 1) * height + y) * 4; | |
rotatedData[destIndex] = imageData.data[srcIndex]; | |
rotatedData[destIndex + 1] = imageData.data[srcIndex + 1]; | |
rotatedData[destIndex + 2] = imageData.data[srcIndex + 2]; | |
rotatedData[destIndex + 3] = imageData.data[srcIndex + 3]; | |
} | |
} | |
return new ImageData(rotatedData, height, width); | |
} | |
function openImageInNewTab(dataUrl) { | |
const newTab = window.open(); | |
newTab.document.write('<html><body style="margin: 0;"><img src="' + dataUrl + '"></body></html>'); | |
newTab.document.close(); | |
} | |
function saveImageAsFile(dataUrl, filename) { | |
// 将 Data URL 转换为 Blob 对象 | |
const blob = dataURLToBlob(dataUrl); | |
// 创建一个链接元素 | |
const link = document.createElement('a'); | |
link.href = URL.createObjectURL(blob); | |
link.download = filename; | |
// 模拟点击下载链接 | |
link.click(); | |
// 释放 URL 对象 | |
URL.revokeObjectURL(link.href); | |
} | |
function dataURLToBlob(dataUrl) { | |
console.log(dataUrl); | |
const commaIndex = dataUrl.indexOf(','); | |
const mime = dataUrl.substring(5, commaIndex); | |
const base64Data = dataUrl.substring(commaIndex + 1); | |
const byteCharacters = atob(base64Data); | |
const byteNumbers = new Array(byteCharacters.length); | |
for (let i = 0; i < byteCharacters.length; i++) { | |
byteNumbers[i] = byteCharacters.charCodeAt(i); | |
} | |
const byteArray = new Uint8Array(byteNumbers); | |
return new Blob([byteArray], { type: mime }); | |
} | |
document.getElementById('saveToClipboard').addEventListener('click',async function() { | |
var data = maskData.data; | |
var tempCanvas = document.createElement('canvas'); | |
var ctx = tempCanvas.getContext('2d'); | |
if (isRotate == true){ | |
var rData = rotateImageData(maskData); | |
tempCanvas.height = maskData.width; | |
tempCanvas.width = maskData.height; | |
ctx.putImageData(rData, 0, 0); | |
} | |
else { | |
tempCanvas.width = canvas.width; | |
tempCanvas.height = canvas.height; | |
ctx.putImageData(maskData, 0, 0); | |
} | |
//await navigator.clipboard.writeText(tempCanvas.toDataURL("image/jpeg", 0.9)); | |
const response = await fetch(tempCanvas.toDataURL("image/png")); | |
const blob = await response.blob(); | |
const item = new ClipboardItem({ [blob.type]: blob }); | |
await navigator.clipboard.write([item]); | |
const img = document.getElementById('outputImg'); | |
img.src = tempCanvas.toDataURL("image/jpeg"); | |
const base64String = img.src.split(',')[1]; | |
const response2 = await fetch( | |
'https://u7leyomozktm-5527.shanghai-01.dayunet.com/uploadVPMask/' + getQueryParameter('id'),{ | |
//'https://api.imgur.com/3/image', { | |
method: 'POST', | |
headers: { | |
'Authorization': 'Client-ID 955c061744537ff', | |
'Content-Type': 'application/json', | |
}, | |
body: JSON.stringify({ image: base64String }), | |
}); | |
/*const r = await response2.json(); | |
img.src = r.data.link; | |
//Telegram.WebApp.sendData("" + Telegram.WebApp.initDataUnsafe.user.id + ";" + r.data.link); | |
const script = document.createElement('script'); | |
script.src = "https://telegram.org/js/telegram-widget.js?22"; | |
script.setAttribute('data-telegram-share-url', r.data.link); | |
script.async = true; | |
*/ | |
const myImg1 = document.getElementById('myImg1'); | |
const firstChild = myImg1.firstChild; | |
let sendback = document.createElement('a'); | |
sendback.href = 'https://t.me/ainudevideo_bot?start=mask_ok';// + r.data.link; | |
sendback.textContent = 'sendback'; | |
sendback.click(); | |
sendback.innerHTML = "如果点击按钮没有反应,请点这个链接 If there is no response when clicking the button, please click on this link"; | |
myImg1.insertBefore(sendback, firstChild); | |
//Telegram.WebApp.close(); | |
}); | |
// 保存蒙版 | |
document.getElementById('save').addEventListener('click', function() { | |
var data = maskData.data; | |
var tempCanvas = document.createElement('canvas'); | |
var ctx = tempCanvas.getContext('2d'); | |
if (isRotate == true){ | |
var rData = rotateImageData(maskData); | |
tempCanvas.height = maskData.width; | |
tempCanvas.width = maskData.height; | |
ctx.putImageData(rData, 0, 0); | |
} | |
else { | |
tempCanvas.width = canvas.width; | |
tempCanvas.height = canvas.height; | |
ctx.putImageData(maskData, 0, 0); | |
} | |
var link = document.createElement('a'); | |
link.href = tempCanvas.toDataURL("image/jpeg", 0.9); | |
link.download = 'mask_' + generateRandomFileName() + '.jpg'; | |
link.click(); | |
var oldMode = selectedMode; | |
selectedMode = "select"; | |
drawImages(); | |
selectedMode = oldMode; | |
//saveImageAsFile(tempCanvas.toDataURL("image/jpeg", 0.9),'mask_' + generateRandomFileName() + '.jpg'); | |
//openImageInNewTab(tempCanvas.toDataURL("image/jpeg", 0.9)); | |
}); | |
// 获取圆圈元素 | |
var circle = document.getElementById('circle'); | |
// 根据 brushSize 设置圆圈大小 | |
function setCircleSize(brushSize) { | |
} | |
// 在屏幕上显示圆圈 | |
function showCircle(x, y, scale) { | |
circle.style.left = (x - brushSize/scale/2) + 'px'; | |
circle.style.top = (y - brushSize/scale/2) + 'px'; | |
circle.style.width = (brushSize / scale) + 'px'; | |
circle.style.height = (brushSize / scale) + 'px'; | |
circle.classList.add('show'); | |
circle.classList.remove('hide'); | |
// 过一秒后隐藏圆圈 | |
setTimeout(hideCircle, 1000); | |
} | |
// 隐藏圆圈 | |
function hideCircle() { | |
circle.classList.remove('show'); | |
circle.classList.add('hide'); | |
} | |
// 手机平台点击事件处理函数 | |
function handleTouchStart(e) { | |
// 只处理单指触摸事件 | |
if (e.touches.length === 1) { | |
var touch = e.touches[0]; | |
var x = touch.clientX; | |
var y = touch.clientY; | |
var [offsetX,offsetY,scaleX,scaleY] = calcCanvasOffset(touch,canvas); | |
// 在屏幕上显示圆圈 | |
showCircle(x + window.scrollX, y + window.scrollY, scaleX); | |
} | |
} | |
async function convertImageUrlToDataUrl(imageUrl) { | |
const response = await fetch(imageUrl); | |
const blob = await response.blob(); | |
return new Promise((resolve, reject) => { | |
const reader = new FileReader(); | |
reader.onloadend = () => resolve(reader.result); | |
reader.onerror = (error) => reject(`Error reading blob: ${error}`); | |
reader.readAsDataURL(blob); | |
}); | |
} | |
// 初始化圆圈大小 | |
setCircleSize(brushSize); | |
hideCircle(); | |
// 设置事件监听 | |
//setEventListeners(); | |
//const imageUrl = getQueryParameter('imageUrl'); | |
//const imageUrl = 'https://i.imgur.com/' + Telegram.WebApp.initDataUnsafe.user.id + '.jpeg'; | |
//const imageUrl = 'https://u7leyomozktm-5527.shanghai-01.dayunet.com/getVPImage/' + Telegram.WebApp.initDataUnsafe.user.id; | |
const imageUrl = 'https://u7leyomozktm-5527.shanghai-01.dayunet.com/getVPImage/' + getQueryParameter('id'); | |
if (imageUrl) { | |
loadImageFromUrl(imageUrl); | |
} | |
} | |
</script> | |
<!-- Eruda is console for mobile browsers --> | |
<!-- <script src="https://cdn.jsdelivr.net/npm/eruda"></script> --> | |
<!-- <script>eruda.init();</script> --> | |
</body> | |
</html> |