CGGradient: มันคืออะไร, ประเภทของเกรเดียนต์และการสร้าง

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-07-21 เวลาอ่าน: 9 นาที

CGGradient เป็นออบเจกต์ Core Graphics ที่แสดงถึงการเปลี่ยนผ่านที่ราบรื่นระหว่างสีสองสีขึ้นไป แตกต่างจากการวาดเกรเดียนต์ผ่านลูปด้วยการเปลี่ยนสี CGGradient ใช้การคำนวณแบบเร่งด้วยฮาร์ดแวร์และรองรับสองประเภท: เชิงเส้น (แนวแกน) และแนวรัศมี ตามเอกสารของ Apple (2026) CGGradient ใช้สำหรับสร้างการเติมที่สมจริง เอฟเฟกต์พื้นหลัง และจำลองแหล่งกำเนิดแสงในส่วนติดต่อ iOS และ macOS

ประเด็นสำคัญ

  • CGGradient เป็นออบเจกต์ Core Graphics สำหรับสร้างการเปลี่ยนสีที่ราบรื่นระหว่างจุด
  • เกรเดียนต์เชิงเส้น (แนวแกน) — การเปลี่ยนสีตามเส้นตรงระหว่างจุดเริ่มต้นและจุดสิ้นสุด
  • เกรเดียนต์แนวรัศมี — การเปลี่ยนสีจากจุดศูนย์กลางไปยังวงกลมด้านนอก
  • เกรเดียนต์สร้างจากอาร์เรย์ของสี CGColor และอาร์เรย์ของตำแหน่ง (locations) ที่สอดคล้องกันตั้งแต่ 0.0 ถึง 1.0
  • Core Graphics เรนเดอร์เกรเดียนต์ด้วยการประกอบอัลฟาและการลดรอยหยัก (antialiasing)

CGGradient คืออะไร?

CGGradient เป็นออบเจกต์ที่ไม่เปลี่ยนรูปใน Core Graphics ซึ่งห่อหุ้มชุดของสีและกฎสำหรับการผสมผสานตามการเปลี่ยนผ่านแบบเกรเดียนต์ ภายใน CGGradient จัดเก็บอาร์เรย์ของ CGColor อาร์เรย์ของตำแหน่ง (locations) ในช่วง [0.0, 1.0] และการอ้างอิงไปยัง CGColorSpace ซึ่งสีจะถูกตีความ แต่ละสีเชื่อมโยงกับตำแหน่งบนสเกลเกรเดียนต์: ตำแหน่ง 0.0 สอดคล้องกับจุดเริ่มต้น 1.0 กับจุดสิ้นสุดของการเปลี่ยนผ่าน

เมื่อสร้าง CGGradient ผ่านฟังก์ชัน CGGradientCreateWithColors Core Graphics จะคำนวณค่าสีกลางล่วงหน้า เกรเดียนต์สามารถมีจำนวนจุดหยุดสี (color stops) ได้ตามต้องการ ทำให้สามารถเปลี่ยนผ่านหลายสีที่ซับซ้อนได้ จำนวนสีต้องมีอย่างน้อยสองสี และแต่ละสีต้องสอดคล้องกับตำแหน่งในอาร์เรย์ locations

สถาปัตยกรรมของ CGGradient แตกต่างจาก API ระดับสูงกว่าเช่น CAGradientLayer จาก Core Animation ตรงที่ทำงานโดยตรงในบริบท Core Graphics ซึ่งให้การควบคุมอย่างสมบูรณ์เหนือกระบวนการวาดและความสามารถในการรวมเกรเดียนต์กับการดำเนินการ Quartz 2D อื่น ๆ — มาสก์ตัด เงา และการแปลง

เกรเดียนต์เชิงเส้นและแนวรัศมี

Core Graphics รองรับเกรเดียนต์สองประเภท: เชิงเส้น (แนวแกน) และแนวรัศมี เกรเดียนต์เชิงเส้นสร้างด้วยฟังก์ชัน CGGradientCreateWithColors และวาดด้วย CGContextDrawLinearGradient เกรเดียนต์แนวรัศมีต้องการโครงสร้าง CGGradient เดียวกันแต่วาดด้วย CGContextDrawRadialGradient

ประเภทฟังก์ชันการวาดพารามิเตอร์การใช้งาน
เชิงเส้นCGContextDrawLinearGradientstartPoint, endPoint, optionsพื้นหลัง ปุ่ม แถบความคืบหน้า
แนวรัศมีCGContextDrawRadialGradientstartCenter, startRadius, endCenter, endRadius, optionsประกายแสง แหล่งกำเนิดแสง เงา

เกรเดียนต์เชิงเส้น (แนวแกน)

เกรเดียนต์เชิงเส้น ขยายการเปลี่ยนสีตามเส้นตรงจากจุดเริ่มต้น startPoint ไปยังจุดสิ้นสุด endPoint สีจะถูกประมาณค่าระหว่างสองจุดนี้ และพฤติกรรมที่เกินจากจุดเหล่านี้ถูกควบคุมโดยตัวเลือกการขยาย เกรเดียนต์เชิงเส้นเหมาะสำหรับการสร้างพื้นหลังที่เรียบเนียน จำลองพื้นผิวโลหะ และการเปลี่ยนสีในองค์ประกอบส่วนติดต่อ

เกรเดียนต์แนวรัศมี

เกรเดียนต์แนวรัศมี สร้างการเปลี่ยนสีจากวงกลมหนึ่งไปยังอีกวงกลมหนึ่ง แต่ละวงกลมกำหนดโดยจุดศูนย์กลาง (startCenter / endCenter) และรัศมี (startRadius / endRadius) สีจะถูกประมาณค่าจากวงกลมด้านในไปยังวงกลมด้านนอก กรณีพิเศษคือเมื่อรัศมีเริ่มต้นเป็น 0: เกรเดียนต์แผ่ออกจากจุดเดียว เกรเดียนต์แนวรัศมีใช้สำหรับจำลองแหล่งกำเนิดแสง เลนส์ วัตถุท้องฟ้า และเอฟเฟกต์สปอตไลต์

การสร้าง CGGradient: สีและตำแหน่ง

CGGradient สร้างด้วยฟังก์ชันพื้นฐานเพียงฟังก์ชันเดียว — CGGradientCreateWithColors ฟังก์ชันรับ CGColorSpace อาร์เรย์ของ CGColor (CFArray) และอาร์เรย์ของ CGFloat locations ถ้า locations เป็น NULL สีจะถูกกระจายอย่างเท่าเทียมกันตามสเกลเกรเดียนต์ ถ้ามีการระบุ locations จำนวนของมันต้องตรงกับจำนวนสี

อาร์เรย์ locations มีค่าตั้งแต่ 0.0 ถึง 1.0 ซึ่งกำหนดจุดหยุดสำหรับแต่ละสี ค่าต้องเพิ่มขึ้นอย่างซ้ำซาก ถ้าค่าแรกมากกว่า 0.0 สีจากจุดเริ่มต้นถึงตำแหน่งนี้จะถูกประมาณภายนอกจากสีที่ตำแหน่ง 0.0 ในทำนองเดียวกันสำหรับค่าสุดท้ายที่น้อยกว่า 1.0 พฤติกรรมนี้ถูกควบคุมโดยตัวเลือกการขยายในระหว่างการวาด

เมื่อเลือก สี สำหรับเกรเดียนต์ สิ่งสำคัญคือต้องพิจารณาพื้นที่สี สีทั้งหมดใน CGGradient เดียวกันต้องอยู่ใน CGColorSpace เดียวกัน — Core Graphics ประมาณค่าส่วนประกอบในพื้นที่นั้น ถ้าสีถูกสร้างขึ้นในพื้นที่ต่างกัน จะต้องแปลงเป็นพื้นที่ร่วมก่อนผ่าน CGColorCreateCopyByMatchingToColorSpace

การวาดเกรเดียนต์ในบริบท

