Animating newly created objects with different keyframes values - javascript

So I'm trying to make simple animation. When you press somewhere inside blue container, a circle should be created in this place and then go up. After some research I found how to put JS values into keyframes, but it's changing values for every object not just for freshly created. If you run snipped and press somewhere high and then somewhere low you will see what I'm talking about.
I found some AWESOME solution with Raphael library, but I'm a beginner and I'm trying to make something like this in JS. Is it even possible? How?
var bubble = {
posX: 0,
posY: 0,
size: 0
};
var aquarium = document.getElementById("container");
var ss = document.styleSheets;
var keyframesRule = [];
function findAnimation(animName) { //function to find keyframes and insert replace values in them
for (var i = 0; i < ss.length; i++) {
for (var j = 0; j < ss[i].cssRules.length; j++) {
if (window.CSSRule.KEYFRAMES_RULE == ss[i].cssRules[j].type && ss[i].cssRules[j].name == animName) {
keyframesRule.push(ss[i].cssRules[j]);
}
}
}
return keyframesRule;
}
function changeAnimation (nameAnim) { //changing top value to cursor position when clicked
var keyframesArr = findAnimation(nameAnim);
for (var i = 0; i < keyframesArr.length; i++) {
keyframesArr[i].deleteRule("0%");
keyframesArr[i].appendRule("0% {top: " + bubble.posY + "px}");
}
}
function createBubble(e) {
"use strict";
bubble.posX = e.clientX;
bubble.posY = e.clientY;
bubble.size = Math.round(Math.random() * 100);
var bubbleCircle = document.createElement("div");
aquarium.appendChild(bubbleCircle);
bubbleCircle.className = "bubble";
var bubbleStyle = bubbleCircle.style;
bubbleStyle.width = bubble.size + "px";
bubbleStyle.height = bubble.size + "px";
bubbleStyle.borderRadius = (bubble.size / 2) + "px";
//bubbleStyle.top = bubble.posY - (bubble.size / 2) + "px";
bubbleStyle.left = bubble.posX - (bubble.size / 2) + "px";
changeAnimation("moveUp");
bubbleCircle.className += " animate";
}
aquarium.addEventListener("click", createBubble);
//console.log(bubble);
body {
background-color: red;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
position: fixed;
top: 80px;
left: 0;
background-color: rgb(20,255,200);
}
#surface {
width: 100%;
height: 40px;
position: fixed;
top: 40px;
opacity: 0.5;
background-color: rgb(250,250,250);
}
.bubble {
position: fixed;
border: 1px solid blue;
}
.animate {
animation: moveUp 5s linear;//cubic-bezier(1, 0, 1, 1);
-webkit-animation: moveUp 5s linear;//cubic-bezier(1, 0, 1, 1);
}
#keyframes moveUp{
0% {
top: 400px;
}
100% {
top: 80px;
}
}
#-webkit-keyframes moveUp{
0% {
top: 400px;
}
100% {
top: 80px;
}
}
<body>
<div id="container">
</div>
<div id="surface">
</div>
</body>

Here is a possible solution. What I did:
Remove your functions changeAnimation () and findAnimation() - we don't need them
Update the keyframe to look like - only take care for the 100%
#keyframes moveUp { 100% {top: 80px;} }
Assign top of the new bubble with the clientY value
After 5 seconds set top of the bubble to the offset of the #container(80px) - exactly when animation is over to keep the position of the bubble, otherwise it will return to initial position
var bubble = {
posX: 0,
posY: 0,
size: 0
};
var aquarium = document.getElementById("container");
function createBubble(e) {
"use strict";
bubble.posX = e.clientX;
bubble.posY = e.clientY;
bubble.size = Math.round(Math.random() * 100);
var bubbleCircle = document.createElement("div");
aquarium.appendChild(bubbleCircle);
bubbleCircle.className = "bubble";
var bubbleStyle = bubbleCircle.style;
bubbleStyle.width = bubble.size + "px";
bubbleStyle.height = bubble.size + "px";
bubbleStyle.borderRadius = (bubble.size / 2) + "px";
bubbleStyle.top = bubble.posY - (bubble.size / 2) + "px";
bubbleStyle.left = bubble.posX - (bubble.size / 2) + "px";
bubbleCircle.className += " animate";
// The following code will take care to reset top to the top
// offset of #container which is 80px, otherwise circle will return to
// the position of which it was created
(function(style) {
setTimeout(function() {
style.top = '80px';
}, 5000);
})(bubbleStyle);
}
aquarium.addEventListener("click", createBubble);
body {
background-color: red;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
position: fixed;
top: 80px;
left: 0;
background-color: rgb(20, 255, 200);
}
#surface {
width: 100%;
height: 40px;
position: fixed;
top: 40px;
opacity: 0.5;
background-color: rgb(250, 250, 250);
}
.bubble {
position: fixed;
border: 1px solid blue;
}
.animate {
animation: moveUp 5s linear;
/*cubic-bezier(1, 0, 1, 1);*/
-webkit-animation: moveUp 5s linear;
/*cubic-bezier(1, 0, 1, 1);*/
}
#keyframes moveUp {
100% {
top: 80px;
}
}
#-webkit-keyframes moveUp {
100% {
top: 80px;
}
}
<body>
<div id="container"></div>
<div id="surface"></div>
</body>
The problem about your code was that it is globally changing the #keyframes moveUp which is causing all the bubbles to move.

The problem with your code is that you're updating keyframes which are applied to all bubbles. I tried another way of doing it by using transition and changing the top position after the element was added to the DOM (otherwise it wouldn't be animated).
The main problem here is to wait the element to be added to the DOM. I tried using MutationObserver but it seems to be called before the element is actually added to the DOM (or at least rendered). So the only way I found is using a timeout which will simulate this waiting, although there must be a better one (because it may be called too early, causing the bubble to directly stick to the top), which I would be happy to hear about.
var bubble = {
posX: 0,
posY: 0,
size: 0
};
var aquarium = document.getElementById("container");
function createBubble(e) {
"use strict";
bubble.posX = e.clientX;
bubble.posY = e.clientY;
bubble.size = Math.round(Math.random() * 100);
var bubbleCircle = document.createElement("div");
aquarium.appendChild(bubbleCircle);
bubbleCircle.classList.add("bubble");
var bubbleStyle = bubbleCircle.style;
bubbleStyle.width = bubble.size + "px";
bubbleStyle.height = bubble.size + "px";
bubbleStyle.borderRadius = (bubble.size / 2) + "px";
bubbleStyle.top = bubble.posY - (bubble.size / 2) + "px";
bubbleStyle.left = bubble.posX - (bubble.size / 2) + "px";
setTimeout(function() {
bubbleCircle.classList.add("moveUp");
}, 50);
}
aquarium.addEventListener("click", createBubble);
body {
background-color: red;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
position: fixed;
top: 80px;
left: 0;
background-color: rgb(20, 255, 200);
}
#surface {
width: 100%;
height: 40px;
position: fixed;
top: 40px;
opacity: 0.5;
background-color: rgb(250, 250, 250);
}
.bubble {
position: fixed;
border: 1px solid blue;
transition: 5s;
}
.moveUp {
top: 80px !important;
}
<body>
<div id="container">
</div>
<div id="surface">
</div>
</body>
Also, I used the classList object instead of className += ... because it is more reliable.

Related

Javascript carosel animation

I'm trying to make an image carousel with center animation. I don't want to use CSS animations, instead I'd like to use jQuery.
By pressing the 'Prev' button the animation will start. One of the slides which will be central begins to grow. I've used jQuery's animate() to animate width and height. Everything works as required except I can't understand why the animation makes the central slide jump.
I have created this sample. If you push the 'Prev' button the animation will start.
var scroll_speed = 4000;
var items_cnt = $('.mg_item').length;
var container_size = $(".main_cnt").innerWidth();
var item_avg_w = container_size / 5;
var item_center_w = ((item_avg_w / 100) * 20) + item_avg_w;
var item_center_h = (item_center_w / 16) * 9 + 30;
var item_w = ((container_size - item_center_w) / 4) - 2;
var item_h = ((item_w / 16) * 9);
var gallery_content = $('.gallery_body').html();
$('.gallery_body').html(gallery_content + gallery_content + gallery_content);
var items_offset = items_cnt * item_w + 14;
$('.gallery_body').css('left', -items_offset);
$('.mg_item').css("width", item_w);
$('.mg_item').css("height", item_h);
//$('.mg_item').css("margin-bottom", (item_center_h - item_h) / 2);
//$('.mg_item').css("margin-top", (item_center_h - item_h) / 2);
//$('.mg_item_с').css("width", item_center_w);
//$('.mg_item_с').css("height", item_center_h);
//document.documentElement.style.setProperty('--center_width', item_center_w + "px");
//document.documentElement.style.setProperty('--center_height', item_center_h + "px");
$('.main_cnt').css("height", item_center_h);
check_visible();
AssignCenter(0);
function gonext() {
AssignCenter(-1);
ZoomIn();
$('.gallery_body').animate({
left: '+=' + (item_w + 2),
}, scroll_speed, "linear", function() {
LoopSlides();
});
}
function goprev() {
AssignCenter(1);
ZoomIn();
$('.gallery_body').animate({
left: '-=' + (item_w + 2),
}, scroll_speed, "linear", function() {
LoopSlides();
});
}
function ZoomIn() {
$('.center').animate({
width: item_center_w + 'px',
height: item_center_h + 'px',
}, scroll_speed, function() {});
}
function LoopSlides() {
var cur_pos = $('.gallery_body').position().left
var left_margin = Math.abs(items_offset * 2 - item_w) * -1;
var right_margin = 0 - item_w;
if (cur_pos < left_margin) {
$('.gallery_body').css('left', -items_offset);
}
if (cur_pos >= 0) {
$('.gallery_body').css('left', -items_offset);
}
check_visible();
AssignCenter(0);
}
function check_visible() {
$('.mg_item').each(function(i, obj) {
var pos = $(this).offset().left;
if (pos < 0 || pos > container_size) {
$(this).addClass("invisible");
$(this).removeClass("active");
} else {
$(this).addClass("active");
$(this).removeClass("invisible");
}
});
}
function AssignCenter(offset) {
var center_slide = $('.active')[2 + offset];
$('.center').each(function(i, obj) {
$(this).removeClass("center");
});
$(center_slide).addClass("center");
//$(center_slide).css("width", item_center_w);
//$(center_slide).css("height", item_center_h);
}
:root {
--center_width: 0px;
--center_height: 0px;
}
.main_cnt {
background-color: rgb(255, 0, 0);
padding: 0px;
overflow: hidden;
margin: 0px;
}
.gallery_body {
width: 500%;
background-color: rgb(128, 128, 128);
position: relative;
}
.mg_item {
width: 198px;
height: 150px;
background-color: blue;
display: inline-block;
position: relative;
margin: -1px;
padding: 0px;
font-size: 120px;
}
.center {
background-color: brown;
/*width: var(--center_width) !important;
height: var(--center_height) !important;*/
}
.item_c {
width: 410px;
height: 150px;
background-color: blueviolet;
display: inline-block;
position: relative;
margin: -1px;
padding: 0px;
font-size: 120px;
}
.video-js .vjs-dock-text {
text-align: right;
}
<script src="https://code.jquery.com/jquery-2.2.0.min.js" type="text/javascript"></script>
<div class="main_cnt">
<div class="gallery_body">
<div class="mg_item">1</div>
<div class="mg_item">2</div>
<div class="mg_item">3</div>
<div class="mg_item">4</div>
<div class="mg_item">5</div>
<div class="mg_item">6</div>
<div class="mg_item">7</div>
</div>
</div>
<br><br>
<button onclick="gonext()">GONEXT</button>
<button onclick="goprev()">GOPREV</button>
<button onclick="check_visible()">CHEVIS</button>

Slider handle needs to restricted inside the container, should not go beyond the container

In the custom slider i have created, the handle is moving beyond the container. But i want it to stay within the container limits. We could just do it simple by setting margin-left as offset in CSS. But My requirement is when the handle right end detect the container's end the handle should not be allowed to move anymore. Any help is appreciated. Thanks.
Demo Link: https://jsfiddle.net/mohanravi/1pbzdyyd/30/
document.getElementsByClassName('contain')[0].addEventListener("mousedown", downHandle);
function downHandle() {
document.addEventListener("mousemove", moveHandle);
document.addEventListener("mouseup", upHandle);
}
function moveHandle(e) {
var left = e.clientX - document.getElementsByClassName('contain')[0].getBoundingClientRect().left;
var num = document.getElementsByClassName('contain')[0].offsetWidth / 100;
var val = (left / num);
if (val < 0) {
val = 0;
} else if (val > 100) {
val = 100;
}
var pos = document.getElementsByClassName('contain')[0].getBoundingClientRect().width * (val / 100);
document.getElementsByClassName('bar')[0].style.left = pos + 'px';
}
function upHandle() {
document.removeEventListener("mousemove", moveHandle);
document.removeEventListener("mouseup", upHandle);
}
.contain {
height: 4px;
width: 450px;
background: grey;
position: relative;
top: 50px;
left: 40px;
}
.bar {
width: 90px;
height: 12px;
background: transparent;
border: 1px solid red;
position: absolute;
top: calc(50% - 7px);
left: 0px;
cursor: ew-resize;
}
<div class='contain'>
<div class='bar'></div>
</div>
You need to change
this
document.getElementsByClassName('bar')[0].style.left = pos + 'px';
to this
if(pos > 90){
document.getElementsByClassName('bar')[0].style.left = pos - 90 + 'px';
}
else{
document.getElementsByClassName('bar')[0].style.left = 0 + 'px';
}
since width of your bar is 90px I am subtracting 90.
See this updated fiddle

Rotating an image when user scrolls up and down the screen

I am fairly new to writing in html, css, and coding in javascript.
I digress; i am trying to have an image of a gear rotate when the a user scrolls up and down the screen (i am hoping to give it an elevator effect when i add a belt).
I am using the jquery $(window).scroll(function(). I know it is working because when i use console.log("hi") it writes every time i scroll. My problem is the .animate() function that doesn't seem to work. I even tried downloading "http://jqueryrotate.com/" and using that to rotate.
Any help would be much appreciated!
## HTML ##
<div class="left_pulley">
<img src="gear2.png" />
</div>
<div class="right_pulley">
<img src="gear2.png" />
</div>
## CSS ##
.left_pulley
{
position: absolute;
margin: 0;
padding: 0;
top: 263px;
left: 87%;
height: 35px;
width: 35px;
}
.left_pulley img
{
width: 100%;
}
.right_pulley
{
position: absolute;
margin: 0;
padding: 0;
top: 263px;
left: 94.2%;
height: 35px;
width: 35px;
}
.right_pulley img
{
width: 100%;
}
## JS ##
First using .rotate({})
$(".left_pulley").rotate({bind:
$(window).scroll(function() {
if ($(this).scrollTop() > 0) {
$(.left_pulley).rotate({
angle: 0,
animateTo: 180,
})
})
})
})
Now using .animate({}) to try and just move it at all.
$(window).scroll(function() {
if ($(this).scrollTop() > 0) {
var scott = $('img');
scott.animate({
left: 180
}
}
});
$(window).scroll(function() {
if ($(this).scrollTop() > 0) {
var scott = $('img');
scott.animate({
left: 180
}
function() {
console.log("hi");
}
});
console.log("hi2");
}
});
.left_pulley {
position: absolute;
margin: 0;
padding: 0;
top: 263px;
left: 87%;
height: 35px;
width: 35px;
}
.left_pulley img {
width: 100%;
}
.right_pulley {
position: absolute;
margin: 0;
padding: 0;
top: 263px;
left: 94.2%;
height: 35px;
width: 35px;
}
.right_pulley img {
width: 100%;
}
<div class="left_pulley">
<img src="gear2.png" />
</div>
<div class="right_pulley">
<img src="gear2.png" />
</div>
[
picture of gears i want to rotate.
]1
You should look into the CSS3 transform property, more specifically the rotate() function. Here
It would also be beneficial to add a transistion property to create an animated 'tween' between rotation values. Here. Make sure to add this transition to the transition property (as this is where rotation is set).\
You can then change the rotation of the gear (with automatic animation!) using jquery by setting the css value of the transition property, for example:
#gear{
transition: transform 300ms;
transform: rotate(7deg);
transform-origin:90% 90%;
position:absolute;
left:100px;
top:100px;
font-size:10rem;
width:100px;
height:100px;
}
You can test it out here by hitting run.
https://jsfiddle.net/oc4hhons/
Borrowing heavily from https://stackoverflow.com/a/17348698/2026508
You could do something like this:
var degrees = 0;
var prevScroll = 0;
$(window).scroll(function() {
if ($(window).scrollTop() > 0) {
if (prevScroll > $(window).scrollTop()) {
$('.woo').css({
'-webkit-transform': 'rotate(' + degrees+++'deg)',
'-moz-transform': 'rotate(' + degrees+++'deg)',
'-ms-transform': 'rotate(' + degrees+++'deg)',
'transform': 'rotate(' + degrees+++'deg)'
});
console.log('prevScroll greater:', prevScroll)
} else if (prevScroll < $(window).scrollTop()) {
$('.woo').css({
'-webkit-transform': 'rotate(' + degrees--+'deg)',
'-moz-transform': 'rotate(' + degrees--+'deg)',
'-ms-transform': 'rotate(' + degrees--+'deg)',
'transform': 'rotate(' + degrees--+'deg)'
});
console.log('prevScroll less:', prevScroll)
}
prevScroll = $(window).scrollTop()
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="height: 40px; width: 100px;background-image: url(' gear2.png ');background-color:blue;" class="woo">turn</div>
JS Fiddle-Updated, now they rotate together same direction but the rotation is depending on whether the scroll is up or down:
JS:
var $gears = $('.gear'),
$i = 0,
$scrollBefore = 0;
$(window).scroll(function () {
if($(this).scrollTop() > $scrollBefore){
$scrollBefore = $(this).scrollTop();
$gears.css("transform", "rotate(" + ($i+=4) + "deg)");
}else if($(this).scrollTop() < $scrollBefore){
$scrollBefore = $(this).scrollTop();
$gears.css("transform", "rotate(" + ($i-=4) + "deg)");
}
});
this JS Fiddle 2, makes them rotate in opposite directions, and each gear direction switches depending if the scrolling is up or down:
JS:
var $gearLeft = $('.left_pulley'),
$gearRight = $('.right_pulley'),
$i = 0,
$j = 0,
$scrollBefore = 0;
$(window).scroll(function() {
if ($(this).scrollTop() > $scrollBefore) {
$scrollBefore = $(this).scrollTop();
$gearLeft.css("transform", "rotate(" + ($i += 4) + "deg)");
$gearRight.css("transform", "rotate(" + ($j -= 4) + "deg)");
} else if ($(this).scrollTop() < $scrollBefore) {
$scrollBefore = $(this).scrollTop();
$gearLeft.css("transform", "rotate(" + ($i -= 4) + "deg)");
$gearRight.css("transform", "rotate(" + ($j += 4) + "deg)");
}
});
Thanks for all the help everyone!
Just want to post my finial code in case anyone else needs help in the future.
/* Scott Louzon 11/24/15
This code is used to rotate two images of a gears when user scrolls */
/*This function see's when user scrolls then calls rotate_right & rotate_left
accordingly */
var scroll_at = 0; //variable to keep track of
//scroll postion
$(window).scroll(function() {
if ($(this).scrollTop() > 0) //if scroll postion is not at
{ //top do this
if ($(this).scrollTop() > scroll_at) //if scroll postion is > than b4
{
rotate_down();
}
else if ($(this).scrollTop() < scroll_at) //if scroll postion is < than b4
{
rotate_up();
}
scroll_at = $(this).scrollTop(); //set varible to were scroll
//postion is at now
}
})
//Both these functions call css to rotate the image of a gear
var rotation = 0;
function rotate_down()
{
rotation+= 8;
$(".left_pulley").css("transform","rotate("+ rotation +"deg)");
$(".right_pulley").css("transform","rotate("+ (-1 * rotation) +"deg)");
}
function rotate_up()
{
rotation += 8;
$(".left_pulley").css("transform","rotate("+ (-1 * rotation)+"deg)");
$(".right_pulley").css("transform","rotate("+ rotation +"deg)");
}
.left_pulley
{
position: absolute;
margin: 0;
padding: 0;
/*Used for gear rotation */
transition: transform 1ms;
transform-origin:50% 50%;
top: 263px;
left: 87%;
height: 35px;
width: 35px;
}
.left_pulley img
{
width: 100%;
}
.right_pulley
{
position: absolute;
margin: 0;
padding: 0;
/* Used for gear rotation */
transition: transform 1ms;
transform-origin:50% 50%;
top: 263px;
left: 94.2%;
height: 35px;
width: 35px;
}
.right_pulley img
{
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="left_pulley">
<img src="gear2.png" />
</div>
<div class="right_pulley">
<img src="gear2.png" />
</div>

jquery reveal image based on get second clock

I'm struggling to find a solution to this and wonder if anyone can help.
I'd like to make a page where an image would disappear over time revealing another image. I'm hoping to achieve this by using the updatesecond/getseconds function. So essentially it would act as a clock, the more minutes/seconds have passed the more it disappears, and have it cycle. For example at the beginning of the day it would be a full image, at 12 it would be half, and at 24hours it would be gone, and repeat. I figure it would be an if else function about the percentage of the page that's left, I just can't figure out how to word it.
Is this possible at all? Any help would be greatly appreciated. Thanks!
Here is the code I'm working with so far. Thank you in advance.
body
{
background-color: #FFF;
padding: 2%;
color: #ccc;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 1em;
}
a
{
color: #FFF;
text-decoration: none;
}
a:hover
{
color: #DCE808;
text-decoration: underline;
}
#mosaic
{
/* background-color: yellow;
font-size: 500px;
color: black;
height: 1310px;
width: 2000px; */
background-image: url('tomorrow4.png');
}
#mosaic span.hover
{
/* background-color: blue;
font-size: 500px;
color: white;
height: 1310px;
width: 2000px;
left: 100px;*/
float: left;
background-image: url('today4.png');
}
and javascript
$(document).ready(function() {
var width = 1400;
var height = 724;
count = 0;
elements = new Array();
var el = $('#mosaic');
el.width(width).height(height);
var horizontal_pieces = 100;
var vertical_pieces = 100;
total_pieces = horizontal_pieces * vertical_pieces;
var box_width = width / horizontal_pieces;
var box_height = height / vertical_pieces;
var vertical_position = 0;
for (i=0; i<total_pieces; i++)
{
var tempEl = $('<span class="hover" id="hover-' + i + '">
</span>');
var horizontal_position = (i % horizontal_pieces) * box_width;
if(i > 0 && i % horizontal_pieces == 0)
{
vertical_position += box_height;
}
tempEl.css('background-position', '-' + horizontal_position + 'px
-' + vertical_position + 'px');
el.append(tempEl);
elements.push(tempEl);
}
elements = shuffleArray(elements);
$('#mosaic .hover').width(box_width).height(box_height);
setInterval(toggleDisplay, 100);
});
function toggleDisplay()
{
var tempEl = elements[count];
var opacity = tempEl.css('opacity');
if(opacity == 0)
{
tempEl.animate({ opacity: 1 })
}
else
{
tempEl.animate({ opacity: 0 })
}
count = (count + 1) % total_pieces;
}
/* shuffleArray source:
http://stackoverflow.com/questions/2450954/how-to-randomize-a-
javascript-array#12646864 */
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor() * (i + 1);
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
Do you mean something like this? http://jsfiddle.net/1r5qer56/
I used 4 sectors (as skewY tends to screw up over 90 degrees) and had them set to a size relative to the amount of minutes that have passed since midnight.
If you want to test it, just put a custom number in for time.
My code is below:
HTML
<ul class='pie'>
<li class='slice tr'><div class='slice-contents'></div></li>
<li class='slice br'><div class='slice-contents'></div></li>
<li class='slice bl'><div class='slice-contents'></div></li>
<li class='slice tl'><div class='slice-contents'></div></li>
<ul>
CSS
.pie {
position: relative;
margin: 1em auto;
border: dashed 1px;
padding: 0;
width: 32em; height: 32em;
border-radius: 50%;
list-style: none;
background-image: url('http://lorempixel.com/output/animals-q-c-512-512-4.jpg');
}
.slice {
overflow: hidden;
position: absolute;
top: 0; right: 0;
width: 50%; height: 50%;
transform-origin: 0% 100%;
}
.slice.tr {
transform: rotate(0deg) skewY(-0deg);
}
.slice.br {
transform: rotate(90deg) skewY(0deg);
}
.slice.bl {
transform: rotate(180deg) skewY(0deg);
}
.slice.tl {
transform: rotate(270deg) skewY(0deg);
}
.slice-contents {
position: absolute;
left: -100%;
width: 200%; height: 200%;
border-radius: 50%;
background: lightblue;
}
.slice.tr .slice-contents {
transform: skewY(0deg); /* unskew slice contents */
}
.slice.br .slice-contents {
transform: skewY(0deg); /* unskew slice contents */
}
.slice.bl .slice-contents {
transform: skewY(0deg); /* unskew slice contents */
}
.slice.tl .slice-contents {
transform: skewY(0deg); /* unskew slice contents */
}
JS+jQuery
updateClock();
setInterval(function(){updateClock();}, 60000);//check for updates once per minute
function updateClock(){
var dt = new Date();
var time = (dt.getHours() * 60) + dt.getMinutes();//number of minutes since 00.00
var timeToDegrees = time / 4;//1440 minutes in 24hours, 360 degrees in a circle. 1440 / 4 = 360
if(timeToDegrees < 90){//deal with top right sector
$('.slice.tr').css('transform', 'rotate('+timeToDegrees+'deg) skewY(-'+timeToDegrees+'deg)');
$('.slice.tr .slice-contents').css('transform', 'skewY('+timeToDegrees+'deg)');
}
else if(timeToDegrees < 180){//deal with bottom right sector
var localDeg = timeToDegrees - 90;
$('.slice.tr').eq(0).css('transform', 'rotate(90deg) skewY(-90deg)');
$('.slice.tr .slice-contents').css('transform', 'skewY(90deg)');
$('.slice.br').css('transform', 'rotate('+(90+localDeg)+'deg) skewY(-'+localDeg+'deg)');
$('.slice.br .slice-contents').css('transform', 'skewY('+localDeg+'deg)');
}
else if(timeToDegrees < 270){//deal with bottom left sector
var localDeg = timeToDegrees - 180;
$('.slice.tr').css('transform', 'rotate(90deg) skewY(-90deg)');
$('.slice.tr .slice-contents').css('transform', 'skewY(90deg)');
$('.slice.br').css('transform', 'rotate(180deg) skewY(-90deg)');
$('.slice.br .slice-contents').css('transform', 'skewY(90deg)');
$('.slice.bl').css('transform', 'rotate('+(180+localDeg)+'deg) skewY(-'+localDeg+'deg)');
$('.slice.bl .slice-contents').css('transform', 'skewY('+localDeg+'deg)');
}
else if(timeToDegrees <= 360){//deal with top left sector
var localDeg = timeToDegrees - 270;
$('.slice.tr').css('transform', 'rotate(90deg) skewY(-90deg)');
$('.slice.tr .slice-contents').css('transform', 'skewY(90deg)');
$('.slice.br').css('transform', 'rotate(90deg) skewY(-90deg)');
$('.slice.br .slice-contents').css('transform', 'skewY(90deg)');
$('.slice.bl').css('transform', 'rotate(270deg) skewY(-90deg)');
$('.slice.bl .slice-contents').css('transform', 'skewY(90deg)');
$('.slice.tl').css('transform', 'rotate('+(270+localDeg)+'deg) skewY(-'+localDeg+'deg)');
$('.slice.tl .slice-contents').css('transform', 'skewY('+localDeg+'deg)');
}
}
Taking a look at the code, from what I gather, you're looking for a picture that is covered with another picture, proportional to the length of the day in seconds. Like one picture sliding over another? Like this picture:
Take a look at the jsBin I've created here http://jsbin.com/xevinakihe/edit?html,css,js,output
The meat of the code is the timing and height adjustment:
function setCoverHeight() {
var d = new Date();
var curSecs = d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds();
var coverHeight = curSecs * 100 / (24 * 3600);
$('.cover').height(coverHeight + '%');
if (curSecs < 24 * 3600) {
setTimeout(setCoverHeight, 1000);
console.log(coverHeight);
} else {
// reset the cover height to 0%
$('.cover').height(0);
// swap the cover image to the bottom
$('.bottom').css('backround-image', $('.cover').css('background-image'));
// set a new cover image
// ... get from Ajax, array, etc
}
}
setCoverHeight();
That is adjusting the HTML:
<div class="wrapper">
<div class="cover"></div>
<div class="bottom"></div>
</div>
Eventually the day will run out and the cover should be swapped with the bottom image, so that you can cycle through individual daily pictures (ex. 'today.jpg' and 'tomorrow.jpg')
Hope that helps!

Keep selected div centered when zooming

I have this HTML code:
<div class="inner">
<div class="nhood">
<div class="image"></div>
</div>
</div>
And this CSS:
.image {
width: 4000px;
height: 4000px;
background: beige;
margin: 150px;
position: absolute;
}
.nhood {
overflow: hidden;
width: 100%;
height: 100%;
box-sizing: border-box;
position: relative;
background: black;
}
The .image div is filled with 400 divs, all floating left, creating a huge 'chess'-pattern, the code is the following:
.image > div {
border: 1px dotted;
width: 5%;
height: 5%;
float: left;
box-sizing:border-box;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
position: relative;
user-select: none;
}
You are able to click on any cell to show its info, and the whole .image div is draggable. Now if you have selected a cell and you ZOOM (which basically only shrinks/extends the 4000x4000 div to 2000x2000 or the other way round) it zooms in ANYWHERE but I want to keep focus on the cell that was selected earlier.
I have made an image of this:
http://smimoo.lima-city.de/zoom.png
I hope this was any clear...
EDIT:
JS
function zoomIn() {
$(draggable).animate({
height: '4000',
width: '4000',
borderWidth: 0
}, 600, function() {
$divs.animate({
borderWidth: 0
});
});
}
function zoomOut() {
$(draggable).animate({
height: '2000',
width: '2000',
borderWidth: 0
}, 600, function() {
$divs.animate({
borderWidth: 1
});
});
EDIT2:
This is my js to center the function (written before Mario helped me out):
function centerField() {
var myObject = $(draggable).find('.selected');
var docWidth = ($(viewport).width() / 2) - (myObject.outerWidth()/2);
var docHeight = ($(viewport).height() / 2) - (myObject.outerWidth()/4);
var myOff = myObject.offset();
var distanceTop = myOff.top - docHeight;
var distanceLeft = myOff.left - docWidth;
var position = $(draggable).position();
var left = position.left;
var top = position.top;
var right = left - $(viewport).width() + draggable.outerWidth(true);
var bottom = top - $(viewport).height() + draggable.outerHeight(true);
if(left - distanceLeft > 0) {
distanceLeft = left;
}
if(right - distanceLeft < 0) {
distanceLeft = right;
}
if(top - distanceTop > 0) {
distanceTop = top;
}
if(bottom - distanceTop < 0) {
distanceTop = bottom;
}
$(draggable).animate({
left: '-=' + distanceLeft,
top: '-=' + distanceTop
}, { duration: 200, queue: false });
}
Assume that the selected div has the class .selected, this function will center the div:
function centerSelected() {
var selectedElement = $('.image .selected');
var p = selectedElement.position();
var w = $('.nhood').width();
var h = $('.nhood').height();
var offsetX = (w/2)-p.left - (selectedElement.width() / 2);
var offsetY = (h/2)-p.top - (selectedElement.height() / 2);
if(offsetX > 0) offsetX = 0;
if(offsetY > 0) offsetY = 0;
$('.image').css('left', offsetX + 'px');
$('.image').css('top', offsetY + 'px');
}
Just call centerSelected after every zoom operation.
Here is a jsfiddle with slightly modified css to get the presentation work:
http://jsfiddle.net/q1r95w3g/3/
Edit
If you want the div to get centered during jQuery animation, you can call centerSelected in the step callback of the animate method, e.g.:
function zoomIn() {
$(draggable).animate({
height: '4000',
width: '4000',
borderWidth: 0
},{
duration: 600,
complete: function() {
$divs.animate({
borderWidth: 0
});
},
step: function(now, fx) {
centerSelected();
}
});
}

Categories

Resources