Now.js Framework Documentation

Now.js Framework Documentation

ImageCropper - ตัดรูปภาพในเบราว์เซอร์

TH 13 Nov 2026 12:43

ImageCropper - ตัดรูปภาพในเบราว์เซอร์

โหลดเมื่อใช้ — อยู่ใน feature bundle now.imagecrop.min.js (+ .css) ไม่ได้อยู่ใน now.core.min.js: ช่องไฟล์ data-crop="true" โหลดให้เอง ส่วนโค้ดที่เรียก ImageCropper ตรง ๆ ให้ await Now.require('ImageCropper') ก่อน — ดู Feature bundle

ImageCropper เปิดรูปหนึ่งรูปในหน้าต่างครอป ให้ผู้ใช้เลื่อน ซูม และหมุนรูปใต้กรอบ แล้วคืนผลเป็น File ใหม่
กรอบคงที่ตามสัดส่วนที่กำหนด รูปเป็นฝ่ายเคลื่อนที่ และต้องคลุมกรอบเต็มเสมอ ผลที่ได้จึงไม่มีขอบว่าง

ทางที่ใช้บ่อยที่สุดคือให้ FileElementFactory เปิดให้ ด้วย data-crop="true" บนช่องไฟล์
หน้านี้อธิบายตัวครอปเอง สำหรับเรียกจากโค้ดโดยตรง

สารบัญ

  1. การใช้งาน
  2. ตัวเลือก
  3. การควบคุมในหน้าต่างครอป
  4. ไฟล์ที่ได้
  5. ครอปซ้ำจากต้นฉบับ
  6. CSS

การใช้งาน

await Now.require('ImageCropper');

const file = await ImageCropper.open(input.files[0], {aspect: '3/4', width: 600});
if (file) {
  // File ที่ครอปแล้ว
} else {
  // ผู้ใช้กดยกเลิก ปุ่มปิด หรือ Escape
}

ImageCropper.open(source, options)

พารามิเตอร์ ประเภท คำอธิบาย
source File, Blob หรือ string รูปที่จะครอป หรือ URL ของรูป (โดเมนเดียวกัน หรือที่ส่ง CORS มา) รวม data:image/...
options Object ทับค่าใน ImageCropper.config (ดู ตัวเลือก)

คืน Promise<File|null> — null เมื่อผู้ใช้ยกเลิก
reject ด้วย Error (ข้อความแปลแล้ว "Unable to open this image") เมื่อเปิดรูปไม่ได้ เช่นไม่ใช่รูป หรือเป็นชนิดที่เบราว์เซอร์อ่านไม่ได้

หน้าต่างครอปแสดงทีละรูป เรียก open() ซ้อนกันได้ รูปถัดไปจะรอจนหน้าต่างก่อนหน้าปิดเสร็จ

ตัวเลือก

ทุกตัวรับได้ทั้งตัวเลขและสตริงแบบที่ data attribute ส่งมา

ตัวเลือก ค่าเริ่มต้น คำอธิบาย
aspect 1 สัดส่วนกรอบ กว้าง/สูง: 1, 0.75, '3/4', '3:4', '16/9' ค่าที่อ่านไม่ได้ใช้ 1
width 0 ความกว้างของรูปที่ได้ (px) ความสูงคิดจากสัดส่วน · 0 = ขนาดจริงของส่วนที่ครอป ไม่เกิน maxWidth
maxWidth 2048 เพดานความกว้างเมื่อ width เป็น 0
shape 'rect' 'rect' หรือ 'circle' — circle เปลี่ยนแค่หน้ากากของกรอบ ไฟล์ที่ได้ยังเป็นสี่เหลี่ยม
format 'auto' 'auto', 'jpeg', 'png', 'webp' — auto คงชนิด JPEG/PNG/WebP ของต้นฉบับ ชนิดอื่นเป็น JPEG
quality 0.9 คุณภาพของ JPEG และ WebP (0-1)
minWidth 0 เตือนในหน้าต่างครอปเมื่อส่วนที่เลือกมีพิกเซลของต้นฉบับกว้างน้อยกว่านี้ · 0 = ไม่เตือน
maxZoom 4 ซูมได้มากสุดกี่เท่า นับจากระดับที่รูปพอดีคลุมกรอบ
title 'Crop image' หัวหน้าต่าง (แปลด้วย Now.translate())