Core Graphics มีสองฟังก์ชันสำหรับวาดเกรเดียนต์: CGContextDrawLinearGradient สำหรับเชิงเส้นและ CGContextDrawRadialGradient สำหรับแนวรัศมี ทั้งสองฟังก์ชันรับบริบทกราฟิก ออบเจกต์ CGGradient ตัวเลือกการขยาย และพารามิเตอร์เรขาคณิตเฉพาะประเภท การวาดดำเนินการโดยคำนึงถึงมาสก์ตัดปัจจุบันและการแปลงบริบท

ตัวเลือกการขยาย (Gradient Options)

ตัวเลือกการขยาย ควบคุมพฤติกรรมของเกรเดียนต์ที่เกินช่วงตำแหน่ง 0.0–1.0 ค่าคงที่ kCGGradientDrawsBeforeStartLocation เติมพื้นที่ก่อนตำแหน่งเริ่มต้นด้วยสีของจุดหยุดแรก kCGGradientDrawsAfterEndLocation เติมด้วยสีของจุดหยุดสุดท้าย ตัวเลือกเหล่านี้สามารถรวมกันผ่านบิตมาสก์ สำหรับเกรเดียนต์แนวรัศมี ตัวเลือกจะใช้กับพื้นที่ที่เกินรัศมีเริ่มต้นและสิ้นสุด

ผลของการแปลง

เกรเดียนต์ถูก วาด ในระบบพิกัดของบริบทกราฟิกปัจจุบัน โดยคำนึงถึงการแปลง (CTM — Current Transformation Matrix) การใช้ CGContextTranslateCTM, CGContextScaleCTM หรือ CGContextRotateCTM ก่อนเรียกฟังก์ชันวาดจะเปลี่ยนตำแหน่งและสเกลของเกรเดียนต์ ซึ่งช่วยให้สามารถใช้ CGGradient เดียวซ้ำสำหรับพื้นที่ต่างกันโดยไม่ต้องสร้างออบเจกต์ใหม่

ตัวเลือก: การขยาย การทำให้เรียบ และการมาสก์

Core Graphics มีกลไกเพิ่มเติมหลายอย่างสำหรับควบคุมเกรเดียนต์: การลดรอยหยัก (antialiasing) การมาสก์ผ่านมาสก์ตัด (clipping mask) และการรวมกับเอฟเฟกต์ความโปร่งใส การลดรอยหยักเปิดใช้งานโดยค่าเริ่มต้นในบริบทกราฟิกและควบคุมผ่าน CGContextSetShouldAntialias

มาสก์ตัด ช่วยให้จำกัดพื้นที่วาดเกรเดียนต์ให้เป็นรูปร่างตามต้องการ ก่อนเรียก CGContextDrawLinearGradient ต้องกำหนดเส้นทางผ่าน CGContextBeginPath, CGContextAddPath และ CGContextClip เกรเดียนต์จะถูกวาดเฉพาะภายในพื้นที่ที่ถูกจำกัดโดยเส้นทางนี้ ซึ่งใช้อย่างแพร่หลายสำหรับสร้างไอคอนเกรเดียนต์ ปุ่ม และแถบความคืบหน้า

การขยายเกรเดียนต์ เป็นอีกพารามิเตอร์สำคัญ เมื่อใช้ kCGGradientDrawsBeforeStartLocation Core Graphics จะประมาณภายนอกสีของจุดหยุดแรกทั่วทั้งพื้นที่ก่อน startPoint โดยไม่มีตัวเลือกนี้ พื้นที่นอกเกรเดียนต์จะไม่ถูกเติม (โปร่งใส) การรวมทั้งสองตัวเลือกช่วยให้มั่นใจว่าสี่เหลี่ยมผืนผ้าทั้งหมดของบริบทกราฟิกจะถูกเติมด้วยเกรเดียนต์ แม้ว่า startPoint และ endPoint จะอยู่ภายใน

ตัวอย่างโค้ด Swift

