From a00ff2ba5ccac1a84d6f9ea15903d1607db21c57 Mon Sep 17 00:00:00 2001 From: neverbiasu <1751162157@qq.com> Date: Wed, 26 Jun 2024 12:37:02 +0800 Subject: [PATCH 1/6] init --- fixtures/css/image-verification.xsml | 97 ++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 fixtures/css/image-verification.xsml diff --git a/fixtures/css/image-verification.xsml b/fixtures/css/image-verification.xsml new file mode 100644 index 0000000..4dfe1e9 --- /dev/null +++ b/fixtures/css/image-verification.xsml @@ -0,0 +1,97 @@ + + + Image Verification Demo + + + + + + + + + + From 88b7cc57602956563ad3a6a6ba5a0f93f3346b9f Mon Sep 17 00:00:00 2001 From: neverbiasu <1751162157@qq.com> Date: Wed, 26 Jun 2024 18:17:44 +0800 Subject: [PATCH 2/6] create image-verification.ts --- fixtures/css/image-verification.ts | 114 +++++++++++++++++++++++++++ fixtures/css/image-verification.xsml | 83 +------------------ 2 files changed, 118 insertions(+), 79 deletions(-) create mode 100644 fixtures/css/image-verification.ts diff --git a/fixtures/css/image-verification.ts b/fixtures/css/image-verification.ts new file mode 100644 index 0000000..a84a115 --- /dev/null +++ b/fixtures/css/image-verification.ts @@ -0,0 +1,114 @@ +import splattingPic from '../textures/splatting.jpg' + +spatialDocument.addEventListener('spaceReady', () => { + const plane = spatialDocument.querySelector('plane') as any; + createImageBitmap(new Blob([splattingPic], { type: 'image/jpeg' })).then(async (bitmap) => { + const canvas = new OffscreenCanvas(bitmap.width, bitmap.height); + const ctx = canvas.getContext('2d'); + if (ctx == null) { + return; + } + + const panel = plane.shadowRoot; + const div = panel.querySelector('div'); + const img = div.querySelector('img'); + + ctx.drawImage(bitmap, 0, 0); + + // const leftImageData = getShapeFromImage(bitmap, 'rect'); + // const rightImageData = cutShapeFromImage(bitmap, 'rect'); + // // const imageData = rightImageData; + + // const imageData = combineImages(leftImageData, rightImageData); + + // console.log('imageData', imageData); + // const planeTexture = new BABYLON.RawTexture( + // imageData.data, + // imageData.width, + // imageData.height, + // BABYLON.Engine.TEXTUREFORMAT_RGBA, + // spatialDocument.scene, + // false, + // false, + // BABYLON.Texture.TRILINEAR_SAMPLINGMODE + // ); + + // const mat = new BABYLON.StandardMaterial('plane', spatialDocument.scene); + // mat.diffuseTexture = planeTexture; + // mat.diffuseColor = new BABYLON.Color3(255, 255, 255); + // plane.asNativeType().material = mat; + }); +}) + +async function convertImageDataToDataURL(imageData: ImageData): Promise { + const canvas = new OffscreenCanvas(imageData.width, imageData.height); + const ctx = canvas.getContext('2d'); + if (ctx == null) { + throw new Error('Could not get 2D context'); + } + ctx.putImageData(imageData, 0, 0); + const blob = await new Promise((resolve) => { + canvas.convertToBlob().then(resolve); + }); + + const dataURL = await new Promise((resolve) => { + const reader = new FileReader(); + reader.onload = () => resolve(reader.result as string); + reader.readAsDataURL(blob); + }); + + return dataURL; +} + +function cutShapeFromImage(image, shape: string) { + const canvas = new OffscreenCanvas(image.width, image.height); + const ctx = canvas.getContext('2d'); + ctx.drawImage(image, 0, 0); + + // 设置合成操作为'destination-out',这样后续的绘制操作会从已有的内容中删除像素 + ctx.globalCompositeOperation = 'destination-out'; + + if (shape === 'rect') { + ctx.fillRect(1/4 * image.width, 1/4 * image.height, 1/2 * image.width, 1/2 * image.height); + } + + const imageData = ctx.getImageData(0, 0, image.width, image.height); + + return imageData +} + +function getShapeFromImage(image, shape: string) { + const canvas = new OffscreenCanvas(image.width, image.height); + const ctx = canvas.getContext('2d'); + + // ctx.fillStyle = 'black'; + ctx.fillRect(0, 0, image.width, image.height); + + // 定义剪辑区域 + if (shape === 'rect') { + ctx.beginPath(); + ctx.rect(1/4 * image.width, 1/4 * image.height, 1/2 * image.width, 1/2 * image.height); + ctx.clip(); + } + + // 在剪辑区域内绘制图像 + ctx.drawImage(image, 0, 0); + + const imageData = ctx.getImageData(0, 0, image.width, image.height); + + return imageData; +} + +function combineImages(image1: ImageData, image2: ImageData): ImageData { + const width = image1.width * 3; + const height = image1.height; + + const canvas = new OffscreenCanvas(width, height); + const ctx = canvas.getContext('2d'); + + ctx.putImageData(image1, 0, 0); + ctx.putImageData(image2, image1.width * 2, 0); + + const combinedImageData = ctx.getImageData(0, 0, width, height); + return combinedImageData; +} diff --git a/fixtures/css/image-verification.xsml b/fixtures/css/image-verification.xsml index 4dfe1e9..b877e43 100644 --- a/fixtures/css/image-verification.xsml +++ b/fixtures/css/image-verification.xsml @@ -8,90 +8,15 @@ plane { display: relative; flex-direction: row; - row-gap: 50px; - padding: 50px; - } - plane#p1 { - background-color: red; - height: 1024px; - width: 3072px; - position: 0.4 0 0; } + - - - - From b881d1d9992d94a2cb95a910013b15730d9f7d21 Mon Sep 17 00:00:00 2001 From: neverbiasu <1751162157@qq.com> Date: Wed, 26 Jun 2024 18:52:48 +0800 Subject: [PATCH 3/6] add --- fixtures/css/image-verification.ts | 19 +++++++++++++++---- fixtures/css/image-verification.xsml | 18 +++++++++++++++++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/fixtures/css/image-verification.ts b/fixtures/css/image-verification.ts index a84a115..9a3c8be 100644 --- a/fixtures/css/image-verification.ts +++ b/fixtures/css/image-verification.ts @@ -10,13 +10,24 @@ spatialDocument.addEventListener('spaceReady', () => { } const panel = plane.shadowRoot; - const div = panel.querySelector('div'); - const img = div.querySelector('img'); + const div = panel.querySelector('div'); + const img1 = div.querySelector('img'); + // const img1 = spatialDocument.getElementById('img1'); + // const img2 = spatialDocument.getElementById('img2'); ctx.drawImage(bitmap, 0, 0); - // const leftImageData = getShapeFromImage(bitmap, 'rect'); - // const rightImageData = cutShapeFromImage(bitmap, 'rect'); + const leftImageData = getShapeFromImage(bitmap, 'rect'); + const rightImageData = cutShapeFromImage(bitmap, 'rect'); + + const leftImageURL = await convertImageDataToDataURL(leftImageData); + const rightImageURL = await convertImageDataToDataURL(rightImageData); + console.log('leftImageURL', leftImageURL); + console.log('rightImageURL', rightImageURL); + + img1.src = leftImageURL; + div.style.backgroundImage = `url(${rightImageURL})`; + // // const imageData = rightImageData; // const imageData = combineImages(leftImageData, rightImageData); diff --git a/fixtures/css/image-verification.xsml b/fixtures/css/image-verification.xsml index b877e43..8bca285 100644 --- a/fixtures/css/image-verification.xsml +++ b/fixtures/css/image-verification.xsml @@ -14,8 +14,24 @@ +
- + +
From 959b5c65b9f8107a1751f33a6905867f66aa5b0d Mon Sep 17 00:00:00 2001 From: neverbiasu <1751162157@qq.com> Date: Thu, 27 Jun 2024 18:22:00 +0800 Subject: [PATCH 4/6] 6.27 --- fixtures/css/image-verification.ts | 53 +++++++++++++++------------- fixtures/css/image-verification.xsml | 28 ++++++++------- 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/fixtures/css/image-verification.ts b/fixtures/css/image-verification.ts index 9a3c8be..3f370f0 100644 --- a/fixtures/css/image-verification.ts +++ b/fixtures/css/image-verification.ts @@ -8,27 +8,27 @@ spatialDocument.addEventListener('spaceReady', () => { if (ctx == null) { return; } - + const panel = plane.shadowRoot; const div = panel.querySelector('div'); - const img1 = div.querySelector('img'); - // const img1 = spatialDocument.getElementById('img1'); - // const img2 = spatialDocument.getElementById('img2'); - - ctx.drawImage(bitmap, 0, 0); + const images = div.querySelectorAll('img'); + const img1 = images[0]; + const img2 = images[1]; const leftImageData = getShapeFromImage(bitmap, 'rect'); const rightImageData = cutShapeFromImage(bitmap, 'rect'); const leftImageURL = await convertImageDataToDataURL(leftImageData); const rightImageURL = await convertImageDataToDataURL(rightImageData); - console.log('leftImageURL', leftImageURL); - console.log('rightImageURL', rightImageURL); + // console.log('leftImageURL', leftImageURL); + // console.log('rightImageURL', rightImageURL); img1.src = leftImageURL; - div.style.backgroundImage = `url(${rightImageURL})`; - - // // const imageData = rightImageData; + img2.src = rightImageURL; + + // console.log('img1.style', img1.style); + + // const imageData = rightImageData; // const imageData = combineImages(leftImageData, rightImageData); @@ -71,6 +71,23 @@ async function convertImageDataToDataURL(imageData: ImageData): Promise return dataURL; } +function moveImageWithRay(img) { + const originMouseX = img.style.originX; + img.addEventListener('mouseclick', (event) => { + const currentMouseX = event.x; + if (currentMouseX < originMouseX + 20 && currentMouseX > originMouseX - 20) { + + } + const gapX = originMouseX - currentMouseX; + img.style.transform = `translateX(${gapX}px)`; + }) + img.addEventListener('mouseLeave', (event) => { + const currentMouseX = event.x; + const gapX = originMouseX - currentMouseX; + img.style.transform = `translateX(${gapX}px)`; + }) +} + function cutShapeFromImage(image, shape: string) { const canvas = new OffscreenCanvas(image.width, image.height); const ctx = canvas.getContext('2d'); @@ -109,17 +126,3 @@ function getShapeFromImage(image, shape: string) { return imageData; } - -function combineImages(image1: ImageData, image2: ImageData): ImageData { - const width = image1.width * 3; - const height = image1.height; - - const canvas = new OffscreenCanvas(width, height); - const ctx = canvas.getContext('2d'); - - ctx.putImageData(image1, 0, 0); - ctx.putImageData(image2, image1.width * 2, 0); - - const combinedImageData = ctx.getImageData(0, 0, width, height); - return combinedImageData; -} diff --git a/fixtures/css/image-verification.xsml b/fixtures/css/image-verification.xsml index 8bca285..301eb08 100644 --- a/fixtures/css/image-verification.xsml +++ b/fixtures/css/image-verification.xsml @@ -13,26 +13,30 @@ - - -
- - +
+ +
+ From 4a857208fc32eabc5dd08fed4830962989db6714 Mon Sep 17 00:00:00 2001 From: neverbiasu <1751162157@qq.com> Date: Wed, 3 Jul 2024 17:45:47 +0800 Subject: [PATCH 5/6] update the codes of image transform --- fixtures/css/image-verification.ts | 69 +++++++--------------------- fixtures/css/image-verification.xsml | 13 +++++- 2 files changed, 28 insertions(+), 54 deletions(-) diff --git a/fixtures/css/image-verification.ts b/fixtures/css/image-verification.ts index 3f370f0..dfa1fd6 100644 --- a/fixtures/css/image-verification.ts +++ b/fixtures/css/image-verification.ts @@ -1,56 +1,33 @@ import splattingPic from '../textures/splatting.jpg' +const plane = spatialDocument.querySelector('plane') as any; +const panel = plane.shadowRoot; +const div = panel.querySelector('div'); +const images = div.querySelectorAll('img'); +const img1 = images[0]; +const img2 = images[1]; +const p = div.querySelector('p'); + spatialDocument.addEventListener('spaceReady', () => { - const plane = spatialDocument.querySelector('plane') as any; createImageBitmap(new Blob([splattingPic], { type: 'image/jpeg' })).then(async (bitmap) => { const canvas = new OffscreenCanvas(bitmap.width, bitmap.height); const ctx = canvas.getContext('2d'); if (ctx == null) { return; } - - const panel = plane.shadowRoot; - const div = panel.querySelector('div'); - const images = div.querySelectorAll('img'); - const img1 = images[0]; - const img2 = images[1]; - const leftImageData = getShapeFromImage(bitmap, 'rect'); const rightImageData = cutShapeFromImage(bitmap, 'rect'); const leftImageURL = await convertImageDataToDataURL(leftImageData); const rightImageURL = await convertImageDataToDataURL(rightImageData); - // console.log('leftImageURL', leftImageURL); - // console.log('rightImageURL', rightImageURL); img1.src = leftImageURL; img2.src = rightImageURL; - - // console.log('img1.style', img1.style); - - // const imageData = rightImageData; - - // const imageData = combineImages(leftImageData, rightImageData); - - // console.log('imageData', imageData); - // const planeTexture = new BABYLON.RawTexture( - // imageData.data, - // imageData.width, - // imageData.height, - // BABYLON.Engine.TEXTUREFORMAT_RGBA, - // spatialDocument.scene, - // false, - // false, - // BABYLON.Texture.TRILINEAR_SAMPLINGMODE - // ); - - // const mat = new BABYLON.StandardMaterial('plane', spatialDocument.scene); - // mat.diffuseTexture = planeTexture; - // mat.diffuseColor = new BABYLON.Color3(255, 255, 255); - // plane.asNativeType().material = mat; }); }) +moveImageWithRay(); + async function convertImageDataToDataURL(imageData: ImageData): Promise { const canvas = new OffscreenCanvas(imageData.width, imageData.height); const ctx = canvas.getContext('2d'); @@ -71,20 +48,14 @@ async function convertImageDataToDataURL(imageData: ImageData): Promise return dataURL; } -function moveImageWithRay(img) { - const originMouseX = img.style.originX; - img.addEventListener('mouseclick', (event) => { - const currentMouseX = event.x; - if (currentMouseX < originMouseX + 20 && currentMouseX > originMouseX - 20) { - +function moveImageWithRay() { + div.addEventListener('mousemove', (event) => { + const mouseX = Math.round(event.x); + const gapX = mouseX - 128; + img1.style.transform = `translateX(${gapX}px)`; + if (gapX >= 763 && gapX <= 773) { + p.textContent = 'Success!'; } - const gapX = originMouseX - currentMouseX; - img.style.transform = `translateX(${gapX}px)`; - }) - img.addEventListener('mouseLeave', (event) => { - const currentMouseX = event.x; - const gapX = originMouseX - currentMouseX; - img.style.transform = `translateX(${gapX}px)`; }) } @@ -93,7 +64,6 @@ function cutShapeFromImage(image, shape: string) { const ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0); - // 设置合成操作为'destination-out',这样后续的绘制操作会从已有的内容中删除像素 ctx.globalCompositeOperation = 'destination-out'; if (shape === 'rect') { @@ -109,17 +79,12 @@ function getShapeFromImage(image, shape: string) { const canvas = new OffscreenCanvas(image.width, image.height); const ctx = canvas.getContext('2d'); - // ctx.fillStyle = 'black'; - ctx.fillRect(0, 0, image.width, image.height); - - // 定义剪辑区域 if (shape === 'rect') { ctx.beginPath(); ctx.rect(1/4 * image.width, 1/4 * image.height, 1/2 * image.width, 1/2 * image.height); ctx.clip(); } - // 在剪辑区域内绘制图像 ctx.drawImage(image, 0, 0); const imageData = ctx.getImageData(0, 0, image.width, image.height); diff --git a/fixtures/css/image-verification.xsml b/fixtures/css/image-verification.xsml index 301eb08..3f6a1ed 100644 --- a/fixtures/css/image-verification.xsml +++ b/fixtures/css/image-verification.xsml @@ -13,27 +13,36 @@ - +
+

From 0142d7cbf383514ce5eb6f0b9895cf288a1d03e4 Mon Sep 17 00:00:00 2001 From: neverbiasu <1751162157@qq.com> Date: Thu, 4 Jul 2024 18:30:36 +0800 Subject: [PATCH 6/6] last dance --- fixtures/css/image-verification.ts | 40 +++++++++++++++++++++++++--- fixtures/css/image-verification.xsml | 6 +++-- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/fixtures/css/image-verification.ts b/fixtures/css/image-verification.ts index dfa1fd6..9c670c2 100644 --- a/fixtures/css/image-verification.ts +++ b/fixtures/css/image-verification.ts @@ -15,8 +15,10 @@ spatialDocument.addEventListener('spaceReady', () => { if (ctx == null) { return; } - const leftImageData = getShapeFromImage(bitmap, 'rect'); - const rightImageData = cutShapeFromImage(bitmap, 'rect'); + + const shape = getRandomShape(); + const leftImageData = getShapeFromImage(bitmap, shape); + const rightImageData = cutShapeFromImage(bitmap, shape); const leftImageURL = await convertImageDataToDataURL(leftImageData); const rightImageURL = await convertImageDataToDataURL(rightImageData); @@ -49,12 +51,15 @@ async function convertImageDataToDataURL(imageData: ImageData): Promise } function moveImageWithRay() { - div.addEventListener('mousemove', (event) => { + div.addEventListener('raymove', (event) => { const mouseX = Math.round(event.x); const gapX = mouseX - 128; img1.style.transform = `translateX(${gapX}px)`; if (gapX >= 763 && gapX <= 773) { p.textContent = 'Success!'; + p.style.color = 'white'; + } else { + p.textContent = ''; } }) } @@ -63,11 +68,21 @@ function cutShapeFromImage(image, shape: string) { const canvas = new OffscreenCanvas(image.width, image.height); const ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0); - ctx.globalCompositeOperation = 'destination-out'; if (shape === 'rect') { ctx.fillRect(1/4 * image.width, 1/4 * image.height, 1/2 * image.width, 1/2 * image.height); + } else if (shape === 'circle') { + ctx.beginPath(); + ctx.arc(image.width / 2, image.height / 2, Math.min(image.width, image.height) / 4, 0, 2 * Math.PI); + ctx.fill(); + } else if (shape === 'triangle') { + ctx.beginPath(); + ctx.moveTo(1/2 * image.width, 1/4 * image.height); + ctx.lineTo(1/4 * image.width, 3/4 * image.height); + ctx.lineTo(3/4 * image.width, 3/4 * image.height); + ctx.closePath(); + ctx.fill(); } const imageData = ctx.getImageData(0, 0, image.width, image.height); @@ -83,6 +98,17 @@ function getShapeFromImage(image, shape: string) { ctx.beginPath(); ctx.rect(1/4 * image.width, 1/4 * image.height, 1/2 * image.width, 1/2 * image.height); ctx.clip(); + } else if (shape === 'circle') { + ctx.beginPath(); + ctx.arc(image.width / 2, image.height / 2, Math.min(image.width, image.height) / 4, 0, 2 * Math.PI); + ctx.clip(); + } else if (shape === 'triangle') { + ctx.beginPath(); + ctx.moveTo(1/2 * image.width, 1/4 * image.height); + ctx.lineTo(1/4 * image.width, 3/4 * image.height); + ctx.lineTo(3/4 * image.width, 3/4 * image.height); + ctx.closePath(); + ctx.clip(); } ctx.drawImage(image, 0, 0); @@ -91,3 +117,9 @@ function getShapeFromImage(image, shape: string) { return imageData; } + +function getRandomShape() { + const shapes = ['rect', 'circle', 'triangle']; + const randomIndex = Math.floor(Math.random() * shapes.length); + return shapes[randomIndex]; +} diff --git a/fixtures/css/image-verification.xsml b/fixtures/css/image-verification.xsml index 3f6a1ed..e201bf5 100644 --- a/fixtures/css/image-verification.xsml +++ b/fixtures/css/image-verification.xsml @@ -17,9 +17,11 @@
-

+

.