PerfectVector
โดย Irene Kimอ่าน 3 นาที

จัดแนวข้อความ SVG ในแนวตั้ง: วางป้ายใหม่ให้อยู่กลาง

จัดแนวป้าย SVG ด้วย dominant-baseline เปรียบเทียบ middle และ central ในสองฟอนต์ และแยกการจัดกลางกล่องข้อความจากรูปร่างตัวอักษรที่มองเห็น

ในหน้านี้

สำหรับป้าย SVG แนวนอน y วางเส้นฐานที่เลือก ไม่ได้วางยอดตัวอักษรที่พิกัดนั้น เริ่มด้วย dominant-baseline="middle" เมื่อวางป้ายละตินสั้นรอบเส้นนำแนวนอน แล้วตรวจผลในฟอนต์จริง ใช้ text-anchor="middle" จัดข้อความกึ่งกลางแนวนอนรอบพิกัด x

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

เลือกเป้าหมายการจัดแนว

y="100" เดียวกันอาจให้ตำแหน่งตัวอักษรต่างกัน:

ค่าบนองค์ประกอบข้อความเส้นฐานหมายถึงอะไรจุดเริ่มต้นที่มีประโยชน์
dominant-baseline="alphabetic"เส้นฐานอักษรคำที่ควรใช้เส้นฐานอ่านร่วมกัน
dominant-baseline="middle"เส้นฐานที่สัมพันธ์กับครึ่งหนึ่งของ x-height ฟอนต์เหนือเส้นฐานอักษรป้ายสั้นที่วางรอบเส้นนำแนวนอน
dominant-baseline="central"เส้นฐานกลางที่สัมพันธ์กับกล่อง emเทียบการจัดกลางกล่องฟอนต์กับเส้นฐาน middle

นิยามเส้นฐานของ W3C แยก middle จาก central ไม่มีนิยามใดรับประกันการจัดกลางเส้นรอบรูปที่ระบายสีของทุกคำ ตารางเส้นฐานฟอนต์และวิธีประมาณของตัวเรนเดอร์ก็มีผล ตามเอกสารอ้างอิง dominant-baseline ของ MDN

สำหรับข้อความแนวนอนทั่วไป text-anchor="middle" จัดการอีกแกนหนึ่ง มันจัดช่วงข้อความรอบตำแหน่งแนวนอนที่ให้ ไม่ได้จัดกึ่งกลางแนวตั้ง ดูเอกสาร text-anchor สำหรับความสัมพันธ์กับช่วงข้อความ

เปรียบเทียบตรากับป้ายข้อความที่แก้ได้

บันทึกตัวอย่างสมบูรณ์นี้เป็น baseline-example.svg แล้วเปิดในเบราว์เซอร์ วงกรอบเป็นเรขาคณิตต้นฉบับ Agyp เป็นสตริงทดสอบที่มีส่วนยื่นขึ้นและหางลง เส้นแดงระบุ y=100

<svg xmlns="http://www.w3.org/2000/svg" width="840" height="400"
     viewBox="0 0 420 200">
  <path fill="#137f74" fill-rule="evenodd"
    d="M55 75A25 25 0 1 1 55 125A25 25 0 1 1 55 75
       M55 86A14 14 0 1 0 55 114A14 14 0 1 0 55 86"/>
  <path d="M20 100H400" fill="none" stroke="#c3594d"/>
  <text id="label" x="250" y="100" font-family="Arial, sans-serif"
        font-size="64" text-anchor="middle" dominant-baseline="middle"
        fill="#193e3a">Agyp</text>
</svg>

เปลี่ยนเฉพาะ dominant-baseline เป็น alphabetic แล้วเป็น central คงพิกัด ขนาดฟอนต์ และถ้อยคำไว้ จากนั้นเทียบฟอนต์ที่มีอีกตัว การเปลี่ยนหลายค่าไปด้วยกันทำให้ระบุยากว่าค่าใดย้ายป้าย

เราเรนเดอร์ทั้งสามค่าด้วยไฟล์ Arial และ Times New Roman ที่โหลดแล้ว ทุกแผงใช้พิกัด SVG และวงกรอบต้นฉบับเดียวกัน สี่เหลี่ยมเขียวแสดงผล getBBox() ของเบราว์เซอร์สำหรับข้อความ

การเปรียบเทียบ Agyp ข้างวงกรอบในเบราว์เซอร์ แสดงเส้นฐาน alphabetic, middle และ central ใน Arial และ Times New Roman พร้อมกล่องข้อความที่วัด
x, y และขนาดฟอนต์เดียวกันให้ตำแหน่งต่างกันด้วยเส้นฐานสามแบบ สี่เหลี่ยมเขียวเป็นกล่องข้อความ SVG ที่เบราว์เซอร์รายงาน ไม่ใช่เส้นรอบรูปชิดตัวอักษรที่มีสี

ตัวอย่าง alphabetic อยู่สูงกว่าเมื่อเทียบกับเส้นกลางวงกรอบ แบบ middle เลื่อนลง ส่วน central วางกล่องที่รายงานใกล้เส้นนำ ค่าวัดที่พิมพ์ใต้แต่ละตัวอย่างใช้กับไฟล์ฟอนต์และการเรนเดอร์เบราว์เซอร์นี้ ไม่ใช่ระยะเยื้องให้คัดลอกไปงานอื่น

ไฟล์ฟอนต์ของเราโหลดก่อนวัด SVG ที่คุณส่งออกอาจเลือกฟอนต์สำรองหากฟอนต์ที่ขอไม่มี แก้การพึ่งพานี้ก่อนตัดสินการจัดแนว คู่มือฟอนต์ SVG เปลี่ยน อธิบายการตรวจฟอนต์จริงและรักษาสำเนาส่งมอบ

กล่องข้อความอยู่กลางแต่ยังดูไม่สมดุลได้

ขอบเขตข้อความ SVG ไม่จำเป็นต้องเป็นสี่เหลี่ยมเล็กที่สุดรอบหมึกที่มองเห็น กฎกล่องขอบเขต SVG ใช้ช่องรูปอักษรและระยะเหนือ/ใต้เส้นฐานฟอนต์ในการคำนวณข้อความ สี่เหลี่ยมรอบช่องเหล่านั้นอาจมีพื้นที่ที่ไม่มีอักษรระบายสี

ความต่างนี้สำคัญกับป้ายอย่าง Agyp: g, y และ p มีหางลงใต้เส้นฐานอักษร ป้ายตัวพิมพ์ใหญ่ทั้งหมดมีการกระจายภาพต่างกัน ควรมีฟอนต์ที่ตั้งใจและถ้อยคำจริงระหว่างจัดแนว

สำหรับแถวป้ายที่ควรอ่านในบรรทัดเดียว รักษาเส้นฐาน alphabetic ร่วม การย้ายทุกคำแยกจนรูปร่างที่เห็นดูอยู่กลางอาจทำให้แถวไม่เสมอกัน

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

จัดกึ่งกลางกล่องข้อความ SVG ที่วัดเมื่อเป็นเป้าหมาย

สำหรับ <text> บรรทัดเดียวเรียบง่ายที่ไม่มี transform ให้คำนวณระยะจากกลางกล่องที่รายงานไปยังเป้าหมาย รันในเอกสารตัวอย่างหลังฟอนต์พร้อม:

await document.fonts.ready;
 
const label = document.querySelector('#label');
const targetY = 100;
const originalY = label.y.baseVal.getItem(0).value;
const box = label.getBBox();
const shift = targetY - (box.y + box.height / 2);
 
label.setAttribute('y', String(originalY + shift));

การคำนวณจัดกล่องข้อความที่รายงานให้ตรง targetY ไม่ได้คำนวณสมดุลทางสายตาหรือตัดพื้นที่ช่องอักษรที่ฟอนต์ไม่ใช้ วัดใหม่หลังเปลี่ยนข้อความ ฟอนต์ น้ำหนัก หรือขนาด

document.fonts.ready รอโหลดฟอนต์และงานจัดวางที่เกี่ยวข้อง แต่ไม่ได้พิสูจน์ว่าได้รับฟอนต์ที่ตั้งใจสำเร็จ ตรวจทรัพยากรฟอนต์หรือข้อมูลฟอนต์ที่เบราว์เซอร์เรนเดอร์ด้วย

โค้ดสมมติว่ามี y ค่าเดียว ไม่มีตำแหน่งรายอักษร ไม่มี dy และไม่มีกลุ่มข้อความที่ใช้ transform getBBox() คืนกล่อง SVG เฉพาะที่ เป้าหมายในระบบพิกัดอื่นต้องแมป ใช้กระบวนการขอบเขต SVG ก่อนผสมพิกเซลจอกับหน่วย SVG

แก้การตั้งค่าที่ขัดกันก่อนเพิ่มระยะเยื้อง

ตรวจข้อความและกลุ่มแม่ dy ที่ค้างอยู่ <tspan> ซ้อน หรือ transform อาจเปลี่ยนตำแหน่งที่กำลังวินิจฉัย ลบการปรับที่สงสัยทีละอย่างในสำเนาแล้วเทียบผล

ตรวจสไตล์หน้าเว็บด้วย CSS แทนแอตทริบิวต์นำเสนอ dominant-baseline ได้ หากเปลี่ยนแอตทริบิวต์แล้วไม่เห็นผล ให้ตรวจค่าที่คำนวณก่อนเพิ่มการแก้ครั้งที่สอง