มาดู ตัวอย่างเชิงปฏิบัติ ของการสร้างและวาดเกรเดียนต์ใน iOS โดยใช้ CGGradient และ Core Graphics

เกรเดียนต์เชิงเส้นที่มีสามสี

ตัวอย่างนี้สร้าง เกรเดียนต์เชิงเส้น ด้วยสามสี (น้ำเงิน เขียว แดง) และวาดตามแนวทแยงของ UIView อาร์เรย์ locations กระจายสีอย่างไม่เท่ากัน: น้ำเงินจาก 0.0 ถึง 0.3 เขียวที่ 0.6 แดงจาก 0.6 ถึง 1.0

swift
func drawLinearGradient(in ctx: CGContext,
                          rect: CGRect) {
    let colors = [
        UIColor.blue.cgColor,
        UIColor.green.cgColor,
        UIColor.red.cgColor
    ] as CFArray

    let locations: [CGFloat] = [0.0, 0.6, 1.0]
    let space = CGColorSpaceCreateDeviceRGB()

    guard let gradient = CGGradientCreateWithColors(
        space, colors, locations
    ) else { return }

    let start = CGPoint(x: 0, y: 0)
    let end = CGPoint(x: rect.width,
                         y: rect.height)

    ctx.drawLinearGradient(gradient,
        start: start, end: end,
        options: [.drawsBeforeStartLocation,
                  .drawsAfterEndLocation])
}

เกรเดียนต์แนวรัศมีพร้อมเอฟเฟกต์เรืองแสง

ตัวอย่างนี้วาด เกรเดียนต์แนวรัศมี ที่จำลองเอฟเฟกต์เรืองแสง จุดเริ่มต้นที่มีรัศมีเป็นศูนย์กำหนดจุดศูนย์กลางการเรืองแสง และวงกลมด้านนอกกำหนดขอบเขตการจางหาย เอฟเฟกต์นี้ใช้สำหรับเน้นองค์ประกอบส่วนติดต่อหรือตัวบ่งชี้กิจกรรม

swift
func drawRadialGlow(in ctx: CGContext,
                     center: CGPoint) {
    let colors = [
        UIColor.white.cgColor,
        UIColor.orange.cgColor,
        UIColor.clear.cgColor
    ] as CFArray
    let locations: [CGFloat] = [0.0, 0.4, 1.0]

    let gradient = CGGradientCreateWithColors(
        CGColorSpaceCreateDeviceRGB(), colors, locations)

    ctx.drawRadialGradient(gradient,
        startCenter: center, startRadius: 0,
        endCenter: center, endRadius: 100,
        options: [.drawsBeforeStartLocation,
                  .drawsAfterEndLocation])
}

เกรเดียนต์พร้อมมาสก์ตัด

ในตัวอย่างนี้ เกรเดียนต์ ถูกจำกัดให้อยู่ในพื้นที่วงกลมผ่านเส้นทางตัด ก่อนวาดเกรเดียนต์ จะกำหนดเส้นทางวงกลมซึ่งกลายเป็นมาสก์บริบทปัจจุบัน เกรเดียนต์เติมเฉพาะพื้นที่ภายในวงกลม สร้างเอฟเฟกต์ไอคอนเกรเดียนต์

swift
func drawGradientInCircle(in ctx: CGContext,
                          rect: CGRect) {
    // Creating circular clip path
    let circlePath = CGMutablePath()
    circlePath.addEllipse(in: rect)
    ctx.addPath(circlePath)
    ctx.clip()

    // Drawing gradient inside clip mask
    let colors = [UIColor.magenta.cgColor,
                    UIColor.cyan.cgColor]
    let gradient = CGGradientCreateWithColors(
        CGColorSpaceCreateDeviceRGB(),
        colors as CFArray, nil)

    ctx.drawLinearGradient(gradient,
        start: CGPoint(x: 0, y: 0),
        end: CGPoint(x: rect.width,
                     y: rect.height),
        options: [.drawsBeforeStartLocation])
}

คำถามที่พบบ่อย

ความแตกต่างระหว่าง CGGradient และ CAGradientLayer คืออะไร?

CGGradient เป็นออบเจกต์ Core Graphics ระดับต่ำสำหรับวาดในบริบทกราฟิก CAGradientLayer เป็นเลเยอร์ Core Animation ระดับสูงพร้อมแอนิเมชันอัตโนมัติและการเร่งด้วยฮาร์ดแวร์ CAGradientLayer ใช้ง่ายกว่ากับ UIKit แต่ CGGradient ให้การควบคุมอย่างสมบูรณ์และความเข้ากันได้กับ CGContext ใด ๆ

สามารถเพิ่มสีใน CGGradient ได้กี่สี?

ขั้นต่ำ คือ 2 สี ขีดจำกัดบนถูกจำกัดโดยหน่วยความจำที่มีเท่านั้น เนื่องจาก Core Graphics จัดเก็บอาร์เรย์ของสีและตารางการประมาณค่าที่คำนวณล่วงหน้า ในทางปฏิบัติ มากกว่า 10–15 สีในเกรเดียนต์เดียวนั้นไม่จำเป็น — การเปลี่ยนทางสายตาจะแยกไม่ออกจากที่ราบรื่น

วิธีสร้างเกรเดียนต์ด้วยความโปร่งใส?

ใช้ CGColor ที่มีช่องอัลฟาน้อยกว่า 1.0 ในอาร์เรย์สี ตัวอย่างเช่น สีที่มีความโปร่งใสสร้างเป็น UIColor(red: 0, green: 0, blue: 1, alpha: 0.5).cgColor Core Graphics ประมาณค่าช่องอัลฟาเช่นเดียวกับส่วนประกอบสี สร้างการเปลี่ยนความโปร่งใสที่ราบรื่น

CGGradient ทำงานบน macOS หรือไม่?

ใช่ CGGradient เป็นส่วนหนึ่งของ Core Graphics ที่มีอยู่บนทั้งสองแพลตฟอร์ม: iOS และ macOS บน macOS เกรเดียนต์ถูกวาดใน NSView ใด ๆ โดยการแทนที่ drawRect ฟังก์ชันทั้งหมด CGGradientCreateWithColors, CGContextDrawLinearGradient และ CGContextDrawRadialGradient เหมือนกันบนทั้งสองแพลตฟอร์ม

วิธีหมุนเกรเดียนต์?

ในการหมุนเกรเดียนต์ ให้ใช้ การแปลง กับบริบทกราฟิกก่อนวาด: CGContextRotateCTM(ctx, angle) จุดเริ่มต้นและสิ้นสุดของเกรเดียนต์ถูกระบุในระบบพิกัดท้องถิ่นของบริบทหลังการแปลง หรือคุณสามารถคำนวณพิกัดที่หมุนของจุดโดยตรงโดยไม่เปลี่ยน CTM

สรุป

  • CGGradient เป็นออบเจกต์ Core Graphics ที่ไม่เปลี่ยนรูปสำหรับการเปลี่ยนสีที่ราบรื่น
  • เกรเดียนต์เชิงเส้น วาดตามเส้นตรงระหว่าง startPoint และ endPoint ผ่าน CGContextDrawLinearGradient
  • เกรเดียนต์แนวรัศมี วาดจากวงกลมหนึ่งไปยังอีกวงกลมผ่าน CGContextDrawRadialGradient
  • เกรเดียนต์สร้างจากอาร์เรย์ของ CGColor และอาร์เรย์ของตำแหน่ง (0.0–1.0)
  • ตัวเลือกการขยาย kCGGradientDrawsBeforeStartLocation และ kCGGradientDrawsAfterEndLocation ควบคุมการเติมภายนอกช่วง
  • มาสก์ตัด จำกัดพื้นที่วาดเกรเดียนต์ให้เป็นเส้นทางตามต้องการ
  • การแปลงบริบท (CTM) ส่งผลต่อตำแหน่ง สเกล และการหมุนของเกรเดียนต์

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม