Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 28.01.2013, 20:55
Интересующийся
Отправить личное сообщение для Moonlight Посмотреть профиль Найти все сообщения от Moonlight
 
Регистрация: 18.05.2011
Сообщений: 25

Html5 canvas эффект наведения
Здравствуйте. У меня такой вопрос по canvas. Я отрисовал на холсте треугольную область. Мне нужно при наведении на неё курсором окрашивать её в другой цвет. Мне не понятно как с помощью методов canvas это сделать. Я вот нашёл один метод - isPointInPath, но мне кажется это будет очень затратно по производительности. Нужно будет на всё перемещения курсора брать его координаты и сравнивать. К тому же что делать, если на одном холсте отрисовано несколько фигур на основе одного и того же контекста (ctx), а закрашивать их нужно по отдельности при наведении на каждую? В общем есть ли ещё какие-то способы решить такую задачу?
Ответить с цитированием
  #2 (permalink)  
Старый 28.01.2013, 21:01
Аватар для 9xakep
сегодня в 12:34|Комментир
Отправить личное сообщение для 9xakep Посмотреть профиль Найти все сообщения от 9xakep
 
Регистрация: 12.04.2011
Сообщений: 1,180

Moonlight,
составь уравнение 3 прямых, и составь неравенство, и каждый раз подставляй в эти неравенства... но по-пойму легче isPointInPath

У тебя прям такое нагруженное приложение, что ты так печешься?

Если ты не понял о чем я, то вот пример, с кругом:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Документ без названия</title>
</head>
<canvas id='canvas'></canvas>
<script>
var _canvas = document.getElementById('canvas'),
	canvas = _canvas.getContext('2d'),
	x=50,y=50, radius = 30,
	colors = ['255,0,0', '0,255,0', '0,0,255', '0,0,0'], i = 0;
	
canvas.strokeRect(0,0,_canvas.width,_canvas.height)
canvas.arc(x,y, radius, 0, Math.PI *2, true)
canvas.fill()
_canvas.addEventListener('mousemove', function (event) {
	// Уравнение окружности: (x-x0)^2 + (y-y0)^2 = r^2
	var mouseX = event.pageX, mouseY = event.pageY;
	
	if ( Math.pow(radius,2) > Math.pow((x-mouseX),2) + Math.pow((y-mouseY),2)) {
		canvas.clearRect(1,1,_canvas.width-2, _canvas.height-2)
		canvas.fillStyle = 'rgb('+colors[i]+')'
		canvas.arc(x,y,radius,0,Math.PI*2,true)
		canvas.fill();
		i == colors.length ? i = 0 : i++;
	}
	
}, false)
</script>
<body>
</body>
</html>
__________________
оляля, ололо

Последний раз редактировалось 9xakep, 28.01.2013 в 21:21.
Ответить с цитированием
  #3 (permalink)  
Старый 28.01.2013, 21:24
Интересующийся
Отправить личное сообщение для Moonlight Посмотреть профиль Найти все сообщения от Moonlight
 
Регистрация: 18.05.2011
Сообщений: 25

Не я просто в принципе не знал как это делается, а про нагрузку просто мои догадки. То есть эффект наведение в canvas делается обычно методом isPointInPath? Мне в таком случае не понятно вот что. Вот нарисовал я несколько фигур в одном контексте.

Пример

То есть оба треугольника отрисованы контекстом context.
И теперь я хочу чтобы при наведении на верхний треугольник, он окрашивался в другой цвет, а нижний не изменялся.
Но как мне это сделать, если метод isPointInPath применяется сразу ко всему контексту?
var isPath = ctx.isPointInPath(50,50);


То есть наверно придётся ещё рассчитывать нужный мне треугольник?
Но с треугольниками ладно, их всего два, а мне нужно сделать карту с двумя десятками отметок, придётся создавать два десятка разных контекстов или как быть?

Код ф-ции с треугольниками:
function drawPath() {
	var canvas=document.getElementById("my-canvas");
	if (canvas.getContext) {
		context = canvas.getContext("2d");
		context.fillStyle = "rgba(255,0,0,1)";
		context.beginPath();
		context.moveTo(0,0);
		context.lineTo(200,0);
		context.lineTo(100,200);
		context.fill();
		context.fillStyle = "rgba(0,0,255,.3)";
		context.beginPath();
		context.moveTo(0,200);
		context.lineTo(200,200);
		context.lineTo(100,0);
		context.fill();
	}
}
Ответить с цитированием
  #4 (permalink)  
Старый 28.01.2013, 21:31
Аватар для Дзен-трансгуманист
√₋̅₁̅
Отправить личное сообщение для Дзен-трансгуманист Посмотреть профиль Найти все сообщения от Дзен-трансгуманист
 
Регистрация: 18.06.2012
Сообщений: 385

Сообщение от 9xakep
составь уравнение 3 прямых
Уравнения не нужны. Векторная алгебра рулит.

function isPointInTriangle ( x, y, x1, y1, x2, y2, x3, y3 ) {
  return (
    ( y-y1 ) * ( x2-x1 ) > ( x-x1 ) * ( y2-y1 ) &&
    ( y-y2 ) * ( x3-x2 ) > ( x-x2 ) * ( y3-y2 ) &&
    ( y-y3 ) * ( x1-x3 ) > ( x-x3 ) * ( y1-y3 ) );
}

Точки треугольника должны следовать по часовой стрелке.
__________________

Гейзенберг, возможно, читал этот тред.
Ответить с цитированием
  #5 (permalink)  