การควบคุมในหน้าต่างครอป

ทำอะไร เมาส์ / จอสัมผัส คีย์บอร์ด (โฟกัสที่พื้นที่ครอป)
เลื่อนรูป ลาก ปุ่มลูกศร (กด Shift ค้างไว้ = ทีละมากขึ้น)
ซูม ล้อเมาส์, สองนิ้วถ่างหรือหุบ, แถบเลื่อน, ปุ่มย่อ/ขยาย + / -
หมุน 90° ตามเข็มนาฬิกา ปุ่มหมุน -
กลับเป็นรูปทั้งรูป ไม่หมุน ปุ่มรีเซ็ต -
ยืนยัน ปุ่มตกลง Enter
ยกเลิก ปุ่มยกเลิก หรือปุ่มปิด Escape

การซูมด้วยล้อเมาส์และสองนิ้วยึดจุดที่ชี้อยู่ไว้กับที่ · Escape ปิดเฉพาะหน้าต่างครอป ไม่ปิด modal ที่เปิดอยู่ข้างใต้
พื้นที่ครอปปรับกรอบตามขนาดหน้าต่างเสมอ (หมุนมือถือหรือย่อหน้าต่างแล้วส่วนที่เลือกไว้ไม่เปลี่ยน)

ไฟล์ที่ได้

  • ขนาด width × round(width / aspect) px (หรือขนาดจริงของส่วนที่ครอปเมื่อ width เป็น 0)
  • ชื่อเดิมของต้นฉบับเมื่อชนิดไม่เปลี่ยน · เปลี่ยนชนิดแล้วนามสกุลเปลี่ยนตาม (photo.png + format: 'jpeg' = photo.jpg)
  • ต้นฉบับที่ไม่มีชื่อ (Blob, data: URL) ได้ชื่อ image + นามสกุล
  • เบราว์เซอร์ที่เขียน WebP ไม่ได้ (Safari) ได้ JPEG แทน
  • JPEG ไม่มีความโปร่งใส ส่วนที่โปร่งใสของต้นฉบับเป็นสีขาว
  • การหมุนของรูปจากกล้อง (EXIF) ถูกนำมาใช้แล้วตั้งแต่ตอนเปิดรูป

การครอปในเบราว์เซอร์ไม่ใช่ด่านความปลอดภัย เซิร์ฟเวอร์ต้องตรวจชนิดไฟล์และบันทึกรูปใหม่เองเสมอ
(เช่น UploadedFile::cropImage() / resizeImage() ของ Kotchasan)

ครอปซ้ำจากต้นฉบับ

File ที่ ImageCropper สร้างจำต้นฉบับและการครอปของมันไว้
ส่ง File นั้นให้ open() อีกครั้งจะเปิดต้นฉบับที่ตำแหน่ง ระดับซูม และการหมุนเดิม รูปจึงไม่ถูกย่อซ้ำทุกครั้งที่แก้

let photo = await ImageCropper.open(original, {aspect: 1, width: 400});
// ภายหลัง: แก้การครอป
photo = await ImageCropper.open(photo, {aspect: 1, width: 400}) || photo;

CSS

ไฟล์ Now/css/image-cropper.css (อยู่ใน now.imagecrop.min.css)

Class คืออะไร
.image-cropper-modal modal ของหน้าต่างครอป
.image-cropper-stage พื้นที่ครอป (รับเมาส์ สัมผัส และคีย์บอร์ด) · .dragging ระหว่างลาก
.image-cropper-image รูปที่เลื่อนอยู่ใต้กรอบ
.image-cropper-frame กรอบ · .circle เมื่อ shape: 'circle'
.image-cropper-toolbar ปุ่มและแถบซูม
.image-cropper-zoom แถบซูม
.image-cropper-warning คำเตือนเมื่อส่วนที่เลือกเล็กกว่า minWidth