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);
}
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>
I have finished a webpage I am working on, but unfortunately, I've only designed it for a 1920x1080 monitor. Whenever the site is viewed on other window sizes/monitor resolutions, the page does not adjust properly. Could someone possibly fix this so that the page is scaled accordingly when the window size is changed or it is viewed on mobile? If anyone could fix the code so that it would adjust to any browser side, that would be great. I've been working on it for a while. Here's the entire page:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Vortex Network</title>
</head>
<link href='https://fonts.googleapis.com/css?family=Luckiest+Guy' rel='stylesheet' type='text/css'>
<script>
window.onresize = function(event) {
...
}
</script>
<script>
(function(){
/**
author: #manufosela
2013/08/27 copyleft 2013
ShootingStar class Main Methods:
launch: launch shooting stars every N seconds received by param. 10 seconds by default.
launchStar: launch a shooting star. Received options object by param with:
- dir (direction between 0 and 1)
- life (between 100 and 400)
- beamSize (between 400 and 700)
- velocity (between 2 and 10)
**/
ShootingStar = function( id ) {
this.n = 0;
this.m = 0;
this.defaultOptions = { velocity:8, starSize:10, life:300, beamSize:400, dir:-1 };
this.options = {};
id = ( typeof id != "undefined" )?id:"";
this.capa = ( $( id ).lenght > 0 )?"body":id;
this.wW = $( this.capa ).innerWidth();
this.hW = $( this.capa ).innerHeight();
};
ShootingStar.prototype.addBeamPart = function( x, y ) {
this.n++;
var name = this.getRandom( 100, 1 );
$( "#star"+name ).remove();
$( this.capa ).append( "<div id='star"+name+"'></div>" );
$( "#star"+name ).append( "<div id='haz"+this.n+"' class='haz' style='position:absolute; color:#FF0; width:10px; height:10px; font-weight:bold; font-size:"+this.options.starSize+"px'>·</div>" );
if ( this.n > 1 ) $( "#haz" + ( this.n - 1 ) ).css( { color:"rgba(255,255,255,0.5)" } );
$( "#haz" + this.n ).css( { top: y + this.n, left: x + ( this.n * this.options.dir ) } );
}
ShootingStar.prototype.delTrozoHaz = function() {
this.m++;
$( "#haz" + this.m ).animate( {opacity:0}, 75 );
if ( this.m >= this.options.beamSize ) { $( "#ShootingStarParams" ).fadeOut( "slow" ); }
}
ShootingStar.prototype.getRandom = function( max, min ) {
return Math.floor( Math.random() * (max - min + 1)) + min;
}
ShootingStar.prototype.toType = function ( obj ) {
if ( typeof obj === "undefined" ) { return "undefined"; /* consider: typeof null === object */ }
if ( obj === null ) { return "null"; }
var type = Object.prototype.toString.call( obj ).match( /^\[object\s(.*)\]$/ )[1] || '';
switch ( type ) {
case 'Number': if ( isNaN( obj ) ) { return "nan"; } else { return "number"; }
case 'String': case 'Boolean': case 'Array': case 'Date': case 'RegExp': case 'Function': return type.toLowerCase();
}
if ( typeof obj === "object" ) { return "object"; }
return undefined;
}
ShootingStar.prototype.launchStar = function( options ) {
if ( this.toType( options ) != "object" ) { options = {}; }
this.options = $.extend( {}, this.defaultOptions, options );
this.n=0;
this.m=0;
var i=0, l=this.options.beamSize,
x=this.getRandom( this.wW - this.options.beamSize - 100, 100 ), y=this.getRandom( this.hW - this.options.beamSize - 100, 100 ),
self = this;
for( ; i<l; i++ ) { setTimeout( function(){ self.addBeamPart( x, y ); }, self.options.life + ( i * self.options.velocity ) ); }
for( i=0; i<l; i++ ) { setTimeout( function(){ self.delTrozoHaz() }, self.options.beamSize + ( i * self.options.velocity ) ); }
$( "#ShootingStarParams" ).html();
$( "#ShootingStarParams" ).fadeIn( "slow" );
}
ShootingStar.prototype.launch = function( everyTime ) {
if ( this.toType( everyTime ) != "number" ) { everyTime = 2; }
everyTime = everyTime * 1000;
this.launchStar();
var self = this;
setInterval( function() {
var options = {
dir: ( self.getRandom( 1, 0 ))?1:-1,
life: self.getRandom( 400, 100 ),
beamSize: self.getRandom( 700, 400 ),
velocity: self.getRandom( 10, 4 )
}
self.launchStar( options );
}, everyTime );
}
})();
</script>
</div>
<style type="text/css">
#top-image {
background:url('https://www.14denoviembre.es/img/stars_5.png') -25px -50px;
position:fixed ;
top:0;
width:100%;
height:100%;
background-size: calc(100% + 50px);
z-index:98;
}
body {
color:#FFF;
height:55%;
width:100%;
height:100%;
color:#FFF;
min-width:100%;
width: auto !important;
}
.stars {
position: absolute;
background-image: url( http://www.14denoviembre.es/img/hori.png ), url( http://www.14denoviembre.es/img/stars_5.png );
background-repeat: repeat-x,repeat-x repeat-y;
transform:translate3D(0em, 0em, 0);
animation: stars 21s ease;
transform-style: preserve-3d;
}
.Icon {
width: 100%;
height: 19%;
top: 5px;
position: fixed;
padding: 10px;
display: block;
margin:auto;
align-content: center;
}
.container {
position: relative;
top: 0px;
text-align: center;
}
#logo {
height:auto;
}
.shadowfilter {
-webkit-filter: drop-shadow(0px 0px 0px rgba(0,0,0,0.80));
-webkit-transition: all 0.5s linear;
-o-transition: all 0.5s linear;
transition: all 0.5s linear;
}
.shadowfilter:hover {
-webkit-filter: drop-shadow(0px 0px 8px rgba(255, 255, 179, 0.8));
}
#thumbs {
position: relative;
width: 52%;
margin-top: 30%;
margin-left: auto;
margin-right: auto;
z-index: 10000;
text-align: justify;
-ms-text-justify: distribute-all-lines;
text-justify: distribute-all-lines;
}
.status {
position: relative;
height: 5%;
margin: auto;
width: 27%;
border: 3px solid #ffffff;
text-align: center;
-moz-box-shadow: inset 0 0 75px #ffffff;
-webkit-box-shadow: inset 0 0 75px #ffffff;
box-shadow: inset 0 0 75px #ffffff;
z-index:99;
}
.stretch {
width: 100%;
display: inline-block;
font-size: 5;
}
.floating{
float: left;
-webkit-animation-name: Floatingx;
-webkit-animation-duration: 3s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: ease-in-out;
-moz-animation-name: Floating;
-moz-animation-duration: 3s;
-moz-animation-iteration-count: infinite;
-moz-animation-timing-function: ease-in-out;
margin-left: 30px;
margin-top: 5px;
}
#-webkit-keyframes Floatingx{
from {-webkit-transform:translate(0, 0px);}
65% {-webkit-transform:translate(0, 15px);}
to {-webkit-transform: translate(0, -0px); }
}
#-moz-keyframes Floating{
from {-moz-transform:translate(0, 0px);}
65% {-moz-transform:translate(0, 15px);}
to {-moz-transform: translate(0, -0px);}
}
.scaling{
float: center;
-webkit-animation-name: scalex;
-webkit-animation-duration:3s;
-webkit-animation-iteration-count:infinite;
-webkit-animation-timing-function:ease-in-out;
-moz-animation-name: scale;
-moz-animation-duration:3s;
-moz-animation-iteration-count:infinite;
-moz-animation-timing-function:ease-in-out;
}
#-webkit-keyframes scalex{
from {-webkit-transform: scale(0.9);}
65% {-webkit-transform: scale(1.0);}
to {-webkit-transform: scale(0.9);}
}
#-moz-keyframes scale{
from {-moz-transform: scale(0.9);}
65% {-moz-transform: scale(1.0);}
to {-moz-transform: scale(0.9);}
}
.zoom_img img{
-moz-transition:-moz-transform 0.2s ease-in;
-webkit-transition:-webkit-transform 0.2s ease-in;
-o-transition:-o-transform 0.2s ease-in;
}
.zoom_img img:hover{
-moz-transform:scale(1.1);
-webkit-transform:scale(1.1);
-o-transform:scale(1.1);
}
p {
font-family: 'Luckiest Guy', cursive;
-webkit-text-stroke: 3px black;
color: #ae00de;
font-size: 2.6em;
margin:0px;
}
</style>
<body class="stars">
<div class="zoom_img">
<div id="thumbs">
<img class="shadowfilter" src="http://s15.postimg.org/i03eeyw23/Forums_After.png" alt="Forums_Icon"/>
<img class="shadowfilter" src="http://s15.postimg.org/vshtalmtn/Vote_After.png" alt="Vote_Icon"/>
<img class="shadowfilter" src="http://s15.postimg.org/j4xgkciiz/Store_After.png" alt="Shop_Icon" height="200" width="190"/>
<img class="shadowfilter" src="http://s15.postimg.org/ds8m67umj/Staff_After_2.png" alt="Staff_Icon" height="200" width="200"/>
<img class="shadowfilter" src="http://s15.postimg.org/5vo4xzj63/Bans_After_2.png" alt="Bans_Icon"/>
<span class="stretch"></span>
</div>
</div>
<div class="container">
<div class="Icon">
<img src="http://files.enjin.com/353719/module_header/10950667/background/Vortex-Network-Logonew.png" class="scaling" width="642" height="460"></img>
</div>
</div>
<div class="status">
<p>play.vortexpvp.com</p>
</div>
<div id="top-image"></div>
<div id="ShootingStarParams"></div>
<script type="text/javascript" src="http://codeorigin.jquery.com/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="ShootingStarClass.js"></script>
<script type="text/javascript">
$( document ).ready( function(){
var shootingStarObj = new ShootingStar( "body" );
shootingStarObj.launch();
});
</script>
</div>
</body>
</html>
Thanks in advance for any help!
Use CSS3 #media Rule
you should apply CSS3 #media Rule to all the elements included in your website,
for example you have a #top-image style css:
#top-image {
background:url('https://www.14denoviembre.es/img/stars_5.png') -25px -50px;
position:fixed ;
top:0;
width:100%;
height:100%;
background-size: calc(100% + 50px);
z-index:98;
}
#media screen and (min-width: 480px) {
#top-image {
width:20%;
height:20%;
}
}
it will alter the #top-image's max width and height if the viewport is 480 pixels wide or wider.
Learn the syntax before you apply it to your website: http://www.w3schools.com/cssref/css3_pr_mediaquery.asp
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.