Pulsating color change on svg image - html

I came across this awesome design today: http://codepen.io/tmrDevelops/pen/jPLpLJ
I really like the pulsating color change. On my website I have an .svg logo that I would like to change color like that when I hover over the image. I would like the actual svg to change color, not the background or anything. I really don't need the on-click animation.
Is this possible with css? I know I have the source right there in the codepen but this is a little above my skills.
Note: It doesn't even have to be based on this code. As long as it looks sort of the same it's ok.
HTML:
<canvas id="canv"></canvas>
<h4>Click For Random Squiggle</h4>
CSS:
#import url(http://fonts.googleapis.com/css?family=Poiret+One);
body {
width: 100%;
margin: 0;
overflow: hidden;
cursor: pointer;
background: hsla(0, 0%, 10%, 1);
font-family: 'Poiret One', serif;
}
h4 {
width: 100%;
position: absolute;
text-align: center;
bottom: 0;
left: 0;
color: hsla(255, 255%, 255%, .5);
font-size: 2em;
letter-spacing: 15px;
user-select: none;
}
JavaScript:
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
var max = 50;
var rad = 200;
var c, $, inc, p;
var c = document.getElementById('canv');
var $ = c.getContext('2d');
var w = c.width = window.innerWidth;
var h = c.height = window.innerHeight;
var u = 0;
var go = function() {
upd();
draw();
}
var upd = function() {
for (var i = 0; i < max; i++) {
if (i % 2 == 0) {
p[i].upd(inc);
} else {
p[i].upd(0);
}
}
}
var draw = function() {
u -= .5;
$.clearRect(0, 0, c.width, c.height);
$.fillStyle = 'hsla(0,0%,10%,1)';
$.fillRect(0, 0, w, h);
var xp1 = (p[0].x + p[max - 1].x) / 2;
var yp1 = (p[0].y + p[max - 1].y) / 2;
/*
first beginPath() set is a shadow mimic -
a black underlay, which is not necessary but
the canvas shadow attr kills the springiness
in FF :/ so using this instead for a lil depth.
*/
$.beginPath();
$.strokeStyle = 'hsla(0,0%,5%,.35)';
$.lineWidth = 26;
$.moveTo(xp1, yp1);
for (var i = 0; i < max - 1; i++) {
var xp = (p[i].x + p[i + 1].x) / 2;
var yp = (p[i].y + p[i + 1].y) / 2;
$.quadraticCurveTo(p[i].x - 2, p[i].y + 2, xp, yp);
}
$.quadraticCurveTo(p[i].x, p[i].y, xp1, yp1);
$.closePath();
$.stroke();
//this one is the actual color circle.
$.beginPath();
$.strokeStyle = 'hsla(' + u + ',100%, 50%,1)';
$.lineWidth = 20;
$.moveTo(xp1, yp1);
for (var i = 0; i < max - 1; i++) {
var xp = (p[i].x + p[i + 1].x) / 2;
var yp = (p[i].y + p[i + 1].y) / 2;
$.quadraticCurveTo(p[i].x, p[i].y, xp, yp);
}
$.quadraticCurveTo(p[i].x, p[i].y, xp1, yp1);
$.closePath();
$.stroke();
}
var set = function() {
var rot = 360 / max;
p = [];
for (var i = 0; i < max; i++) {
var pt = new Pt(w / 2, h / 2);
pt.radii = rot * i;
pt.rad = rad;
pt.ready();
p.push(pt);
}
}
window.addEventListener('mousedown', function() {
var rnd = (Math.random() * 410) + 10;
inc = (inc == 0) ? rnd : 0;
}, false);
var ready = function(e) {
inc = 0;
set();
run();
}
var run = function() {
window.requestAnimFrame(run);
go();
}
var Pt = function(midX, midY) {
this.acc = 5;
this.chng = 1.35;
this.midX = midX;
this.midY = midY;
this.vert = 0;
this.x, this.y, this.rad, this.radii, this.dia;
this.ready = function() {
this.dia = this.rad;
this.XY();
}
this.upd = function(inc) {
var r = this.dia + inc;
this.rad = this.getRad(r, this.rad);
this.XY();
}
this.XY = function() {
var cos = Math.cos(this.radii * (Math.PI / 180)) * this.rad;
var sin = Math.sin(this.radii * (Math.PI / 180)) * this.rad;
this.x = cos + this.midX;
this.y = sin + this.midY;
}
this.getRad = function(mv, cur) {
this.vert = (this.vert + ((mv - cur) / this.acc)) / this.chng;
return this.vert + cur;
}
}
window.addEventListener('resize', function() {
c.width = w = window.innerWidth;
c.height = h = window.innerHeight;
set();
}, false);
ready();

Like this?
.hue {
fill: red;
}
.hue:hover {
animation: pulse 10s infinite;
-webkit-animation: pulse 10s infinite;
}
#keyframes pulse {
0% { fill: #ff0000 }
17% { fill: #ffff00 }
33% { fill: #00ff00 }
50% { fill: #00ffff }
67% { fill: #0000ff }
83% { fill: #ff00ff }
100% { fill: #ff0000 }
}
#-webkit-keyframes pulse {
0% { fill: #ff0000 }
17% { fill: #ffff00 }
33% { fill: #00ff00 }
50% { fill: #00ffff }
67% { fill: #0000ff }
83% { fill: #ff00ff }
100% { fill: #ff0000 }
}
<svg>
<circle cx="150" cy="75" r="70" class="hue"/>
</svg>
This should work in Firefox and Chrome.

Related

How can I make an iframe resizeable without JavaScript?

I am trying to make iframes resizable the same way that a frameset with frames are. This is what I am trying to reproduce:
<!DOCTYPE html>
<html>
<frameset rows="80%,20%">
<frame src="https://www.w3schools.com" />
<frame src="https://www.tutorialspoint.com/html/top_frame.htm" />
</frameset>
</html>
See: Online Html Editor
I don't want to use JavaScript because it's widely claimed the iframe has the same functionality as frames and framesets, see: Obsolete Eements - W3. Its simply bad practice to use JavaScript for something that can be achieved perfectly without.
Using the resize property, is no good because it produces an icon in the bottom right hand corner the same as textarea. See: Resizable Columns without JQuery.
I decided to give up trying to do it without JavaScript. I managed to get it to work smoothly by making sure it gets the position of the mouse cursor correctly, even when hovering over the iframe. It requires access to the domain in the iframe to use postMessage to get the mouse coordinates but no problem, I am only going to use this to create debug tools on my own website anyway. It can be resized in all directions by dragging an edge or corner.
<!DOCTYPE html>
<style>
iframe {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
border: none;
}
.frame_holder {
display: block;
top: 300px;
left: 200px;
height: 500px;
width: 350px;
position: absolute;
}
.resizer {
position: absolute;
width: 7px;
height: 7px;
z-index: 2;
}
.resizer.n {
top: -7px;
left: 0px;
width: 100%;
cursor: n-resize;
}
.resizer.s {
bottom: -7px;
left: 0px;
width: 100%;
cursor: s-resize;
}
.resizer.w {
top: 0px;
left: -7px;
height:100%;
cursor: w-resize;
}
.resizer.e {
top: 0px;
right: -7px;
height:100%;
cursor: e-resize;
}
.resizer.nw {
top: -7px;
left: -7px;
cursor: nw-resize;
}
.resizer.ne {
top: -7px;
right: -7px;
cursor: ne-resize;
}
.resizer.sw {
bottom: -7px;
left: -7px;
cursor: sw-resize;
}
.resizer.se {
bottom: -7px;
right: -7px;
cursor: se-resize;
}
</style>
<body>
<div class="frame_holder">
<div class="resizer n"></div>
<div class="resizer s"></div>
<div class="resizer w"></div>
<div class="resizer e"></div>
<div class="resizer ne"></div>
<div class="resizer nw"></div>
<div class="resizer sw"></div>
<div class="resizer se"></div>
<iframe class="frame" src="https://stackoverflow.com/questions/74724195/how-can-i-make-an-iframe-resizeable-without-javascript"></iframe>
</div>
</body>
<script>
$ = typeof $ == "undefined" ? [] : $;
$[window.location.pathname]=function()
{
window.addEventListener('contextmenu', (e) => {e.preventDefault()});
const el = document.querySelector(".frame_holder");
const iframe = document.querySelector(".frame");
const resizers = document.querySelectorAll(".resizer");
var currentResizer = 0;
var prevX;
var prevY;
function resize(el, size)
{
Object.keys(size).forEach((i) =>
{
el.style[i] = size[i] + "px";
});
}
window.onmessage = function(e)
{
try
{
var msg = JSON.parse(e.data);
}
catch (e)
{
return;
}
if (msg.type == "mouseUp")
{
el.isResizing=false;
//window.removeEventListener("mousemove", mousemove);
//window.removeEventListener("mouseup", mouseup);
return
}
if (!el.isResizing)
{
try
{
window.removeEventListener("mousemove", mousemove);
//window.removeEventListener("mouseup", mouseup);
}
catch (e)
{ }
return;
}
const rect = el.getBoundingClientRect();
let mouseX = msg.mouseX + rect.left;
let mouseY = msg.mouseY + rect.top;
//let top = Math.min(rect.top - (prevY - mouseY), 0);
//let left = Math.min(rect.left - (prevX - mouseX), 0);
let top = rect.top - (prevY - mouseY);
let left = rect.left - (prevX - mouseX);
let width = rect.width + (prevX - mouseX);
let width1 = rect.width - (prevX - mouseX);
let height= rect.height - (prevY - mouseY);
let height1 = rect.height + (prevY - mouseY);
//let vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
//let vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
let currentResizer = this.currentResizer;
if (currentResizer.classList.contains("n"))
resize(el, {top: top, height: height1});
else if (currentResizer.classList.contains("w"))
resize(el, {left: left, width: width});
else if (currentResizer.classList.contains("s"))
resize(el, {height: height});
else if (currentResizer.classList.contains("e"))
resize(el, {width: width1});
else if (currentResizer.classList.contains("sw"))
resize(el, {left: left, width: width, height: height});
else if (currentResizer.classList.contains("ne"))
resize(el, {top: top, width: width1, height: height1});
else if (currentResizer.classList.contains("nw"))
resize(el, {top: top, left: left, width: width, height: height1});
else if (currentResizer.classList.contains("se"))
resize(el, {width: width1, height: height});
else
resize(el, {left: left, top: top});
prevX = mouseX;
prevY = mouseY;
};
for (let resizer of resizers)
{
if (resizer.classList.contains("n"))
iframe.style.borderTop = "groove 2px";
else if (resizer.classList.contains("s"))
iframe.style.borderBottom = "groove 2px";
else if (resizer.classList.contains("w"))
iframe.style.borderLeft = "groove 2px";
else if (resizer.classList.contains("e"))
iframe.style.borderRight = "groove 2px";
resizer.addEventListener("mousedown", mousedown);
function mousedown(e)
{
currentResizer = e.target;
//window.currentResizer = e.target;
window.currentResizer = currentResizer;
el.isResizing = true;
prevX = e.clientX;
prevY = e.clientY;
window.addEventListener("mousemove", mousemove);
window.addEventListener("mouseup", mouseup);
//msg.mouseX=344, msg.mouseY=830
//e.clientX=551, e.clientY=800
function mousemove(e)
{
if (!el.isResizing)
{
window.removeEventListener("mousemove", mousemove);
window.removeEventListener("mouseup", mouseup);
return;
}
const rect = el.getBoundingClientRect();
//let top = Math.min(rect.top - (prevY - e.clientY), 0);
//let left = Math.min(rect.left - (prevX - e.clientX), 0);
let top = rect.top - (prevY - e.clientY);
let left = rect.left - (prevX - e.clientX);
let width = rect.width + (prevX - e.clientX);
let width1 = rect.width - (prevX - e.clientX);
let height= rect.height - (prevY - e.clientY);
let height1 = rect.height + (prevY - e.clientY);
if (currentResizer.classList.contains("n"))
resize(el, {top: top, height: height1});
else if (currentResizer.classList.contains("w"))
resize(el, {left: left, width: width});
else if (currentResizer.classList.contains("s"))
resize(el, {height: height});
else if (currentResizer.classList.contains("e"))
resize(el, {width: width1});
else if (currentResizer.classList.contains("sw"))
resize(el, {left: left, width: width, height: height});
else if (currentResizer.classList.contains("ne"))
resize(el, {top: top, width: width1, height: height1});
else if (currentResizer.classList.contains("nw"))
resize(el, {top: top, left: left, width: width, height: height1});
else if (currentResizer.classList.contains("se"))
resize(el, {width: width1, height: height});
else
resize(el, {left: left, top: top});
prevX = e.clientX;
prevY = e.clientY;
}
function mouseup()
{
el.isResizing = false;
console.log("mouseup");
window.removeEventListener("mousemove", mousemove);
//window.removeEventListener("mouseup", mouseup);
}
}
}
}
if (document.readyState!='loading') $[window.location.pathname](); else document.addEventListener('DOMContentLoaded', $[window.location.pathname]);
</script>
This code goes inside the iframe:
if (!window.isTop)
{
function mouseup(e)
{
window.top.postMessage(JSON.stringify({ type: "mouseUp" }), '*');
}
function mousemove(e)
{
window.top.postMessage(JSON.stringify({ type: "mouseMove", mouseX: e.clientX, mouseY: e.clientY }), '*');
}
window.addEventListener("mouseup", mouseup);
window.addEventListener("mousemove", mousemove);
}

Html canvas, pixel manipulation and alpha channel

In html canvas, what I want to achieve is a white noise effect on a picture. So I get the picture, get its ImageData, modify it's alpha and draw it back.
var bat = new Image();
bat.src = "data:image/png;base64,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"
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = 250;
canvas.height = 250;
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(bat, 0, 0);
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
if (data[i] != 0 || data[i + 1] != 0 || data[i + 2] != 0) {
data[i + 3] = Math.floor(Math.random() * 255);
}
}
ctx.putImageData(imageData, 0, 0);
requestAnimationFrame(animate);
}
animate();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Bat</title>
<link rel="stylesheet" href="style.css" />
<style>
#main {
display: flex;
flex-direction: row;
}
#canvas {
border: 1px solid black;
width: 150px;
height: 150px;
}
</style>
</head>
<body>
<div id="main">
<canvas id="canvas"></canvas>
<br />
</div>
<script src="script.js"></script>
</body>
</html>
The result is what I need. But the issue is that when you use putImageData, even if the alpha is 0, it won't be transparent.
So I use a temporary canvas, draw the picture on it, modify it and then draw it back on the canvas.
var bat = new Image();
bat.src = "data:image/png;base64,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";
var canvas2 = document.getElementById('canvas2');
var ctx2 = canvas2.getContext('2d');
var tempCanvas = document.createElement('canvas');
var tempContext = tempCanvas.getContext('2d');
canvas2.width = 250;
canvas2.height = 250;
tempCanvas.width = 250;
tempCanvas.height = 250;
var img = new Image();
var alpha = 0;
function animate2() {
alpha += 0.1;
ctx2.clearRect(0, 0, canvas.width, canvas.height);
ctx2.fillStyle = 'blue';
ctx2.fillRect(0, 0, 250, 250);
tempContext.drawImage(bat, 0, 0);
var imageData = tempContext.getImageData(
0,
0,
tempCanvas.width,
tempCanvas.height
);
var data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
if (data[i] != 0 || data[i + 1] != 0 || data[i + 2] != 0) {
//data[i + 3] = Math.floor(Math.random() * 255);
data[i + 3] = 123;
//data[i + 3] = alpha;
}
}
tempContext.putImageData(imageData, 0, 0);
img.src = tempCanvas.toDataURL('image/png');
ctx2.drawImage(img, 0, 0);
requestAnimationFrame(animate2);
}
animate2();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Bat</title>
<link rel="stylesheet" href="style.css" />
<style>
#main {
display: flex;
flex-direction: row;
}
#canvas2 {
border: 1px solid black;
width: 150px;
height: 150px;
}
</style>
</head>
<body>
<div id="main">
<canvas id="canvas"></canvas>
<br />
<canvas id="canvas2"></canvas>
</div>
<script src="script.js"></script>
</body>
</html>
But whenever I want to change the alpha randomly with:
data[i + 3] = Math.floor(Math.random() * 255);
The picture won't display. And if I want to update the alpha other time with:
var alpha = 0;
alpha += 0.1
data[i + 3] = alpha;
The picture flickers...
What is the correct way to get my "white noise" picture that would be transparent so I can see the background through it?
Here is a link of a stackblitz with the demo in it.
First, don't call getImageData every frame. All you need is to know where the black pixels are in the image, these won't change so you can keep the same ImageData object all along, avoid slow read-backs from the GPU.
Then, you can drawImage() a canvas directly. No need to go through a new Image with a toDataURL() which will load your image async and indeed make your animation flicker.
So this would give:
var bat = new Image();
bat.src = "data:image/png;base64,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";
var canvas2 = document.getElementById('canvas2');
var ctx2 = canvas2.getContext('2d');
var tempCanvas = document.createElement('canvas');
var tempContext = tempCanvas.getContext('2d');
canvas2.width = 250;
canvas2.height = 250;
tempCanvas.width = 250;
tempCanvas.height = 250;
// store the ImageData in a way it's accessible at every frame
var imageData;
bat.onload = (evt) => { // always wait for the assets to load
ctx2.drawImage(bat, 0, 0);
imageData = ctx2.getImageData(0, 0, 250, 250);
animate2();
}
var alpha = 0;
function animate2() {
ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
ctx2.fillStyle = 'blue';
ctx2.fillRect(0, 0, 250, 250);
var data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
if (data[i] != 0 || data[i + 1] != 0 || data[i + 2] != 0) {
data[i + 3] = Math.floor(Math.random() * 255);
}
}
tempContext.putImageData(imageData, 0, 0);
// drawImage the tempCanvas directly
ctx2.drawImage(tempCanvas, 0, 0);
requestAnimationFrame(animate2);
}
#main {
display: flex;
flex-direction: row;
}
#canvas2 {
border: 1px solid black;
width: 150px;
height: 150px;
}
<div id="main">
<canvas id="canvas2"></canvas>
</div>
But you don't even need a second canvas here, you can draw "behind" the current drawing on a canvas thanks to the "destination-over" compositing mode. You can even use more compositing operations to clip that background so that only the image is "colored":
var bat = new Image();
bat.src = "data:image/png;base64,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";
var canvas2 = document.getElementById('canvas2');
var ctx2 = canvas2.getContext('2d');
canvas2.width = 250;
canvas2.height = 250;
// store the ImageData in a way it's accessible at every frame
var imageData;
bat.onload = (evt) => { // always wait for the assets to load
ctx2.drawImage(bat, 0, 0);
imageData = ctx2.getImageData(0, 0, 250, 250);
animate2();
}
function animate2() {
var data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
if (data[i] != 0 || data[i + 1] != 0 || data[i + 2] != 0) {
data[i + 3] = Math.floor(Math.random() * 255);
}
}
ctx2.putImageData(imageData, 0, 0);
ctx2.globalCompositeOperation = "destination-over"; // draw behind
ctx2.fillStyle = 'blue';
ctx2.fillRect(0, 0, 250, 250);
ctx2.globalCompositeOperation = "destination-in"; // keep only where new pixels are opaque
ctx2.drawImage(bat, 0, 0);
ctx2.globalCompositeOperation = "source-over"; // default
requestAnimationFrame(animate2);
}
#main {
display: flex;
flex-direction: row;
}
#canvas2 {
border: 1px solid black;
width: 150px;
height: 150px;
background: yellow
}
<div id="main">
<canvas id="canvas2"></canvas>
</div>

Aligning SVG Clip Path on top of image

EDIT 1: Quick codepen of my current issue: https://codepen.io/zuffdaddy/pen/QWGewKr
See how the clip path is massive while the image is small? How do align those two?
Original:
Intro:
I'm making an Attack Disc for a submarine simulator game.
The disc has multiple circular rings that all rotate and so far I have that part complete, but there's some overlapping transparent plastic parts that sit on top the rings and rotate as well.
Problem:
The problem is the plastic pieces that rotate on top are complex shapes (image of the shape here). The user needs to be able to click around them to manipulate the rings beneath them but also be able to click on them to rotate them as well.
SVG Clipping paths seem to be the way to go but I cannot get the svg clip path to align with the image.
Please ignore the JS, it's a temporary rotating script I pulled from another question here and will be rewritten towards finalization.
///////////////////////////////
// ------- rotate -------- //
///////////////////////////////
(function() {
var init, rotate, start, stop,
active = false,
angle = 0,
rotation = 0,
startAngle = 0,
center = {
x: 0,
y: 0
},
R2D = 180 / Math.PI,
rot = document.getElementById('attack_disc');
init = function() {
rot.addEventListener("mousedown", start, false);
$(document).bind('mousemove', function(event) {
if (active === true) {
event.preventDefault();
rotate(event);
}
});
$(document).bind('mouseup', function(event) {
event.preventDefault();
stop(event);
});
};
start = function(e) {
e.preventDefault();
var bb = this.getBoundingClientRect(),
t = bb.top,
l = bb.left,
h = bb.height,
w = bb.width,
x, y;
center = {
x: l + (w / 2),
y: t + (h / 2)
};
x = e.clientX - center.x;
y = e.clientY - center.y;
startAngle = R2D * Math.atan2(y, x);
return active = true;
};
rotate = function(e) {
e.preventDefault();
var x = e.clientX - center.x,
y = e.clientY - center.y,
d = R2D * Math.atan2(y, x);
rotation = d - startAngle;
return rot.style.webkitTransform = "rotate(" + (angle + rotation) + "deg)";
};
stop = function() {
angle += rotation;
return active = false;
};
init();
}).call(this);
(function() {
var init, rotate, start, stop,
active = false,
angle = 0,
rotation = 0,
startAngle = 0,
center = {
x: 0,
y: 0
},
R2D = 180 / Math.PI,
rot = document.getElementById('course_disc');
init = function() {
rot.addEventListener("mousedown", start, false);
$(document).bind('mousemove', function(event) {
if (active === true) {
event.preventDefault();
rotate(event);
}
});
$(document).bind('mouseup', function(event) {
event.preventDefault();
stop(event);
});
};
start = function(e) {
e.preventDefault();
var bb = this.getBoundingClientRect(),
t = bb.top,
l = bb.left,
h = bb.height,
w = bb.width,
x, y;
center = {
x: l + (w / 2),
y: t + (h / 2)
};
x = e.clientX - center.x;
y = e.clientY - center.y;
startAngle = R2D * Math.atan2(y, x);
return active = true;
};
rotate = function(e) {
e.preventDefault();
var x = e.clientX - center.x,
y = e.clientY - center.y,
d = R2D * Math.atan2(y, x);
rotation = d - startAngle;
return rot.style.webkitTransform = "rotate(" + (angle + rotation) + "deg)";
};
stop = function() {
angle += rotation;
return active = false;
};
init();
}).call(this);
(function() {
var init, rotate, start, stop,
active = false,
angle = 0,
rotation = 0,
startAngle = 0,
center = {
x: 0,
y: 0
},
R2D = 180 / Math.PI,
rot = document.getElementById('aob_disc');
init = function() {
rot.addEventListener("mousedown", start, false);
$(document).bind('mousemove', function(event) {
if (active === true) {
event.preventDefault();
rotate(event);
}
});
$(document).bind('mouseup', function(event) {
event.preventDefault();
stop(event);
});
};
start = function(e) {
e.preventDefault();
var bb = this.getBoundingClientRect(),
t = bb.top,
l = bb.left,
h = bb.height,
w = bb.width,
x, y;
center = {
x: l + (w / 2),
y: t + (h / 2)
};
x = e.clientX - center.x;
y = e.clientY - center.y;
startAngle = R2D * Math.atan2(y, x);
return active = true;
};
rotate = function(e) {
e.preventDefault();
var x = e.clientX - center.x,
y = e.clientY - center.y,
d = R2D * Math.atan2(y, x);
rotation = d - startAngle;
return rot.style.webkitTransform = "rotate(" + (angle + rotation) + "deg)";
};
stop = function() {
angle += rotation;
return active = false;
};
init();
}).call(this);
(function() {
var init, rotate, start, stop,
active = false,
angle = 0,
rotation = 0,
startAngle = 0,
center = {
x: 0,
y: 0
},
R2D = 180 / Math.PI,
rot = document.getElementById('bearing_lead_disc');
init = function() {
rot.addEventListener("mousedown", start, false);
$(document).bind('mousemove', function(event) {
if (active === true) {
event.preventDefault();
rotate(event);
}
});
$(document).bind('mouseup', function(event) {
event.preventDefault();
stop(event);
});
};
start = function(e) {
e.preventDefault();
var bb = this.getBoundingClientRect(),
t = bb.top,
l = bb.left,
h = bb.height,
w = bb.width,
x, y;
center = {
x: l + (w / 2),
y: t + (h / 2)
};
x = e.clientX - center.x;
y = e.clientY - center.y;
startAngle = R2D * Math.atan2(y, x);
return active = true;
};
rotate = function(e) {
e.preventDefault();
var x = e.clientX - center.x,
y = e.clientY - center.y,
d = R2D * Math.atan2(y, x);
rotation = d - startAngle;
return rot.style.webkitTransform = "rotate(" + (angle + rotation) + "deg)";
};
stop = function() {
angle += rotation;
return active = false;
};
init();
}).call(this);
html {
height: 100%;
overflow: hidden;
}
body {
background: #1c1c1c;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.wrapper {
height: 100%;
max-height: 960px;
width: 100%;
max-width: 960px;
position: relative;
margin: auto;
}
#attack_disc {
background-image: url('https://zuffdaddy.github.io/uboat-attack-disc/images/1.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
width: 30vw;
max-width: 1124px;
height: 30vw;
max-height: 1124px;
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
transform-origin: 50% 50%;
border-radius: 50%;
}
#course_disc {
background-image: url('https://zuffdaddy.github.io/uboat-attack-disc/images/2.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
width: 23vw;
max-width: 868px;
height: 23vw;
max-height: 868px;
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
transform-origin: 50% 50%;
border-radius: 50%;
}
#aob_disc {
background-image: url('https://zuffdaddy.github.io/uboat-attack-disc/images/3.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
width: 15.5vw;
max-width: 592px;
height: 15.5vw;
max-height: 592px;
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
transform-origin: 50% 50%;
border-radius: 50%;
}
#bearing_lead_disc {
background-image: url('https://zuffdaddy.github.io/uboat-attack-disc/images/4.png');
background-size: cover;
background-repeat: no-repeat;
background-position: center;
width: 23.5vw;
max-width: 884px;
height: 23.5vw;
max-height: 884px;
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
clip-path: url('#my-clip-path');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="attack_disc"></div>
<div id="course_disc"></div>
<div id="aob_disc"></div>
<div id="bearing_lead_disc">
<svg class="svg">
<clipPath id="my-clip-path" clipPathUnits="objectBoundingBox"><path d="M0.501,0 C0.556,0,0.555,0.04,0.555,0.04 C0.555,0.099,0.984,0.229,0.994,0.232 S1,0.243,0.999,0.251 C0.976,0.284,0.874,0.421,0.656,0.469 C0.656,0.469,0.648,0.47,0.647,0.474 C0.646,0.48,0.572,0.984,0.57,0.992 C0.569,0.996,0.569,0.999,0.561,0.999 C0.522,1,0.516,1,0.502,1 C0.487,1,0.482,1,0.443,0.999 C0.434,0.999,0.434,0.996,0.433,0.992 C0.432,0.984,0.358,0.48,0.357,0.474 C0.356,0.47,0.347,0.469,0.347,0.469 H0.347 C0.129,0.421,0.027,0.284,0.005,0.251 C0,0.243,0,0.236,0.01,0.232 S0.449,0.099,0.449,0.04 C0.449,0.04,0.447,0,0.502,0"></path></clipPath>
</svg>
</div>
</div>
The problem appears to be that you extracted the shape and converted it to objectBoundingBox coordinates relative to itself. So the objectBoundingBox coords are no longer relative to your attack disc image.
What you can do is apply a transform to the clip path to scale it down to where it should be. By trial and error I worked out an appropriate scaling that gets it to match the shape it is supposed to clip.
transform="translate(0.5,1) scale(0.415,0.52) translate(-0.5,-1)"
.svg {
position: absolute;
width: 0;
height: 0;
}
.clipped {
width: 884px;
height: 884px;
background: turquoise url(https://zuffdaddy.github.io/uboat-attack-disc/images/4.png);
background-size: cover;
-webkit-clip-path: url(#my-clip-path);
clip-path: url(#my-clip-path);
}
<svg class="svg">
<clipPath id="my-clip-path" clipPathUnits="objectBoundingBox"><path d="M0.501,0 C0.556,0,0.555,0.04,0.555,0.04 C0.555,0.099,0.984,0.229,0.994,0.232 S1,0.243,0.999,0.251 C0.976,0.284,0.874,0.421,0.656,0.469 C0.656,0.469,0.648,0.47,0.647,0.474 C0.646,0.48,0.572,0.984,0.57,0.992 C0.569,0.996,0.569,0.999,0.561,0.999 C0.522,1,0.516,1,0.502,1 C0.487,1,0.482,1,0.443,0.999 C0.434,0.999,0.434,0.996,0.433,0.992 C0.432,0.984,0.358,0.48,0.357,0.474 C0.356,0.47,0.347,0.469,0.347,0.469 H0.347 C0.129,0.421,0.027,0.284,0.005,0.251 C0,0.243,0,0.236,0.01,0.232 S0.449,0.099,0.449,0.04 C0.449,0.04,0.447,0,0.502,0" transform="translate(0.5,1) scale(0.415,0.52) translate(-0.5,-1)"></path></clipPath>
</svg>
<div class="clipped"></div>
Svg better to be inside div
Svg better to be inside div so you have more control on the shape and it's also can be scale.
First I fix your path 'd' with this site (https://aydos.com/svgedit/)
Second I put the svg inside the div
Third I order the svg with view box to suitable (with color red some transparent) like the background-image link in 'bearing_lead_disc' and use css pointer-events:none for ignore clicking on the div and then we can rotate the circles even we clicked on the shape.
link: (https://codepen.io/omergal/pen/qBqzeQa)
pic:
///////////////////////////////
// ------- rotate -------- //
///////////////////////////////
(function() {
var init, rotate, start, stop,
active = false,
angle = 0,
rotation = 0,
startAngle = 0,
center = {
x: 0,
y: 0
},
R2D = 180 / Math.PI,
rot = document.getElementById('attack_disc');
init = function() {
rot.addEventListener("mousedown", start, false);
$(document).bind('mousemove', function(event) {
if (active === true) {
event.preventDefault();
rotate(event);
}
});
$(document).bind('mouseup', function(event) {
event.preventDefault();
stop(event);
});
};
start = function(e) {
e.preventDefault();
var bb = this.getBoundingClientRect(),
t = bb.top,
l = bb.left,
h = bb.height,
w = bb.width,
x, y;
center = {
x: l + (w / 2),
y: t + (h / 2)
};
x = e.clientX - center.x;
y = e.clientY - center.y;
startAngle = R2D * Math.atan2(y, x);
return active = true;
};
rotate = function(e) {
e.preventDefault();
var x = e.clientX - center.x,
y = e.clientY - center.y,
d = R2D * Math.atan2(y, x);
rotation = d - startAngle;
return rot.style.webkitTransform = "rotate(" + (angle + rotation) + "deg)";
};
stop = function() {
angle += rotation;
return active = false;
};
init();
}).call(this);
(function() {
var init, rotate, start, stop,
active = false,
angle = 0,
rotation = 0,
startAngle = 0,
center = {
x: 0,
y: 0
},
R2D = 180 / Math.PI,
rot = document.getElementById('course_disc');
init = function() {
rot.addEventListener("mousedown", start, false);
$(document).bind('mousemove', function(event) {
if (active === true) {
event.preventDefault();
rotate(event);
}
});
$(document).bind('mouseup', function(event) {
event.preventDefault();
stop(event);
});
};
start = function(e) {
e.preventDefault();
var bb = this.getBoundingClientRect(),
t = bb.top,
l = bb.left,
h = bb.height,
w = bb.width,
x, y;
center = {
x: l + (w / 2),
y: t + (h / 2)
};
x = e.clientX - center.x;
y = e.clientY - center.y;
startAngle = R2D * Math.atan2(y, x);
return active = true;
};
rotate = function(e) {
e.preventDefault();
var x = e.clientX - center.x,
y = e.clientY - center.y,
d = R2D * Math.atan2(y, x);
rotation = d - startAngle;
return rot.style.webkitTransform = "rotate(" + (angle + rotation) + "deg)";
};
stop = function() {
angle += rotation;
return active = false;
};
init();
}).call(this);
(function() {
var init, rotate, start, stop,
active = false,
angle = 0,
rotation = 0,
startAngle = 0,
center = {
x: 0,
y: 0
},
R2D = 180 / Math.PI,
rot = document.getElementById('aob_disc');
init = function() {
rot.addEventListener("mousedown", start, false);
$(document).bind('mousemove', function(event) {
if (active === true) {
event.preventDefault();
rotate(event);
}
});
$(document).bind('mouseup', function(event) {
event.preventDefault();
stop(event);
});
};
start = function(e) {
e.preventDefault();
var bb = this.getBoundingClientRect(),
t = bb.top,
l = bb.left,
h = bb.height,
w = bb.width,
x, y;
center = {
x: l + (w / 2),
y: t + (h / 2)
};
x = e.clientX - center.x;
y = e.clientY - center.y;
startAngle = R2D * Math.atan2(y, x);
return active = true;
};
rotate = function(e) {
e.preventDefault();
var x = e.clientX - center.x,
y = e.clientY - center.y,
d = R2D * Math.atan2(y, x);
rotation = d - startAngle;
return rot.style.webkitTransform = "rotate(" + (angle + rotation) + "deg)";
};
stop = function() {
angle += rotation;
return active = false;
};
init();
}).call(this);
(function() {
var init, rotate, start, stop,
active = false,
angle = 0,
rotation = 0,
startAngle = 0,
center = {
x: 0,
y: 0
},
R2D = 180 / Math.PI,
rot = document.getElementById('bearing_lead_disc');
init = function() {
rot.addEventListener("mousedown", start, false);
$(document).bind('mousemove', function(event) {
if (active === true) {
event.preventDefault();
rotate(event);
}
});
$(document).bind('mouseup', function(event) {
event.preventDefault();
stop(event);
});
};
start = function(e) {
e.preventDefault();
var bb = this.getBoundingClientRect(),
t = bb.top,
l = bb.left,
h = bb.height,
w = bb.width,
x, y;
center = {
x: l + (w / 2),
y: t + (h / 2)
};
x = e.clientX - center.x;
y = e.clientY - center.y;
startAngle = R2D * Math.atan2(y, x);
return active = true;
};
rotate = function(e) {
e.preventDefault();
var x = e.clientX - center.x,
y = e.clientY - center.y,
d = R2D * Math.atan2(y, x);
rotation = d - startAngle;
return rot.style.webkitTransform = "rotate(" + (angle + rotation) + "deg)";
};
stop = function() {
angle += rotation;
return active = false;
};
init();
}).call(this);
html {
height: 100%;
overflow: hidden;
}
body {
background: #1c1c1c;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.wrapper {
height: 100%;
max-height: 960px;
width: 100%;
max-width: 960px;
position: relative;
margin: auto;
}
#attack_disc {
background-image: url('https://zuffdaddy.github.io/uboat-attack-disc/images/1.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
width: 30vw;
max-width: 1124px;
height: 30vw;
max-height: 1124px;
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
transform-origin:50% 50%;
border-radius:50%;
}
#course_disc {
background-image: url('https://zuffdaddy.github.io/uboat-attack-disc/images/2.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
width: 23vw;
max-width: 868px;
height: 23vw;
max-height: 868px;
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
transform-origin:50% 50%;
border-radius:50%;
}
#aob_disc {
background-image: url('https://zuffdaddy.github.io/uboat-attack-disc/images/3.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
width: 15.5vw;
max-width: 592px;
height: 15.5vw;
max-height: 592px;
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
transform-origin:50% 50%;
border-radius:50%;
}
#bearing_lead_disc {
background-image: url('https://zuffdaddy.github.io/uboat-attack-disc/images/4.png');
/* background-color: red; */
background-size: contain;
background-repeat: no-repeat;
background-position: center;
width: 23.5vw;
max-width: 884px;
height: 23.5vw;
max-height: 884px;
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
clip-path: url('#myPath');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="attack_disc"></div>
<div id="course_disc"></div>
<div id="aob_disc"></div>
<div id="bearing_lead_disc" style="pointer-events:none;">
<svg viewBox="0 0 512 512" style="width:100%; height:100%;">
<path style="pointer-events:all;" fill="#ff00004d" d="M255.77 26.76c20 0 19.5 18.5 19.5 18.5 0 27 155.5 86.5 159 88s3.61 5.03 1.78 8.5c-8.07 15.27-45.11 77.9-124.18 99.85 0 0-3.05.81-3.32 2.67-.38 2.6-27.27 233.45-27.88 237.47-.27 1.76-.27 2.84-3.35 2.97-14.18.56-16.1.53-21.37.53s-7.19.03-21.37-.53c-3.08-.12-3.09-1.2-3.35-2.97-.61-4.03-27.5-234.88-27.88-237.47-.27-1.86-3.32-2.69-3.32-2.69-79.01-21.98-116.01-84.57-124.08-99.84-1.83-3.47-1.72-7 1.78-8.5s159-61 159-88c0 0-.5-18.5 19.5-18.5" />
</svg>
</div>
</div>

Inverse Canvas Colors

This code produces a mathematical object: a white geometric shape that builds upon a white background. I can change the background color in the canvas tag, and the color of the lines that build the shape. The problem is a black square remains even when I change the canvas color. My goal is just to simply invert the colors, from a black background with a white shape to a black shape with a white background.
var canvas;
var ctx;
var canvasWidth = 600;
var canvasHeight = 600;
var circleR = 300;
var timeout = 0;
var often = 15;
function init() {
if (location.hash)
often = 5;
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
drawLines();
}
function drawLines() {
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
ctx.translate(canvasWidth / 2, canvasHeight / 2);
for (var i = 0; i < 25; i++) {
for (var a = -45; a <= 45; a += often) {
setTimeout("drawTimeout(" + a + ");", 100 * timeout);
timeout++;
}
}
}
function drawTimeout(a) {
ctx.beginPath();
ctx.moveTo(0, circleR);
var radians = Math.PI / 180 * a;
var x = (circleR * Math.sin(radians)) / Math.sin(Math.PI / 2 - radians);
ctx.lineTo(x, 0);
if (Math.abs(a) == 45) {
ctx.strokeStyle = "rgb(255,255,255)";
ctx.lineWidth = 1;
} else if (a == 0) {
ctx.strokeStyle = "rgb(200,200,200)";
ctx.lineWidth = 0.5;
} else {
ctx.strokeStyle = "rgb(110,110,110)";
ctx.lineWidth = 0.2;
}
ctx.stroke();
ctx.rotate((Math.PI / 180) * 15);
}
function redirect() {
if (window.location.hash) window.location.href = '';
else window.location.href = '#more';
window.location.reload(true);
}
init();
body {
margin: 0;
background-color: black;
}
canvas {
display: block;
margin: 10px auto;
background-color: black;
}
<canvas id="canvas" width="600" height="600"></canvas>
Here is a white on black version of your animation, didn't made so much changes, just the stroke colors and css.
var canvas;
var ctx;
var canvasWidth = 600;
var canvasHeight = 600;
var circleR = 300;
var timeout = 0;
var often = 15;
function init() {
if (location.hash)
often = 5;
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.fillStyle = "#FFF";
drawLines();
}
function drawLines() {
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
ctx.translate(canvasWidth / 2, canvasHeight / 2);
for (var i = 0; i < 25; i++) {
for (var a = -45; a <= 45; a += often) {
setTimeout("drawTimeout(" + a + ");", 100 * timeout);
timeout++;
}
}
}
function drawTimeout(a) {
ctx.beginPath();
ctx.moveTo(0, circleR);
var radians = Math.PI / 180 * a;
var x = (circleR * Math.sin(radians)) / Math.sin(Math.PI / 2 - radians);
ctx.lineTo(x, 0);
// store a variable for our color, since you only use shades of grey;
var c;
if (Math.abs(a) == 45) {
c = 0; // 255-255
ctx.strokeStyle = "rgb("+c+","+c+","+c+")";
ctx.lineWidth = 1;
} else if (a == 0) {
c = 55; // 255-200
ctx.strokeStyle = "rgb("+c+","+c+","+c+")";
ctx.lineWidth = 0.5;
} else {
c = 145; // 255-110
ctx.strokeStyle = "rgb("+c+","+c+","+c+")";
ctx.lineWidth = 0.2;
}
ctx.stroke();
ctx.rotate((Math.PI / 180) * 15);
}
function redirect() {
if (window.location.hash) window.location.href = '';
else window.location.href = '#more';
window.location.reload(true);
}
init();
body {
margin: 0;
background-color: black;
}
canvas {
display: block;
margin: 10px auto;
background-color: white;
}
<canvas id="canvas" width="600" height="600"></canvas>

Slider with visible slides from sides and costum animation

1. slider animation shema n1
2. slider animation shema n2
Imagine that there are two sliders one behind another. Both moves synchroniously, to the same side. The first one moves with inertion, to strech, and the bottom one (the main one) starts moving from start.
3. This is how it should look like in browser
4. This is what I have achieved so far
HTML
<div id="ghostCarousel">
<div id="content">
<div>
<img src="http://dqsvds7jo3ykg.cloudfront.net/files/2011/12/Post-Apocalyptic1-820x330.jpg" />
</div>
<div>
<img src="http://dqsvds7jo3ykg.cloudfront.net/files/2011/12/Post-Apocalyptic1-820x330.jpg" />
</div>
<div>
<img src="http://dqsvds7jo3ykg.cloudfront.net/files/2011/12/Post-Apocalyptic1-820x330.jpg" />
</div>
<div>
<img src="http://dqsvds7jo3ykg.cloudfront.net/files/2011/12/Post-Apocalyptic1-820x330.jpg" />
</div>
<div>
<img src="http://dqsvds7jo3ykg.cloudfront.net/files/2011/12/Post-Apocalyptic1-820x330.jpg" />
</div>
</div>
<div class="bg-block"></div>
<div id="gcNav">
</div>
CSS
html, body {
padding:0;
margin:0;
}
#ghostCarousel {
overflow: hidden;
/*position: relative;*/
}
#ghostCarousel #content > div {
width: 820px;
height: 330px;
float: left;
position: relative;
/* nuemus padding reikia padding ploti nustatyt i 0*/
padding-left:15px;
padding-right: 15px;
/*z-index: 99;*/
}
#ghostCarousel #content > div > img {
filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");
/* Firefox 10+, Firefox on Android */
filter: gray;
/* IE6-9 */
-webkit-filter: grayscale(100%);
/* Chrome 19+, Safari 6+, Safari 6+ iOS */
/*z-index: 99;*/
}
#content .active {
z-index: 9999;
}
#content .active img {
/*background: #FFF;*/
filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'1 0 0 0 0, 0 1 0 0 0, 0 0 1 0 0, 0 0 0 1 0\'/></filter></svg>#grayscale") !important;
-webkit-filter: grayscale(0%) !important;
}
.bg-block {
width:880px;
height: 500px;
position: absolute;
top: 0px;
left: 50%;
margin-left: -440px;
background: #FFF;
/*z-index: 100;*/
}
#gcNav {
width: 960px;
position: absolute;
top: 135px;
left: 50%;
/* move the left edge to the center … */
margin-left: -480px;
/* … and move it to the left half the box’ width. */
/*z-index: 9999;*/
}
#gcNav a {
display: block;
width: 40px;
height: 80px;
background: url("http://bisonai.infoaleja.lt/wp-content/themes/bisonai/img/controls.png") no-repeat;
}
#gcNav .left {
background-position: 0 0;
float: left;
}
#gcNav .right {
background-position: -40px 0;
float: right;
}
JS
$(function () {
var content = '#ghostCarousel #content';
var section = content + ' > div';
var v = $(window).width();
var w = $(section).width();
var c;
var itemuKiekis = $('#content div').length;
var vidurinioNr;
var paddingPlotis = 30;
var itemuSarasas = [];
function ghostCarousel() {
for (var i = 1; i <= itemuKiekis; i++) {
itemuSarasas[i] = $('#content div:nth-child(' + (i) + ')').html();
$('#content h3').hide();
$('#content p').hide();
//console.log(itemuSarasas[i]);
}
if (itemuKiekis % 2 === 0) {
c = ((w + paddingPlotis) * $(section).length - v + w) / 2;
vidurinioNr = itemuKiekis / 2 + 1;
var index = 1;
for (var i = vidurinioNr; i <= itemuKiekis; i++) {
$('#content div:nth-child(' + i + ')').html(itemuSarasas[index]);
$('#content div:nth-child(' + index + ')').html(itemuSarasas[i]);
console.log("i:" + i + " index:" + index);
index++;
}
for (var i = 1; i <= vidurinioNr; i++) {
$('#content div:nth-child(' + i + ')').html(itemuSarasas[index]);
console.log("i:" + i + " index:" + index);
index++;
}
} else {
c = ((w + paddingPlotis) * $(section).length - v) / 2;
vidurinioNr = (itemuKiekis + 1) / 2;
var index = 1;
for (var i = vidurinioNr; i <= itemuKiekis; i++) {
$('#content div:nth-child(' + i + ')').html(itemuSarasas[index]);
//console.log("i:" + i);
index++;
}
for (var i = 1; i < vidurinioNr; i++) {
$('#content div:nth-child(' + i + ')').html(itemuSarasas[index]);
console.log("i:" + i);
index++;
}
}
$('#content div:nth-child(' + vidurinioNr + ')').attr("class", "active");
console.log("v:" + v);
console.log("w:" + w);
console.log("c:" + c);
console.log("itemuKiekis:" + itemuKiekis);
console.log("vidurinioNr:" + vidurinioNr);
//TODO: keisti ilgi kad tilptu visos ft, jei netelpa
$(content).width((w + paddingPlotis * 2) * $(section).length);
$(content).css('margin-left', -c);
$('#gcNav a.left').click(function (e) {
e.preventDefault();
if ($(content).is(':animated')) return false;
$('#content .active h3').fadeOut();
$('#content .active p').fadeOut();
$('#content div:nth-child(' + (vidurinioNr + 1) + ')').attr("class", "active");
$('#content div:nth-child(' + (vidurinioNr) + ')').removeClass("active");
$(content).animate({
marginLeft: '-=' + w
}, 500, function () {
var first = $(section).eq(0);
$(section).eq(0).remove();
$(this).animate({
marginLeft: '+=' + w
}, 0);
$(this).append(first);
$('#content .active h3').fadeIn();
$('#content .active p').fadeIn();
});
});
$('#gcNav a.right').click(function (e) {
e.preventDefault();
if ($(content).is(':animated')) return false;
$('#content .active h3').fadeOut();
$('#content .active p').fadeOut();
$('#content div:nth-child(' + (vidurinioNr - 1) + ')').attr("class", "active");
$('#content div:nth-child(' + (vidurinioNr) + ')').removeClass("active");
$(content).animate({
marginLeft: '+=' + w
}, 500, function () {
var end = $(section).length - 1;
var last = $(section).eq(end);
$(section).eq(end).remove();
$(this).animate({
marginLeft: '-=' + w
}, 0);
$(this).prepend(last);
//$('#content div:nth-child(' + vidurinioNr + ')').attr("class","active");
$('#content .active h3').fadeIn();
$('#content .active p').fadeIn();
});
});
}
ghostCarousel();
$(window).resize(function () {
v = $(window).width();
w = $(section).width();
c = ((w + paddingPlotis) * $(section).length - v) / 2;
$(content).css('margin-left', -c);
});
});
working jsfiddle example - http://jsfiddle.net/V9RyW/
If you check fiddle, you will see that pictures make straight line and goes one by one when clicked. Also, the incoming photo gets 'active' class.
How to modify the code, that 1/3 of 3rd and 5th slide in n1 scheme would be hidden behind 4?
Also, how to achieve animation like in shema n2?
This question is quite broad but you can do something like
li{
display:inline-block;
}
li .arrows{
position:relative;
top:50%;
}
I found a JavaScript library called SimplyScroll that allows a group of images to be manually scolled from side-to-side, which appears to be your intention here.
I also found a working example that appears to meet your exact specifications.