Use maphilight for permanent enlight an area and multiple clicks
I'm using maphilight js plugin to create an interactive image by which a user can select multiple areas, and each click an area should enlight and keep a specific color and a text-field will be filled.
While I created a routine both to enlight the areas and fill the text fields, I wasn't able to change and keep the color of the areas.
Here is my draft code:
(function($) {
var has_VML, has_canvas, create_canvas_for, add_shape_to, clear_canvas, shape_from_area,
canvas_style, hex_to_decimal, css3color, is_image_loaded, options_from_area;
has_canvas = !!document.createElement('canvas').getContext;
// VML: more complex
has_VML = (function() {
var a = document.createElement('div');
a.innerHTML = '<v:shape id="vml_flag1" adj="1" />';
var b = a.firstChild;
b.style.behavior = "url(#default#VML)";
return b ? typeof b.adj == "object": true;
})();
if(!(has_canvas || has_VML)) {
$.fn.maphilight = function() { return this; };
return;
}
if(has_canvas) {
hex_to_decimal = function(hex) {
return Math.max(0, Math.min(parseInt(hex, 16), 255));
};
css3color = function(color, opacity) {
return 'rgba('+hex_to_decimal(color.substr(0,2))+','+hex_to_decimal(color.substr(2,2))+','+hex_to_decimal(color.substr(4,2))+','+opacity+')';
};
create_canvas_for = function(img) {
var c = $('<canvas style="width:'+img.width+'px;height:'+img.height+'px;"></canvas>').get(0);
c.getContext("2d").clearRect(0, 0, c.width, c.height);
return c;
};
var draw_shape = function(context, shape, coords, x_shift, y_shift) {
x_shift = x_shift || 0;
y_shift = y_shift || 0;
context.beginPath();
if(shape == 'rect') {
// x, y, width, height
context.rect(coords[0] + x_shift, coords[1] + y_shift, coords[2] - coords[0], coords[3] - coords[1]);
} else if(shape == 'poly') {
context.moveTo(coords[0] + x_shift, coords[1] + y_shift);
for(i=2; i < coords.length; i+=2) {
context.lineTo(coords[i] + x_shift, coords[i+1] + y_shift);
}
} else if(shape == 'circ') {
// x, y, radius, startAngle, endAngle, anticlockwise
context.arc(coords[0] + x_shift, coords[1] + y_shift, coords[2], 0, Math.PI * 2, false);
}
context.closePath();
}
add_shape_to = function(canvas, shape, coords, options, name) {
var i, context = canvas.getContext('2d');
// Because I don't want to worry about setting things back to a base state
// Shadow has to happen first, since it's on the bottom, and it does some clip /
// fill operations which would interfere with what comes next.
if(options.shadow) {
context.save();
if(options.shadowPosition == "inside") {
// Cause the following stroke to only apply to the inside of the path
draw_shape(context, shape, coords);
context.clip();
}
// Redraw the shape shifted off the canvas massively so we can cast a shadow
// onto the canvas without having to worry about the stroke or fill (which
// cannot have 0 opacity or width, since they're what cast the shadow).
var x_shift = canvas.width * 100;
var y_shift = canvas.height * 100;
draw_shape(context, shape, coords, x_shift, y_shift);
context.shadowOffsetX = options.shadowX - x_shift;
context.shadowOffsetY = options.shadowY - y_shift;
context.shadowBlur = options.shadowRadius;
context.shadowColor = css3color(options.shadowColor, options.shadowOpacity);
// Now, work out where to cast the shadow from! It looks better if it's cast
// from a fill when it's an outside shadow or a stroke when it's an interior
// shadow. Allow the user to override this if they need to.
var shadowFrom = options.shadowFrom;
if (!shadowFrom) {
if (options.shadowPosition == 'outside') {
shadowFrom = 'fill';
} else {
shadowFrom = 'stroke';
}
}
if (shadowFrom == 'stroke') {
context.strokeStyle = "rgba(0,0,0,1)";
context.stroke();
} else if (shadowFrom == 'fill') {
context.fillStyle = "rgba(0,0,0,1)";
context.fill();
}
context.restore();
// and now we clean up
if(options.shadowPosition == "outside") {
context.save();
// Clear out the center
draw_shape(context, shape, coords);
context.globalCompositeOperation = "destination-out";
context.fillStyle = "rgba(0,0,0,1);";
context.fill();
context.restore();
}
}
context.save();
draw_shape(context, shape, coords);
// fill has to come after shadow, otherwise the shadow will be drawn over the fill,
// which mostly looks weird when the shadow has a high opacity
if(options.fill) {
context.fillStyle = css3color(options.fillColor, options.fillOpacity);
context.fill();
}
// Likewise, stroke has to come at the very end, or it'll wind up under bits of the
// shadow or the shadow-background if it's present.
if(options.stroke) {
context.strokeStyle = css3color(options.strokeColor, options.strokeOpacity);
context.lineWidth = options.strokeWidth;
context.stroke();
}
context.restore();
/*Fjodor [fix voor Chrome]:
if(options.fade) {
$(canvas).css('opacity', 0).animate({opacity: 1}, 100);
} fix:
https://github.com/kemayo/maphilight/issues/33
*/
if (options.fade && !window.skipAnimateOpacity) {
$(canvas).css('opacity', 0).animate({ opacity: 1 }, 100);
if ($(canvas).css('opacity') == 0)
{
$(canvas).css('opacity', 1);
window.skipAnimateOpacity = true;
}
}
};
clear_canvas = function(canvas) {
canvas.getContext('2d').clearRect(0, 0, canvas.width,canvas.height);
};
} else { // ie executes this code
create_canvas_for = function(img) {
return $('<var style="zoom:1;overflow:hidden;display:block;width:'+img.width+'px;height:'+img.height+'px;"></var>').get(0);
};
add_shape_to = function(canvas, shape, coords, options, name) {
var fill, stroke, opacity, e;
for (var i in coords) { coords[i] = parseInt(coords[i], 10); }
fill = '<v:fill color="#'+options.fillColor+'" opacity="'+(options.fill ? options.fillOpacity : 0)+'" />';
stroke = (options.stroke ? 'strokeweight="'+options.strokeWidth+'" stroked="t" strokecolor="#'+options.strokeColor+'"' : 'stroked="f"');
opacity = '<v:stroke opacity="'+options.strokeOpacity+'"/>';
if(shape == 'rect') {
e = $('<v:rect name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+coords[0]+'px;top:'+coords[1]+'px;width:'+(coords[2] - coords[0])+'px;height:'+(coords[3] - coords[1])+'px;"></v:rect>');
} else if(shape == 'poly') {
e = $('<v:shape name="'+name+'" filled="t" '+stroke+' coordorigin="0,0" coordsize="'+canvas.width+','+canvas.height+'" path="m '+coords[0]+','+coords[1]+' l '+coords.join(',')+' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:'+canvas.width+'px;height:'+canvas.height+'px;"></v:shape>');
} else if(shape == 'circ') {
e = $('<v:oval name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+(coords[0] - coords[2])+'px;top:'+(coords[1] - coords[2])+'px;width:'+(coords[2]*2)+'px;height:'+(coords[2]*2)+'px;"></v:oval>');
}
e.get(0).innerHTML = fill+opacity;
$(canvas).append(e);
};
clear_canvas = function(canvas) {
// jquery1.8 + ie7
var $html = $("<div>" + canvas.innerHTML + "</div>");
$html.children('[name=highlighted]').remove();
canvas.innerHTML = $html.html();
};
}
shape_from_area = function(area) {
var i, coords = area.getAttribute('coords').split(',');
for (i=0; i < coords.length; i++) { coords[i] = parseFloat(coords[i]); }
return [area.getAttribute('shape').toLowerCase().substr(0,4), coords];
};
options_from_area = function(area, options) {
var $area = $(area);
return $.extend({}, options, $.metadata ? $area.metadata() : false, $area.data('maphilight'));
};
is_image_loaded = function(img) {
if(!img.complete) { return false; } // IE
if(typeof img.naturalWidth != "undefined" && img.naturalWidth === 0) { return false; } // Others
return true;
};
canvas_style = {
position: 'absolute',
left: 0,
top: 0,
padding: 0,
border: 0
};
var ie_hax_done = false;
$.fn.maphilight = function(opts) {
opts = $.extend({}, $.fn.maphilight.defaults, opts);
if(!has_canvas && !ie_hax_done) {
$(window).ready(function() {
document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
var style = document.createStyleSheet();
var shapes = ['shape','rect', 'oval', 'circ', 'fill', 'stroke', 'imagedata', 'group','textbox'];
$.each(shapes,
function() {
style.addRule('v\:' + this, "behavior: url(#default#VML); antialias:true");
}
);
});
ie_hax_done = true;
}
return this.each(function() {
var img, wrap, options, map, canvas, canvas_always, mouseover, highlighted_shape, usemap;
img = $(this);
if(!is_image_loaded(this)) {
// If the image isn't fully loaded, this won't work right. Try again later.
return window.setTimeout(function() {
img.maphilight(opts);
}, 200);
}
options = $.extend({}, opts, $.metadata ? img.metadata() : false, img.data('maphilight'));
// jQuery bug with Opera, results in full-url#usemap being returned from jQuery's attr.
// So use raw getAttribute instead.
usemap = img.get(0).getAttribute('usemap');
if (!usemap) {
return
}
map = $('map[name="'+usemap.substr(1)+'"]');
if(!(img.is('img,input[type="image"]') && usemap && map.size() > 0)) {
return;
}
if(img.hasClass('maphilighted')) {
// We're redrawing an old map, probably to pick up changes to the options.
// Just clear out all the old stuff.
var wrapper = img.parent();
img.insertBefore(wrapper);
wrapper.remove();
$(map).unbind('.maphilight').find('area[coords]').unbind('.maphilight');
}
wrap = $('<div></div>').css({
display:'block',
background:'url("'+this.src+'")',
position:'relative',
padding:0,
width:this.width,
height:this.height
});
if(options.wrapClass) {
if(options.wrapClass === true) {
wrap.addClass($(this).attr('class'));
} else {
wrap.addClass(options.wrapClass);
}
}
img.before(wrap).css('opacity', 0).css(canvas_style).remove();
if(has_VML) { img.css('filter', 'Alpha(opacity=0)'); }
wrap.append(img);
canvas = create_canvas_for(this);
$(canvas).css(canvas_style);
canvas.height = this.height;
canvas.width = this.width;
mouseover = function(e) {
var shape, area_options;
area_options = options_from_area(this, options);
if(
!area_options.neverOn
&&
!area_options.alwaysOn
) {
shape = shape_from_area(this);
add_shape_to(canvas, shape[0], shape[1], area_options, "highlighted");
if(area_options.groupBy) {
var areas;
// two ways groupBy might work; attribute and selector
if(/^[a-zA-Z][-a-zA-Z]+$/.test(area_options.groupBy)) {
areas = map.find('area['+area_options.groupBy+'="'+$(this).attr(area_options.groupBy)+'"]');
} else {
areas = map.find(area_options.groupBy);
}
var first = this;
areas.each(function() {
if(this != first) {
var subarea_options = options_from_area(this, options);
if(!subarea_options.neverOn && !subarea_options.alwaysOn) {
var shape = shape_from_area(this);
add_shape_to(canvas, shape[0], shape[1], subarea_options, "highlighted");
}
}
});
}
// workaround for IE7, IE8 not rendering the final rectangle in a group
if(!has_canvas) {
$(canvas).append('<v:rect></v:rect>');
}
}
}
$(map).bind('alwaysOn.maphilight', function() {
// Check for areas with alwaysOn set. These are added to a *second* canvas,
// which will get around flickering during fading.
if(canvas_always) {
clear_canvas(canvas_always);
}
if(!has_canvas) {
$(canvas).empty();
}
$(map).find('area[coords]').each(function() {
var shape, area_options;
area_options = options_from_area(this, options);
if(area_options.alwaysOn) {
if(!canvas_always && has_canvas) {
canvas_always = create_canvas_for(img[0]);
$(canvas_always).css(canvas_style);
canvas_always.width = img[0].width;
canvas_always.height = img[0].height;
img.before(canvas_always);
}
area_options.fade = area_options.alwaysOnFade; // alwaysOn shouldn't fade in initially
shape = shape_from_area(this);
if (has_canvas) {
add_shape_to(canvas_always, shape[0], shape[1], area_options, "");
} else {
add_shape_to(canvas, shape[0], shape[1], area_options, "");
}
}
});
});
$(map).trigger('alwaysOn.maphilight').find('area[coords]')
.bind('mouseover.maphilight', mouseover)
.bind('mouseout.maphilight', function(e) { clear_canvas(canvas); });
img.before(canvas); // if we put this after, the mouseover events wouldn't fire.
img.addClass('maphilighted');
});
};
$.fn.maphilight.defaults = {
fill: true,
fillColor: 'ffffff',
fillOpacity: 0.2,
stroke: true,
strokeColor: 'ff0000',
strokeOpacity: 1,
strokeWidth: 1,
fade: true,
alwaysOn: false,
neverOn: false,
groupBy: false,
wrapClass: true,
// plenty of shadow:
shadow: false,
shadowX: 0,
shadowY: 0,
shadowRadius: 6,
shadowColor: '000000',
shadowOpacity: 0.8,
shadowPosition: 'outside',
shadowFrom: false
};
$.fn.maphilight.defaults.prova = {
fill: true,
fillColor: '00ff00',
};
})(jQuery);
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Documento senza titolo</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<!-- Add maphilight plugin -->
<script type="text/javascript" src="js/jquery.maphilight.js"></script>
<!-- Activate maphilight plugin -->
<script type="text/javascript">$(function() {
$('.map').maphilight();
});
</script>
</head>
<body>
<p><img src="https://www.dike.lib.ia.us/images/sample-1.jpg" usemap="#Map" class="map" /></p>
<p>
<map name="Map">
<area shape="circle" coords="247,160,42" href="#" alt="test" id="test">
<area shape="circle" coords="152,186,35" href="#" alt="test2" id="test2">
</map>
</p>
<p><input type="text" id="count" value="1"></p>
<p><input type="text" id="count2" value="1"></p>
<script>
var count = 0
$("#test").click(function() {
count++;
if(count == 1) {
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('2');
}else if(count == 2){
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('3');
}else if(count == 3){
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('4');
count = 0;
}
})
var count = 0
$("#test2").click(function() {
count++;
if(count == 1) {
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('a');
}else if(count == 2){
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('s');
}else if(count == 3){
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('d');
count = 0;
}
})
</script>
</body>
</html>
javascript dictionary maphilight
add a comment |
I'm using maphilight js plugin to create an interactive image by which a user can select multiple areas, and each click an area should enlight and keep a specific color and a text-field will be filled.
While I created a routine both to enlight the areas and fill the text fields, I wasn't able to change and keep the color of the areas.
Here is my draft code:
(function($) {
var has_VML, has_canvas, create_canvas_for, add_shape_to, clear_canvas, shape_from_area,
canvas_style, hex_to_decimal, css3color, is_image_loaded, options_from_area;
has_canvas = !!document.createElement('canvas').getContext;
// VML: more complex
has_VML = (function() {
var a = document.createElement('div');
a.innerHTML = '<v:shape id="vml_flag1" adj="1" />';
var b = a.firstChild;
b.style.behavior = "url(#default#VML)";
return b ? typeof b.adj == "object": true;
})();
if(!(has_canvas || has_VML)) {
$.fn.maphilight = function() { return this; };
return;
}
if(has_canvas) {
hex_to_decimal = function(hex) {
return Math.max(0, Math.min(parseInt(hex, 16), 255));
};
css3color = function(color, opacity) {
return 'rgba('+hex_to_decimal(color.substr(0,2))+','+hex_to_decimal(color.substr(2,2))+','+hex_to_decimal(color.substr(4,2))+','+opacity+')';
};
create_canvas_for = function(img) {
var c = $('<canvas style="width:'+img.width+'px;height:'+img.height+'px;"></canvas>').get(0);
c.getContext("2d").clearRect(0, 0, c.width, c.height);
return c;
};
var draw_shape = function(context, shape, coords, x_shift, y_shift) {
x_shift = x_shift || 0;
y_shift = y_shift || 0;
context.beginPath();
if(shape == 'rect') {
// x, y, width, height
context.rect(coords[0] + x_shift, coords[1] + y_shift, coords[2] - coords[0], coords[3] - coords[1]);
} else if(shape == 'poly') {
context.moveTo(coords[0] + x_shift, coords[1] + y_shift);
for(i=2; i < coords.length; i+=2) {
context.lineTo(coords[i] + x_shift, coords[i+1] + y_shift);
}
} else if(shape == 'circ') {
// x, y, radius, startAngle, endAngle, anticlockwise
context.arc(coords[0] + x_shift, coords[1] + y_shift, coords[2], 0, Math.PI * 2, false);
}
context.closePath();
}
add_shape_to = function(canvas, shape, coords, options, name) {
var i, context = canvas.getContext('2d');
// Because I don't want to worry about setting things back to a base state
// Shadow has to happen first, since it's on the bottom, and it does some clip /
// fill operations which would interfere with what comes next.
if(options.shadow) {
context.save();
if(options.shadowPosition == "inside") {
// Cause the following stroke to only apply to the inside of the path
draw_shape(context, shape, coords);
context.clip();
}
// Redraw the shape shifted off the canvas massively so we can cast a shadow
// onto the canvas without having to worry about the stroke or fill (which
// cannot have 0 opacity or width, since they're what cast the shadow).
var x_shift = canvas.width * 100;
var y_shift = canvas.height * 100;
draw_shape(context, shape, coords, x_shift, y_shift);
context.shadowOffsetX = options.shadowX - x_shift;
context.shadowOffsetY = options.shadowY - y_shift;
context.shadowBlur = options.shadowRadius;
context.shadowColor = css3color(options.shadowColor, options.shadowOpacity);
// Now, work out where to cast the shadow from! It looks better if it's cast
// from a fill when it's an outside shadow or a stroke when it's an interior
// shadow. Allow the user to override this if they need to.
var shadowFrom = options.shadowFrom;
if (!shadowFrom) {
if (options.shadowPosition == 'outside') {
shadowFrom = 'fill';
} else {
shadowFrom = 'stroke';
}
}
if (shadowFrom == 'stroke') {
context.strokeStyle = "rgba(0,0,0,1)";
context.stroke();
} else if (shadowFrom == 'fill') {
context.fillStyle = "rgba(0,0,0,1)";
context.fill();
}
context.restore();
// and now we clean up
if(options.shadowPosition == "outside") {
context.save();
// Clear out the center
draw_shape(context, shape, coords);
context.globalCompositeOperation = "destination-out";
context.fillStyle = "rgba(0,0,0,1);";
context.fill();
context.restore();
}
}
context.save();
draw_shape(context, shape, coords);
// fill has to come after shadow, otherwise the shadow will be drawn over the fill,
// which mostly looks weird when the shadow has a high opacity
if(options.fill) {
context.fillStyle = css3color(options.fillColor, options.fillOpacity);
context.fill();
}
// Likewise, stroke has to come at the very end, or it'll wind up under bits of the
// shadow or the shadow-background if it's present.
if(options.stroke) {
context.strokeStyle = css3color(options.strokeColor, options.strokeOpacity);
context.lineWidth = options.strokeWidth;
context.stroke();
}
context.restore();
/*Fjodor [fix voor Chrome]:
if(options.fade) {
$(canvas).css('opacity', 0).animate({opacity: 1}, 100);
} fix:
https://github.com/kemayo/maphilight/issues/33
*/
if (options.fade && !window.skipAnimateOpacity) {
$(canvas).css('opacity', 0).animate({ opacity: 1 }, 100);
if ($(canvas).css('opacity') == 0)
{
$(canvas).css('opacity', 1);
window.skipAnimateOpacity = true;
}
}
};
clear_canvas = function(canvas) {
canvas.getContext('2d').clearRect(0, 0, canvas.width,canvas.height);
};
} else { // ie executes this code
create_canvas_for = function(img) {
return $('<var style="zoom:1;overflow:hidden;display:block;width:'+img.width+'px;height:'+img.height+'px;"></var>').get(0);
};
add_shape_to = function(canvas, shape, coords, options, name) {
var fill, stroke, opacity, e;
for (var i in coords) { coords[i] = parseInt(coords[i], 10); }
fill = '<v:fill color="#'+options.fillColor+'" opacity="'+(options.fill ? options.fillOpacity : 0)+'" />';
stroke = (options.stroke ? 'strokeweight="'+options.strokeWidth+'" stroked="t" strokecolor="#'+options.strokeColor+'"' : 'stroked="f"');
opacity = '<v:stroke opacity="'+options.strokeOpacity+'"/>';
if(shape == 'rect') {
e = $('<v:rect name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+coords[0]+'px;top:'+coords[1]+'px;width:'+(coords[2] - coords[0])+'px;height:'+(coords[3] - coords[1])+'px;"></v:rect>');
} else if(shape == 'poly') {
e = $('<v:shape name="'+name+'" filled="t" '+stroke+' coordorigin="0,0" coordsize="'+canvas.width+','+canvas.height+'" path="m '+coords[0]+','+coords[1]+' l '+coords.join(',')+' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:'+canvas.width+'px;height:'+canvas.height+'px;"></v:shape>');
} else if(shape == 'circ') {
e = $('<v:oval name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+(coords[0] - coords[2])+'px;top:'+(coords[1] - coords[2])+'px;width:'+(coords[2]*2)+'px;height:'+(coords[2]*2)+'px;"></v:oval>');
}
e.get(0).innerHTML = fill+opacity;
$(canvas).append(e);
};
clear_canvas = function(canvas) {
// jquery1.8 + ie7
var $html = $("<div>" + canvas.innerHTML + "</div>");
$html.children('[name=highlighted]').remove();
canvas.innerHTML = $html.html();
};
}
shape_from_area = function(area) {
var i, coords = area.getAttribute('coords').split(',');
for (i=0; i < coords.length; i++) { coords[i] = parseFloat(coords[i]); }
return [area.getAttribute('shape').toLowerCase().substr(0,4), coords];
};
options_from_area = function(area, options) {
var $area = $(area);
return $.extend({}, options, $.metadata ? $area.metadata() : false, $area.data('maphilight'));
};
is_image_loaded = function(img) {
if(!img.complete) { return false; } // IE
if(typeof img.naturalWidth != "undefined" && img.naturalWidth === 0) { return false; } // Others
return true;
};
canvas_style = {
position: 'absolute',
left: 0,
top: 0,
padding: 0,
border: 0
};
var ie_hax_done = false;
$.fn.maphilight = function(opts) {
opts = $.extend({}, $.fn.maphilight.defaults, opts);
if(!has_canvas && !ie_hax_done) {
$(window).ready(function() {
document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
var style = document.createStyleSheet();
var shapes = ['shape','rect', 'oval', 'circ', 'fill', 'stroke', 'imagedata', 'group','textbox'];
$.each(shapes,
function() {
style.addRule('v\:' + this, "behavior: url(#default#VML); antialias:true");
}
);
});
ie_hax_done = true;
}
return this.each(function() {
var img, wrap, options, map, canvas, canvas_always, mouseover, highlighted_shape, usemap;
img = $(this);
if(!is_image_loaded(this)) {
// If the image isn't fully loaded, this won't work right. Try again later.
return window.setTimeout(function() {
img.maphilight(opts);
}, 200);
}
options = $.extend({}, opts, $.metadata ? img.metadata() : false, img.data('maphilight'));
// jQuery bug with Opera, results in full-url#usemap being returned from jQuery's attr.
// So use raw getAttribute instead.
usemap = img.get(0).getAttribute('usemap');
if (!usemap) {
return
}
map = $('map[name="'+usemap.substr(1)+'"]');
if(!(img.is('img,input[type="image"]') && usemap && map.size() > 0)) {
return;
}
if(img.hasClass('maphilighted')) {
// We're redrawing an old map, probably to pick up changes to the options.
// Just clear out all the old stuff.
var wrapper = img.parent();
img.insertBefore(wrapper);
wrapper.remove();
$(map).unbind('.maphilight').find('area[coords]').unbind('.maphilight');
}
wrap = $('<div></div>').css({
display:'block',
background:'url("'+this.src+'")',
position:'relative',
padding:0,
width:this.width,
height:this.height
});
if(options.wrapClass) {
if(options.wrapClass === true) {
wrap.addClass($(this).attr('class'));
} else {
wrap.addClass(options.wrapClass);
}
}
img.before(wrap).css('opacity', 0).css(canvas_style).remove();
if(has_VML) { img.css('filter', 'Alpha(opacity=0)'); }
wrap.append(img);
canvas = create_canvas_for(this);
$(canvas).css(canvas_style);
canvas.height = this.height;
canvas.width = this.width;
mouseover = function(e) {
var shape, area_options;
area_options = options_from_area(this, options);
if(
!area_options.neverOn
&&
!area_options.alwaysOn
) {
shape = shape_from_area(this);
add_shape_to(canvas, shape[0], shape[1], area_options, "highlighted");
if(area_options.groupBy) {
var areas;
// two ways groupBy might work; attribute and selector
if(/^[a-zA-Z][-a-zA-Z]+$/.test(area_options.groupBy)) {
areas = map.find('area['+area_options.groupBy+'="'+$(this).attr(area_options.groupBy)+'"]');
} else {
areas = map.find(area_options.groupBy);
}
var first = this;
areas.each(function() {
if(this != first) {
var subarea_options = options_from_area(this, options);
if(!subarea_options.neverOn && !subarea_options.alwaysOn) {
var shape = shape_from_area(this);
add_shape_to(canvas, shape[0], shape[1], subarea_options, "highlighted");
}
}
});
}
// workaround for IE7, IE8 not rendering the final rectangle in a group
if(!has_canvas) {
$(canvas).append('<v:rect></v:rect>');
}
}
}
$(map).bind('alwaysOn.maphilight', function() {
// Check for areas with alwaysOn set. These are added to a *second* canvas,
// which will get around flickering during fading.
if(canvas_always) {
clear_canvas(canvas_always);
}
if(!has_canvas) {
$(canvas).empty();
}
$(map).find('area[coords]').each(function() {
var shape, area_options;
area_options = options_from_area(this, options);
if(area_options.alwaysOn) {
if(!canvas_always && has_canvas) {
canvas_always = create_canvas_for(img[0]);
$(canvas_always).css(canvas_style);
canvas_always.width = img[0].width;
canvas_always.height = img[0].height;
img.before(canvas_always);
}
area_options.fade = area_options.alwaysOnFade; // alwaysOn shouldn't fade in initially
shape = shape_from_area(this);
if (has_canvas) {
add_shape_to(canvas_always, shape[0], shape[1], area_options, "");
} else {
add_shape_to(canvas, shape[0], shape[1], area_options, "");
}
}
});
});
$(map).trigger('alwaysOn.maphilight').find('area[coords]')
.bind('mouseover.maphilight', mouseover)
.bind('mouseout.maphilight', function(e) { clear_canvas(canvas); });
img.before(canvas); // if we put this after, the mouseover events wouldn't fire.
img.addClass('maphilighted');
});
};
$.fn.maphilight.defaults = {
fill: true,
fillColor: 'ffffff',
fillOpacity: 0.2,
stroke: true,
strokeColor: 'ff0000',
strokeOpacity: 1,
strokeWidth: 1,
fade: true,
alwaysOn: false,
neverOn: false,
groupBy: false,
wrapClass: true,
// plenty of shadow:
shadow: false,
shadowX: 0,
shadowY: 0,
shadowRadius: 6,
shadowColor: '000000',
shadowOpacity: 0.8,
shadowPosition: 'outside',
shadowFrom: false
};
$.fn.maphilight.defaults.prova = {
fill: true,
fillColor: '00ff00',
};
})(jQuery);
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Documento senza titolo</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<!-- Add maphilight plugin -->
<script type="text/javascript" src="js/jquery.maphilight.js"></script>
<!-- Activate maphilight plugin -->
<script type="text/javascript">$(function() {
$('.map').maphilight();
});
</script>
</head>
<body>
<p><img src="https://www.dike.lib.ia.us/images/sample-1.jpg" usemap="#Map" class="map" /></p>
<p>
<map name="Map">
<area shape="circle" coords="247,160,42" href="#" alt="test" id="test">
<area shape="circle" coords="152,186,35" href="#" alt="test2" id="test2">
</map>
</p>
<p><input type="text" id="count" value="1"></p>
<p><input type="text" id="count2" value="1"></p>
<script>
var count = 0
$("#test").click(function() {
count++;
if(count == 1) {
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('2');
}else if(count == 2){
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('3');
}else if(count == 3){
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('4');
count = 0;
}
})
var count = 0
$("#test2").click(function() {
count++;
if(count == 1) {
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('a');
}else if(count == 2){
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('s');
}else if(count == 3){
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('d');
count = 0;
}
})
</script>
</body>
</html>
javascript dictionary maphilight
add a comment |
I'm using maphilight js plugin to create an interactive image by which a user can select multiple areas, and each click an area should enlight and keep a specific color and a text-field will be filled.
While I created a routine both to enlight the areas and fill the text fields, I wasn't able to change and keep the color of the areas.
Here is my draft code:
(function($) {
var has_VML, has_canvas, create_canvas_for, add_shape_to, clear_canvas, shape_from_area,
canvas_style, hex_to_decimal, css3color, is_image_loaded, options_from_area;
has_canvas = !!document.createElement('canvas').getContext;
// VML: more complex
has_VML = (function() {
var a = document.createElement('div');
a.innerHTML = '<v:shape id="vml_flag1" adj="1" />';
var b = a.firstChild;
b.style.behavior = "url(#default#VML)";
return b ? typeof b.adj == "object": true;
})();
if(!(has_canvas || has_VML)) {
$.fn.maphilight = function() { return this; };
return;
}
if(has_canvas) {
hex_to_decimal = function(hex) {
return Math.max(0, Math.min(parseInt(hex, 16), 255));
};
css3color = function(color, opacity) {
return 'rgba('+hex_to_decimal(color.substr(0,2))+','+hex_to_decimal(color.substr(2,2))+','+hex_to_decimal(color.substr(4,2))+','+opacity+')';
};
create_canvas_for = function(img) {
var c = $('<canvas style="width:'+img.width+'px;height:'+img.height+'px;"></canvas>').get(0);
c.getContext("2d").clearRect(0, 0, c.width, c.height);
return c;
};
var draw_shape = function(context, shape, coords, x_shift, y_shift) {
x_shift = x_shift || 0;
y_shift = y_shift || 0;
context.beginPath();
if(shape == 'rect') {
// x, y, width, height
context.rect(coords[0] + x_shift, coords[1] + y_shift, coords[2] - coords[0], coords[3] - coords[1]);
} else if(shape == 'poly') {
context.moveTo(coords[0] + x_shift, coords[1] + y_shift);
for(i=2; i < coords.length; i+=2) {
context.lineTo(coords[i] + x_shift, coords[i+1] + y_shift);
}
} else if(shape == 'circ') {
// x, y, radius, startAngle, endAngle, anticlockwise
context.arc(coords[0] + x_shift, coords[1] + y_shift, coords[2], 0, Math.PI * 2, false);
}
context.closePath();
}
add_shape_to = function(canvas, shape, coords, options, name) {
var i, context = canvas.getContext('2d');
// Because I don't want to worry about setting things back to a base state
// Shadow has to happen first, since it's on the bottom, and it does some clip /
// fill operations which would interfere with what comes next.
if(options.shadow) {
context.save();
if(options.shadowPosition == "inside") {
// Cause the following stroke to only apply to the inside of the path
draw_shape(context, shape, coords);
context.clip();
}
// Redraw the shape shifted off the canvas massively so we can cast a shadow
// onto the canvas without having to worry about the stroke or fill (which
// cannot have 0 opacity or width, since they're what cast the shadow).
var x_shift = canvas.width * 100;
var y_shift = canvas.height * 100;
draw_shape(context, shape, coords, x_shift, y_shift);
context.shadowOffsetX = options.shadowX - x_shift;
context.shadowOffsetY = options.shadowY - y_shift;
context.shadowBlur = options.shadowRadius;
context.shadowColor = css3color(options.shadowColor, options.shadowOpacity);
// Now, work out where to cast the shadow from! It looks better if it's cast
// from a fill when it's an outside shadow or a stroke when it's an interior
// shadow. Allow the user to override this if they need to.
var shadowFrom = options.shadowFrom;
if (!shadowFrom) {
if (options.shadowPosition == 'outside') {
shadowFrom = 'fill';
} else {
shadowFrom = 'stroke';
}
}
if (shadowFrom == 'stroke') {
context.strokeStyle = "rgba(0,0,0,1)";
context.stroke();
} else if (shadowFrom == 'fill') {
context.fillStyle = "rgba(0,0,0,1)";
context.fill();
}
context.restore();
// and now we clean up
if(options.shadowPosition == "outside") {
context.save();
// Clear out the center
draw_shape(context, shape, coords);
context.globalCompositeOperation = "destination-out";
context.fillStyle = "rgba(0,0,0,1);";
context.fill();
context.restore();
}
}
context.save();
draw_shape(context, shape, coords);
// fill has to come after shadow, otherwise the shadow will be drawn over the fill,
// which mostly looks weird when the shadow has a high opacity
if(options.fill) {
context.fillStyle = css3color(options.fillColor, options.fillOpacity);
context.fill();
}
// Likewise, stroke has to come at the very end, or it'll wind up under bits of the
// shadow or the shadow-background if it's present.
if(options.stroke) {
context.strokeStyle = css3color(options.strokeColor, options.strokeOpacity);
context.lineWidth = options.strokeWidth;
context.stroke();
}
context.restore();
/*Fjodor [fix voor Chrome]:
if(options.fade) {
$(canvas).css('opacity', 0).animate({opacity: 1}, 100);
} fix:
https://github.com/kemayo/maphilight/issues/33
*/
if (options.fade && !window.skipAnimateOpacity) {
$(canvas).css('opacity', 0).animate({ opacity: 1 }, 100);
if ($(canvas).css('opacity') == 0)
{
$(canvas).css('opacity', 1);
window.skipAnimateOpacity = true;
}
}
};
clear_canvas = function(canvas) {
canvas.getContext('2d').clearRect(0, 0, canvas.width,canvas.height);
};
} else { // ie executes this code
create_canvas_for = function(img) {
return $('<var style="zoom:1;overflow:hidden;display:block;width:'+img.width+'px;height:'+img.height+'px;"></var>').get(0);
};
add_shape_to = function(canvas, shape, coords, options, name) {
var fill, stroke, opacity, e;
for (var i in coords) { coords[i] = parseInt(coords[i], 10); }
fill = '<v:fill color="#'+options.fillColor+'" opacity="'+(options.fill ? options.fillOpacity : 0)+'" />';
stroke = (options.stroke ? 'strokeweight="'+options.strokeWidth+'" stroked="t" strokecolor="#'+options.strokeColor+'"' : 'stroked="f"');
opacity = '<v:stroke opacity="'+options.strokeOpacity+'"/>';
if(shape == 'rect') {
e = $('<v:rect name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+coords[0]+'px;top:'+coords[1]+'px;width:'+(coords[2] - coords[0])+'px;height:'+(coords[3] - coords[1])+'px;"></v:rect>');
} else if(shape == 'poly') {
e = $('<v:shape name="'+name+'" filled="t" '+stroke+' coordorigin="0,0" coordsize="'+canvas.width+','+canvas.height+'" path="m '+coords[0]+','+coords[1]+' l '+coords.join(',')+' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:'+canvas.width+'px;height:'+canvas.height+'px;"></v:shape>');
} else if(shape == 'circ') {
e = $('<v:oval name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+(coords[0] - coords[2])+'px;top:'+(coords[1] - coords[2])+'px;width:'+(coords[2]*2)+'px;height:'+(coords[2]*2)+'px;"></v:oval>');
}
e.get(0).innerHTML = fill+opacity;
$(canvas).append(e);
};
clear_canvas = function(canvas) {
// jquery1.8 + ie7
var $html = $("<div>" + canvas.innerHTML + "</div>");
$html.children('[name=highlighted]').remove();
canvas.innerHTML = $html.html();
};
}
shape_from_area = function(area) {
var i, coords = area.getAttribute('coords').split(',');
for (i=0; i < coords.length; i++) { coords[i] = parseFloat(coords[i]); }
return [area.getAttribute('shape').toLowerCase().substr(0,4), coords];
};
options_from_area = function(area, options) {
var $area = $(area);
return $.extend({}, options, $.metadata ? $area.metadata() : false, $area.data('maphilight'));
};
is_image_loaded = function(img) {
if(!img.complete) { return false; } // IE
if(typeof img.naturalWidth != "undefined" && img.naturalWidth === 0) { return false; } // Others
return true;
};
canvas_style = {
position: 'absolute',
left: 0,
top: 0,
padding: 0,
border: 0
};
var ie_hax_done = false;
$.fn.maphilight = function(opts) {
opts = $.extend({}, $.fn.maphilight.defaults, opts);
if(!has_canvas && !ie_hax_done) {
$(window).ready(function() {
document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
var style = document.createStyleSheet();
var shapes = ['shape','rect', 'oval', 'circ', 'fill', 'stroke', 'imagedata', 'group','textbox'];
$.each(shapes,
function() {
style.addRule('v\:' + this, "behavior: url(#default#VML); antialias:true");
}
);
});
ie_hax_done = true;
}
return this.each(function() {
var img, wrap, options, map, canvas, canvas_always, mouseover, highlighted_shape, usemap;
img = $(this);
if(!is_image_loaded(this)) {
// If the image isn't fully loaded, this won't work right. Try again later.
return window.setTimeout(function() {
img.maphilight(opts);
}, 200);
}
options = $.extend({}, opts, $.metadata ? img.metadata() : false, img.data('maphilight'));
// jQuery bug with Opera, results in full-url#usemap being returned from jQuery's attr.
// So use raw getAttribute instead.
usemap = img.get(0).getAttribute('usemap');
if (!usemap) {
return
}
map = $('map[name="'+usemap.substr(1)+'"]');
if(!(img.is('img,input[type="image"]') && usemap && map.size() > 0)) {
return;
}
if(img.hasClass('maphilighted')) {
// We're redrawing an old map, probably to pick up changes to the options.
// Just clear out all the old stuff.
var wrapper = img.parent();
img.insertBefore(wrapper);
wrapper.remove();
$(map).unbind('.maphilight').find('area[coords]').unbind('.maphilight');
}
wrap = $('<div></div>').css({
display:'block',
background:'url("'+this.src+'")',
position:'relative',
padding:0,
width:this.width,
height:this.height
});
if(options.wrapClass) {
if(options.wrapClass === true) {
wrap.addClass($(this).attr('class'));
} else {
wrap.addClass(options.wrapClass);
}
}
img.before(wrap).css('opacity', 0).css(canvas_style).remove();
if(has_VML) { img.css('filter', 'Alpha(opacity=0)'); }
wrap.append(img);
canvas = create_canvas_for(this);
$(canvas).css(canvas_style);
canvas.height = this.height;
canvas.width = this.width;
mouseover = function(e) {
var shape, area_options;
area_options = options_from_area(this, options);
if(
!area_options.neverOn
&&
!area_options.alwaysOn
) {
shape = shape_from_area(this);
add_shape_to(canvas, shape[0], shape[1], area_options, "highlighted");
if(area_options.groupBy) {
var areas;
// two ways groupBy might work; attribute and selector
if(/^[a-zA-Z][-a-zA-Z]+$/.test(area_options.groupBy)) {
areas = map.find('area['+area_options.groupBy+'="'+$(this).attr(area_options.groupBy)+'"]');
} else {
areas = map.find(area_options.groupBy);
}
var first = this;
areas.each(function() {
if(this != first) {
var subarea_options = options_from_area(this, options);
if(!subarea_options.neverOn && !subarea_options.alwaysOn) {
var shape = shape_from_area(this);
add_shape_to(canvas, shape[0], shape[1], subarea_options, "highlighted");
}
}
});
}
// workaround for IE7, IE8 not rendering the final rectangle in a group
if(!has_canvas) {
$(canvas).append('<v:rect></v:rect>');
}
}
}
$(map).bind('alwaysOn.maphilight', function() {
// Check for areas with alwaysOn set. These are added to a *second* canvas,
// which will get around flickering during fading.
if(canvas_always) {
clear_canvas(canvas_always);
}
if(!has_canvas) {
$(canvas).empty();
}
$(map).find('area[coords]').each(function() {
var shape, area_options;
area_options = options_from_area(this, options);
if(area_options.alwaysOn) {
if(!canvas_always && has_canvas) {
canvas_always = create_canvas_for(img[0]);
$(canvas_always).css(canvas_style);
canvas_always.width = img[0].width;
canvas_always.height = img[0].height;
img.before(canvas_always);
}
area_options.fade = area_options.alwaysOnFade; // alwaysOn shouldn't fade in initially
shape = shape_from_area(this);
if (has_canvas) {
add_shape_to(canvas_always, shape[0], shape[1], area_options, "");
} else {
add_shape_to(canvas, shape[0], shape[1], area_options, "");
}
}
});
});
$(map).trigger('alwaysOn.maphilight').find('area[coords]')
.bind('mouseover.maphilight', mouseover)
.bind('mouseout.maphilight', function(e) { clear_canvas(canvas); });
img.before(canvas); // if we put this after, the mouseover events wouldn't fire.
img.addClass('maphilighted');
});
};
$.fn.maphilight.defaults = {
fill: true,
fillColor: 'ffffff',
fillOpacity: 0.2,
stroke: true,
strokeColor: 'ff0000',
strokeOpacity: 1,
strokeWidth: 1,
fade: true,
alwaysOn: false,
neverOn: false,
groupBy: false,
wrapClass: true,
// plenty of shadow:
shadow: false,
shadowX: 0,
shadowY: 0,
shadowRadius: 6,
shadowColor: '000000',
shadowOpacity: 0.8,
shadowPosition: 'outside',
shadowFrom: false
};
$.fn.maphilight.defaults.prova = {
fill: true,
fillColor: '00ff00',
};
})(jQuery);
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Documento senza titolo</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<!-- Add maphilight plugin -->
<script type="text/javascript" src="js/jquery.maphilight.js"></script>
<!-- Activate maphilight plugin -->
<script type="text/javascript">$(function() {
$('.map').maphilight();
});
</script>
</head>
<body>
<p><img src="https://www.dike.lib.ia.us/images/sample-1.jpg" usemap="#Map" class="map" /></p>
<p>
<map name="Map">
<area shape="circle" coords="247,160,42" href="#" alt="test" id="test">
<area shape="circle" coords="152,186,35" href="#" alt="test2" id="test2">
</map>
</p>
<p><input type="text" id="count" value="1"></p>
<p><input type="text" id="count2" value="1"></p>
<script>
var count = 0
$("#test").click(function() {
count++;
if(count == 1) {
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('2');
}else if(count == 2){
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('3');
}else if(count == 3){
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('4');
count = 0;
}
})
var count = 0
$("#test2").click(function() {
count++;
if(count == 1) {
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('a');
}else if(count == 2){
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('s');
}else if(count == 3){
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('d');
count = 0;
}
})
</script>
</body>
</html>
javascript dictionary maphilight
I'm using maphilight js plugin to create an interactive image by which a user can select multiple areas, and each click an area should enlight and keep a specific color and a text-field will be filled.
While I created a routine both to enlight the areas and fill the text fields, I wasn't able to change and keep the color of the areas.
Here is my draft code:
(function($) {
var has_VML, has_canvas, create_canvas_for, add_shape_to, clear_canvas, shape_from_area,
canvas_style, hex_to_decimal, css3color, is_image_loaded, options_from_area;
has_canvas = !!document.createElement('canvas').getContext;
// VML: more complex
has_VML = (function() {
var a = document.createElement('div');
a.innerHTML = '<v:shape id="vml_flag1" adj="1" />';
var b = a.firstChild;
b.style.behavior = "url(#default#VML)";
return b ? typeof b.adj == "object": true;
})();
if(!(has_canvas || has_VML)) {
$.fn.maphilight = function() { return this; };
return;
}
if(has_canvas) {
hex_to_decimal = function(hex) {
return Math.max(0, Math.min(parseInt(hex, 16), 255));
};
css3color = function(color, opacity) {
return 'rgba('+hex_to_decimal(color.substr(0,2))+','+hex_to_decimal(color.substr(2,2))+','+hex_to_decimal(color.substr(4,2))+','+opacity+')';
};
create_canvas_for = function(img) {
var c = $('<canvas style="width:'+img.width+'px;height:'+img.height+'px;"></canvas>').get(0);
c.getContext("2d").clearRect(0, 0, c.width, c.height);
return c;
};
var draw_shape = function(context, shape, coords, x_shift, y_shift) {
x_shift = x_shift || 0;
y_shift = y_shift || 0;
context.beginPath();
if(shape == 'rect') {
// x, y, width, height
context.rect(coords[0] + x_shift, coords[1] + y_shift, coords[2] - coords[0], coords[3] - coords[1]);
} else if(shape == 'poly') {
context.moveTo(coords[0] + x_shift, coords[1] + y_shift);
for(i=2; i < coords.length; i+=2) {
context.lineTo(coords[i] + x_shift, coords[i+1] + y_shift);
}
} else if(shape == 'circ') {
// x, y, radius, startAngle, endAngle, anticlockwise
context.arc(coords[0] + x_shift, coords[1] + y_shift, coords[2], 0, Math.PI * 2, false);
}
context.closePath();
}
add_shape_to = function(canvas, shape, coords, options, name) {
var i, context = canvas.getContext('2d');
// Because I don't want to worry about setting things back to a base state
// Shadow has to happen first, since it's on the bottom, and it does some clip /
// fill operations which would interfere with what comes next.
if(options.shadow) {
context.save();
if(options.shadowPosition == "inside") {
// Cause the following stroke to only apply to the inside of the path
draw_shape(context, shape, coords);
context.clip();
}
// Redraw the shape shifted off the canvas massively so we can cast a shadow
// onto the canvas without having to worry about the stroke or fill (which
// cannot have 0 opacity or width, since they're what cast the shadow).
var x_shift = canvas.width * 100;
var y_shift = canvas.height * 100;
draw_shape(context, shape, coords, x_shift, y_shift);
context.shadowOffsetX = options.shadowX - x_shift;
context.shadowOffsetY = options.shadowY - y_shift;
context.shadowBlur = options.shadowRadius;
context.shadowColor = css3color(options.shadowColor, options.shadowOpacity);
// Now, work out where to cast the shadow from! It looks better if it's cast
// from a fill when it's an outside shadow or a stroke when it's an interior
// shadow. Allow the user to override this if they need to.
var shadowFrom = options.shadowFrom;
if (!shadowFrom) {
if (options.shadowPosition == 'outside') {
shadowFrom = 'fill';
} else {
shadowFrom = 'stroke';
}
}
if (shadowFrom == 'stroke') {
context.strokeStyle = "rgba(0,0,0,1)";
context.stroke();
} else if (shadowFrom == 'fill') {
context.fillStyle = "rgba(0,0,0,1)";
context.fill();
}
context.restore();
// and now we clean up
if(options.shadowPosition == "outside") {
context.save();
// Clear out the center
draw_shape(context, shape, coords);
context.globalCompositeOperation = "destination-out";
context.fillStyle = "rgba(0,0,0,1);";
context.fill();
context.restore();
}
}
context.save();
draw_shape(context, shape, coords);
// fill has to come after shadow, otherwise the shadow will be drawn over the fill,
// which mostly looks weird when the shadow has a high opacity
if(options.fill) {
context.fillStyle = css3color(options.fillColor, options.fillOpacity);
context.fill();
}
// Likewise, stroke has to come at the very end, or it'll wind up under bits of the
// shadow or the shadow-background if it's present.
if(options.stroke) {
context.strokeStyle = css3color(options.strokeColor, options.strokeOpacity);
context.lineWidth = options.strokeWidth;
context.stroke();
}
context.restore();
/*Fjodor [fix voor Chrome]:
if(options.fade) {
$(canvas).css('opacity', 0).animate({opacity: 1}, 100);
} fix:
https://github.com/kemayo/maphilight/issues/33
*/
if (options.fade && !window.skipAnimateOpacity) {
$(canvas).css('opacity', 0).animate({ opacity: 1 }, 100);
if ($(canvas).css('opacity') == 0)
{
$(canvas).css('opacity', 1);
window.skipAnimateOpacity = true;
}
}
};
clear_canvas = function(canvas) {
canvas.getContext('2d').clearRect(0, 0, canvas.width,canvas.height);
};
} else { // ie executes this code
create_canvas_for = function(img) {
return $('<var style="zoom:1;overflow:hidden;display:block;width:'+img.width+'px;height:'+img.height+'px;"></var>').get(0);
};
add_shape_to = function(canvas, shape, coords, options, name) {
var fill, stroke, opacity, e;
for (var i in coords) { coords[i] = parseInt(coords[i], 10); }
fill = '<v:fill color="#'+options.fillColor+'" opacity="'+(options.fill ? options.fillOpacity : 0)+'" />';
stroke = (options.stroke ? 'strokeweight="'+options.strokeWidth+'" stroked="t" strokecolor="#'+options.strokeColor+'"' : 'stroked="f"');
opacity = '<v:stroke opacity="'+options.strokeOpacity+'"/>';
if(shape == 'rect') {
e = $('<v:rect name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+coords[0]+'px;top:'+coords[1]+'px;width:'+(coords[2] - coords[0])+'px;height:'+(coords[3] - coords[1])+'px;"></v:rect>');
} else if(shape == 'poly') {
e = $('<v:shape name="'+name+'" filled="t" '+stroke+' coordorigin="0,0" coordsize="'+canvas.width+','+canvas.height+'" path="m '+coords[0]+','+coords[1]+' l '+coords.join(',')+' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:'+canvas.width+'px;height:'+canvas.height+'px;"></v:shape>');
} else if(shape == 'circ') {
e = $('<v:oval name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+(coords[0] - coords[2])+'px;top:'+(coords[1] - coords[2])+'px;width:'+(coords[2]*2)+'px;height:'+(coords[2]*2)+'px;"></v:oval>');
}
e.get(0).innerHTML = fill+opacity;
$(canvas).append(e);
};
clear_canvas = function(canvas) {
// jquery1.8 + ie7
var $html = $("<div>" + canvas.innerHTML + "</div>");
$html.children('[name=highlighted]').remove();
canvas.innerHTML = $html.html();
};
}
shape_from_area = function(area) {
var i, coords = area.getAttribute('coords').split(',');
for (i=0; i < coords.length; i++) { coords[i] = parseFloat(coords[i]); }
return [area.getAttribute('shape').toLowerCase().substr(0,4), coords];
};
options_from_area = function(area, options) {
var $area = $(area);
return $.extend({}, options, $.metadata ? $area.metadata() : false, $area.data('maphilight'));
};
is_image_loaded = function(img) {
if(!img.complete) { return false; } // IE
if(typeof img.naturalWidth != "undefined" && img.naturalWidth === 0) { return false; } // Others
return true;
};
canvas_style = {
position: 'absolute',
left: 0,
top: 0,
padding: 0,
border: 0
};
var ie_hax_done = false;
$.fn.maphilight = function(opts) {
opts = $.extend({}, $.fn.maphilight.defaults, opts);
if(!has_canvas && !ie_hax_done) {
$(window).ready(function() {
document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
var style = document.createStyleSheet();
var shapes = ['shape','rect', 'oval', 'circ', 'fill', 'stroke', 'imagedata', 'group','textbox'];
$.each(shapes,
function() {
style.addRule('v\:' + this, "behavior: url(#default#VML); antialias:true");
}
);
});
ie_hax_done = true;
}
return this.each(function() {
var img, wrap, options, map, canvas, canvas_always, mouseover, highlighted_shape, usemap;
img = $(this);
if(!is_image_loaded(this)) {
// If the image isn't fully loaded, this won't work right. Try again later.
return window.setTimeout(function() {
img.maphilight(opts);
}, 200);
}
options = $.extend({}, opts, $.metadata ? img.metadata() : false, img.data('maphilight'));
// jQuery bug with Opera, results in full-url#usemap being returned from jQuery's attr.
// So use raw getAttribute instead.
usemap = img.get(0).getAttribute('usemap');
if (!usemap) {
return
}
map = $('map[name="'+usemap.substr(1)+'"]');
if(!(img.is('img,input[type="image"]') && usemap && map.size() > 0)) {
return;
}
if(img.hasClass('maphilighted')) {
// We're redrawing an old map, probably to pick up changes to the options.
// Just clear out all the old stuff.
var wrapper = img.parent();
img.insertBefore(wrapper);
wrapper.remove();
$(map).unbind('.maphilight').find('area[coords]').unbind('.maphilight');
}
wrap = $('<div></div>').css({
display:'block',
background:'url("'+this.src+'")',
position:'relative',
padding:0,
width:this.width,
height:this.height
});
if(options.wrapClass) {
if(options.wrapClass === true) {
wrap.addClass($(this).attr('class'));
} else {
wrap.addClass(options.wrapClass);
}
}
img.before(wrap).css('opacity', 0).css(canvas_style).remove();
if(has_VML) { img.css('filter', 'Alpha(opacity=0)'); }
wrap.append(img);
canvas = create_canvas_for(this);
$(canvas).css(canvas_style);
canvas.height = this.height;
canvas.width = this.width;
mouseover = function(e) {
var shape, area_options;
area_options = options_from_area(this, options);
if(
!area_options.neverOn
&&
!area_options.alwaysOn
) {
shape = shape_from_area(this);
add_shape_to(canvas, shape[0], shape[1], area_options, "highlighted");
if(area_options.groupBy) {
var areas;
// two ways groupBy might work; attribute and selector
if(/^[a-zA-Z][-a-zA-Z]+$/.test(area_options.groupBy)) {
areas = map.find('area['+area_options.groupBy+'="'+$(this).attr(area_options.groupBy)+'"]');
} else {
areas = map.find(area_options.groupBy);
}
var first = this;
areas.each(function() {
if(this != first) {
var subarea_options = options_from_area(this, options);
if(!subarea_options.neverOn && !subarea_options.alwaysOn) {
var shape = shape_from_area(this);
add_shape_to(canvas, shape[0], shape[1], subarea_options, "highlighted");
}
}
});
}
// workaround for IE7, IE8 not rendering the final rectangle in a group
if(!has_canvas) {
$(canvas).append('<v:rect></v:rect>');
}
}
}
$(map).bind('alwaysOn.maphilight', function() {
// Check for areas with alwaysOn set. These are added to a *second* canvas,
// which will get around flickering during fading.
if(canvas_always) {
clear_canvas(canvas_always);
}
if(!has_canvas) {
$(canvas).empty();
}
$(map).find('area[coords]').each(function() {
var shape, area_options;
area_options = options_from_area(this, options);
if(area_options.alwaysOn) {
if(!canvas_always && has_canvas) {
canvas_always = create_canvas_for(img[0]);
$(canvas_always).css(canvas_style);
canvas_always.width = img[0].width;
canvas_always.height = img[0].height;
img.before(canvas_always);
}
area_options.fade = area_options.alwaysOnFade; // alwaysOn shouldn't fade in initially
shape = shape_from_area(this);
if (has_canvas) {
add_shape_to(canvas_always, shape[0], shape[1], area_options, "");
} else {
add_shape_to(canvas, shape[0], shape[1], area_options, "");
}
}
});
});
$(map).trigger('alwaysOn.maphilight').find('area[coords]')
.bind('mouseover.maphilight', mouseover)
.bind('mouseout.maphilight', function(e) { clear_canvas(canvas); });
img.before(canvas); // if we put this after, the mouseover events wouldn't fire.
img.addClass('maphilighted');
});
};
$.fn.maphilight.defaults = {
fill: true,
fillColor: 'ffffff',
fillOpacity: 0.2,
stroke: true,
strokeColor: 'ff0000',
strokeOpacity: 1,
strokeWidth: 1,
fade: true,
alwaysOn: false,
neverOn: false,
groupBy: false,
wrapClass: true,
// plenty of shadow:
shadow: false,
shadowX: 0,
shadowY: 0,
shadowRadius: 6,
shadowColor: '000000',
shadowOpacity: 0.8,
shadowPosition: 'outside',
shadowFrom: false
};
$.fn.maphilight.defaults.prova = {
fill: true,
fillColor: '00ff00',
};
})(jQuery);
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Documento senza titolo</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<!-- Add maphilight plugin -->
<script type="text/javascript" src="js/jquery.maphilight.js"></script>
<!-- Activate maphilight plugin -->
<script type="text/javascript">$(function() {
$('.map').maphilight();
});
</script>
</head>
<body>
<p><img src="https://www.dike.lib.ia.us/images/sample-1.jpg" usemap="#Map" class="map" /></p>
<p>
<map name="Map">
<area shape="circle" coords="247,160,42" href="#" alt="test" id="test">
<area shape="circle" coords="152,186,35" href="#" alt="test2" id="test2">
</map>
</p>
<p><input type="text" id="count" value="1"></p>
<p><input type="text" id="count2" value="1"></p>
<script>
var count = 0
$("#test").click(function() {
count++;
if(count == 1) {
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('2');
}else if(count == 2){
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('3');
}else if(count == 3){
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('4');
count = 0;
}
})
var count = 0
$("#test2").click(function() {
count++;
if(count == 1) {
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('a');
}else if(count == 2){
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('s');
}else if(count == 3){
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('d');
count = 0;
}
})
</script>
</body>
</html>
(function($) {
var has_VML, has_canvas, create_canvas_for, add_shape_to, clear_canvas, shape_from_area,
canvas_style, hex_to_decimal, css3color, is_image_loaded, options_from_area;
has_canvas = !!document.createElement('canvas').getContext;
// VML: more complex
has_VML = (function() {
var a = document.createElement('div');
a.innerHTML = '<v:shape id="vml_flag1" adj="1" />';
var b = a.firstChild;
b.style.behavior = "url(#default#VML)";
return b ? typeof b.adj == "object": true;
})();
if(!(has_canvas || has_VML)) {
$.fn.maphilight = function() { return this; };
return;
}
if(has_canvas) {
hex_to_decimal = function(hex) {
return Math.max(0, Math.min(parseInt(hex, 16), 255));
};
css3color = function(color, opacity) {
return 'rgba('+hex_to_decimal(color.substr(0,2))+','+hex_to_decimal(color.substr(2,2))+','+hex_to_decimal(color.substr(4,2))+','+opacity+')';
};
create_canvas_for = function(img) {
var c = $('<canvas style="width:'+img.width+'px;height:'+img.height+'px;"></canvas>').get(0);
c.getContext("2d").clearRect(0, 0, c.width, c.height);
return c;
};
var draw_shape = function(context, shape, coords, x_shift, y_shift) {
x_shift = x_shift || 0;
y_shift = y_shift || 0;
context.beginPath();
if(shape == 'rect') {
// x, y, width, height
context.rect(coords[0] + x_shift, coords[1] + y_shift, coords[2] - coords[0], coords[3] - coords[1]);
} else if(shape == 'poly') {
context.moveTo(coords[0] + x_shift, coords[1] + y_shift);
for(i=2; i < coords.length; i+=2) {
context.lineTo(coords[i] + x_shift, coords[i+1] + y_shift);
}
} else if(shape == 'circ') {
// x, y, radius, startAngle, endAngle, anticlockwise
context.arc(coords[0] + x_shift, coords[1] + y_shift, coords[2], 0, Math.PI * 2, false);
}
context.closePath();
}
add_shape_to = function(canvas, shape, coords, options, name) {
var i, context = canvas.getContext('2d');
// Because I don't want to worry about setting things back to a base state
// Shadow has to happen first, since it's on the bottom, and it does some clip /
// fill operations which would interfere with what comes next.
if(options.shadow) {
context.save();
if(options.shadowPosition == "inside") {
// Cause the following stroke to only apply to the inside of the path
draw_shape(context, shape, coords);
context.clip();
}
// Redraw the shape shifted off the canvas massively so we can cast a shadow
// onto the canvas without having to worry about the stroke or fill (which
// cannot have 0 opacity or width, since they're what cast the shadow).
var x_shift = canvas.width * 100;
var y_shift = canvas.height * 100;
draw_shape(context, shape, coords, x_shift, y_shift);
context.shadowOffsetX = options.shadowX - x_shift;
context.shadowOffsetY = options.shadowY - y_shift;
context.shadowBlur = options.shadowRadius;
context.shadowColor = css3color(options.shadowColor, options.shadowOpacity);
// Now, work out where to cast the shadow from! It looks better if it's cast
// from a fill when it's an outside shadow or a stroke when it's an interior
// shadow. Allow the user to override this if they need to.
var shadowFrom = options.shadowFrom;
if (!shadowFrom) {
if (options.shadowPosition == 'outside') {
shadowFrom = 'fill';
} else {
shadowFrom = 'stroke';
}
}
if (shadowFrom == 'stroke') {
context.strokeStyle = "rgba(0,0,0,1)";
context.stroke();
} else if (shadowFrom == 'fill') {
context.fillStyle = "rgba(0,0,0,1)";
context.fill();
}
context.restore();
// and now we clean up
if(options.shadowPosition == "outside") {
context.save();
// Clear out the center
draw_shape(context, shape, coords);
context.globalCompositeOperation = "destination-out";
context.fillStyle = "rgba(0,0,0,1);";
context.fill();
context.restore();
}
}
context.save();
draw_shape(context, shape, coords);
// fill has to come after shadow, otherwise the shadow will be drawn over the fill,
// which mostly looks weird when the shadow has a high opacity
if(options.fill) {
context.fillStyle = css3color(options.fillColor, options.fillOpacity);
context.fill();
}
// Likewise, stroke has to come at the very end, or it'll wind up under bits of the
// shadow or the shadow-background if it's present.
if(options.stroke) {
context.strokeStyle = css3color(options.strokeColor, options.strokeOpacity);
context.lineWidth = options.strokeWidth;
context.stroke();
}
context.restore();
/*Fjodor [fix voor Chrome]:
if(options.fade) {
$(canvas).css('opacity', 0).animate({opacity: 1}, 100);
} fix:
https://github.com/kemayo/maphilight/issues/33
*/
if (options.fade && !window.skipAnimateOpacity) {
$(canvas).css('opacity', 0).animate({ opacity: 1 }, 100);
if ($(canvas).css('opacity') == 0)
{
$(canvas).css('opacity', 1);
window.skipAnimateOpacity = true;
}
}
};
clear_canvas = function(canvas) {
canvas.getContext('2d').clearRect(0, 0, canvas.width,canvas.height);
};
} else { // ie executes this code
create_canvas_for = function(img) {
return $('<var style="zoom:1;overflow:hidden;display:block;width:'+img.width+'px;height:'+img.height+'px;"></var>').get(0);
};
add_shape_to = function(canvas, shape, coords, options, name) {
var fill, stroke, opacity, e;
for (var i in coords) { coords[i] = parseInt(coords[i], 10); }
fill = '<v:fill color="#'+options.fillColor+'" opacity="'+(options.fill ? options.fillOpacity : 0)+'" />';
stroke = (options.stroke ? 'strokeweight="'+options.strokeWidth+'" stroked="t" strokecolor="#'+options.strokeColor+'"' : 'stroked="f"');
opacity = '<v:stroke opacity="'+options.strokeOpacity+'"/>';
if(shape == 'rect') {
e = $('<v:rect name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+coords[0]+'px;top:'+coords[1]+'px;width:'+(coords[2] - coords[0])+'px;height:'+(coords[3] - coords[1])+'px;"></v:rect>');
} else if(shape == 'poly') {
e = $('<v:shape name="'+name+'" filled="t" '+stroke+' coordorigin="0,0" coordsize="'+canvas.width+','+canvas.height+'" path="m '+coords[0]+','+coords[1]+' l '+coords.join(',')+' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:'+canvas.width+'px;height:'+canvas.height+'px;"></v:shape>');
} else if(shape == 'circ') {
e = $('<v:oval name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+(coords[0] - coords[2])+'px;top:'+(coords[1] - coords[2])+'px;width:'+(coords[2]*2)+'px;height:'+(coords[2]*2)+'px;"></v:oval>');
}
e.get(0).innerHTML = fill+opacity;
$(canvas).append(e);
};
clear_canvas = function(canvas) {
// jquery1.8 + ie7
var $html = $("<div>" + canvas.innerHTML + "</div>");
$html.children('[name=highlighted]').remove();
canvas.innerHTML = $html.html();
};
}
shape_from_area = function(area) {
var i, coords = area.getAttribute('coords').split(',');
for (i=0; i < coords.length; i++) { coords[i] = parseFloat(coords[i]); }
return [area.getAttribute('shape').toLowerCase().substr(0,4), coords];
};
options_from_area = function(area, options) {
var $area = $(area);
return $.extend({}, options, $.metadata ? $area.metadata() : false, $area.data('maphilight'));
};
is_image_loaded = function(img) {
if(!img.complete) { return false; } // IE
if(typeof img.naturalWidth != "undefined" && img.naturalWidth === 0) { return false; } // Others
return true;
};
canvas_style = {
position: 'absolute',
left: 0,
top: 0,
padding: 0,
border: 0
};
var ie_hax_done = false;
$.fn.maphilight = function(opts) {
opts = $.extend({}, $.fn.maphilight.defaults, opts);
if(!has_canvas && !ie_hax_done) {
$(window).ready(function() {
document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
var style = document.createStyleSheet();
var shapes = ['shape','rect', 'oval', 'circ', 'fill', 'stroke', 'imagedata', 'group','textbox'];
$.each(shapes,
function() {
style.addRule('v\:' + this, "behavior: url(#default#VML); antialias:true");
}
);
});
ie_hax_done = true;
}
return this.each(function() {
var img, wrap, options, map, canvas, canvas_always, mouseover, highlighted_shape, usemap;
img = $(this);
if(!is_image_loaded(this)) {
// If the image isn't fully loaded, this won't work right. Try again later.
return window.setTimeout(function() {
img.maphilight(opts);
}, 200);
}
options = $.extend({}, opts, $.metadata ? img.metadata() : false, img.data('maphilight'));
// jQuery bug with Opera, results in full-url#usemap being returned from jQuery's attr.
// So use raw getAttribute instead.
usemap = img.get(0).getAttribute('usemap');
if (!usemap) {
return
}
map = $('map[name="'+usemap.substr(1)+'"]');
if(!(img.is('img,input[type="image"]') && usemap && map.size() > 0)) {
return;
}
if(img.hasClass('maphilighted')) {
// We're redrawing an old map, probably to pick up changes to the options.
// Just clear out all the old stuff.
var wrapper = img.parent();
img.insertBefore(wrapper);
wrapper.remove();
$(map).unbind('.maphilight').find('area[coords]').unbind('.maphilight');
}
wrap = $('<div></div>').css({
display:'block',
background:'url("'+this.src+'")',
position:'relative',
padding:0,
width:this.width,
height:this.height
});
if(options.wrapClass) {
if(options.wrapClass === true) {
wrap.addClass($(this).attr('class'));
} else {
wrap.addClass(options.wrapClass);
}
}
img.before(wrap).css('opacity', 0).css(canvas_style).remove();
if(has_VML) { img.css('filter', 'Alpha(opacity=0)'); }
wrap.append(img);
canvas = create_canvas_for(this);
$(canvas).css(canvas_style);
canvas.height = this.height;
canvas.width = this.width;
mouseover = function(e) {
var shape, area_options;
area_options = options_from_area(this, options);
if(
!area_options.neverOn
&&
!area_options.alwaysOn
) {
shape = shape_from_area(this);
add_shape_to(canvas, shape[0], shape[1], area_options, "highlighted");
if(area_options.groupBy) {
var areas;
// two ways groupBy might work; attribute and selector
if(/^[a-zA-Z][-a-zA-Z]+$/.test(area_options.groupBy)) {
areas = map.find('area['+area_options.groupBy+'="'+$(this).attr(area_options.groupBy)+'"]');
} else {
areas = map.find(area_options.groupBy);
}
var first = this;
areas.each(function() {
if(this != first) {
var subarea_options = options_from_area(this, options);
if(!subarea_options.neverOn && !subarea_options.alwaysOn) {
var shape = shape_from_area(this);
add_shape_to(canvas, shape[0], shape[1], subarea_options, "highlighted");
}
}
});
}
// workaround for IE7, IE8 not rendering the final rectangle in a group
if(!has_canvas) {
$(canvas).append('<v:rect></v:rect>');
}
}
}
$(map).bind('alwaysOn.maphilight', function() {
// Check for areas with alwaysOn set. These are added to a *second* canvas,
// which will get around flickering during fading.
if(canvas_always) {
clear_canvas(canvas_always);
}
if(!has_canvas) {
$(canvas).empty();
}
$(map).find('area[coords]').each(function() {
var shape, area_options;
area_options = options_from_area(this, options);
if(area_options.alwaysOn) {
if(!canvas_always && has_canvas) {
canvas_always = create_canvas_for(img[0]);
$(canvas_always).css(canvas_style);
canvas_always.width = img[0].width;
canvas_always.height = img[0].height;
img.before(canvas_always);
}
area_options.fade = area_options.alwaysOnFade; // alwaysOn shouldn't fade in initially
shape = shape_from_area(this);
if (has_canvas) {
add_shape_to(canvas_always, shape[0], shape[1], area_options, "");
} else {
add_shape_to(canvas, shape[0], shape[1], area_options, "");
}
}
});
});
$(map).trigger('alwaysOn.maphilight').find('area[coords]')
.bind('mouseover.maphilight', mouseover)
.bind('mouseout.maphilight', function(e) { clear_canvas(canvas); });
img.before(canvas); // if we put this after, the mouseover events wouldn't fire.
img.addClass('maphilighted');
});
};
$.fn.maphilight.defaults = {
fill: true,
fillColor: 'ffffff',
fillOpacity: 0.2,
stroke: true,
strokeColor: 'ff0000',
strokeOpacity: 1,
strokeWidth: 1,
fade: true,
alwaysOn: false,
neverOn: false,
groupBy: false,
wrapClass: true,
// plenty of shadow:
shadow: false,
shadowX: 0,
shadowY: 0,
shadowRadius: 6,
shadowColor: '000000',
shadowOpacity: 0.8,
shadowPosition: 'outside',
shadowFrom: false
};
$.fn.maphilight.defaults.prova = {
fill: true,
fillColor: '00ff00',
};
})(jQuery);
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Documento senza titolo</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<!-- Add maphilight plugin -->
<script type="text/javascript" src="js/jquery.maphilight.js"></script>
<!-- Activate maphilight plugin -->
<script type="text/javascript">$(function() {
$('.map').maphilight();
});
</script>
</head>
<body>
<p><img src="https://www.dike.lib.ia.us/images/sample-1.jpg" usemap="#Map" class="map" /></p>
<p>
<map name="Map">
<area shape="circle" coords="247,160,42" href="#" alt="test" id="test">
<area shape="circle" coords="152,186,35" href="#" alt="test2" id="test2">
</map>
</p>
<p><input type="text" id="count" value="1"></p>
<p><input type="text" id="count2" value="1"></p>
<script>
var count = 0
$("#test").click(function() {
count++;
if(count == 1) {
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('2');
}else if(count == 2){
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('3');
}else if(count == 3){
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('4');
count = 0;
}
})
var count = 0
$("#test2").click(function() {
count++;
if(count == 1) {
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('a');
}else if(count == 2){
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('s');
}else if(count == 3){
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('d');
count = 0;
}
})
</script>
</body>
</html>
(function($) {
var has_VML, has_canvas, create_canvas_for, add_shape_to, clear_canvas, shape_from_area,
canvas_style, hex_to_decimal, css3color, is_image_loaded, options_from_area;
has_canvas = !!document.createElement('canvas').getContext;
// VML: more complex
has_VML = (function() {
var a = document.createElement('div');
a.innerHTML = '<v:shape id="vml_flag1" adj="1" />';
var b = a.firstChild;
b.style.behavior = "url(#default#VML)";
return b ? typeof b.adj == "object": true;
})();
if(!(has_canvas || has_VML)) {
$.fn.maphilight = function() { return this; };
return;
}
if(has_canvas) {
hex_to_decimal = function(hex) {
return Math.max(0, Math.min(parseInt(hex, 16), 255));
};
css3color = function(color, opacity) {
return 'rgba('+hex_to_decimal(color.substr(0,2))+','+hex_to_decimal(color.substr(2,2))+','+hex_to_decimal(color.substr(4,2))+','+opacity+')';
};
create_canvas_for = function(img) {
var c = $('<canvas style="width:'+img.width+'px;height:'+img.height+'px;"></canvas>').get(0);
c.getContext("2d").clearRect(0, 0, c.width, c.height);
return c;
};
var draw_shape = function(context, shape, coords, x_shift, y_shift) {
x_shift = x_shift || 0;
y_shift = y_shift || 0;
context.beginPath();
if(shape == 'rect') {
// x, y, width, height
context.rect(coords[0] + x_shift, coords[1] + y_shift, coords[2] - coords[0], coords[3] - coords[1]);
} else if(shape == 'poly') {
context.moveTo(coords[0] + x_shift, coords[1] + y_shift);
for(i=2; i < coords.length; i+=2) {
context.lineTo(coords[i] + x_shift, coords[i+1] + y_shift);
}
} else if(shape == 'circ') {
// x, y, radius, startAngle, endAngle, anticlockwise
context.arc(coords[0] + x_shift, coords[1] + y_shift, coords[2], 0, Math.PI * 2, false);
}
context.closePath();
}
add_shape_to = function(canvas, shape, coords, options, name) {
var i, context = canvas.getContext('2d');
// Because I don't want to worry about setting things back to a base state
// Shadow has to happen first, since it's on the bottom, and it does some clip /
// fill operations which would interfere with what comes next.
if(options.shadow) {
context.save();
if(options.shadowPosition == "inside") {
// Cause the following stroke to only apply to the inside of the path
draw_shape(context, shape, coords);
context.clip();
}
// Redraw the shape shifted off the canvas massively so we can cast a shadow
// onto the canvas without having to worry about the stroke or fill (which
// cannot have 0 opacity or width, since they're what cast the shadow).
var x_shift = canvas.width * 100;
var y_shift = canvas.height * 100;
draw_shape(context, shape, coords, x_shift, y_shift);
context.shadowOffsetX = options.shadowX - x_shift;
context.shadowOffsetY = options.shadowY - y_shift;
context.shadowBlur = options.shadowRadius;
context.shadowColor = css3color(options.shadowColor, options.shadowOpacity);
// Now, work out where to cast the shadow from! It looks better if it's cast
// from a fill when it's an outside shadow or a stroke when it's an interior
// shadow. Allow the user to override this if they need to.
var shadowFrom = options.shadowFrom;
if (!shadowFrom) {
if (options.shadowPosition == 'outside') {
shadowFrom = 'fill';
} else {
shadowFrom = 'stroke';
}
}
if (shadowFrom == 'stroke') {
context.strokeStyle = "rgba(0,0,0,1)";
context.stroke();
} else if (shadowFrom == 'fill') {
context.fillStyle = "rgba(0,0,0,1)";
context.fill();
}
context.restore();
// and now we clean up
if(options.shadowPosition == "outside") {
context.save();
// Clear out the center
draw_shape(context, shape, coords);
context.globalCompositeOperation = "destination-out";
context.fillStyle = "rgba(0,0,0,1);";
context.fill();
context.restore();
}
}
context.save();
draw_shape(context, shape, coords);
// fill has to come after shadow, otherwise the shadow will be drawn over the fill,
// which mostly looks weird when the shadow has a high opacity
if(options.fill) {
context.fillStyle = css3color(options.fillColor, options.fillOpacity);
context.fill();
}
// Likewise, stroke has to come at the very end, or it'll wind up under bits of the
// shadow or the shadow-background if it's present.
if(options.stroke) {
context.strokeStyle = css3color(options.strokeColor, options.strokeOpacity);
context.lineWidth = options.strokeWidth;
context.stroke();
}
context.restore();
/*Fjodor [fix voor Chrome]:
if(options.fade) {
$(canvas).css('opacity', 0).animate({opacity: 1}, 100);
} fix:
https://github.com/kemayo/maphilight/issues/33
*/
if (options.fade && !window.skipAnimateOpacity) {
$(canvas).css('opacity', 0).animate({ opacity: 1 }, 100);
if ($(canvas).css('opacity') == 0)
{
$(canvas).css('opacity', 1);
window.skipAnimateOpacity = true;
}
}
};
clear_canvas = function(canvas) {
canvas.getContext('2d').clearRect(0, 0, canvas.width,canvas.height);
};
} else { // ie executes this code
create_canvas_for = function(img) {
return $('<var style="zoom:1;overflow:hidden;display:block;width:'+img.width+'px;height:'+img.height+'px;"></var>').get(0);
};
add_shape_to = function(canvas, shape, coords, options, name) {
var fill, stroke, opacity, e;
for (var i in coords) { coords[i] = parseInt(coords[i], 10); }
fill = '<v:fill color="#'+options.fillColor+'" opacity="'+(options.fill ? options.fillOpacity : 0)+'" />';
stroke = (options.stroke ? 'strokeweight="'+options.strokeWidth+'" stroked="t" strokecolor="#'+options.strokeColor+'"' : 'stroked="f"');
opacity = '<v:stroke opacity="'+options.strokeOpacity+'"/>';
if(shape == 'rect') {
e = $('<v:rect name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+coords[0]+'px;top:'+coords[1]+'px;width:'+(coords[2] - coords[0])+'px;height:'+(coords[3] - coords[1])+'px;"></v:rect>');
} else if(shape == 'poly') {
e = $('<v:shape name="'+name+'" filled="t" '+stroke+' coordorigin="0,0" coordsize="'+canvas.width+','+canvas.height+'" path="m '+coords[0]+','+coords[1]+' l '+coords.join(',')+' x e" style="zoom:1;margin:0;padding:0;display:block;position:absolute;top:0px;left:0px;width:'+canvas.width+'px;height:'+canvas.height+'px;"></v:shape>');
} else if(shape == 'circ') {
e = $('<v:oval name="'+name+'" filled="t" '+stroke+' style="zoom:1;margin:0;padding:0;display:block;position:absolute;left:'+(coords[0] - coords[2])+'px;top:'+(coords[1] - coords[2])+'px;width:'+(coords[2]*2)+'px;height:'+(coords[2]*2)+'px;"></v:oval>');
}
e.get(0).innerHTML = fill+opacity;
$(canvas).append(e);
};
clear_canvas = function(canvas) {
// jquery1.8 + ie7
var $html = $("<div>" + canvas.innerHTML + "</div>");
$html.children('[name=highlighted]').remove();
canvas.innerHTML = $html.html();
};
}
shape_from_area = function(area) {
var i, coords = area.getAttribute('coords').split(',');
for (i=0; i < coords.length; i++) { coords[i] = parseFloat(coords[i]); }
return [area.getAttribute('shape').toLowerCase().substr(0,4), coords];
};
options_from_area = function(area, options) {
var $area = $(area);
return $.extend({}, options, $.metadata ? $area.metadata() : false, $area.data('maphilight'));
};
is_image_loaded = function(img) {
if(!img.complete) { return false; } // IE
if(typeof img.naturalWidth != "undefined" && img.naturalWidth === 0) { return false; } // Others
return true;
};
canvas_style = {
position: 'absolute',
left: 0,
top: 0,
padding: 0,
border: 0
};
var ie_hax_done = false;
$.fn.maphilight = function(opts) {
opts = $.extend({}, $.fn.maphilight.defaults, opts);
if(!has_canvas && !ie_hax_done) {
$(window).ready(function() {
document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
var style = document.createStyleSheet();
var shapes = ['shape','rect', 'oval', 'circ', 'fill', 'stroke', 'imagedata', 'group','textbox'];
$.each(shapes,
function() {
style.addRule('v\:' + this, "behavior: url(#default#VML); antialias:true");
}
);
});
ie_hax_done = true;
}
return this.each(function() {
var img, wrap, options, map, canvas, canvas_always, mouseover, highlighted_shape, usemap;
img = $(this);
if(!is_image_loaded(this)) {
// If the image isn't fully loaded, this won't work right. Try again later.
return window.setTimeout(function() {
img.maphilight(opts);
}, 200);
}
options = $.extend({}, opts, $.metadata ? img.metadata() : false, img.data('maphilight'));
// jQuery bug with Opera, results in full-url#usemap being returned from jQuery's attr.
// So use raw getAttribute instead.
usemap = img.get(0).getAttribute('usemap');
if (!usemap) {
return
}
map = $('map[name="'+usemap.substr(1)+'"]');
if(!(img.is('img,input[type="image"]') && usemap && map.size() > 0)) {
return;
}
if(img.hasClass('maphilighted')) {
// We're redrawing an old map, probably to pick up changes to the options.
// Just clear out all the old stuff.
var wrapper = img.parent();
img.insertBefore(wrapper);
wrapper.remove();
$(map).unbind('.maphilight').find('area[coords]').unbind('.maphilight');
}
wrap = $('<div></div>').css({
display:'block',
background:'url("'+this.src+'")',
position:'relative',
padding:0,
width:this.width,
height:this.height
});
if(options.wrapClass) {
if(options.wrapClass === true) {
wrap.addClass($(this).attr('class'));
} else {
wrap.addClass(options.wrapClass);
}
}
img.before(wrap).css('opacity', 0).css(canvas_style).remove();
if(has_VML) { img.css('filter', 'Alpha(opacity=0)'); }
wrap.append(img);
canvas = create_canvas_for(this);
$(canvas).css(canvas_style);
canvas.height = this.height;
canvas.width = this.width;
mouseover = function(e) {
var shape, area_options;
area_options = options_from_area(this, options);
if(
!area_options.neverOn
&&
!area_options.alwaysOn
) {
shape = shape_from_area(this);
add_shape_to(canvas, shape[0], shape[1], area_options, "highlighted");
if(area_options.groupBy) {
var areas;
// two ways groupBy might work; attribute and selector
if(/^[a-zA-Z][-a-zA-Z]+$/.test(area_options.groupBy)) {
areas = map.find('area['+area_options.groupBy+'="'+$(this).attr(area_options.groupBy)+'"]');
} else {
areas = map.find(area_options.groupBy);
}
var first = this;
areas.each(function() {
if(this != first) {
var subarea_options = options_from_area(this, options);
if(!subarea_options.neverOn && !subarea_options.alwaysOn) {
var shape = shape_from_area(this);
add_shape_to(canvas, shape[0], shape[1], subarea_options, "highlighted");
}
}
});
}
// workaround for IE7, IE8 not rendering the final rectangle in a group
if(!has_canvas) {
$(canvas).append('<v:rect></v:rect>');
}
}
}
$(map).bind('alwaysOn.maphilight', function() {
// Check for areas with alwaysOn set. These are added to a *second* canvas,
// which will get around flickering during fading.
if(canvas_always) {
clear_canvas(canvas_always);
}
if(!has_canvas) {
$(canvas).empty();
}
$(map).find('area[coords]').each(function() {
var shape, area_options;
area_options = options_from_area(this, options);
if(area_options.alwaysOn) {
if(!canvas_always && has_canvas) {
canvas_always = create_canvas_for(img[0]);
$(canvas_always).css(canvas_style);
canvas_always.width = img[0].width;
canvas_always.height = img[0].height;
img.before(canvas_always);
}
area_options.fade = area_options.alwaysOnFade; // alwaysOn shouldn't fade in initially
shape = shape_from_area(this);
if (has_canvas) {
add_shape_to(canvas_always, shape[0], shape[1], area_options, "");
} else {
add_shape_to(canvas, shape[0], shape[1], area_options, "");
}
}
});
});
$(map).trigger('alwaysOn.maphilight').find('area[coords]')
.bind('mouseover.maphilight', mouseover)
.bind('mouseout.maphilight', function(e) { clear_canvas(canvas); });
img.before(canvas); // if we put this after, the mouseover events wouldn't fire.
img.addClass('maphilighted');
});
};
$.fn.maphilight.defaults = {
fill: true,
fillColor: 'ffffff',
fillOpacity: 0.2,
stroke: true,
strokeColor: 'ff0000',
strokeOpacity: 1,
strokeWidth: 1,
fade: true,
alwaysOn: false,
neverOn: false,
groupBy: false,
wrapClass: true,
// plenty of shadow:
shadow: false,
shadowX: 0,
shadowY: 0,
shadowRadius: 6,
shadowColor: '000000',
shadowOpacity: 0.8,
shadowPosition: 'outside',
shadowFrom: false
};
$.fn.maphilight.defaults.prova = {
fill: true,
fillColor: '00ff00',
};
})(jQuery);
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Documento senza titolo</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<!-- Add maphilight plugin -->
<script type="text/javascript" src="js/jquery.maphilight.js"></script>
<!-- Activate maphilight plugin -->
<script type="text/javascript">$(function() {
$('.map').maphilight();
});
</script>
</head>
<body>
<p><img src="https://www.dike.lib.ia.us/images/sample-1.jpg" usemap="#Map" class="map" /></p>
<p>
<map name="Map">
<area shape="circle" coords="247,160,42" href="#" alt="test" id="test">
<area shape="circle" coords="152,186,35" href="#" alt="test2" id="test2">
</map>
</p>
<p><input type="text" id="count" value="1"></p>
<p><input type="text" id="count2" value="1"></p>
<script>
var count = 0
$("#test").click(function() {
count++;
if(count == 1) {
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('2');
}else if(count == 2){
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('3');
}else if(count == 3){
$("#test").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count').val('4');
count = 0;
}
})
var count = 0
$("#test2").click(function() {
count++;
if(count == 1) {
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('a');
}else if(count == 2){
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('s');
}else if(count == 3){
$("#test2").maphilight({ stroke: false, fillColor: '009DDF', fillOpacity: 1 });
$('#count2').val('d');
count = 0;
}
})
</script>
</body>
</html>
javascript dictionary maphilight
javascript dictionary maphilight
edited Nov 25 '18 at 21:53
Francesco Coschino
asked Nov 25 '18 at 21:47
Francesco CoschinoFrancesco Coschino
33
33
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53472323%2fuse-maphilight-for-permanent-enlight-an-area-and-multiple-clicks%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53472323%2fuse-maphilight-for-permanent-enlight-an-area-and-multiple-clicks%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown