How to create image zoom effect using jquery? - javascript

I'm trying to create an image zoom effect similar to this one. I've managed to search a plugin called prefixfree.js and tried it in my code, but it did not work, its just showing the image but when I hover it there is no image zoom effect.
The link for the plugin is this. It should suppose to work like this.
Also for additional info, the size for the large image is 1406X1275 and the small image is 200X200. Kindly help me on solving this one or provide better alternatives.
$(document).ready(function() {
var native_width$ = 0;
var native_height = 0;
$(".magnify").mousemove(function(e) {
//When the user hovers on the image, the script will first calculate
//the native dimensions if they don't exist. Only after the native dimensions
//are available, the script will show the zoomed version.
if (!native_width && !native_height) {
//This will create a new image object with the same image as that in .small
//We cannot directly get the dimensions from .small because of the
//width specified to 200px in the html. To get the actual dimensions we have
//created this image object.
var image_object = new Image();
image_object.src = $(".small").attr("src");
//This code is wrapped in the .load function which is important.
//width and height of the object would return 0 if accessed before
//the image gets loaded.
native_width = image_object.width;
native_height = image_object.height;
} else {
//x/y coordinates of the mouse
//This is the position of .magnify with respect to the document.
var magnify_offset = $(this).offset();
//We will deduct the positions of .magnify from the mouse positions with
//respect to the document to get the mouse positions with respect to the
//container(.magnify)
var mx = e.pageX - magnify_offset.left;
var my = e.pageY - magnify_offset.top;
//Finally the code to fade out the glass if the mouse is outside the container
if (mx < $(this).width() && my < $(this).height( && mx > 0 && my > 0) {
$(".large").fadeIn(100);
} else {
$(".large").fadeOut(100);
}
if ($(".large").is(":visible")) {
//The background position of .large will be changed according to the position
//of the mouse over the .small image. So we will get the ratio of the pixel
//under the mouse pointer with respect to the image and use that to position the
//large image inside the magnifying glass
var rx = Math.round(mx / $(".small").width() * native_width - $(".large").width() / 2) * -1;
var ry = Math.round(my / $(".small").height() * native_height - $(".large").height() / 2) * -1;
var bgp = rx + "px " + ry + "px";
//Time to move the magnifying glass with the mouse
var px = mx - $(".large").width() / 2;
var py = my - $(".large").height() / 2;
//Now the glass moves with the mouse
//The logic is to deduct half of the glass's width and height from the
//mouse coordinates to place it with its center at the mouse coordinates
//If you hover on the image now, you should see the magnifying glass in action
$(".large").css({
left: px,
top: py,
backgroundPosition: bgp
});
}
}
})
})
* {
margin: 0;
padding: 0;
}
.magnify {
width: 200px;
margin: 50px auto;
position: relative;
}
.large {
width: 175px;
height: 175px;
position: absolute;
border-radius: 100%;
/*Multiple box shadows to achieve the glass effect*/
box-shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
/*Lets load up the large image first*/
background: url('microsoftLogo1.jpg') no-repeat;
/*hide the glass by default*/
display: none;
}
#subPic1 {
border: 1px solid black;
margin: 5px;
width: 50px;
height: 50px;
}
#subPic2 {
border: 1px solid black;
margin: 5px;
width: 50px;
height: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="magnify">
<div class="large"></div>
<img class="small" src="microsoftLogo1Small.jpg" />
</div>
<script src="http://thecodeplayer.com/uploads/js/prefixfree.js" type="text/javascript"></script>
<img id="subPic1" src="microsoftLogo1.jpg" onclick="getImage1()" /><br/>
<img id="subPic2" src="microsoftLogo2.jpg" onclick="getImage2()" />

HTML
<img src="sample.png" class="zoom" />
CSS
img.zoom {
width: 350px;
height: 200px;
-webkit-transition: all .2s ease-in-out;
-moz-transition: all .2s ease-in-out;
-o-transition: all .2s ease-in-out;
-ms-transition: all .2s ease-in-out;
}
.transition {
-webkit-transform: scale(1.8);
-moz-transform: scale(1.8);
-o-transform: scale(1.8);
transform: scale(1.8);
}
JavaScript
$(document).ready(function(){
$('.zoom').hover(function() {
$(this).addClass('transition');
}, function() {
$(this).removeClass('transition');
});
});

HTML
<div class="item">
<img src="pepsi.jpg" alt="pepsi" width="540" height="548">
<div class="item-overlay top"></div>
</div>
CSS
* {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;
}
.item {
position: relative;
border: 1px solid #333;
margin: 2%;
overflow: hidden;
width: 540px;
}
.item img {
max-width: 100%;
-moz-transition: all 0.3s;
-webkit-transition: all 0.3s;
transition: all 0.3s;
}
.item:hover img {
-moz-transform: scale(1.1);
-webkit-transform: scale(1.1);
transform: scale(1.1);
}

Related

How to conform top glare to all child elements

Goal
Make the glare layer on all visible children like a clip-path
––––––––––––
Heads Up
Child elements can be any shape with any animation
Child elements can be any svg shape with any kind of animation attached to it
So glare must be automatically dynamic and conforming
––––––––––––
What I've Done
I create an apple TV effect…
But the glare only works as a box on top of other boxes.
The glare does not conform to other shapes
Example Below
––––––––––––
What I Can't Use
Canvas - No Canvas Please - I'm not familiar with it
Clip-Path - Because child elements can be anything overflowing outside of the glare
––––––––––––
What I'm looking for
Some kind of magical CSS line of code that makes the glare layer conform to all elements under it… like a normal glare would work.
Is this possible?
Is there some way Javascript can glare it automatically?
Is there some kind of mix-blend-mode I can use to make the glare just work?
Or is this something that is just impossible?
Glare should not look like a box
––––––––––––
What I tried
I tried to scale the glare layer to scale(1.1) and use some mix-blend-mode
But I couldn't figure out how to make it work.
appleTV();
function appleTV(){
appleTVComponents = 0;
function rotateX(n) {return ' rotateX('+n+'deg)'}
function rotateY(n) {return ' rotateY('+n+'deg)'}
function translateX(n) {return ' translateX('+n+'px)'}
function translateY(n) {return ' translateY('+n+'px)'}
function perspective(n) {return 'perspective('+n+'px)'}
function scale(n) {return ' scale3d('+n+','+n+','+n+')'}
function section(s='',e) {e=document.createElement('section');e.className='appletv_'+s;return e;}
function getWidth(e) {return e.clientWidth || e.offsetWidth || e.scrollWidth}
function setPerspective(e) {e.style.transform = perspective(getWidth(e)*3);}
function preventScroll(state) {if(supportsTouch){win.preventScroll=state||false;}}
function preventDefault(e) {if (supportsTouch&&win.preventScroll){e.preventDefault();}}
function isTouchScreen() {return 'ontouchstart' in window || navigator.msMaxTouchPoints}
function child(e) {return e.firstChild;}
function children(e) {return [...e.children]}
let body = document.body,
win = window,
imgs = document.querySelectorAll('.appletv'),
totalImgs = imgs.length,
supportsTouch = isTouchScreen(),
move = 'mousemove',
start = 'mouseenter',
end = 'mouseleave';
if(supportsTouch){move='touchmove'; start='touchstart'; end='touchend';}
if(totalImgs <= 0){return;}
for(var l=0;l<totalImgs;l++){
var thisImg = imgs[l],
layerElems = [...thisImg.querySelectorAll('.appletv_layer')];
if(!layerElems.length){continue;}
while(thisImg.firstChild) {thisImg.removeChild(thisImg.firstChild);}
var containerHTML = section(''),
shineHTML = section('gloss'),
shadowHTML = section('shadow'),
layersHTML = section('layer'),
layers = [];
thisImg.id = 'appletv_'+(++appleTVComponents);
layerElems.forEach((e,i)=>{
let layer_ = section('rendered_layer')
layer = section(''),
img = e.getAttribute('data-img');
layer_.setAttribute('data-layer',i);
[...e.children].forEach(c=>{layer.appendChild(c)})
if (img) {layer.style.backgroundImage = 'url('+img+')';}
layer_.appendChild(layer);
layersHTML.appendChild(layer_);
layers.push(layer);
});
[shadowHTML,layersHTML,shineHTML].forEach(e=>{containerHTML.appendChild(e)});
thisImg.appendChild(containerHTML);
var w = getWidth(thisImg);
setPerspective(thisImg)
preventScroll();
(function enableMovements(_thisImg,_layers,_totalLayers,_shine) {
thisImg.addEventListener(move, e=>{processMovement(e,supportsTouch,_thisImg,_layers,_totalLayers,_shine);});
thisImg.addEventListener(start, e=>{processEnter(_thisImg);});
thisImg.addEventListener(end, e=>{processExit(_thisImg,_layers,_totalLayers,_shine);});
})(thisImg,layers,layerElems.length,shineHTML);
};
function processMovement(e, touchEnabled, elem, layers, totalLayers, shine){
preventDefault(e)
let bdst = body.scrollTop,
bdsl = body.scrollLeft,
pageX = (touchEnabled)? e.touches[0].pageX : e.pageX,
pageY = (touchEnabled)? e.touches[0].pageY : e.pageY,
offsets = elem.getBoundingClientRect(),
w = elem.clientWidth || elem.offsetWidth || elem.scrollWidth, // width
h = elem.clientHeight || elem.offsetHeight || elem.scrollHeight, // height
wMultiple = 320/w,
offsetX = 0.52 - (pageX - offsets.left - bdsl)/w, //cursor position X
offsetY = 0.52 - (pageY - offsets.top - bdst)/h, //cursor position Y
dy = (pageY - offsets.top - bdst) - h / 2, //#h/2 = center of container
dx = (pageX - offsets.left - bdsl) - w / 2, //#w/2 = center of container
yRotate = (offsetX - dx)*(0.07 * wMultiple), //rotation for container Y
xRotate = (dy - offsetY)*(0.1 * wMultiple), //rotation for container X
imgCSS = rotateX(xRotate)+rotateY(yRotate), //img transform
arad = Math.atan2(dy, dx), //angle between cursor and center of container in RAD
angle = arad * 180 / Math.PI - 90; //convert rad in degrees
if (angle < 0) {angle = angle + 360;}
if(elem.firstChild.className.indexOf(' over') != -1){imgCSS += scale(1.07);}
elem.firstChild.style.transform = imgCSS;
shine.style.background = 'linear-gradient(' + angle + 'deg, rgba(255,255,255,' + (pageY - offsets.top - bdst)/h * 0.4 + ') 0%,rgba(255,255,255,0) 80%)';
shine.style.transform = translateX((offsetX * totalLayers) - 0.1)+translateY((offsetY * totalLayers) - 0.1);
var revNum = totalLayers;
for(var ly=0;ly<totalLayers;ly++){
layers[ly].style.transform = translateX((offsetX * revNum) * ((ly * 2.5) / wMultiple))+translateX((offsetY * totalLayers) * ((ly * 2.5) / wMultiple));
revNum--;
}
}
function processEnter(e){preventScroll(true);setPerspective(e);child(e)&&child(e).classList.add('over');}
function processExit(elem, layers, totalLayers, shine){preventScroll();
child(elem).classList.remove('over')
child(elem).style.transform = '';
shine.style = '';
layers.forEach(e=>{e.style.transform = ''})
}
}
body,
html {
height: 100%;
min-height: 100%;
}
body {background: linear-gradient(to bottom, #f6f7fc 0%, #d5e1e8 40%);}
.center{
position: absolute;
left: 50%;
margin: 10px auto;
transform: translateX(-50%);
}
.appletv {
position: relative !important;
margin: 0 auto !important;
display: inline-block;
width: 300px;
height: 150px;
border-radius: 5px;
transform-style: preserve-3d;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
cursor: pointer;
backface-visibility: hidden;
}
.appletv.depressed {
margin-top: 25px;
box-shadow: 0 5px 30px rgba(0, 0, 0, 0.4);
}
.appletv_ {
position: relative;
width: 100%;
height: 100%;
border-radius: 5px;
transition: all 0.2s ease-out;
background: teal;
}
.appletv_container.over {z-index: 1;}
.appletv_container.over .appletv_shadow {box-shadow: 0 45px 100px rgba(14, 21, 47, 0.4), 0 16px 40px rgba(14, 21, 47, 0.4);}
.appletv_layer {
position: relative;
width: 100%;
height: 100%;
border-radius: 5px;
/*overflow: hidden;*/
transform-style: preserve-3d;
}
.appletv_rendered_layer {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
overflow: hidden;
border-radius: 5px;
transition: all 0.1s ease-out;
transform-style: preserve-3d;
}
.appletv_rendered_layer > :first-child {
position: absolute;
width: 104%;
height: 104%;
top: -2%;
left: -2%;
background-repeat: no-repeat;
background-position: center;
background-color: transparent;
background-size: cover;
transition: all 0.1s ease-out;
}
.appletv_shadow {
position: absolute;
top: 5%;
left: 5%;
width: 90%;
height: 90%;
transition: all 0.2s ease-out;
box-shadow: 0 8px 30px rgba(14, 21, 47, 0.6);
}
.appletv_gloss {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 5px;
/*display: none !important;*/
background: linear-gradient(135deg, rgba(255, 255, 255, 0.25) 0%, rgba(255, 255, 255, 0) 40%);
}
[data-layer="1"] {overflow: visible !important;}
[data-layer="1"] > section > section {
position: absolute;
background: rgb(50, 141, 210);
width: 60px;
height: 60px;
border-radius: 10px;
}
[data-layer="1"] > section > section:first-child {
left: -30px;
top: -10px;
}
[data-layer="1"] > section > section:last-child {
right: -20px;
top: 50px;
}
#keyframes rotate {
0% {transform: rotate(0);}
100% {transform: rotate(359deg);}
}
.appletv_gloss {
/*display: none;*/
background-blend-mode: multiply;
}
.appletv [data-layer="1"] {
transform: scale(0.5);
transition: .3s ease-in-out 0s;
}
.appletv:hover [data-layer="1"] {
transform: scale(1);
}
.appletv:hover [data-layer="1"] > section > section {
animation: rotate 10s linear 0s infinite;
}
.appletv:hover [data-layer="1"] > section > section:last-child {
animation: rotate 25s linear 0s infinite;
}
#hover {
font-size: 30px;
position: absolute;
top: 37%;
text-align: center;
width: 100%;
color: white;
text-shadow: 0 2px 2px rgba(0,0,0,0.3) ;
}
<html>
<body>
<section class="center">
<section class="appletv">
<section class="appletv appletv_layer" data-img="https://source.unsplash.com/random">
<section id="hover">Hover Corners</section>
</section>
<section class="appletv appletv_layer">
<section></section>
<section></section>
</section>
</section>
</section>
</body>
</html>

Removing custom cursor with js on touch devices

I have a custom cursor on my site that I want to hide on touch devices (mobile/tablet). I have successfully done this but for a split second when you visit the website the cursor appears in the top left corner then is hidden. Is there any way to stop it displaying at all?
This is the code im using to remove the ID of the cursor on touch devices.
jQuery(document).ready(function($) {
{
if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent)) {
$('#custom-cursor').remove();
}
}
});
jQuery(document).ready(function($) {
let cursor = document.querySelector('#custom-cursor');
document.addEventListener('mousemove', evt => {
let { clientX: x, clientY: y } = evt;
let scale = 1;
if (evt.target.matches('a,span,[onclick],img,video,i')) {
cursor.classList.add('active');
scale = 0.5;
} else {
cursor.classList.remove('active');
}
cursor.style.transform = `translate(${x}px, ${y}px) scale(${scale})`;
});
});
* {
cursor: none;
}
#custom-cursor {
position: fixed;
width: 20px; height: 20px;
top: -10px;
left: -10px;
border: 2px solid black;
border-radius: 50%;
opacity: 1;
background-color: #fb4d98;
pointer-events: none;
z-index: 99999999;
transition:
transform ease-out 0.15s,
border 0.5s,
opacity 0.5s,
background-color 0.5s;
}
#custom-cursor.active {
opacity: 0.5;
background-color: #000;
border: 2px solid #fb4d98;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="custom-cursor"></div>
Without seeing more of your code it's not possible to be absolutely sure, but from the info in the question it looks as though the whole page is loaded before the cursor is removed.
You could tackle this in a variety of ways, for example not having the cursor element in the initial HTML but adding it if required onload.
Alternatively you could leave your initial HTML as it is, but set the cursor to have display: none in your CSS. Then onload the JS adds setting the style.display to block if the cursor is not to be removed.
UPDATE: now having seen more of the code here is a snippet to show how the second method (cursor to have display: none until the page is loaded) might be implemented:
jQuery(document).ready(function($) {
let cursor = document.querySelector('#custom-cursor');
if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent)) {
$('#custom-cursor').remove();
}
else { cursor.style.display = 'block';}
document.addEventListener('mousemove', evt => {
let { clientX: x, clientY: y } = evt;
let scale = 1;
if (evt.target.matches('a,span,[onclick],img,video,i')) {
cursor.classList.add('active');
scale = 0.5;
} else {
cursor.classList.remove('active');
}
cursor.style.transform = `translate(${x}px, ${y}px) scale(${scale})`;
});
});
* {
cursor: none;
}
#custom-cursor {
position: fixed;
width: 20px; height: 20px;
top: -10px;
left: -10px;
border: 2px solid black;
border-radius: 50%;
opacity: 1;
background-color: #fb4d98;
pointer-events: none;
z-index: 99999999;
transition:
transform ease-out 0.15s,
border 0.5s,
opacity 0.5s,
background-color 0.5s;
display: none;
}
#custom-cursor.active {
opacity: 0.5;
background-color: #000;
border: 2px solid #fb4d98;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="custom-cursor"></div>

Perfectly positioned tooltips with position: fixed

I'm trying to create some very basic tooltips but I'm having trouble calculating the exact position these should go in with some JavaScript. The reason for wanting a fixed position is to make sure these work whenever there is overflow hidden and such.
This is my code so far:
var overflowTooltip = function (elem) {
let legendRow = elem.currentTarget.getBoundingClientRect();
let tooltip = elem.currentTarget.children[2];
let topPosition;
let leftPosition;
if ((elem.currentTarget.offsetWidth < elem.currentTarget.scrollWidth) && tooltip !== undefined) {
tooltip.classList.add('total-opacity');
$timeout(function () {
if (tooltip.offsetHeight > 35) {
topPosition = (legendRow.top - tooltip.offsetHeight / 4) - 65;
} else {
topPosition = legendRow.top - 65;
}
leftPosition = (legendRow.left + elem.currentTarget.offsetWidth) / 2;
tooltip.style.left = leftPosition + 'px';
tooltip.style.top = topPosition + 'px';
$timeout(function () {
tooltip.classList.remove('total-opacity');
}, 400)
}, 100);
} else {
elem.currentTarget.children[2].style.left = '-9999px';
}
}
And some SASS:
.custom-tooltip {
font-family: $brand-font-condensed;
font-size: 14px;
font-weight: 400;
position: fixed;
text-align: left;
overflow: visible !important;
background-color: rgba($dark-gray, 0.95);
color: #fff;
height: auto;
padding: 7px 10px;
z-index: 9000;
visibility: hidden;
opacity: 0;
border-radius: 2px;
box-shadow: 0 2px 5px 0 rgba(#000, 0.16), 0 2px 10px 0 rgba(#000, 0.12);
#include transition (.2s ease-in);
left: -9999px;
&:hover {
visibility: visible;
opacity: 1;
#include transition (.2s ease-out);
-webkit-transition-delay: .3s;
transition-delay: .3s;
}
}
The above works but it's not perfect. if I wanna change around the position for it to appear on the left, right, bottom. I'd have to so some refactoring. If the tooltip's height is bigger or smaller, the position changes, If I scroll up or down, the tooltip stays stuck on screen for a few seconds. etc. Lots of these little details which are pretty annoying.
Not interested in using a plugin at the moment nor jQuery. Thanks for any suggestion or feedback :)

Rotate drop-shadow effect with CSS

The question is almost the same as this: how to rotate the shadow effect with CSS?
But my question is a bit more complicated: i use "filter: drop-shadow" because object that i want to have shadow effect is composite - it consists of two primitive figures.
I achieved the desired effect with JS - just rotating the main object and then calculating drop-shadow direction. But the shadow blinks on rerendering, it is visible at least in Chrome.
(function() {
const RAD_TO_DEG = 180/Math.PI,
DEG_TO_RAD = Math.PI/180;
var arrow = document.getElementsByClassName('arrow')[0],
arrow_shadow_color = 'rgba(50,50,50,0.25)',
previous_x = 0,
previous_y = 0,
shadow_angle = -45,
shadow_blur_radius = 5,
shadow_offset = 15,
shadow_string_right = 'px ' + shadow_blur_radius + 'px ' + arrow_shadow_color + ')',
amount_of_attempts_to_skip = 10,
n = 0;
dropShadow(180);
document.addEventListener('mousemove', mouseMove);
function mouseMove(e) {
n++;
if (n%amount_of_attempts_to_skip === 0) {
var angle = Math.atan2( previous_y - e.pageY, e.pageX - previous_x ) * RAD_TO_DEG;
arrow.style.transform = 'rotate(' + (180 - ~~angle) + 'deg)';
dropShadow(angle);
previous_x = e.pageX;
previous_y = e.pageY;
}
}
function dropShadow(angle) {
angle = 180 - shadow_angle + angle;
var x = ( shadow_offset * Math.cos( angle * DEG_TO_RAD) ).toFixed(2),
y = ( shadow_offset * Math.sin( angle * DEG_TO_RAD) ).toFixed(2);
arrow.style.filter = 'drop-shadow(' + x + 'px ' + y + shadow_string_right;
}
})();
html, body {
width: 100%;
height: 100%;
box-sizing: border-box;
}
* {
margin: 0;
border: 0;
padding: 0;
position: relative;
box-sizing: inherit;
}
.container {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-100%, -50%);
}
.arrow {
width: 75px;
height: 20px;
background: #2ECC40;
transform-origin: right;
transition: all 0.15s ease;
}
.arrow:before {
content: "";
position: absolute;
border-bottom: 15px solid transparent;
border-right: 20px solid #2ECC40;
border-top: 15px solid transparent;
height: 0px;
width: 0px;
margin-left: -20px;
margin-top: -5px;
}
<div class="container"><div class="arrow"></div></div>
So the question is: is it possible to create a shadow effect for a composite object with CSS and then rotate it so that it keeps the absolute angle with CSS?
Or maybe at least with JS but some other way but manually setting x and y filter offsets.
UPD: i just realized that there is just no need to dynamically apply drop-shadow style - it can be applied to a container: there will be no rerendering flashes, no need to apply some techniques to smoothen the shadow movement, no need to manually calculate shadow offset, that's it. I answered my own question 'cuz it was silly.
I just realized that there is just no need to dynamically apply drop-shadow style - it can be applied to a container: there will be no rerendering flashes, no need to apply some techniques to smoothen the shadow movement, no need to manually calculate shadow offset, that's it. All of these will be rendered automatically.
So the answer for "is it possible to create a shadow effect for a composite object with CSS and then rotate it so that it keeps the absolute angle with CSS?" is Yes, it is possible: just apply drop-shadow filter to the container of the element that you want to have a shadow effect.
Stackoverflow, sorry for asking silly questions.
Shadow blinking is out of bug. I fixed your thing at my CodePen and below. Your project's arrow will get dynamic shadow with only CSS if you create pseudo element which will move with cursor.
That flickering of the shadow of 3D objects upon cursor move is browser specific long known CSS related kind of bug with fixes available everywhere. You only needed to know that matter. You can search StackOverflow and perform web search now. Two ways has minor difference in CSS. But both actually works. I have not changed your javascript.
You can read/see W3C docs, CSS tricks's this, CSS trick's this,W3 School and this code pen for CSS pseudo element drag-able drop shadow.
For your case I modified this :
.arrow {
width: 75px;
height: 20px;
background: #2ECC40;
transform-origin: right;
transition: all 0.01s ease;
transform-style: preserve-3d;
-webkit-transform: rotateY(60deg);
-webkit-transform-style: preserve-3d;
transform: rotateY(60deg);
(function() {
const RAD_TO_DEG = 180/Math.PI,
DEG_TO_RAD = Math.PI/180;
var arrow = document.getElementsByClassName('arrow')[0],
arrow_shadow_color = 'rgba(50,50,50,0.25)',
previous_x = 0,
previous_y = 0,
shadow_angle = -45,
shadow_blur_radius = 5,
shadow_offset = 15,
shadow_string_right = 'px ' + shadow_blur_radius + 'px ' + arrow_shadow_color + ')',
amount_of_attempts_to_skip = 10,
n = 0;
dropShadow(180);
document.addEventListener('mousemove', mouseMove);
function mouseMove(e) {
n++;
if (n%amount_of_attempts_to_skip === 0) {
var angle = Math.atan2( previous_y - e.pageY, e.pageX - previous_x ) * RAD_TO_DEG;
arrow.style.transform = 'rotate(' + (180 - ~~angle) + 'deg)';
dropShadow(angle);
previous_x = e.pageX;
previous_y = e.pageY;
}
}
function dropShadow(angle) {
angle = 180 - shadow_angle + angle;
var x = ( shadow_offset * Math.cos( angle * DEG_TO_RAD) ).toFixed(2),
y = ( shadow_offset * Math.sin( angle * DEG_TO_RAD) ).toFixed(2);
arrow.style.filter = 'drop-shadow(' + x + 'px ' + y + shadow_string_right;
}
})();
html, body {
width: 100%;
height: 100%;
box-sizing: border-box;
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
}
* {
margin: 0;
border: 0;
padding: 0;
position: relative;
box-sizing: inherit;
transform-style: preserve-3d;
}
.container {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-100%, -50%);
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
}
.arrow {
width: 75px;
height: 20px;
background: #2ECC40;
transform-origin: right;
transition: all 0.01s ease;
transform-style: preserve-3d;
-webkit-transform: rotateY(60deg);
-webkit-transform-style: preserve-3d;
transform: rotateY(60deg);
}
.arrow:before {
content: "";
position: absolute;
border-bottom: 15px solid transparent;
border-right: 20px solid #2ECC40;
border-top: 15px solid transparent;
height: 0px;
width: 0px;
margin-left: -20px;
margin-top: -5px;
}
<div class="container"><div class="arrow"></div></div>
Depends on what kind of solution you are looking for. If you need a lot of elements with shadows, it's better to use a prerendered image. Browser won't spend time calculating all the shadows and rotations for each element.
If you absolutely need a shadow on a composite object with CSS, use box-shadow. There is a hacky way to make a triangle with the shadow. It's much better and efficient to use an image though!
Here by rotating the wrapper element we rotate all of its children and automatically their box-shadow:
(matrix value is taken from the computed style)
<!doctype html>
<html>
<head>
<style>
#keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.arrow {
top: 150px;
left: 50px;
position: relative;
display: block;
width: 280px;
animation: rotate 5s infinite linear;
}
.arrow div {
display: inline-block;
position: absolute;
}
.arrow-body {
width: 251px;
height: 25px;
top: 16px;
background: green;
box-shadow: 1px 5px 0 0 black;
}
.arrow-head {
width: 0;
height: 0;
right: 0;
bottom: -84px;
box-sizing: border-box;
border: 1em solid black;
border-color: transparent transparent green green;
transform-origin: 0 0;
transform: rotate(225deg);
box-shadow: -5px 1px 0 0 black;
}
#log {
font-family: monospace;
}
</style>
<script>
setInterval(function(){
var a = document.getElementById("arrow");
var l = document.getElementById("log");
l.innerHTML = ".arrow { transform: " + window.getComputedStyle(a, null).getPropertyValue("transform") + " }";
}, 10);
</script>
</head>
<body>
<span id="log"></span>
<div class="arrow" id="arrow">
<div class="arrow-body"></div>
<div class="arrow-head"></div>
</div>
</body>
</html>

Make android swipe end effect [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I try to make this effect using css.
This is the effect:
I try to make div that:
div {
height: 300px;
width: 10px;
position: absolute;
border-radius: 0px 500px 500px 0;
-moz-border-radius: 0px 500px 500px 0;
-webkit-border-radius: 0px 500px 500px 0;
background-color: grey;
opacity:0.1;
}
and then by css change the width of this effect.But it look very ugly it more square then circle and also I the change in the width dont make it become like the effect. it looks like the shape become bigger in width but not become more circle...
How can I make this effect by css/js ? everything that I tried with the div look very bad.
Thanks.
The effect is a little tricky because of its shape. The key is that the circle that you are creating with the div has to be moved mostly off screen to get a curve that aligns more with the example you gave.
.container .effect{
position:absolute;
width:200px;
height:80%;
top:10%;
right:-140px;
background-color:#fff;
border-radius:100% 100% 100% 100%;
transition:width 500ms ease-in-out, right 500ms ease-in-out, opacity 500ms ease-in-out;
opacity:.7;
}
Here is a fiddle with more details. Try turning the overflow:hidden off on the .container element to see more details of whats going on. The JavaScript is just to show the effect happening.
**Side note: the background image is not my own and was used for education purposes. Credit belongs with the original owner.
Just give it a try (Don't forget to emulate touch events in chrome):
var _div = document.getElementById('wrapper');
var _elem = document.getElementById('div');
_div.addEventListener('touchmove', function () {
_elem.style.width = '60px';
});
_div.addEventListener('touchend', function () {
_elem.style.width = '0';
});
*, html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
#div {
height: 95%;
width: 0;
top: 2.5%;
position: absolute;
border-radius: 0 500px 500px 0;
-moz-border-radius: 0 500px 500px 0;
-webkit-border-radius: 0 500px 500px 0;
background-color: gray;
opacity: 0.1;
-webkit-transition: width .2s; /* Safari */
transition: width .2s;
}
#wrapper {
width: 100%;
height: 100%;
background: darkgreen;
}
<div id="wrapper">
<div id='div'></div>
</div>
Here is another take using pseudo-elements and transforms. When scroll reaches end on both sides, the faux-rubber-banding effect will show up.
Works with mouse scroll to test on non-touch screen desktops. For Chrome, can emulate mouse events to test.
Demo Fiddle: http://jsfiddle.net/abhitalks/v4mLkttL/
Demo Snippet:
var $wrap = $('#wrap'), startX, isDrag = false;
$wrap.on('touchstart', function(e) {
startX = e.originalEvent.touches[0].clientX; isDrag = true;
});
$wrap.on('touchmove', function(e) {
var delta = e.originalEvent.changedTouches[0].clientX - startX,
pos = $(this).scrollLeft(), w = $(this).width(),
iw = $(this).innerWidth(), sh = this.scrollWidth
;
if (isDrag) {
if ((delta > 0) && (pos <= 0)) {
$wrap.addClass('rubberLeft');
isDrag = false; e.preventDefault();
}
if ((delta < 0) && (pos + iw >= sh)) {
$wrap.addClass('rubberRight');
isDrag = false; e.preventDefault();
}
}
});
$wrap.on('touchend', function(e) {
isDrag = false; clearRubber();
});
$wrap.on('mousewheel DOMMouseScroll', function(e) {
var start = e.originalEvent,
delta = start.wheelDelta || -start.detail,
pos = $(this).scrollLeft(), w = $(this).width(),
iw = $(this).innerWidth(), sh = this.scrollWidth
;
this.scrollLeft += delta * -1;
if (pos <= 0) { $wrap.addClass('rubberLeft'); setTimeout(clearRubber, 600); }
else if (pos + iw >= sh) { $wrap.addClass('rubberRight'); setTimeout(clearRubber, 600); }
else { clearRubber(); }
e.preventDefault();
});
function clearRubber() { $wrap.removeClass('rubberLeft').removeClass('rubberRight'); }
* { box-sizing: border-box; padding: 0; margin: 0; }
html, body { height: 100vh; width: 100vw; overflow: hidden; }
#wrap {
min-width: 100vw; height: 100vh;
overflow-y: hidden; overflow-x: scroll;
background-color: #000; white-space: nowrap;
-webkit-overflow-scrolling: touch;
}
#wrap img { display: inline-block; vertical-align: top; }
#wrap::before, #wrap::after {
content: ''; display: block;
position: absolute; top: 4%;
width: 100px; height: 90%;
background-color: rgba(255,255,255,0.6);
box-shadow: 0 0 10px 4px rgba(0,0,0,0.5);
border-radius: 50%; transform: translateX(0px);
transition: transform 0.5s;
}
#wrap::before { left: -105px; }
#wrap::after { right: -105px; }
#wrap.rubberLeft::before { transform: translateX(45px); }
#wrap.rubberRight::after { transform: translateX(-45px); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrap">
<img class="page" src='//lorempixel.com/240/320' />
<img class="page" src='//lorempixel.com/241/320' />
<img class="page" src='//lorempixel.com/239/320' />
<img class="page" src='//lorempixel.com/240/320' />
<img class="page" src='//lorempixel.com/241/320' />
<img class="page" src='//lorempixel.com/239/320' />
</div>

Categories

Resources