Dear community is there any way to do a text next to the cursor hover effect (in css?) like on this site here?
http://manuelraeder.co.uk/
I tried it with abbr and span style, but it doesn't seem to work. Text should be changeable with every picture.
Thanks in advance!
From the website you linked, they appear to be using Javascript. I don't think there is a way to do this purely with CSS.
When you hover your mouse over an image on the website, a new HTML tag is created at the end of the body:
<p class="tooltip" style="display: block; top: ...; left: ...;">TEXT</p>
Where top and left correspond to the pixel values that your cursor is at, and the text would be whatever text you want to float next to the cursor.
In the Javascript, you would create a hover observer for the associated images, and inside the trigger function create the new p tooltip element. You would set the text for your p element to be the respective image's alt title. Looking at the website's Javascript, this is what they did for their tooltip:
$(document).ready(function() {
// Tooltip only Text
$('.masterTooltip').hover(function(){
// Hover over code
var title = $(this).attr('title');
$(this).data('tipText', title).removeAttr('title');
$('<p class="tooltip"></p>')
.text(title)
.appendTo('body')
.fadeIn('fast');
}, function() {
// Hover out code
$(this).attr('title', $(this).data('tipText'));
$('.tooltip').remove();
}).mousemove(function(e) {
var mousex = e.pageX + 20; //Get X coordinates
var mousey = e.pageY + 10; //Get Y coordinates
$('.tooltip')
.css({ top: mousey, left: mousex })
});
});
Related
Please look at
https://stackblitz.com/edit/js-wxidql
Here is my code.
import { fabric } from "fabric";
const canvas = new fabric.Canvas("c", { isDrawingMode: true });
canvas.setBackgroundColor("rgb(255,73,64)", canvas.renderAll.bind(canvas));
canvas.on("path:created", e => {
let mousePath = e.path;
let offsetPath = new fabric.Path();
let offsetLeft = mousePath.left + 60;
let offsetTop = mousePath.top + 60;
offsetPath.setOptions({
path: mousePath.path,
left: offsetLeft,
top: offsetTop,
width: mousePath.width,
height: mousePath.height,
fill: '',
stroke: 'black'
});
canvas.add(offsetPath);
canvas.requestRenderAll();
});
Here is an resulting image of my drawing session.
I drew the happy face in the top left corner of the canvas with my mouse.
The offset image was added by my code.
How can I change my code to make the offset drawing look like the one drawn with my mouse?
Edit: from https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords
I tried using
offsetDraw.setCoords();
but I was unable to find a way to make it work.
Edit: What I have presented here is a minimized example. I am working on an larger project where I save each path drawn by the user. Later I recreate those paths in an animation like sequence.
Edit: I made some changes to my code in a effort to understand fabricjs.
const canvas = new fabric.Canvas("c", { isDrawingMode: true });
canvas.setBackgroundColor("rgb(255,73,64)", canvas.renderAll.bind(canvas));
canvas.on("path:created", e => {
let mousePath = e.path;
let offsetPath = new fabric.Path();
let offsetLeft = mousePath.left + 60;
let offsetTop = mousePath.top + 60;
offsetPath.setOptions({
path: mousePath.path,
//left: offsetLeft,
//top: offsetTop,
width: mousePath.width,
height: mousePath.height,
fill: '',
stroke: 'black'
});
canvas.add(offsetPath);
canvas.requestRenderAll();
console.log("mousePath left " + mousePath.left + " top " + mousePath.top);
console.log("offsetPath left " + offsetPath.left + " top " + offsetPath.top);
});
In that code, I commented out the setting of the left and top properties of the offsetPath and added console.log lines. I drew a circle in the top left corner of the canvas with my mouse. The resulting image was the following.
The following was printed in the console.
mousePath left 7.488148148148148 top 10.5
offsetPath left -0.5 top -0.5
I don't understand the results. Why was the offset circle rendered in that position?
Edit: I drew another test with my mouse.
It seems that the code repeats the paths of concentric circles rather well. But, the vertical lines are moved out of their correct position. Their displacements increase as the distance from the center increases. Why?
I found a solution for my own question. But, if someone has a better one, then please post it. Look at
https://stackblitz.com/edit/js-ncxvpg
The following is the code.
const canvas = new fabric.Canvas("c", { isDrawingMode: true });
canvas.setBackgroundColor("rgb(255,73,64)", canvas.renderAll.bind(canvas));
canvas.on("path:created", e => {
let mousePath = e.path;
mousePath.clone(clone => {
clone.setOptions({
left: mousePath.left + 100,
top: mousePath.top + 100
});
canvas.add(clone);
});
});
If someone has an explaination as to why my original code didn't work, then please post it.
thanks for sharing your comments on my question. I am facing a similar issue, just that if I click anywhere on the Canvas the first time. Then the offset issue vanishes. This happens for any object that I programmatically insert into the canvas.
In my case, I suspect that the canvas.pointer is having some offset of the current mouse position. However, when I click and add one very small path of 1pixel, then the pointer offset gets corrected. After this, all subsequent paths or objects created programatically are shown at the correct positions.
I want to use image-maps inside fancybox 3. Goal is to display mountain panoramas, where the user could point on a summit and get name and data. The usual recommendation is to use a SVG based image map for this like in this pen. Due to the size of the images the fancybox zoom functionality is important.
While fancybox will display SVGs as an image like in this pen it is not possible to use the <image> tag with an external source inside the SVG file. Even worse: SVG files used as source of an <img> tag would not show the map functionality (see this question).
I tried to replace the <img> tag in fancybox with an <object> tag using the SVG file as data attribute. This shows the image with the map functionality correctly but fancybox won't zoom it any more.
So eventually the question boils down to how I can make an <object> (or an inline SVG or an iframe) zoomable just like an image in fancybox 3.
I'm open to other solutions as well. I only want to use fancybox to keep the appearance and usage the same as other image galleries on the same page. I'd even use an old style <map>, where I would change the coords using jquery to have it responsive. I tried that, attaching the map manually in developer tools as well as programmatically in afterLoad event handler, but apparently this doesn't work in fancybox 3 either.
The areas are polygons, so using positioned div's as overlays is no solution.
Edit: I just discovered that I can replace <img> with a <canvas> in fancybox without loosing the zoom and drag functionality. So in theory it would be possible to use canvas paths and isPointInPath() methode. Unfortunately I need more than one path, which requires the Path2D object, which is not available in IE...
Since all options discussed in the question turned out to be not feasible and I found the pnpoly point in polygon algorithm, I did the whole thing on my own. I put the coordinates as percentages (in order to be size-independent) in an array of javascript objects like so:
var maps = {
alpen : [
{type:'poly',name:'Finsteraarhorn (4274m)',vertx:[56.48,56.08,56.06,56.46], verty:[28.5,28.75,40.25,40.25]},
{type:'rect',name:'Fiescherhörner (4049m)',coords:[58.08,29.5,59.26,43.5]},
{type:'poly',name:'Eiger (3970m)',vertx:[61.95,61.31,61.31,60.5,60.5], verty:[43,35.25,30.25,30.25,45.5]}
]
}; // maps
Since the pnpoly function requires the vertices for x and y separately I provide the coordinates this way already.
The Id of the map is stored in a data attribute in the source link:
<a href="/img/bilder/Alpen.jpg" data-type='image' data-Id='alpen' data-fancybox="img" data-caption="<h5>panorama of the alps from the black forest Belchen at sunset</h5>">
<img src="/_pano/bilder/Alpen.jpg">
</a>
CSS for the tooltip:
.my-tooltip {
color: #ccc;
background: rgba(30,30,30,.6);
position: absolute;
padding: 5px;
text-align: left;
border-radius: 5px;
font-size: 12px;
}
pnpoly and pnrect are provided as simple functions, the handling of that all is done in the afterShow event handler:
// PNPoly algorithm checkes whether point in polygon
function pnpoly(vertx, verty, testx, testy) {
var i, j, c = false;
var nvert = vertx.length;
for(i=0, j=nvert-1; i<nvert; j=i++) {
if (((verty[i] > testy) != (verty[j] > testy)) &&
(testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i])) {
c = !c;
}
}
return c;
}
// checks whether point in rectangle
function pnrect(coords,testx,testy) {
return ((testx >= coords[0]) && (testx <= coords[2]) && (testy >= coords[1]) && (testy <= coords[3]));
}
$("[data-fancybox]").fancybox({
afterShow: function( instance, slide ) {
var map = maps[$(slide.opts.\$orig).data('id')]; // Get map name from source link data-ID
if (map && map.length) { // if map present
$(".fancybox-image")
.after("<span class='my-tooltip' style='display: none'></span>") // append tooltip after image
.mousemove(function(event) { // create mousemove event handler
var offset = $(this).offset(); // get image offset, since mouse coords are global
var perX = ((event.pageX - offset.left)*100)/$(this).width(); // calculate mouse coords in image as percentages
var perY = ((event.pageY - offset.top)*100)/$(this).height();
var found = false;
var i;
for (i = 0; i < map.length; i++) { // loop over map entries
if (found = (map[i].type == 'poly') // depending on area type
?pnpoly(map[i].vertx, map[i].verty, perX, perY) // look whether coords are in polygon
:pnrect(map[i].coords, perX, perY)) // or coords are in rectangle
break; // if found stop looping
} // for (i = 0; i < map.length; i++)
if (found) {
$(".my-tooltip")
.css({bottom: 'calc(15px + '+ (100 - perY) + '%'}) // tooltip 15px above mouse coursor
.css((perX < 50) // depending on which side we are
?{right:'', left: perX + '%'} // tooltip left of mouse cursor
:{right: (100 - perX) + '%', left:''}) // or tooltip right of mouse cursor
.text(map[i].name) // set tooltip text
.show(); // show tooltip
} else {
$(".my-tooltip").hide(); // if nothing found: hide.
}
});
} else { // if (map && map.length) // if no map present
$(".fancybox-image").off('mousemove'); // remove event mousemove handler
$(".my-tooltip").remove(); // remove tooltip
} // else if (map && map.length)
} // function( instance, slide )
});
Things left to do: Find a solution for touch devices, f.e. provide a button to show all tooltips (probably rotated 90°).
As soon as the page is online I'll provide a link here to see it working...
I need to position text inputs at various places on a KonvaJS layer. I found the following code at https://konvajs.github.io/docs/sandbox/Editable_Text.html and I'm trying to understand the textPosition, stageBox, and areaPosition vars in this code. I want my stage centered in the browser window, but when I do that, the textarea (activated on dblclick) pops up way off to the left. I can't get a console readout of the x/y coordinates, so I can't visualize how the positioning works &, thus, how to change it. Can anyone explain, or point me in the right direction?
var text_overlay = new Konva.Layer();
stage.add(text_overlay);
var textNode = new Konva.Text({
text: 'Some text here',
x: 20,
y: 50,
fontSize: 20
});
text_overlay.add(textNode);
text_overlay.draw();
textNode.on('dblclick', () => {
// create textarea over canvas with absolute position
// first we need to find its position
var textPosition = textNode.getAbsolutePosition();
var stageBox = stage.getContainer().getBoundingClientRect();
var areaPosition = {
x: textPosition.x + stageBox.left,
y: textPosition.y + stageBox.top
};
// create textarea and style it
var textarea = document.createElement('textarea');
document.body.appendChild(textarea);
textarea.value = textNode.text();
textarea.style.position = 'absolute';
textarea.style.top = areaPosition.y + 'px';
textarea.style.left = areaPosition.x + 'px';
textarea.style.width = textNode.width();
textarea.focus();
textarea.addEventListener('keydown', function (e) {
// hide on enter
if (e.keyCode === 13) {
textNode.text(textarea.value);
text_overlay.draw();
document.body.removeChild(textarea);
}
});
})
// add the layer to the stage
stage.add(text_overlay);
UPDATE: I solved part of the problem--the textarea showing up way out of position. You need to use 2 divs in the HTML file instead of one, like so:
<div id="containerWrapper" align="center"><div id="container"></div></div>
Thanks to Frens' answer on Draw border edges of the Konvajs container Stage in html for that one!
can you help me to place a Highchart inside a SVG element instead of an HTML . Cascaded elements work fine. I have already done it with the jquery SVG plot. But Highchart throws an error 13. What can i do?
Kind regards
Markus Breitinger
You can generate chart in div, which will have negative margin. Then use getSVG() function and paste it ot svg element.
http://api.highcharts.com/highcharts#Chart.getSVG()
Unfortunately it is not suppored, highcharts renders the chart in additional divs and adds elements like labels/datalabels as html objects.
But you can copy the SVG of highstock in you SVG. But you will lose all attached events.
Like drag and drop, click ....
Here an Example of it.
http://jsfiddle.net/L6SA4/10/
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-c.json&callback=?', function(data) {
// Create a hidden and not attached div container.
var div = $('<div>This is an hidden unatached container.</div>');
// Create the chart
div.highcharts('StockChart', {
chart: {
width: 480,
height: 400,
events: {
load: function () {
// If hidden div was generated, take the svg content and put it into svg.
var stockSvg = $('svg', this.container);
var svgObj = $('#mySvg').svg();
// Force position of highstock
stockSvg.attr('x', 20);
stockSvg.attr('y', 30);
// Replace ugly rect with highstock
$('#container', svgObj).replaceWith(stockSvg);
}
}
},
series : [{
name : 'AAPL',
data : data,
tooltip: {
valueDecimals: 2
}
}]
});
});
I want to draw text on canvas., how to do it any sample example?
The canvas already contains some shape drawn, i want to show text on the top of that shape on canvas
How can i do it?
Also be aware that you need to actually have loaded a cufon font. There is no default font when using Fabric.js.
<script src="fabric.js"></script>
<script src="cufon.calibri.js"></script>
There are so many fonts available from http://www.cufonfonts.com/
This being the case the author is planning on removing the need for cufon. Discussed here: Fabric.js + Google Fonts
If you're wanting to render a block, then some text inside of that block. I would do something like this.
//Render the block
var block = canvas.add(new fabric.Rect({
left: 100,
top: 100,
fill: 'blue'
}));
//Render the text after the block (so that it is in front of the block)
var text = canvas.add(new fabric.Text('I love fabricjs', {
left: block.left, //Take the block's position
top: block.top,
fill: 'white'
}));
//Render the text and block on the canvas
//This is to get the width and height of the text element
canvas.renderAll();
//Set the block to be the same width and height as the text with a bit of padding
block.set({ width: text.width + 15, height: text.height + 10 });
//Update the canvas to see the text and block positioned together,
//with the text neatly fitting inside the block
canvas.renderAll();
Take a look at How to render text tutorial.
It's as simple as:
canvas.add(new fabric.Text('foo', {
fontFamily: 'Delicious_500',
left: 100,
top: 100
}));
Also worth noting that you might need to adjust Cufon's offsetLeft to help correctly position the text. Something like:
Cufon.fonts[your-fontname-in-lowercase-here].offsetLeft = 120;
The kitchen sink demo of fabric uses this:
http://kangax.github.com/fabric.js/lib/font_definitions.js