12.02.2020, 03:51
|
Новичок на форуме
|
|
Регистрация: 12.02.2020
Сообщений: 2
|
|
Проблема приоритета слоев отрисовки
Здравствуйте. У меня проблема - я уже много времени потратил впустую.
Задача такая - нужно чтобы линии отрисовки секторов были поверх секторов заливки и были эти линии только черного цвета и не еле прозрачные. 054 строка кода как раз начинается отрисовка здесь - в цикле проблема.Помогите, ребят.
С уважением, countervector.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Canvas в HTML5</title>
</head>
<body onload='draw()'>
<canvas id='canvas' height='800' width='1000'></canvas>
<script>
</script>
<script>
function draw() {
var contex = document.getElementById('canvas').getContext('2d');
var img = new Image();
var R1=320.0;
var R2=260.0;
var R3=220.0;
var delta=330.0;
var p1=(2*Math.PI)/366;
var p2=(2*Math.PI)/(24*366);
var x1 = [366+1];
var y1 = [366+1];
var x2 = [366+1];
var y2 = [366+1];
var x3 = [366*24+1];
var y3 = [366*24+1];
var x4 = [366*24+1];
var y4 = [366*24+1];
for(var i=0;i<=366;i++){
y1[i]=R1*(Math.sin(i*p1))+delta;
x1[i]=R1*(Math.cos(i*p1))+delta;
y2[i]=R2*(Math.sin(i*p1))+delta;
x2[i]=R2*(Math.cos(i*p1))+delta;
y3[i]=R2*(Math.sin(i*p2))+delta;
x3[i]=R2*(Math.cos(i*p2))+delta;
y4[i]=R3*(Math.sin(i*p2))+delta;
x4[i]=R3*(Math.cos(i*p2))+delta;
}
contex.beginPath();
contex.lineWidth=1; // толщина линии
contex.strokeStyle = "#000000"; //цвет линии
//отрисовка кругов и перемычек (здесь проблема отрисовка нужно чтобы была поверх полигонов)
for(var i=0;i+1<=366;i++){
contex.moveTo(x1[i],y1[i]);
contex.lineTo(x1[i+1],y1[i+1]);
contex.moveTo(x2[i],y2[i]);
contex.lineTo(x2[i+1],y2[i+1]);
contex.moveTo(x3[i],y3[i]);
contex.lineTo(x3[i+1],y3[i+1]);
//рисуем перемычки между кольцами
contex.moveTo(x1[i],y1[i]);
contex.lineTo(x2[i],y2[i]);
}
var now = new Date();
var start = new Date(now.getFullYear(), 0, 0);
var diff = (now - start) + ((start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000);
var oneDay = 1000 * 60 * 60 * 24;
var day = Math.floor(diff / oneDay);
contex.beginPath();
for(var i=0;i+1<=366;i++){
//заполняем сектора (полигоны) желтым цветом
contex.fillStyle = "#ffbb00"; //цвет линии
contex.beginPath();
contex.moveTo(x1[i], y1[i]);
contex.lineTo(x1[i+1],y1[i+1]);
contex.lineTo(x2[i+1], y2[i+1]);
contex.lineTo(x2[i], y2[i]);
contex.closePath();
contex.fill();
}
contex.beginPath();
for(var ii=0;ii<=day;ii++){
//заполняем сектора (полигоны) зеленым цветом
contex.fillStyle = "#39e600"; //цвет линии
contex.beginPath();
contex.lineCap = "round"; // закругляем наконечник
contex.stroke();
contex.moveTo(x1[ii], y1[ii]);
contex.lineTo(x1[ii+1],y1[ii+1]);
contex.lineTo(x2[ii+1], y2[ii+1]);
contex.lineTo(x2[ii], y2[ii]);
contex.closePath();
contex.fill();
}
//пишем буквы (String);
contex.fillStyle = "#000000";
contex.strokeStyle = "black";
contex.lineWidth = 1;
contex.font = "100px sans-serif";
contex.fillText("Hello", 50, 100);
contex.strokeText("Hello", 50, 100);
}
</script>
</body>
</html>
Последний раз редактировалось countervector, 12.02.2020 в 10:19.
|
|
16.02.2020, 00:31
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,791
|
|
Так?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Canvas в HTML5</title>
</head>
<body>
<canvas id='canvas' height='800' width='1000'></canvas>
<script>
var contex = document.getElementById('canvas').getContext('2d');
var img = new Image();
var R1 = 320.0;
var R2 = 260.0;
var R3 = 220.0;
var delta = 330.0;
var p1 = (2 * Math.PI) / 366;
var p2 = (2 * Math.PI) / (24 * 366);
var x1 = [366 + 1];
var y1 = [366 + 1];
var x2 = [366 + 1];
var y2 = [366 + 1];
var x3 = [366 * 24 + 1];
var y3 = [366 * 24 + 1];
var x4 = [366 * 24 + 1];
var y4 = [366 * 24 + 1];
for (var i = 0; i <= 366; i++) {
y1[i] = R1 * (Math.sin(i * p1)) + delta;
x1[i] = R1 * (Math.cos(i * p1)) + delta;
y2[i] = R2 * (Math.sin(i * p1)) + delta;
x2[i] = R2 * (Math.cos(i * p1)) + delta;
y3[i] = R2 * (Math.sin(i * p2)) + delta;
x3[i] = R2 * (Math.cos(i * p2)) + delta;
y4[i] = R3 * (Math.sin(i * p2)) + delta;
x4[i] = R3 * (Math.cos(i * p2)) + delta;
}
var now = new Date();
var start = new Date(now.getFullYear(), 0, 0);
var diff = (now - start) + ((start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000);
var oneDay = 1000 * 60 * 60 * 24;
var day = Math.floor(diff / oneDay);
contex.beginPath();
for (var i = 0; i + 1 <= 366; i++) {
//заполняем сектора (полигоны) желтым цветом
contex.fillStyle = "#ffbb00"; //цвет линии
contex.beginPath();
contex.moveTo(x1[i], y1[i]);
contex.lineTo(x1[i + 1], y1[i + 1]);
contex.lineTo(x2[i + 1], y2[i + 1]);
contex.lineTo(x2[i], y2[i]);
contex.closePath();
contex.fill();
}
contex.beginPath();
for (var ii = 0; ii <= day; ii++) {
//заполняем сектора (полигоны) зеленым цветом
contex.fillStyle = "#39e600"; //цвет линии
contex.beginPath();
contex.lineCap = "round"; // закругляем наконечник
contex.stroke();
contex.moveTo(x1[ii], y1[ii]);
contex.lineTo(x1[ii + 1], y1[ii + 1]);
contex.lineTo(x2[ii + 1], y2[ii + 1]);
contex.lineTo(x2[ii], y2[ii]);
contex.closePath();
contex.fill();
}
//отрисовка кругов и перемычек (здесь проблема отрисовка нужно чтобы была поверх полигонов)
contex.lineWidth = 1; // толщина линии
contex.strokeStyle = "#000000"; //цвет линии
for (var i = 0; i + 1 <= 366; i++) {
contex.beginPath();
contex.moveTo(x1[i], y1[i]);
contex.lineTo(x1[i + 1], y1[i + 1]);
contex.moveTo(x2[i], y2[i]);
contex.lineTo(x2[i + 1], y2[i + 1]);
contex.moveTo(x3[i], y3[i]);
contex.lineTo(x3[i + 1], y3[i + 1]);
//рисуем перемычки между кольцами
contex.moveTo(x1[i], y1[i]);
contex.lineTo(x2[i], y2[i]);
contex.stroke();
}
//пишем буквы (String);
contex.fillStyle = "#000000";
contex.strokeStyle = "black";
contex.lineWidth = 1;
contex.font = "100px sans-serif";
contex.fillText("Hello", 50, 100);
contex.strokeText("Hello", 50, 100);
</script>
</body>
</html>
|
|
16.02.2020, 12:01
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,791
|
|
Rise,
Сообщение от countervector
|
Задача такая - нужно чтобы линии отрисовки секторов были поверх секторов заливки и были эти линии только черного цвета и не еле прозрачные
|
Я не вижу ничего про артефакты, код автора был изменен минимально.
|
|
16.02.2020, 12:14
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,791
|
|
Rise, извини, неправильно понял.
Нет, не иллюзия.
Я их тоже наблюдаю.
|
|
16.02.2020, 18:11
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Сообщение от Rise
|
странно только почему вектор также искажается как растр
|
В конечном то итоге это растровое изображение будет.
|
|
16.02.2020, 21:17
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Rise,
никто не спорит, что масштабирование вектора и растра вещи разные, оно и понятно, ибо у второго при операциях неизбежны потери на границах переходов. Но ведь вектор сам по себе ничего не несет, это всего лишь "границы в которых ..." так же. И нельзя сравнить svg залитую локальным цветом, хотя бы с примерами выше, при равных условиях при масштабировании результаты естественно будут разными. Даже текст, это вектор залитый локальным цветом и тот не всегда хорошо выглядит. Плюс физические особенности устройств, например тот же текст на ЭЛТ и матричном экране выглядит по разному.
А как бы не рисовалось, пусть и с привлечением GPU конечный результат это растр, и все решают методы интерполяции. Ну и мы видим не так как компьютер, наш мозг легко обмануть анимацей, которая на самом деле статическая картинка. Вот мы и видим одно и тоже в разных ракурсах/разворотах по разному.
Или, из недавнего что меня удивило. Есть две картинки, они разные по размеру и по преобладающим цветам. Обе уменьшаются по ширине до 1000px. Все это на канве в JS. Затем на них рисуется пунктирная линия в 1px шириной в градациях серого, почти близко к белому. Вопрос - одинаково ли должна выглядеть такая линия на этих изображениях? Я вижу на одной из них линию шириной в 2px, а на другой четкую в 1px. Так в один или в два пикселя шириной нарисовал линию компьютер? Просто линия, а вы удивляетесь почему "зебра в мелкую полоску" разная.
|
|
16.02.2020, 23:44
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Сообщение от Rise
|
Не знаю об этом ли речь, да есть в canvas такая особенность c горизонтальными и вертикальными линиями
|
Об этом, но еще есть и многие другие факторы которые нужно учитывать. Вообще canvas это ведь базовое, если можно так выразиться, а чтобы что-то получить стоящее нужно повозиться. Это ведь не только canvas страдает этим, взять ту же GD и сравнить с Image Magik, разница большая.
Вот картинки, пока не увеличишь, кажется что на первой 2px, а на второй 1px ширина, а огрехи просто маскируется соседним цветом и плотностью почти такой же как и линии. А рядом, для сравнения, наложил направляющие фотошопа. Если увеличить, то заметен подход в разности отрисовки линий. Плюс цвет локальный и контрастный.
Последний раз редактировалось laimas, 12.10.2020 в 16:58.
|
|
17.02.2020, 21:55
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Живые примеры из постов №№2 и 7 в Chrome 80 отображаются нормально, а вот на присланных скриншотах из постов №№3 и 6 видно неточное сглаживание, очевидно у вас 1 пиксель из программы неожиданно равен пикселю на экране. «Антиалиасинг» можно отключить вообще (если не получилось настроить), тогда в браузере таких проблем не будет (правда это не вариант, если у вас пиксели размером с блюдечко!)
В Chrome 80 пример из поста №2 у меня выглядит так...
Сообщение от laimas
|
Затем на них рисуется пунктирная линия в 1px шириной в градациях серого, почти близко к белому. Вопрос - одинаково ли должна выглядеть такая линия на этих изображениях? Я вижу на одной из них линию шириной в 2px, а на другой четкую в 1px.
|
Так вы наверное на разных экранах смотрели на эту полоску. В этом нет ничего странного, в CSS пишем border-width: 1px, а на экране — 4px, так устроены современные экраны (например, Retina), вам не нужно об этом беспокоиться и вглядываться в экран через микроскоп!
try {
alert(devicePixelRatio >= 1.5 ? "Вот оно, качество!" : devicePixelRatio >= 4 ? "Оргазм от одного взгляда на экран" : "У тебя кошерные пиксели размером с блюдечко")
} catch(error) {
alert("Ты должен быть доволен тем, что твоё корыто хоть что-то показывает!");
}
Сообщение от Rise
|
В векторе такая же фигня.
|
Значит у вас devicePixelRatio === 1
Сообщение от Rise
|
Кстати, в растре также можно.
|
Сообщение от Rise
|
да есть в canvas такая особенность c горизонтальными и вертикальными линиями,
|
Вам нужно учитывать devicePixelRatio, т. е. используем каждый пиксел, (а не блоки по 2×2px, или по 3×3px или по 4×4px, как один пиксель)
<html>
<head>
<title>Canvas dashed circle</title>
</head>
<body>
<canvas width="640" height="640"></canvas>
<script>
var canvas = document.querySelector('canvas');
canvas.style.width = canvas.width + "px";
canvas.style.height = canvas.height + "px";
var scale = devicePixelRatio;
canvas.width *= scale;
canvas.height *= scale;
var ctx = document.querySelector('canvas').getContext('2d');
ctx.scale(scale, scale);
ctx.translate(320, 320);
ctx.arc(0, 0, 290, 0, 2 * Math.PI);
ctx.lineWidth = 60;
ctx.strokeStyle = "#ffbb00";
ctx.stroke();
ctx.setLineDash([1, 4]);
ctx.strokeStyle = "#000000";
ctx.stroke();
</script>
</body>
</html>
|
|
17.02.2020, 22:43
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Сообщение от Malleys
|
Так вы наверное на разных экранах смотрели на эту полоску.
|
Конечно, у меня их как в магазине на прилавке, в ряд, ходил и смотрел на каждый. Ну что хрень пороть?
Это из редактора приготовления выделений для SVG. Эти линии ограничивают рабочую зону от края изображения равную 2 см. Оригинальное изображение конечно гораздо больше 1000 рх и с разрешением 300dpi. Оригинал при производстве может увеличиваться до 2 м, при этом граница в 2 см постоянная. В редакторе это тоже учитывается, и эти границы в нем сдвигаются к краю. Когда линия границы попадает на четный ряд, то рисуется четкая линия.
|
|
17.02.2020, 23:35
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,112
|
|
Malleys,
пост #13
devicePixelRatio = 1.25
Chrome 80
"артефакт" на 3 часа
|
|
|
|