I'm creating an interactive app allowing people to customise doors. To allow them to select the letterbox I want to show it when they hover over the door and remove it when they hover out. This works fine, but when I hover the letter box the doors 'hover out' is fired.
This causes a strange flickering effect.
I have created a jsfiddle here showing this effect
Just wondering if anyone has a solution to this?
I basically need the letterbox to stay in place when the user hovers the door, I also need a click state for both the door and letterbox.
not sure if this is the most efficient method, but it works. jsfiddle
var doorClickState, letterbox, inletterbox = false;
$(function() {
var paper = Raphael("canvas", 330, 457);
//draw the door
doorClickState = paper.path("M0,0v200h117V0H0z").translate(0, 0).attr({
fill: "#FF0000",
stroke: 0,
opacity: 0.9
}).toFront();
//draw and hide letterbox
letterbox = paper.path("M0,0v15h60V0H0z").translate(30, 100).attr({
fill: "#000000",
stroke: 0,
opacity: 0.9
}).hide();
//click states for both
doorClickState.click(function() {
alert('door clicked');
});
letterbox.click(function() {
alert('letterbox clicked');
});
doorClickState[0].onmouseover = function() {
letterbox.show();
}
letterbox[0].onmouseover = function() {
inletterbox = true;
}
letterbox[0].onmouseout = function() {
inletterbox = false;
}
doorClickState[0].onmouseout = function() {
setTimeout(function() {
if (!inletterbox) {
letterbox.hide();
}
}, 20);
};
});
Related
this is my layer and i have assigned it to a button, but the zoom is not working when I click the layer button. i tried adding the zoom inside the layer but its not working.
rainfall1 = new ol.layer.Vector({
//title: 'CA_DEVELOPMENT_PLAN',
// extent: [-180, -90, -180, 90],
visible:false,
source: new ol.source.Vector({
url:"./data/village.geojson",
zoom: 12,
format: new ol.format.GeoJSON()
}),
style:function(feature) {
labelStyle.getText().setText(feature.getProperties().CA_NAME);
return style1;
},
declutter: true,
});
document.getElementById("lyr").onclick = function() {
layer1.setVisible(!rainfall1.getVisible());
};
var bindLayerButtonToggle = function (lyr, layer) {
document.getElementById(lyr).onclick = function() {
layer.setVisible(!layer.getVisible());
};
}
bindLayerButtonToggle("lyr", rainfall1);
setVisible will not zoom to a layer, it just turns it on or off.
Instead, you would have to update the view extent, and match it with the layer extent
map.getView().fit(rainfall1.getSource().getExtent());
#JGH's answer might work in some cases but if this is the first time the layer is made visible the source will not be loaded, so if there are no features you will need to wait for it to load before zooming.
if (rainfall1.getSource().getFeatures().length > 0) {
map.getView().fit(rainfall1.getSource().getExtent());
} else {
rainfall1.getSource().once('featuresloadend', function() [
map.getView().fit(rainfall1.getSource().getExtent());
});
}
I'd like to know if you have any idea on how I could click and drag on a canva to create a div.
Like in a video-game where you drag & drop to create an area.
Is there any plugin or things that were made in order to achieve that?
Thanks for your replies.
Building on Ludwig's snippet ... this will draw some squares on the page using mousedown and mouseup event listeners :)
EDIT: Had too much fun playing with this so here is an updated version with a select box to help you draw the selection, and now working in all directions :) I'd still recommend using a library like this one (https://github.com/Simonwep/selection) though, especially if you want touchscreen support.
// declare some global variables
let showSelection = false;
let Xstart;
let Ystart;
$(document).ready(function(){
$(document).mousedown(function(event){
// set a variable that indicates the user is drawing a selection
showSelection=true;
// save the position where the mouse click started
Xstart=event.pageX;
Ystart=event.pageY;
// create the select box element and give it some starting positions
$('<div id="selection"></div>')
.css({
"left": Xstart + 'px',
"top": Ystart + 'px',
})
.appendTo(document.body);
});
$(document).mousemove(function(event){
// if we are making a selection lets keep updating our select box dimensions
if(showSelection == true) {
// horizontal selection
if (event.pageX > Xstart) {
// left to right
$('#selection').css({
"width": event.pageX-Xstart + 'px'
})
} else {
// right to left
$('#selection').css({
"left": event.pageX,
"width": Xstart-event.pageX + 'px'
})
}
// vertical selection
if (event.pageY > Ystart) {
// top to bottom
$('#selection').css({
"height": event.pageY-Ystart + 'px'
})
} else {
// bottom to top
$('#selection').css({
"top": event.pageY,
"height": Ystart-event.pageY + 'px'
})
}
}
});
$(document).mouseup(function(event){
// we can borrow the needed values from the #selection element to draw our 'area' :)
LeftVal = $("#selection").css('left')
TopVal = $("#selection").css('top')
WidthVal = $("#selection").css('width')
HeightVal = $("#selection").css('height')
// create the area element and give it the dimensions
$('<div class="area"></div>')
.css({
"left": LeftVal,
"top": TopVal,
"width": WidthVal,
"height": HeightVal
})
.appendTo(document.body);
// get rid of the selection element from the DOM
$( "#selection" ).remove();
// and set our showSelection variable back to false
showSelection=false;
});
});
.area {
position: absolute;
background-color:lightgray;
}
#selection {
position: absolute;
background-color: lightblue;
border: 2px solid blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You could use this:
https://simonwep.github.io/selection/
In combination with something like this:
$(document).ready(function(){
$(document).click(function(event){
$('<div id="kenobi">Hello there</div>')
.css({
"left": event.pageX + 'px',
"top": event.pageY + 'px'
})
.appendTo(document.body);
});
});
body {
position: relative;
}
#kenobi {
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
canvas.on('object:over', function(e) {
//I want change opacity of object on mouse over on object
});
canvas.on('object:out', function(e) {
});
I want opacity one when object:over and otherwise opacity should be 0
If the context is 2d. Using context.globalAlpha will solve the case.
<script>
window.onload = function() {
var canvas=document.getElementById("drawing"); // grabs the canvas element
var context=canvas.getContext("2d"); // returns the 2d context object
canvas.on('object:over', function(e) {
//I want change opacity of object on mouse over on object
//blue rectangle
context.fillStyle= "#b0c2f7";
context.globalAlpha=0; // Half opacity
context.fillRect(10,10,100,50);
});
canvas.on('object:out', function(e) {
context.fillStyle= "#b0c2f7";
context.globalAlpha=1; // full opacity
context.fillRect(10,10,100,50);
});
}
</script>
I am export of fabric.js. But the canvas in fabric.js haven't object:over and object:out.
fabric.js have mouse:over, mouse:out, object:moving: doc address http://fabricjs.com/docs/fabric.Canvas.html
when mouse:over
canvas.on('mouse:over', function(e) {
var targetObj = e.target;
targetObj.setOpacity(0.5);
});
canvas.on('mouse:out', function(e) {
var targetObj = e.target;
targetObj.setOpacity(1);
});
I am trying making a photo frame pattern on canvas. In which I want to put two, three or maybe more photos under an overlay frame. Where few parts of the overlay frame are transparent.
If I upload photo1 into first section of frame its visible into second section also and uploading photo2 into section two is also visible into first section. Depending on which photo is uploaded first or edited at last is overlapping the other photo.
I want to know how to hide the overflow of photo so it should not be visible into other sections. How can I achieve this?
I have done this so far:
canvas.on({
'object:moving': onChange,
'object:scaling': onChange,
'object:rotating': onChange,
});
function onChange(options) {
options.target.setCoords();
canvas.forEachObject(function (obj) {
if (obj === options.target)
return;
if (obj.id != 'cover1' && obj.id != 'cover2')
return;
if (options.target.intersectsWithObject(obj)) {
// Hide this portion
canvas.renderAll();
}
});
}
Kindly provide me the best solution
You need to apply a clipTo() method onto the image.
var canvas;
$(function(){
canvas = window._canvas = new fabric.Canvas('canvas');
var radius = 200;
fabric.Image.fromURL('http://fabricjs.com/assets/pug_small.jpg', function(img) {
img.scale(0.5).set({
left: 250,
top: 250,
angle: -15,
clipTo: function (ctx) {
ctx.arc(0, 0, radius, 0, Math.PI * 2, true);
}
});
canvas.add(img).setActiveObject(img);
});
});
This fiddle show the technique
Fiddle
here is my code:
$('myButton').addEvents({
mouseenter: function(){
$('myImage').setStyle('display','block');
$('myImage').morph({
'duration': 500,
'transition': Fx.Transitions.Sine.in,
'opacity': 1,
'top': -205
});
},
mouseleave: function(){
$('myImage').morph({
'opacity': 0,
'top': -175,
'onComplete': hidemyImage
});
}
});
function hidemyImage() {
$('myImage').setStyle('display','none')
}
the onComplete inside the mouseleave does not work as expected... it hides the image immediately when i move away from myButton instead of hiding it after the morph has finished... i tried several solutions but none worked so far. any idea / help? thanks in advance!
you need to work with the instance and not pass on things in the morph function directly, that takes properties to morph and it probably runs your function immediately in the hope it will return a property value. you can do el.set('morph', {onComplete: hideImagefn}) before that and it will work but read on...
one way to do it is to set your morph options/instance once and work with it afterwards like so:
(function() {
var img = document.id('myImage').set('morph', {
duration: 500,
transition: Fx.Transitions.Sine.in,
link: 'cancel',
onStart: function() {
this.element.setStyle('display', 'block');
}
}), fx = img.get('morph');
// of you can just do var fx = new Fx.Morph(img, { options});
document.id('myButton').addEvents({
mouseenter: function(){
fx.start({
opacity: 1,
top: -205
});
},
mouseleave: function(){
fx.addEvent('complete', function() {
this.element.setStyle('display', 'none');
this.removeEvents('complete');
}).start({
opacity: 0,
top: -175
});
}
});
})();
the start ensures its always visible when mouseovered, the link is cancel which means it will stop execution if you mouse out too early and if you do mouseout, it will then hide the image and remove the onComplete event so that if you show it once more, it stays visible when it comes into view.
if you don't plan on being able to bring it back you can clean-up better and even use event pseudos like onComplete:once etc - though thats part of Event.Pseudos from mootools-more.
in general - .get/.set morph is your setup. el.morph() passes values to morphInstance.start()
play here: http://jsfiddle.net/dimitar/NkNHX/