alignment-baseline จัดการว่าเส้นฐานองค์ประกอบจัดแนวกับเส้นฐานที่สอดคล้องขององค์ประกอบแม่อย่างไร ไม่ใช่คำพ้องทั่วไปของ “จัดป้ายนี้ไว้กลาง SVG” เอกสาร alignment-baseline ของ MDN ยังระบุข้อจำกัดการรองรับเบราว์เซอร์ สำหรับป้ายเดี่ยวนี้ ให้ทดสอบเฉพาะ dominant-baseline แล้วตรวจปลายทางส่งออกจริง

ตัวอย่างครอบคลุมข้อความละตินแนวนอนในเบราว์เซอร์เดียว ป้ายโค้งต้องตรวจตำแหน่งอีกแบบ คู่มือข้อความ SVG ตามพาธทีละขั้น แยกตัวอักษรจากเส้นนำของมัน อักษรอื่นและการเขียนแนวตั้งต้องตัดสินใจเส้นฐานของตนเอง

เก็บสัญลักษณ์แยกจากตัวอักษร

หากมีตราเวกเตอร์สะอาดอยู่แล้ว รักษาไว้และสร้างป้ายใหม่เป็นข้อความ การย้ายป้ายหรือเลือกฟอนต์ไม่ต้องแปลงเวกเตอร์

เมื่อตรามีเพียง PNG หรือ JPG เครื่องมือแปลงโลโก้เป็นเวกเตอร์ของ PerfectVector เตรียมเรขาคณิตสำหรับประเมินในส่วนนั้นได้ ตรวจเส้นรอบนอกและช่องเปิด แล้ววางข้างข้อความที่พิมพ์ใหม่ด้วยเส้นฐานที่เลือก การแปลงเวกเตอร์ไม่ระบุฟอนต์ต้นฉบับหรือคืนตัวพิมพ์ที่แก้ไขได้จากราสเตอร์

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

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

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

dominant-baseline="middle" เหมือน central หรือไม่? ไม่ Middle ใช้เส้นฐานที่สัมพันธ์กับ x-height ส่วน central ใช้เส้นฐานกลางฟอนต์ที่สัมพันธ์กับกล่อง em ตำแหน่งอาจต่างกัน และไม่มีแบบใดรับประกันกึ่งกลางทางสายตาของทุกคำ

text-anchor="middle" จัดข้อความ SVG กลางแนวตั้งหรือไม่? สำหรับข้อความแนวนอนทั่วไป text-anchor ควบคุมตำแหน่งแนวนอนรอบพิกัด x เลือกเส้นฐานแนวตั้งแยกด้วย dominant-baseline แล้วตรวจผลในฟอนต์ที่ต้องการ

getBBox จัดตัวอักษรที่เห็นให้อยู่กลางพอดีได้หรือไม่? มันจัดกล่องข้อความ SVG ที่เบราว์เซอร์รายงานให้อยู่กลางได้ ขอบเขตข้อความอาจมีพื้นที่ช่องอักษรเกินตัวอักษรที่ระบายสี การคำนวณนี้จึงไม่รับประกันกึ่งกลางทางสายตาหรือการจัดแนวเส้นรอบรูปแบบชิด

แหล่งอ้างอิง

  1. W3C — การจัดแนวเส้นฐาน SVG — นิยามเส้นฐาน alphabetic, middle และ central
  2. MDN — dominant-baseline — อธิบายตารางเส้นฐาน วิธีประมาณฟอนต์ และความสำคัญ CSS
  3. MDN — text-anchor — อธิบายการยึดช่วงข้อความรอบตำแหน่งที่ให้
  4. W3C — กล่องขอบเขต SVG — อธิบายแบบจำลองช่องอักษรสำหรับขอบเขตข้อความ
  5. MDN — FontFaceSet.ready — นิยามเวลาที่โหลดฟอนต์และจัดวางเสร็จ
  6. MDN — getBBox — อธิบายขอบเขต SVG เฉพาะที่และ transform ที่ไม่รวม
  7. MDN — alignment-baseline — อธิบายการจัดแนวเส้นฐานขององค์ประกอบแม่และข้อจำกัดเบราว์เซอร์

หากโลโก้ที่สร้างใหม่ยังต้องมีตราที่แก้ได้ เตรียม SVG สำหรับประเมินด้วย PerfectVector ตรวจเส้นรอบนอกที่สร้างกลับ แล้วจับคู่กับตัวอักษรที่แก้ได้และตรวจการจัดแนวในปลายทางสุดท้าย

เพิ่มเติมจากบล็อก

เริ่มต้นด้วย SVG ที่เรียบร้อยขึ้น
และแก้ไขได้ง่ายกว่า