Старый 28.01.2013, 21:37
Интересующийся
Отправить личное сообщение для Moonlight Посмотреть профиль Найти все сообщения от Moonlight
 
Регистрация: 18.05.2011
Сообщений: 25

В общем для моей задачи не понадобится ни векторная алгебра ни построение уравнения 3 прямых, думаю мне подойдёт метод isPointInPath). Мне бы только ещё пояснения по моему предыдущему посту не помешали.
Ответить с цитированием
  #6 (permalink)  
Старый 28.01.2013, 21:40
Аватар для 9xakep
сегодня в 12:34|Комментир
Отправить личное сообщение для 9xakep Посмотреть профиль Найти все сообщения от 9xakep
 
Регистрация: 12.04.2011
Сообщений: 1,180

Дзен-трансгуманист,
вау, прикольно)

Moonlight,
даже не думай об этом, я сейчас воспользовался им, вообще какой-то левый метод, у меня тот же вопрос: если несколько фигур, и каждая в beginPath() новом? Да и вообще, он посреди фигуры показывает: false, лучше используй то, что Дзен-гуманист предложил
__________________
оляля, ололо
Ответить с цитированием
  #7 (permalink)  
Старый 28.01.2013, 21:46
Интересующийся
Отправить личное сообщение для Moonlight Посмотреть профиль Найти все сообщения от Moonlight
 
Регистрация: 18.05.2011
Сообщений: 25

Подождите, вопрос был в том как это делается обычно, неужели обычно это делается так как предложил Дзен-гуманист? К тому же про треугольники я сказал для примера. На самом деле это будут произвольные области с потенциально неограниченным количеством углов, которые админ будет сам вырисовывать в панели управления. И вот их и нужно будет окрашивать.
Ответить с цитированием
  #8 (permalink)  
Старый 28.01.2013, 22:00
Аватар для kobezzza
Быдлокодер;)
Отправить личное сообщение для kobezzza Посмотреть профиль Найти все сообщения от kobezzza
 
Регистрация: 19.11.2010
Сообщений: 4,338

Используй SVG, там события просто вешаются на DOM узлы
__________________
kobezzza
code monkey
Ответить с цитированием
  #9 (permalink)  
Старый 28.01.2013, 22:01
Аватар для Дзен-трансгуманист
√₋̅₁̅
Отправить личное сообщение для Дзен-трансгуманист Посмотреть профиль Найти все сообщения от Дзен-трансгуманист
 
Регистрация: 18.06.2012
Сообщений: 385

Ой, надо ж подкрепить свою функцию тестом.
<body style="padding: 0px; margin: 0px;">
<canvas id="canvas" width="300" height="300"></canvas>
<script>

var canvas = document.getElementById( 'canvas' );
var ctx = canvas.getContext( '2d' );

var triangle = [
  { x: 200, y:  50 },
  { x: 160, y: 240 },
  { x:  60, y: 100 }
];

function isPointInTriangle ( x, y, x1, y1, x2, y2, x3, y3 ) {
  return (
    ( y-y1 ) * ( x2-x1 ) > ( x-x1 ) * ( y2-y1 ) &&
    ( y-y2 ) * ( x3-x2 ) > ( x-x2 ) * ( y3-y2 ) &&
    ( y-y3 ) * ( x1-x3 ) > ( x-x3 ) * ( y1-y3 ) );
}

function renderTest ( mouseX, mouseY ) {

  ctx.clearRect( 0, 0, canvas.width, canvas.height );

  ctx.lineWidth = 2;
  ctx.fillStyle = isPointInTriangle( mouseX, mouseY,
    triangle[0].x, triangle[0].y,
    triangle[1].x, triangle[1].y,
    triangle[2].x, triangle[2].y ) ? 'red' : 'blue';

  ctx.beginPath();
  ctx.moveTo( triangle[0].x, triangle[0].y );
  ctx.lineTo( triangle[1].x, triangle[1].y );
  ctx.lineTo( triangle[2].x, triangle[2].y );
  ctx.fill();

  ctx.fillStyle = 'black';
  ctx.beginPath();
  ctx.moveTo( mouseX + 3, mouseY );
  ctx.arc( mouseX, mouseY, 3, 0, Math.PI*2, false );
  ctx.fill();
}

canvas.addEventListener( 'mousemove', function ( event ) {
  renderTest( event.pageX, event.pageY );
}, false );

renderTest( -100, -100 );

</script>
</body>
__________________

Гейзенберг, возможно, читал этот тред.

Последний раз редактировалось Дзен-трансгуманист, 29.01.2013 в 19:30.
Ответить с цитированием
  #10 (permalink)  
Старый 28.01.2013, 22:08
Аватар для Gozar
Отправить личное сообщение для Gozar Посмотреть профиль Найти все сообщения от Gozar
 
Регистрация: 07.06.2007
Сообщений: 7,504

http://en.wikipedia.org/wiki/Hit-testing

http://neimke.blogspot.ru/2011/03/de...d-on-html.html

бу!
__________________
Последний раз редактировалось Gozar, Сегодня в 24:14.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
HTML5 CANVAS slava878787 Оффтопик 20 23.06.2014 02:32
html5. Canvas Valdemor (X)HTML/CSS 2 25.08.2012 00:26
html5, Canvas, KineticJS, cvg, google chrome N3K Библиотеки/Тулкиты/Фреймворки 0 20.07.2012 12:43
Canvas html5 Иваннн Оффтопик 9 16.01.2012 00:41
html5 Canvas как кэш для изображений JAre Элементы интерфейса 6 20.07.2011 03:22