On my web page, I'd like to have a group of several concentric circles of varying size, with each displaying a menu when they are moused over.
So far, I have created 4 pictures that is 100% transparent except for the circle and have layered them on top of each other. However, when I mouse-over the group of circles, the transparent part of the top image causes the mouse-over event to fire. How can I deal with this?
For reference, here is the code that I have so far.
<html>
<head>
<style type="text/css">
img
{
position:fixed;
left: 0;
bottom: 0;
}
</style>
<title>Circle Test</title>
</head>
<body>
<img src="Circle2.png" onMouseover="alert('Button2')"/>
<img src="Circle4.png" onMouseover="alert('Button4')"/>
<img src="Circle3.png" onMouseover="alert('Button3')"/>
<img src="Circle1.png" onMouseover="alert('Button1')"/>
</body>
</html>
This would be hard with pure images as it's difficult to tell when the mouse is actually over the circle part of the image. I would suggest a client side image map as they let you define clickable areas in non-rectangular shapes. Set the href to something like "javascript:circleClicked(); void 0;" :D
There's no way to tell that the mouse is over a transparent pixel of your circle: you must check if the mouse intersects with the actual circle (yeah, really). Actually, that's easier than it might seem. Considering your circle's diameter is your image's width (which appears quite possible to me), you just have to check that the mouse cursor is within the radius of the circle (which would be width / 2):
function intersectsCircle(diameter, center, mousePosition)
{
var radius = diameter / 2;
// compute the distance between mousePosition and center
var deltaX = mousePosition.x - center.x;
var deltaY = mousePosition.y - center.y;
return Math.sqrt(deltaX * deltaX + deltaY * deltaY) < radius;
}
And the you just have to pass the required informations (my Javascript's rusty so what follows might not be exactly accurate, especially double-check the events part):
function intersects(target, event)
{
var center = {x: target.x + target.width / 2, y: target.y + target.height / 2};
var mousePosition = {x: event.clientX, y: event.clientY};
if(intersectsCircle(target.width, center, mousePosition))
alert('Foo');
}
<img onmouseover="intersects(this, event)" src="circle.png" />
Related
I have some content on a page that serves as a global background.
I put a sprite (div with background-image: url(...), changing frames by modifying background-position) on top of that using position: absolute. The sprite is a PNG with alpha-channel.
Now I'm trying to add some tint to that image (greenish or blueish or other).
I've studied the similar questions and apparently the only possible solutions are:
Create a div on top of the sprite with the desired color as its background-color, desired tint strength as opacity and the original sprite image as mask-image (and setting the mask-type: alpha). While it should work on paper, it doesn't in practice - this new div is just invisible :(
Use mix-blend-mode for the overlaying colored div and specify something like multiply or overlay. It produces perfect results as long as the global background is black. If it's something else - it gets included in the calculations and the overlay div modifies it as well, producing a tinted rectangle instead of tinted sprite...
Use SVG filter as described in an answer here: https://stackoverflow.com/a/30949302/306470 .
I didn't try this one yet, but it feels unnecessary complicated for this task. I'm concerned about the performance here too, will it slow down things a lot if there will be multiple tinted sprites on the screen at the same time? If anyone had experience with it - please comment here :)
Prepare a tinted version of the sprite using an invisible canvas. Sounds even more complicated, has a disadvantage of having to spend time to prepare the tinted version of the sprite, but should work as fast as the original sprite once it's prepared? Implementation should be pretty complicated though. Pure CSS solution would be much better...
Am I missing something? Are there any other options? Or should I go with #3 or #4?
Here is a working example of the outlined comment I left, hope it helps. I use a created div element to overlay on top of the image. Get the image elements position using boundingClientRect and this.width/this.height inside a for loop looping over the image elements. Set the overlay elements position to that of the image element being looped over and randomize a color using function with rgb setting alpha to 0.5.
let fgrp = document.getElementById("group");
let images = document.querySelectorAll(".imgs");
//function to randomize the RGB overlay color
function random() {
var o = Math.round,
r = Math.random,
s = 255;
return o(r() * s);
}
//function to randomize a margin for each image to show the overlay will snap to the image
function randomWidth() {
var n = Math.round,
ran = Math.random,
max = 400;
return n(ran() * max);
}
// loop through the img elements and create an overlay div element for each img element
for (let i = 0; i < images.length; i++) {
// load the images and get their wisth and height
images[i].onload = function() {
let width = this.width;
let height = this.height;
this.style.marginLeft = randomWidth() + "px";
// create the overlay element
let overlay = document.createElement("DIV");
// append the overlay element
fgrp.append(overlay);
// get the image elements top, left positions using `getBoundingClientRect()`
let rect = this.getBoundingClientRect();
// set the css for the overlay using the images height, width, left and top positions
// set position to absolute incase scrolling page, zindex to 2
overlay.style.cssText = "width: " + this.offsetWidth + "px; height: " + this.offsetHeight + "px; background-color: rgba(" + random() + ", " + random() + ", " + random() + ", 0.5); left: " + rect.left + "px; top: " + rect.top + "px; position: absolute; display: block; z-index: 2; cursor pointer;";
}
}
img {
margin: 50px 0;
display: block;
}
<div id="group">
<image src="https://artbreeder.b-cdn.net/imgs/275c7c05efca3a40e3178208.jpeg?width=256" class="imgs"></image>
<image src="https://artbreeder.b-cdn.net/imgs/275c7c05efca3a40e3178208.jpeg?width=256" class="imgs"></image>
<image src="https://artbreeder.b-cdn.net/imgs/275c7c05efca3a40e3178208.jpeg?width=256" class="imgs"></image>
</div>
Following the guide below, it is possible to at a colorful tint over a div/image using only CSS, like so:
<html>
<head>
<style>
.hero-image {
position: relative;
width: 100%;
}
.hero-image:after {
position: absolute;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, .5);
top: 0;
left: 0;
display: block;
content: "";
}
</style>
</head>
<body>
<div class="hero-image">
<img src="https://cdn.jpegmini.com/user/images/slider_puffin_before_mobile.jpg" alt="after tint" />
</div>
<div>
<img src="https://cdn.jpegmini.com/user/images/slider_puffin_before_mobile.jpg" alt="before tint" />
</div>
</body>
</html>
Since you are trying to place it on top of an absolute position image, as the guide says, add a z-index of 1 (for example) to the :after chunk.
Edit: It might need some tweaking on the width's percentage!
Source: https://ideabasekent.com/wiki/adding-image-overlay-tint-using-css
I want to create a hover-activated 3D Parallax Effect for my homepage.
I want to achive something like that:
https://www.hellomonday.com/
It has a 3D effect but also it is responsive to my mouse movement. What should I search? How can I create this effect?
Parallax.js by Matt Wagerfield (#mwagerfield) and Claudio Guglieri (#claudioguglieri)
It is a robust little parallax engine, giving you a quick, simple api to get going with all your parallax needs. Forget scrolling though, parallax.js utilizes your devices orientation and will fall back to cursor positions if no motion detection is available… this really gives you that sexy responsive feel.
May be this could help you to acheive what you are seeking for :)
Alternatively if you want to use Primitive JS Then you have to track the movement of mouse and trigger some event accordingly.
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 200px;
height: 100px;
border: 1px solid black;
}
</style>
</head>
<body>
<div id="myDIV"></div>
<p>Mouse over the rectangle above, and get the coordinates of your mouse pointer.</p>
<p id="demo"></p>
<p id="demo1"></p>
<script>
document.getElementById("myDIV").addEventListener("mousemove", function(event) {
myFunction(event);
});
function myFunction(e) {
var x = e.clientX;
var y = e.clientY;
var coor = "Coordinates: (" + x + "," + y + ")";
document.getElementById("demo").innerHTML = coor;
if( x == "54")
alert("Cordinate triggered")
}
</script>
As soon as you hit x coordinate as 54, alert box will appear
I have written a flipUp function by using svg.js for fliping up and down an image. I need a side flip function also but I can not be able to implement side flip function by using scale(1,-1). Can anyone help me out?
function flipUp written in personalise.js as under:
function flipUp()
{
var angle = parseInt(target.trans.rotation,10) + 180;
//if(angle > 360) angle = angle -360
console.log(angle)
target.animate().rotate(angle)
//target.animate().transform('matrix' ,'-1,0,0,-1,0,0')
}
And the function is called from design.html as under:
<img src='flip_up.PNG' alt="" height="20" width="20" style='margin-top:-41px;margin-left:267px'>
You can accomplish this wouldn't the need for svg.js. You just need to use transform, in particular rotate. Also dont forget to add deg to the angle.
DEMO
HTML:
<img src='flip_up.PNG' alt="" height="20" width="20" style='margin-top:-41px;margin-left:267px'>
JAVASCRIPT:
// el is the anchor element (a)
// el.children[0] is the img
// however, this assumes the first child of the anchor element is the img
var angle = 15;
function flipUp(el){
el.children[0].style.transform = 'rotate(' + angle + 'deg)';
// add 15 degs on every click
angle += 15;
}
Hope this helps and let me know if you have any questions.
I tried to create a rotating animation of an arc. Even after trying all those examples, I am not able to rotate it around the center. It is getting rotated around the top left corner.
private function init():void
{
var hgroup:Group=new Group();
this.addElement(hgroup);
arc1=new Graphic();
arc1.graphics.lineStyle(12,0xff0000,1,false,"normal",CapsStyle.SQUARE);
draw_arc(arc1,CENTER,CENTER,70,14,288,1);
hgroup.addElement(arc1);
var matrix:Matrix = arc1.transform.matrix;
var rect:Rectangle = arc1.getBounds(arc1.parent);
matrix.translate(- (rect.left + (rect.width/2)), - (rect.top + (rect.height/2)));
matrix.rotate((90/180)*Math.PI);
matrix.translate(rect.left + (rect.width/2), rect.top + (rect.height/2));
var rot:Rotate = new Rotate();
rot.angleBy = 360;
rot.duration = 1000;
rot.target = arc1;
rot.play();
}
public function draw_arc(movieclip:Sprite,center_x:Number,center_y:Number,radius:Number,angle_from:Number,angle_to:Number,precision:Number):void {
var angle_diff:Number=angle_to-angle_from;
var steps:Number=Math.round(angle_diff*precision);
var angle:Number=angle_from;
var px:Number=center_x+radius*Math.cos(angle*deg_to_rad);
var py:Number=center_y+radius*Math.sin(angle*deg_to_rad);
movieclip.graphics.moveTo(px,py);
for (var i:Number=1; i<=steps; i++) {
angle=angle_from+angle_diff/steps*i;
movieclip.graphics.lineTo(center_x+radius*Math.cos(angle*deg_to_rad),center_y+radius*Math.sin(angle*deg_to_rad));
}
}
you need this property:
rot.autoCenterTransform="true"
see the example at the bottom of the documentation: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/effects/Rotate.html
I had a similar issue (with a rotating arrow) and I fixed it like this:
<s:Group width="0" height="0" verticalCenter="0" right="14">
<s:Graphic id="arrow" rotation="90" rotation.selectedStates="0">
<s:Path data="M 0 0 L 5 5 L 0 10 Z" left="-2.5" top="-5">
<s:fill>
<s:SolidColor id="arrowFill"/>
</s:fill>
</s:Path>
</s:Graphic>
</s:Group>
The container Group has its size set to 0 as it serves only as an anchor point for the graphic it contains. The position of this Group is the rotating center point. The Path in the Graphic is positioned so that its anchor point is in its center (i.e. it's 5px wide and 10px heigh, so it's repositioned 2.5px to the left and 5px to the top).
The actual rotation is done through States and Transformations here, but an Effect does the same thing.
I've used this solution before; it works well and is very simple:
http://www.chadupton.com/blog/2008/02/rotate-on-center-in-adobe-flex/
To rotate image at the center you have to specify this properties
rot.autoCenterTransform="true";
rot.applyChangesPostLayout = false;
I will start off by admitting I have never used canvas before so I don't know if this is possible but I can't seem to find the solution.
I am trying to create a canvas that draws a simple regular polygon shape (all sides are equal) in canvas based on the number of sides and size of the polygon that the user inputs most likely in HTML/PHP form. Nothing is actually saved to a server or database, just used for the one drawing.
Does anyone have any advice?
You should use a JavaScript library to make it easier to draw on the canvas.
Here's a really good demo of the functionality that you're looking for:
http://fabricjs.com/
And the the library is Fabric.js, which you can download here: http://fabricjs.com/
I looked up on google and there was an interesting tutorial/code which draws a regular polygon with n-sides & size. So I thought of making a function out of it, one of the technical problems I encountered is that when the canvas is drawed and I click to draw another canvas, the second canvas is "overwritten" on the first one. Luckily someone here solved this problem by clearing the canvas.
So here's my code, you may change it to your needs:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Regular Polygon</title>
</head>
<body>
<canvas id="regular_polygon" width="400" height="400"></canvas>
<p>Polygon drawer:</p>
<p>Number of sides <input type="text" id="nSides"></p>
<p>Size <input type="text" id="size"></p>
<p>Color <input type="text" id="color"></p>
<p>Width <input type="text" id="width"></p>
<button id="draw">Draw!</button>
<script type="text/javascript">
function polygon (element_id, nSides, psize, pcolor, pwidth) {
var c = document.getElementById(element_id);
c.width = c.width;
var cxt = c.getContext("2d");
var numberOfSides = nSides,
size = psize,
Xcenter = c.width/2,
Ycenter = c.height/2;
cxt.beginPath();
cxt.moveTo (Xcenter + size * Math.cos(0), Ycenter + size * Math.sin(0));
for (var i = 1; i <= numberOfSides;i += 1) {
cxt.lineTo (
Xcenter + size * Math.cos(i * 2 * Math.PI / numberOfSides),
Ycenter + size * Math.sin(i * 2 * Math.PI / numberOfSides)
);
}
cxt.strokeStyle = pcolor;
cxt.lineWidth = pwidth;
cxt.stroke();
}
(function () {
polygon("regular_polygon", 3, 40, "#000000", 2);
document.querySelector('#draw').addEventListener('click', function (e) {
e.preventDefault();
var nSides = document.querySelector('#nSides'),
size = document.querySelector('#size'),
color = document.querySelector('#color'),
width = document.querySelector('#width');
polygon("regular_polygon", nSides.value, size.value, color.value, width.value);
});
})();
</script>
</body>
</html>