আমি কীভাবে আমার এইচটিএমএল 5 ক্যানভাসে অস্পষ্ট পাঠ্য ঠিক করব?


89

আমি মোট am n00b সঙ্গে HTML5সঙ্গে কাজ করছি canvasরেন্ডার করতে আকৃতি, রং, এবং টেক্সট। আমার অ্যাপ্লিকেশনে, আমার কাছে একটি ভিউ অ্যাডাপ্টার রয়েছে যা গতিশীল ক্যানভাস তৈরি করে এবং এটি সামগ্রী দিয়ে পূরণ করে। আমার পাঠ্যটি খুব अस्पष्ट / অস্পষ্ট / প্রসারিত ব্যতীত এটি সত্যিই দুর্দান্ত কাজ করে। আমি কেন সংজ্ঞা অন্যান্য পোস্টের মধ্যে অনেক দেখেছি প্রস্থ এবং উচ্চতা মধ্যে CSSএই সমস্যা সৃষ্টি হবে, কিন্তু আমি এটা সব সংজ্ঞায়িত javascript

প্রাসঙ্গিক কোড ( ফিডল দেখুন ):

var width  = 500;//FIXME:size.w;
var height = 500;//FIXME:size.h;
    
var canvas = document.createElement("canvas");
//canvas.className="singleUserCanvas";
canvas.width=width;
canvas.height=height;
canvas.border = "3px solid #999999";
canvas.bgcolor = "#999999";
canvas.margin = "(0, 2%, 0, 2%)";
    
var context = canvas.getContext("2d");

//////////////////
////  SHAPES  ////
//////////////////
    
var left = 0;

//draw zone 1 rect
context.fillStyle = "#8bacbe";
context.fillRect(0, (canvas.height*5/6)+1, canvas.width*1.5/8.5, canvas.height*1/6);

left = left + canvas.width*1.5/8.5;

//draw zone 2 rect
context.fillStyle = "#ffe381";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*2.75/8.5, canvas.height*1/6);

left = left + canvas.width*2.75/8.5 + 1;

//draw zone 3 rect
context.fillStyle = "#fbbd36";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*1.25/8.5, canvas.height*1/6);

left = left + canvas.width*1.25/8.5;

//draw target zone rect
context.fillStyle = "#004880";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*0.25/8.5, canvas.height*1/6);

left = left + canvas.width*0.25/8.5;
    
//draw zone 4 rect
context.fillStyle = "#f8961d";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width*1.25/8.5, canvas.height*1/6);

left = left + canvas.width*1.25/8.5 + 1;

//draw zone 5 rect
context.fillStyle = "#8a1002";
context.fillRect(left+1, (canvas.height*5/6)+1, canvas.width-left, canvas.height*1/6);

////////////////
////  TEXT  ////
////////////////

//user name
context.fillStyle = "black";
context.font = "bold 18px sans-serif";
context.textAlign = 'right';
context.fillText("User Name", canvas.width, canvas.height*.05);

//AT:
context.font = "bold 12px sans-serif";
context.fillText("AT: 140", canvas.width, canvas.height*.1);

//AB:
context.fillText("AB: 94", canvas.width, canvas.height*.15);
       
//this part is done after the callback from the view adapter, but is relevant here to add the view back into the layout.
var parent = document.getElementById("layout-content");
parent.appendChild(canvas);
<div id="layout-content"></div>

আমি যে ফলাফলগুলি দেখছি ( সাফারিতে ) ফিডল দেখানো তার চেয়ে অনেক বেশি স্কঙ্কযুক্ত:

আমার

সাফারিতে রেন্ডার আউটপুট

ফিডল

জেএসফিডেলে রেন্ডার আউটপুট

আমি কী ভুল করছি? প্রতিটি পাঠ্যের উপাদানগুলির জন্য আমার কি আলাদা ক্যানভাস দরকার? এটা কি ফন্ট? আমার কি প্রথমে HTML5 লেআউটে ক্যানভাসটি সংজ্ঞায়িত করতে হবে? টাইপো আছে? আমি হারিয়ে গেলাম।


মনে হচ্ছে আপনি কল করছেন না clearRect
ডেভিড

4
এই পলিফিলটি হিডিপিআই ব্রাউজারগুলির সাথে সর্বাধিক বেসিক ক্যানভাস অপারেশনগুলি ঠিক করে যা স্বয়ংক্রিয়ভাবে উপরে উঠে যায় না (বর্তমানে সাফারিই
jondavidjohn

আমি একটি জেএস ফ্রেমওয়ার্ক বিকাশ করছি যা ডিআইভি মোজাইক দিয়ে ক্যানভাস ব্লার সমস্যা সমাধান করে। আমি মেম / সিপিইউ js2dx.com
গনকি

উত্তর:


160

ক্যানভাস উপাদানটি ডিভাইস বা মনিটরের পিক্সেল অনুপাত থেকে স্বতন্ত্রভাবে চালিত হয়।

আইপ্যাড 3+ এ, এই অনুপাতটি 2 This ভাগ্যক্রমে আমাদের জন্য, এটি ব্রাউজার দ্বারা স্বয়ংক্রিয়ভাবে সম্পন্ন হয়। অন্যদিকে, ইমেজ এবং ক্যানভাস উপাদানগুলির তুলনায় আপনি কম সংজ্ঞা দেখতে পান যা তাদের দৃশ্যমান অঞ্চলটি সরাসরি ফিট করার জন্য তৈরি হয়েছিল। যেহেতু আপনার ক্যানভাসটি কেবল 1000px পূরণ করতে জানে তবে 2000px এ আঁকতে বলা হয়েছে, তাই ব্রাউজারটি অবশ্যই সঠিক আকারে উপাদানটি প্রদর্শন করতে পিক্সেলের মধ্যে ফাঁকা স্থান পূরণ করতে হবে।

আমি আপনাকে এইচটিএমএল 5 রকস থেকে এই নিবন্ধটি পড়ার জন্য সুপারিশ করব যা উচ্চ সংজ্ঞা উপাদানগুলি কীভাবে তৈরি করবেন তার আরও বিশদে ব্যাখ্যা করে।

tl; dr? এখানে একটি উদাহরণ (উপরের টুট উপর ভিত্তি করে) যা আমি আমার নিজস্ব প্রকল্পগুলিতে যথাযথ রেজোলিউশন সহ একটি ক্যানভাস আউট করতে ব্যবহার করি:

var PIXEL_RATIO = (function () {
    var ctx = document.createElement("canvas").getContext("2d"),
        dpr = window.devicePixelRatio || 1,
        bsr = ctx.webkitBackingStorePixelRatio ||
              ctx.mozBackingStorePixelRatio ||
              ctx.msBackingStorePixelRatio ||
              ctx.oBackingStorePixelRatio ||
              ctx.backingStorePixelRatio || 1;

    return dpr / bsr;
})();


createHiDPICanvas = function(w, h, ratio) {
    if (!ratio) { ratio = PIXEL_RATIO; }
    var can = document.createElement("canvas");
    can.width = w * ratio;
    can.height = h * ratio;
    can.style.width = w + "px";
    can.style.height = h + "px";
    can.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
    return can;
}

//Create canvas with the device resolution.
var myCanvas = createHiDPICanvas(500, 250);

//Create canvas with a custom resolution.
var myCustomCanvas = createHiDPICanvas(500, 200, 4);

আশাকরি এটা সাহায্য করবে!


4
ভেবেছি এটি উল্লেখ করার মতো হবে যে আমার ক্রিয়েটহিডিপিআই () পদ্ধতিটি কিছুটা খারাপ নাম দেওয়া হয়েছে। ডিপিআই হ'ল কেবল মুদ্রণের জন্য একটি শব্দ এবং পিপিআই আরও সঠিক সংক্ষিপ্ত রূপ হিসাবে মনিটরসগুলি বিন্দুগুলির বিপরীতে পিক্সেল ব্যবহার করে চিত্র প্রদর্শন করে।
MyNameIsKo

4
নোট করুন যে পৃষ্ঠার জীবদ্দশায় এই অনুপাতটি আসলে পরিবর্তিত হতে পারে। উদাহরণস্বরূপ, আমি যদি কোনও ম্যাকবুকের অন্তর্নির্মিত রেটিনা স্ক্রিনে কোনও পুরানো "স্ট্যান্ডার্ড" রেজ সহ বহিরাগত মনিটর থেকে একটি ক্রোম উইন্ডো টেনে আছি তবে কোডটি একটি ভিন্ন অনুপাত গণনা করবে। আপনি যদি এই মানটি ক্যাশে করার পরিকল্পনা করেন তবে কেবল একটি এফওয়াইআই। (বাহ্যিক অনুপাত 1, রেটিনা স্ক্রিন 2 আপনি
কৌতূহলের

4
এই ব্যাখ্যার জন্য ধন্যবাদ। তবে কীভাবে ইমেজ সম্পদ? আমাদের কি প্রতিটি ক্যানভাস চিত্র ডাবল রেজুলেশনে সরবরাহ করতে হবে এবং ম্যানুয়ালি এটিকে স্কেল করতে হবে?
কোকোডোকো

4
আরও ট্রিভিয়া: উইন্ডোজ ফোন 8 এর আইই সর্বদা উইন্ডো.ডভাইসপিক্সেল রেশিওর জন্য 1 প্রতিবেদন করে (এবং পিক্সেল কল ব্যাক করে না)। 1 এ ভয়াবহ লাগছে, তবুও 2 এর অনুপাতটি ভাল দেখাচ্ছে। আপাতত আমার অনুপাতের গণনাগুলি যাইহোক কমপক্ষে একটি 2 ফেরত দেয় (ক্র্যাপি ওয়ার্কআরাউন্ড, তবে আমার টার্গেট প্ল্যাটফর্মগুলি আধুনিক ফোন যা প্রায় সকলেরই উচ্চ ডিপিআই স্ক্রিন বলে মনে হয়)। এইচটিসি 8 এক্স এবং লুমিয়া 1020
--আর্ডভার্ক

4
@আর্ডওয়ার্ক: এটিও মনে হয় যে এমএসব্যাকিংস্টোরপিক্সেল রেটিও সর্বদা অপরিজ্ঞাত। এখানে সে সম্পর্কে একটি নতুন প্রশ্ন জিজ্ঞাসা করেছেন: stackoverflow.com/questions/22483296/…
টিভি এর ফ্রাঙ্ক

29

সলভ!

আমি কীভাবে ক্যানভাসের আকারকে প্রভাবিত করেছি তা দেখার জন্য আমি যে প্রস্থ এবং উচ্চতার বৈশিষ্ট্যগুলি সেট করেছি সেটি কী পরিবর্তন করব তা দেখার সিদ্ধান্ত নিয়েছি javascriptand এবং তা হয়নি। এটি রেজুলেশন পরিবর্তন করে।

আমি যে ফলাফলটি চেয়েছিলাম তা পেতে, আমাকে canvas.style.widthএট্রিবিউটও সেট করতে হয়েছিল , যা শারীরিক আকার পরিবর্তন করে canvas:

canvas.width=1000;//horizontal resolution (?) - increase for better looking text
canvas.height=500;//vertical resolution (?) - increase for better looking text
canvas.style.width=width;//actual width of canvas
canvas.style.height=height;//actual height of canvas

4
আদর্শ ফলাফলের জন্য আপনার ক্যানভাসের শৈলীর বৈশিষ্ট্যগুলি একেবারে স্পর্শ করা উচিত নয় এবং কেবল ক্যানভাসের প্রস্থ এবং উচ্চতার বৈশিষ্ট্যের সাহায্যে আকার নিয়ন্ত্রণ করা উচিত নয়। এইভাবে আপনি নিশ্চিত হন যে ক্যানভাসের একটি পিক্সেল স্ক্রিনের এক পিক্সেলের সমান।
ফিলিপ

7
আমি একমত নই স্টাইল.উইথ / উচ্চতার বৈশিষ্ট্যগুলি পরিবর্তন করা হ'ল আপনি কীভাবে হাইডিপিআই ক্যানভাস তৈরি করেন।
MyNameIsKo

4
আপনার উত্তরে আপনি ক্যানভাস.উইথথকে 1000 এবং ক্যানভাস.স্টাইল.উইথথকে অর্ধেক 500 এ সেট করেছেন This এটি কেবলমাত্র একটি পিক্সেল রেশিও 2 ডিভাইসের জন্য কাজ করে যা আপনার ডেস্কটপের মনিটরের মতো, ক্যানভাস এখন অপ্রয়োজনীয় পিক্সেল আঁকুন। উচ্চতর অনুপাতের জন্য আপনি এখনই ফিরে এসেছেন যেখানে আপনি অস্পষ্ট, কম পুনরায় সম্পদ / উপাদান দিয়ে শুরু করেছেন। ফিলিপকে অন্য যে ইস্যুটি ইঙ্গিত করে বলে মনে হচ্ছে তা হ'ল আপনি আপনার প্রসঙ্গে আঁকেন এমন প্রতিটি বিষয় অবশ্যই আপনার দ্বিগুণ প্রস্থ / উচ্চতায় আঁকতে হবে যদিও এটি অর্ধিক মানটি প্রদর্শিত হচ্ছে। এটির সমাধানটি হ'ল আপনার ক্যানভাসের প্রসঙ্গটি দ্বিগুণ করতে।
MyNameIsKo

4
নেই window.devicePixelRatio, এবং এটি ভাল এটি অত্যাধুনিক ব্রাউজারে বাস্তবায়িত হচ্ছে।
চেন

6

প্যারেন্ট এলিমেন্টের পুরো প্রস্থ নিতে আমি CSS এর মাধ্যমে ক্যানভাস উপাদানটির আকার পরিবর্তন করি। আমি লক্ষ্য করেছি যে আমার উপাদানটির প্রস্থ এবং উচ্চতা মাপানো হয়নি। আমি আকার নির্ধারণ করার সর্বোত্তম উপায় খুঁজছিলাম যা হওয়া উচিত।

canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;

আপনি যে পর্দা ব্যবহার করবেন তা বিবেচনা না করেই এই সহজ উপায়ে আপনার ক্যানভাসটি পুরোপুরি সেট হয়ে যাবে।


5

এটি আমার জন্য 100% সমাধান করেছে:

var canvas = document.getElementById('canvas');
canvas.width = canvas.getBoundingClientRect().width;
canvas.height = canvas.getBoundingClientRect().height;

(এটি অ্যাডাম ম্যাকোভস্কির সমাধানের খুব কাছাকাছি)।


4

আমি অন্যান্য উত্তরে উল্লেখ না করে একটি বিবরণ লক্ষ্য করেছি। ক্যানভাস রেজোলিউশন পূর্ণসংখ্যার মানগুলিকে সঙ্কুচিত করে।

ডিফল্ট ক্যানভাস রেজোলিউশন মাত্রা canvas.width: 300এবং canvas.height: 150

আমার পর্দায় window.devicePixelRatio: 1.75,।

সুতরাং যখন আমি সেট canvas.height = 1.75 * 150মানটি কাঙ্ক্ষিত থেকে 262.5নীচে থেকে কাটা হয় 262

একটি সমাধান হ'ল window.devicePixelRatioরেজোলিউশনের স্কেলিংয়ের ক্ষেত্রে কাটাটি ঘটবে না এর জন্য সিএসএস বিন্যাসের মাত্রা বেছে নেওয়া ।

উদাহরণস্বরূপ, আমি ব্যবহার করতে পারতাম width: 300pxএবং height: 152pxযা দ্বারা গুণিতকালে সম্পূর্ণ সংখ্যা পাওয়া যায় 1.75

সম্পাদনা : আরেকটি সমাধান হ'ল সিএসএস পিক্সেলগুলি স্কেলিং ক্যানভাস পিক্সেলের কাটা কাটা লড়াইয়ের জন্য ভগ্নাংশ হতে পারে তার সুবিধা গ্রহণ করা।

নীচে এই কৌশলটি ব্যবহার করে একটি ডেমো রয়েছে।

সম্পাদনা : এখানে ওপি এর বেহালার এ কৌশলের ব্যবহার করতে আপডেট করা হয় http://jsfiddle.net/65maD/83/

main();

// Rerun on window resize.
window.addEventListener('resize', main);


function main() {
  // Prepare canvas with properly scaled dimensions.
  scaleCanvas();

  // Test scaling calculations by rendering some text.
  testRender();
}


function scaleCanvas() {
  const container = document.querySelector('#container');
  const canvas = document.querySelector('#canvas');

  // Get desired dimensions for canvas from container.
  let {width, height} = container.getBoundingClientRect();

  // Get pixel ratio.
  const dpr = window.devicePixelRatio;
  
  // (Optional) Report the dpr.
  document.querySelector('#dpr').innerHTML = dpr.toFixed(4);

  // Size the canvas a bit bigger than desired.
  // Use exaggeration = 0 in real code.
  const exaggeration = 20;
  width = Math.ceil (width * dpr + exaggeration);
  height = Math.ceil (height * dpr + exaggeration);

  // Set the canvas resolution dimensions (integer values).
  canvas.width = width;
  canvas.height = height;

  /*-----------------------------------------------------------
                         - KEY STEP -
   Set the canvas layout dimensions with respect to the canvas
   resolution dimensions. (Not necessarily integer values!)
   -----------------------------------------------------------*/
  canvas.style.width = `${width / dpr}px`;
  canvas.style.height = `${height / dpr}px`;

  // Adjust canvas coordinates to use CSS pixel coordinates.
  const ctx = canvas.getContext('2d');
  ctx.scale(dpr, dpr);
}


function testRender() {
  const canvas = document.querySelector('#canvas');
  const ctx = canvas.getContext('2d');
  
  // fontBaseline is the location of the baseline of the serif font
  // written as a fraction of line-height and calculated from the top
  // of the line downwards. (Measured by trial and error.)
  const fontBaseline = 0.83;
  
  // Start at the top of the box.
  let baseline = 0;

  // 50px font text
  ctx.font = `50px serif`;
  ctx.fillText("Hello World", 0, baseline + fontBaseline * 50);
  baseline += 50;

  // 25px font text
  ctx.font = `25px serif`;
  ctx.fillText("Hello World", 0, baseline + fontBaseline * 25);
  baseline += 25;

  // 12.5px font text
  ctx.font = `12.5px serif`;
  ctx.fillText("Hello World", 0, baseline + fontBaseline * 12.5);
}
/* HTML is red */

#container
{
  background-color: red;
  position: relative;
  /* Setting a border will mess up scaling calculations. */
  
  /* Hide canvas overflow (if any) in real code. */
  /* overflow: hidden; */
}

/* Canvas is green */ 

#canvas
{
  background-color: rgba(0,255,0,.8);
  animation: 2s ease-in-out infinite alternate both comparison;
}

/* animate to compare HTML and Canvas renderings */

@keyframes comparison
{
  33% {opacity:1; transform: translate(0,0);}
  100% {opacity:.7; transform: translate(7.5%,15%);}
}

/* hover to pause */

#canvas:hover, #container:hover > #canvas
{
  animation-play-state: paused;
}

/* click to translate Canvas by (1px, 1px) */

#canvas:active
{
  transform: translate(1px,1px) !important;
  animation: none;
}

/* HTML text */

.text
{
  position: absolute;
  color: white;
}

.text:nth-child(1)
{
  top: 0px;
  font-size: 50px;
  line-height: 50px;
}

.text:nth-child(2)
{
  top: 50px;
  font-size: 25px;
  line-height: 25px;
}

.text:nth-child(3)
{
  top: 75px;
  font-size: 12.5px;
  line-height: 12.5px;
}
<!-- Make the desired dimensions strange to guarantee truncation. -->
<div id="container" style="width: 313.235px; height: 157.122px">
  <!-- Render text in HTML. -->
  <div class="text">Hello World</div>
  <div class="text">Hello World</div>
  <div class="text">Hello World</div>
  
  <!-- Render text in Canvas. -->
  <canvas id="canvas"></canvas>
</div>

<!-- Interaction instructions. -->
<p>Hover to pause the animation.<br>
Click to translate the green box by (1px, 1px).</p>

<!-- Color key. -->
<p><em style="color:red">red</em> = HTML rendered<br>
<em style="color:green">green</em> = Canvas rendered</p>

<!-- Report pixel ratio. -->
<p>Device pixel ratio: <code id="dpr"></code>
<em>(physical pixels per CSS pixel)</em></p>

<!-- Info. -->
<p>Zoom your browser to re-run the scaling calculations.
(<code>Ctrl+</code> or <code>Ctrl-</code>)</p>


3

আমি সামান্য ক্যানভিগের অধীনে MyNameIsKo কোডটি মানিয়েছি (এসভিজি ক্যানভাস জেএস লাইব্রেরিতে)। আমি কিছু সময়ের জন্য বিভ্রান্ত হয়ে পড়েছিলাম এবং এর জন্য কিছুটা সময় ব্যয় করেছি। আশা করি এটি কারও সাহায্য করবে।

এইচটিএমএল

<div id="chart"><canvas></canvas><svg>Your SVG here</svg></div>

জাভাস্ক্রিপ্ট

window.onload = function() {

var PIXEL_RATIO = (function () {
    var ctx = document.createElement("canvas").getContext("2d"),
        dpr = window.devicePixelRatio || 1,
        bsr = ctx.webkitBackingStorePixelRatio ||
              ctx.mozBackingStorePixelRatio ||
              ctx.msBackingStorePixelRatio ||
              ctx.oBackingStorePixelRatio ||
              ctx.backingStorePixelRatio || 1;

    return dpr / bsr;
})();

setHiDPICanvas = function(canvas, w, h, ratio) {
    if (!ratio) { ratio = PIXEL_RATIO; }
    var can = canvas;
    can.width = w * ratio;
    can.height = h * ratio;
    can.style.width = w + "px";
    can.style.height = h + "px";
    can.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
}

var svg = document.querySelector('#chart svg'),
    canvas = document.querySelector('#chart canvas');

var svgSize = svg.getBoundingClientRect();
var w = svgSize.width, h = svgSize.height;
setHiDPICanvas(canvas, w, h);

var svgString = (new XMLSerializer).serializeToString(svg);
var ctx = canvas.getContext('2d');
ctx.drawSvg(svgString, 0, 0, w, h);

}

2

আপনারা যারা রিঅ্যাক্টজে কাজ করছেন তাদের জন্য আমি মাইনেইমসকো এর উত্তরটি অভিযোজিত করেছি এবং এটি দুর্দান্ত কাজ করে। কোডটি এখানে।

import React from 'react'

export default class CanvasComponent extends React.Component {
    constructor(props) {
        this.calcRatio = this.calcRatio.bind(this);
    } 

    // Use componentDidMount to draw on the canvas
    componentDidMount() {  
        this.updateChart();
    }

    calcRatio() {
        let ctx = document.createElement("canvas").getContext("2d"),
        dpr = window.devicePixelRatio || 1,
        bsr = ctx.webkitBackingStorePixelRatio ||
          ctx.mozBackingStorePixelRatio ||
          ctx.msBackingStorePixelRatio ||
          ctx.oBackingStorePixelRatio ||
          ctx.backingStorePixelRatio || 1;
        return dpr / bsr;
    }

    // Draw on the canvas
    updateChart() {

        // Adjust resolution
        const ratio = this.calcRatio();
        this.canvas.width = this.props.width * ratio;
        this.canvas.height = this.props.height * ratio;
        this.canvas.style.width = this.props.width + "px";
        this.canvas.style.height = this.props.height + "px";
        this.canvas.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
        const ctx = this.canvas.getContext('2d');

       // now use ctx to draw on the canvas
    }


    render() {
        return (
            <canvas ref={el=>this.canvas=el} width={this.props.width} height {this.props.height}/>
        )
    }
}

এই উদাহরণে, আমি প্রপস হিসাবে ক্যানভাসের প্রস্থ এবং উচ্চতায় পাস করি।


2

আপনার ক্যানভাসে সিএসএসের এই এক লাইনটি ব্যবহার করে দেখুন: image-rendering: pixelated

অনুযায়ী MDN :

চিত্রটি স্কেলিংয়ের সময়, নিকটতম-প্রতিবেশী অ্যালগরিদম অবশ্যই ব্যবহার করা উচিত, যাতে চিত্রটি বড় পিক্সেলের সমন্বয়ে গঠিত বলে মনে হয়।

সুতরাং এটি সম্পূর্ণরূপে অ্যান্টি-এলিয়জিং প্রতিরোধ করে।


2

@ মাইনেম আইসকো এর উত্তরটি এখনও কার্যকর হলেও, ২০২০ সালে এটি এখন কিছুটা পুরানো এবং উন্নত হতে পারে:

function createHiPPICanvas(w, h) {
    let ratio = window.devicePixelRatio;
    let cv = document.createElement("canvas");
    cv.width = w * ratio;
    cv.height = h * ratio;
    cv.style.width = w + "px";
    cv.style.height = h + "px";
    cv.getContext("2d").scale(ratio, ratio);
    return cv;
}

সাধারণভাবে, আমরা নিম্নলিখিত উন্নতিগুলি করি:

  • আমরা backingStorePixelRatioউল্লেখগুলি মুছে ফেলি, কারণ এগুলি কোনও ব্রাউজারে কোনও গুরুত্বপূর্ণ উপায়ে বাস্তবায়িত হয় না (বাস্তবে কেবল সাফারি ছাড়া অন্য কিছু প্রত্যাবর্তন করে undefined, এবং এই সংস্করণটি এখনও সাফারিতে পুরোপুরি কাজ করে);
  • আমরা সেই অনুপাতের কোডটি সমস্ত দিয়ে প্রতিস্থাপন করি window.devicePixelRatio, যার দুর্দান্ত সমর্থন রয়েছে
  • এর অর্থ হ'ল আমরা একটি কম বৈশ্বিক সম্পত্তি ঘোষণা করি --- হুররে !!
  • আমরা || 1ফ্যালব্যাকটিও মুছে ফেলতে পারি window.devicePixelRatio, কারণ এটি অর্থহীন: সমস্ত ব্রাউজার যারা এই সম্পত্তি সমর্থন করে না .setTransformবা সমর্থন করে না .scale, তাই এই ফাংশনটি তাদের উপর কাজ করবে না, ফ্যালব্যাক বা না;
  • রূপান্তর ম্যাট্রিক্সে যাওয়ার চেয়ে প্রস্থ এবং উচ্চতায় পাস করা কিছুটা স্বজ্ঞাত হিসাবে আমরা এর .setTransformদ্বারা প্রতিস্থাপন করতে পারি .scale
  • ফাংশনটির নাম বদলে দেওয়া createHiDPICanvasহয়েছে createHiPPICanvas। @ মাইনেম আইসকো যেমন নিজের উত্তরের মন্তব্যে নিজেরাই উল্লেখ করেছেন, ডিপিআই (প্রতি ইঞ্চিতে ডটস) মুদ্রণ পরিভাষা (যেমন প্রিন্টাররা রঙিন কালিযুক্ত ছোট বিন্দুগুলির মধ্যে চিত্রগুলি তৈরি করে)। অনুরূপ হিসাবে, মনিটরসগুলি পিক্সেল ব্যবহার করে চিত্রগুলি প্রদর্শন করে এবং যেমন পিপিআই (পঞ্চস প্রতি ইঞ্চি) আমাদের ব্যবহারের ক্ষেত্রে আরও ভাল সংক্ষিপ্ত রূপ হিসাবে ব্যবহার করে।

এই সরলকরণের একটি বড় সুবিধা হ'ল এই উত্তরটি এখন টাইপস্ক্রিপ্টে ব্যবহার করা যেতে পারে // @ts-ignore(যেমন টিএসের ধরণের ধরণ নেই backingStorePixelRatio)।


0

আমার জন্য, শুধুমাত্র বিভিন্ন 'পিক্সেল নিখুঁত' কৌশলগুলির সংমিশ্রণ ফলাফল সংরক্ষণাগারভুক্ত করতে সাহায্য করেছিল:

  1. @ MyNameIsKo প্রস্তাবিত হিসাবে পিক্সেল অনুপাতের সাথে পান এবং স্কেল করুন।

    পিক্সেলরেটিও = উইন্ডো। ডিভাইসপিক্সেল রেটিও / সিটিএক্স.ব্যাকিং স্টোরপিক্সেল রেসিও

  2. আকার পরিবর্তন করে ক্যানভাস স্কেল করুন (ক্যানভাসের ডিফল্ট প্রসারিত স্কেলিং এড়ান)।

  3. যথাযথ 'রিয়েল' পিক্সেল লাইনের বেধ খুঁজতে পিক্সেল تناسبের সাথে লাইনপথ একাধিক করুন:

    context.lineWidth = বেধ * পিক্সেলরতি;

  4. লাইনের বেধ বিজোড় বা এমনকি কিনা তা পরীক্ষা করে দেখুন। বিজোড় বেধের মানগুলির জন্য পিক্সেলরেটির অর্ধেকটি রেখা অবস্থানে যুক্ত করুন।

    x = x + পিক্সেল রেশিও / 2;

বিজোড় লাইনটি পিক্সেলের মাঝখানে স্থাপন করা হবে। উপরের লাইনটি কিছুটা সরানোর জন্য ব্যবহৃত হয়।

function getPixelRatio(context) {
  dpr = window.devicePixelRatio || 1,
    bsr = context.webkitBackingStorePixelRatio ||
    context.mozBackingStorePixelRatio ||
    context.msBackingStorePixelRatio ||
    context.oBackingStorePixelRatio ||
    context.backingStorePixelRatio || 1;

  return dpr / bsr;
}


var canvas = document.getElementById('canvas');
var context = canvas.getContext("2d");
var pixelRatio = getPixelRatio(context);
var initialWidth = canvas.clientWidth * pixelRatio;
var initialHeight = canvas.clientHeight * pixelRatio;


window.addEventListener('resize', function(args) {
  rescale();
  redraw();
}, false);

function rescale() {
  var width = initialWidth * pixelRatio;
  var height = initialHeight * pixelRatio;
  if (width != context.canvas.width)
    context.canvas.width = width;
  if (height != context.canvas.height)
    context.canvas.height = height;

  context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
}

function pixelPerfectLine(x) {

  context.save();
  context.beginPath();
  thickness = 1;
  // Multiple your stroke thickness  by a pixel ratio!
  context.lineWidth = thickness * pixelRatio;

  context.strokeStyle = "Black";
  context.moveTo(getSharpPixel(thickness, x), getSharpPixel(thickness, 0));
  context.lineTo(getSharpPixel(thickness, x), getSharpPixel(thickness, 200));
  context.stroke();
  context.restore();
}

function pixelPerfectRectangle(x, y, w, h, thickness, useDash) {
  context.save();
  // Pixel perfect rectange:
  context.beginPath();

  // Multiple your stroke thickness by a pixel ratio!
  context.lineWidth = thickness * pixelRatio;
  context.strokeStyle = "Red";
  if (useDash) {
    context.setLineDash([4]);
  }
  // use sharp x,y and integer w,h!
  context.strokeRect(
    getSharpPixel(thickness, x),
    getSharpPixel(thickness, y),
    Math.floor(w),
    Math.floor(h));
  context.restore();
}

function redraw() {
  context.clearRect(0, 0, canvas.width, canvas.height);
  pixelPerfectLine(50);
  pixelPerfectLine(120);
  pixelPerfectLine(122);
  pixelPerfectLine(130);
  pixelPerfectLine(132);
  pixelPerfectRectangle();
  pixelPerfectRectangle(10, 11, 200.3, 443.2, 1, false);
  pixelPerfectRectangle(41, 42, 150.3, 443.2, 1, true);
  pixelPerfectRectangle(102, 100, 150.3, 243.2, 2, true);
}

function getSharpPixel(thickness, pos) {

  if (thickness % 2 == 0) {
    return pos;
  }
  return pos + pixelRatio / 2;

}

rescale();
redraw();
canvas {
  image-rendering: -moz-crisp-edges;
  image-rendering: -webkit-crisp-edges;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  width: 100vh;
  height: 100vh;
}
<canvas id="canvas"></canvas>

পুনরায় মাপ ঘটনা স্নিপেড মধ্যে বহিস্কার করা হয় না তাই আপনি ফাইল চেষ্টা করে দেখতে পারেন GitHub


0

আমার জন্য এটি কেবল চিত্র ছিল না তবে পাঠ্যের খারাপ মানের ছিল। রেটিনা / নন-রেটিনা ডিসপ্লেগুলির সহজতম ক্রস ব্রাউজারের সমাধান হ'ল এই ছেলের পরামর্শ মতো ইচ্ছাকৃত এবং স্কেল ক্যানভাস প্রসঙ্গে চিত্রটিকে দ্বিগুণ করে রেন্ডার করা হয়েছিল: https://stackoverflow.com/a/53921030/4837965

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.