Skip to content

Commit 4ccd801

Browse files
committed
Update qrcode process script, add 3 papers effect
1 parent d348502 commit 4ccd801

File tree

3 files changed

+85
-10
lines changed

3 files changed

+85
-10
lines changed

bin/qr-code.cut.js

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import path from 'path'
55
import { fileURLToPath } from 'url'
66

77
/**
8-
* Crop QR code image - cut 340px from top, 230px from bottom, 100px from left, 100px from right
8+
* Crop QR code image - cut 350px from top, 100px from bottom, 120px from left, 120px from right
9+
* Create 3-paper stack effect with rotated background papers
910
* Uses pure Node.js with Canvas API for image processing
1011
*/
1112

@@ -17,8 +18,9 @@ const __dirname = path.dirname(__filename)
1718

1819
async function cropImage () {
1920
try {
21+
const fix = process.env.TEST ? '-test' : ''
2022
const inputPath = path.join(__dirname, '../src/static/electerm-wechat-group-qr.jpg')
21-
const outputPath = path.join(__dirname, '../src/static/electerm-wechat-group-qr.jpg')
23+
const outputPath = path.join(__dirname, '../src/static/electerm-wechat-group-qr' + fix + '.jpg')
2224

2325
// Check if input file exists
2426
if (!fs.existsSync(inputPath)) {
@@ -36,7 +38,7 @@ async function cropImage () {
3638
console.log(`Original dimensions: ${originalWidth}x${originalHeight}`)
3739

3840
// Calculate new dimensions
39-
const cropTop = 340
41+
const cropTop = 350
4042
const cropBottom = 100
4143
const cropLeft = 120
4244
const cropRight = 120
@@ -53,25 +55,97 @@ async function cropImage () {
5355
console.log(`New dimensions: ${newWidth}x${newHeight}`)
5456
console.log(`Cropping: ${cropTop}px from top, ${cropBottom}px from bottom, ${cropLeft}px from left, ${cropRight}px from right`)
5557

56-
// Create canvas with new dimensions
57-
const canvas = createCanvas(newWidth, newHeight)
58+
// Paper stack settings
59+
const paperPadding = 60 // Extra space for rotated papers
60+
const rotationAngle = 5 * Math.PI / 180 // 5 degrees in radians
61+
62+
// Create canvas with extra space for rotated papers
63+
const canvasWidth = newWidth + paperPadding * 2
64+
const canvasHeight = newHeight + paperPadding * 2
65+
const canvas = createCanvas(canvasWidth, canvasHeight)
5866
const ctx = canvas.getContext('2d')
5967

60-
// Draw the cropped portion of the image
68+
// Fill background with light color
69+
ctx.fillStyle = '#f8f8f8'
70+
ctx.fillRect(0, 0, canvasWidth, canvasHeight)
71+
72+
// Helper function to draw a paper with shadow
73+
function drawPaper (x, y, width, height, rotation, shadowIntensity) {
74+
ctx.save()
75+
76+
// Move to center of where paper should be
77+
ctx.translate(x + width / 2, y + height / 2)
78+
ctx.rotate(rotation)
79+
80+
// Draw shadow
81+
ctx.shadowColor = `rgba(0, 0, 0, ${shadowIntensity})`
82+
ctx.shadowBlur = 8
83+
ctx.shadowOffsetX = 4
84+
ctx.shadowOffsetY = 4
85+
86+
// Draw paper
87+
ctx.fillStyle = '#ffffff'
88+
ctx.fillRect(-width / 2, -height / 2, width, height)
89+
90+
// Add subtle border
91+
ctx.shadowColor = 'transparent'
92+
ctx.strokeStyle = 'rgba(0, 0, 0, 0.1)'
93+
ctx.lineWidth = 1
94+
ctx.strokeRect(-width / 2, -height / 2, width, height)
95+
96+
ctx.restore()
97+
}
98+
99+
// Draw background papers (rotated)
100+
const centerX = canvasWidth / 2 - newWidth / 2
101+
const centerY = canvasHeight / 2 - newHeight / 2
102+
103+
// Bottom paper (rotated left)
104+
drawPaper(centerX - 3, centerY + 6, newWidth, newHeight, -rotationAngle, 0.15)
105+
106+
// Middle paper (rotated right)
107+
drawPaper(centerX + 3, centerY + 3, newWidth, newHeight, rotationAngle, 0.2)
108+
109+
// Top paper (no rotation) - we'll draw the actual image on this one
110+
ctx.save()
111+
ctx.shadowColor = 'rgba(0, 0, 0, 0.25)'
112+
ctx.shadowBlur = 10
113+
ctx.shadowOffsetX = 2
114+
ctx.shadowOffsetY = 2
115+
116+
// Draw white background for top paper
117+
ctx.fillStyle = '#ffffff'
118+
ctx.fillRect(centerX, centerY, newWidth, newHeight)
119+
120+
// Reset shadow for the actual image
121+
ctx.shadowColor = 'transparent'
122+
ctx.shadowBlur = 0
123+
ctx.shadowOffsetX = 0
124+
ctx.shadowOffsetY = 0
125+
126+
// Draw the cropped portion of the image onto the top paper
61127
ctx.drawImage(
62128
image,
63129
cropLeft, cropTop, // Source x, y (start from cropLeft pixels right and cropTop pixels down)
64130
newWidth, newHeight, // Source width, height
65-
0, 0, // Destination x, y
131+
centerX, centerY, // Destination x, y (centered on top paper)
66132
newWidth, newHeight // Destination width, height
67133
)
134+
135+
// Add subtle border to top paper
136+
ctx.strokeStyle = 'rgba(0, 0, 0, 0.1)'
137+
ctx.lineWidth = 1
138+
ctx.strokeRect(centerX, centerY, newWidth, newHeight)
139+
140+
ctx.restore()
68141

69142
// Save the cropped image
70143
const buffer = canvas.toBuffer('image/jpeg', { quality: 0.9 })
71144
fs.writeFileSync(outputPath, buffer)
72145

73-
console.log('Successfully cropped image saved to:', outputPath)
74-
console.log(`Final dimensions: ${newWidth}x${newHeight}`)
146+
console.log('Successfully created 3-paper stack effect with QR code saved to:', outputPath)
147+
console.log(`Final dimensions: ${canvasWidth}x${canvasHeight} (including paper stack)`)
148+
console.log(`QR code content: ${newWidth}x${newHeight}`)
75149
} catch (error) {
76150
console.error('Error processing image:', error)
77151
process.exit(1)

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"rm": "rm -rf public/ && mkdir public",
2323
"c": "node bin/vite/dev-server.js",
2424
"s": "node bin/server.mjs",
25-
"bb": "NODE_ENV=production vite build --config bin/vite/conf.js"
25+
"bb": "NODE_ENV=production vite build --config bin/vite/conf.js",
26+
"cut": "./bin/qr-code.cut.js"
2627
},
2728
"repository": {
2829
"type": "git",
27.1 KB
Loading

0 commit comments

Comments
 (0)