Draw polygon using JavaScript and the CSS clip-path attribute - javascript

I have the following as my code which gives me my desired effect.
#overlay {
background-color: rgba(0, 0, 0, 0.66);
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
clip-path: polygon( 0% 0%, /*exterior top left*/
0% 100%, /*exterior bottom left*/
220px 100%, /*overlapping point exterior 1*/
220px 50%, /*overlapping point interior 1*/
220px 310px, /*interior top left*/
683px 310px, /*interior top right*/
683px 450px, /*interior bottom right*/
220px 450px, /*overlapping point interior 2*/
220px 100%, /*overlapping point exterior 2*/
100% 100%, /*exterior bottom right*/
100% 0%);
/*exterior top right*/
}
<body>
<div>Some background</div>
<div id="overlay">
</div>
<div id="closeButton">
<p>
Close
</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
function main() {
$("#overlay").hide();
$("#overlay").fadeIn(500);
$("#closeButton").on("click", function() {
$("#overlay").toggle();
});
}
$(document).ready(main);
</script>
</body>
I want to know if I could write a function to do the same thing that takes in an array of coordinates so that I don't have to hard code it in every time I want to move the window. It would trigger when the closeButton is pressed.

You could certainly compute a polygon string in JavaScript, then set that style on the element. Here's an example function that can take 2 pixel coordinates to create a similar polygon:
#overlay {
background-color: rgba(0, 0, 0, 0.66);
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
<body>
<div>Some background</div>
<div id="overlay">
</div>
<div id="closeButton">
<p>
Close
</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
// Copy this function:
function generatePoly(p1, p2) {
var a = p1[0] + 'px';
var b = p1[1] + 'px';
var c = p2[0] + 'px';
var d = p2[1] + 'px';
return 'polygon(' + [
'0% 0%',
'0% 100%',
a + ' 100%',
a + ' 50%',
a + ' ' + b,
c + ' ' + b,
c + ' ' + d,
a + ' ' + d,
a + ' 100%',
'100% 100%',
'100% 0%'
].join(', ') + ')';
}
function main() {
// Run this when you want to set the polygon:
$("#overlay").css('clip-path', generatePoly([40, 80], [120, 200]));
$("#overlay").hide();
$("#overlay").fadeIn(500);
$("#closeButton").on("click", function() {
$("#overlay").toggle();
});
}
$(document).ready(main);
</script>
</body>

Related

Transform orgin not being implemented

Attempting to transform an images scale (zoom) BUT maintain it inside it's parents left and top div so only trying to transform it down and to the right. Setting the transform orgin does not seem to work, what am I missing?
the following code zooms the image on each button click, but pushes the left and top out of the parent div.
$('element').click(function{
$('#element').css({'transform':'scale(' + scale + ')' });
$('#element').css({'transform-orgin':'top left'});
})
<div style "max-wdith:1080px; height: 700px; overflow-x:scroll; overflow-y:scroll">
<img id="element" src=" src="https://images.techhive.com/images/article/2017/03/castle_moat-100714623-large.jpg" " class="img-flud">
</div>
You can try the below code
var x = 400 + 'px';
var y = 300 + 'px';
$('#element').css({
'transform-origin': x + ' ' + y + ' 0px',
'-webkit-transform-origin': x + ' ' + y + ' 0px'
});
Updated answer!
const btn = document.querySelector('button');
function zoomIn(e) {
const scale = 0.1;
const img = document.querySelector('#my-image');
$('#my-image').css({transformOrigin: "top left", transform: 'scale(' + scale + ')'});
}
btn.addEventListener('click', zoomIn);
div {
width: 400px;
height: 400px;
border: 1px solid black;
overflow: hidden;
float: left;
}
div > img {
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<img id="my-image" src="https://images.techhive.com/images/article/2017/03/castle_moat-100714623-large.jpg" />
</div>
<button>Zoom In</button>

Need help scaling and rotating an image in a viewport

I have the code in this JSFidle - https://jsfiddle.net/pmi2018/smewua0k/211/
Javascript
$('#rotate').click(function(e) {
updateImage(90, 0)
console.log("rotation");
});
$('#zoom-in').click(function() {
updateImage(0, 0.1);
console.log("Zoomed in");
});
$('#zoom-out').click(function() {
updateImage(0, -0.1);
console.log("Zoomed out");
});
var zoomLevel = 1;
var rotation = 0;
var updateImage = function(angle, zoom) {
zoomLevel += zoom;
var img_scale = ' scale(' + zoomLevel + ') ';
rotation += angle;
if (rotation == 360) {
rotation = 0;
}
var str_rotation = ' rotate(' + rotation + 'deg) ';
console.log("rotation=" + str_rotation + " scale=" + img_scale);
var img = document.getElementById('sam');
img.style.transform = img_scale + str_rotation
//if (angle == 0) {
// img.style.transformOrigin = '0 0';
// img.style.transform = img_scale;
// }
// else {
// img.style.transformOrigin = 'center center';
// img.style.transform = str_rotation;
// }
}
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="zoom-in">zoom in</button> <button type="button" id="zoom-out">zoom out</button>
<div id=imageblock>
<img id="sam" src="http://placekitten.com/g/250/250" />
</div>
<div>
<a id="rotate" href="#">Rotate 90 degrees</a>
</div>
CSS
#imageblock {
width: 300px;
height: 300px;
border: 1px solid #000000;
overflow: auto;
display: block;
}
#sam {
transform-origin: center, center;
}
The problem is I need the have the origin be upper left corner when I scale the image to keep the scaled image in the box; but the origin has to be center, center when I rotate the image to keep the image in the box. However the CSS articles I have read say when rotating and scaling an image, they have to be done together.
I tried applying the rotation and scale separately so I could set the origin correctly (the commented out code), but only the first transform fires, and not the second.
How can I rotate and scale the image in the #imagebox?
Thanks!
Mark
The reason why it "goes together" is because the transform property can only have one origin. So if you apply multiple transformations on a single object, they will all use the same origin.
An easy solution would be to put the image in a div. Then, use the zoom on the div, and the rotate on the image for exemple so that both can have different origins.
$('#rotate').click(function(e) {
updateImage(90, 0)
});
$('#zoom-in').click(function() {
updateImage(0, 0.1);
});
$('#zoom-out').click(function() {
updateImage(0, -0.1);
});
var zoomLevel = 1;
var rotation = 0;
var updateImage = function(angle, zoom) {
zoomLevel += zoom;
var img_scale = ' scale(' + zoomLevel + ') ';
rotation += angle;
if (rotation == 360) {
rotation = 0;
}
var str_rotation = ' rotate(' + rotation + 'deg) ';
// Here I modified the syntax just a bit, to use JQuery methods instead of pur Javascript. I hope you are ok with it
// I modify the image rotate property, and then the div scale property
$('#sam').css('transform',str_rotation)
$('#zoom').css('transform', img_scale);
}
#imageblock {
width: 300px;
height: 300px;
border: 1px solid #000000;
overflow: auto;
display: block;
overflow: hidden; /* To hide the scrollbar when you zoom in */
}
#zoom {
transform:scale(1);
transform-origin:top left;
}
#sam {
transform: rotate(0deg)
transform-origin: center center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="zoom-in">zoom in</button> <button type="button" id="zoom-out">zoom out</button>
<div id=imageblock>
<div id="zoom"> <!-- I added this div -->
<img id="sam" src="http://placekitten.com/g/250/250" />
</div>
</div>
<div>
<a id="rotate" href="#">Rotate 90 degrees</a>
</div>
Also, please note that there is no coma in transform-origin: center center;.
Ask them if you have any questions. I hope it helped !

Zoom container with div using transform translate and scale

I would like to zoom a container with divs on click, using only css transform and scale. The problem is, that it works only on first click, on second, third... my divs are translating strange. For me very thing important is to scale background.
var scale =0.5;
var interval = 5;
var line_weight =1;
$('document').ready(function(){
$('#container').click(function(){
$('.test').each(function(i){
var position = $(this).position();
var positionL=position.left;
var positionT=position.top;
var positionTscale=positionT*scale;
var positionLscale=positionL*scale;
var translateX = -(positionL-positionLscale)*(1/scale);
var translateY = -(positionT-positionTscale) *(1/scale);
$(this).css( 'transform', 'scale('+ scale +')' + ' translate('+ translateX + 'px'+','+ translateY +'px )' );
});
$(".test").css('background', 'repeating-linear-gradient(0deg, #000, #000' + line_weight/scale+ ' #ffffff 0, #ffffff ' + scale*interval+ 'px');
$(".test").css('border-right', (line_weight) +'px solid');
});
$('#container').dblclick(function(){
$(".test").css('transform', 'scale(1.0)');
$(".test").css('background', 'repeating-linear-gradient(0deg, #000, #000' +line_weight+' , #ffffff 0, #ffffff ' + interval + 'px');
$(".test").css('border-right', line_weight+'px solid');
});
});
</script>
body{
width: 19200px;
height: 10750px;
}
.test{
height: 200px;
width: 160px;
display: inline-block;
border-right: 1px solid;
background: repeating-linear-gradient(0deg, #000, #000 1px, #ffffff 0, #ffffff 5px);
}
#container{
width: 340px;
height: 400px;
}
.column{
display: inline-block;
}
<script src="jquery-3.0.0.min.js"></script>
<body>
<div id="container">
<div>
<div class="test" >
<p class="click">test1</p>
</div>
<div class="test" >
<p class="click">test2</p>
</div>
</div>
<div>
<div class="test">
<p class="click">test3</p>
</div>
<div class="test">
<p class="click">test4</p>
</div>
</div>
</div>
</body>
Code on jsfiiddle
What you need is just change the value in transform: scale(value).
I added two buttons for the example for you to zoom in and zoom out:
<p class="zoom _bigger">
zoom++
</p>
<p class="zoom _smaller">
zoom--
</p>
And here is all js to solve your problem:
$('document').ready(function(){
// We set value as 2, because further we will zoom with a half
var zoomValue = 2;
$('.zoom').on('click', function(){
if ($(this).hasClass('_bigger')) {
zoomValue++;
} else if (zoomValue > 2) {
zoomValue--;
} else {
return false;
}
$('#container').css('transform', 'scale(' + zoomValue * 0.5 + ')');
});
});
I used a half value for zooming, and you can play with it and set what you wish.
You can check out my example on jsfiddle.

style conflict between javascript and css

I have built a little element 3d rotator for infinite rotating in either direction on the X or Y axis. However I am running into what I think is a css style conflict. #face2 has a css property that rotates it -180deg . however its not being implemented by the browser.
is this a css conflict perhaps?
you can see the code and the effect in this code pen :
//declaring global variables
window.RotXFrontVal = 0; // by how much to rotate the X value of the front face
window.RotXBackVal = -180; // by how much to rotate the X value of the back face
window.RotYFrontVal = 0; // by how much to rotate the Y value of the front face
window.RotYBackVal = 180; // by how much to rotate the Y value of the back face
$(document).ready(function() {
//$('#face2').css({'transform': 'rotateX(-180deg)'}, 0);
//$('#face2').animate({'transform', 'rotateX(-180deg)'}, 0);
//$('#face2').animate({'transform': 'rotateX(-180deg)'}, 0);
var MyDivSlider = function() { // Here will come the Div Slider by Scroll
var scl = $.now(); // Take a time stamp to prevent function from triggering too often
$(document).on('DOMMouseScroll mousewheel', function MyScroll(event) {
if (($.now() - scl) > 500) {
if (event.originalEvent.detail > 0 || event.originalEvent.wheelDelta < 0) {
//Scroll Down
window.RotXFrontVal = window.RotXFrontVal - 180;
window.RotXBackVal = window.RotXBackVal - 180;
console.log("Down. Front: " + RotXFrontVal + "and" + RotXBackVal + " is Back");
}
//Up Scroll
else {
window.RotXFrontVal = window.RotXFrontVal + 180;
window.RotXBackVal = window.RotXBackVal + 180;
console.log("Up. Front: " + RotXFrontVal + "and" + RotXBackVal + " is Back");
}
$('#face2').css('transform', 'rotateX(' + RotXBackVal + 'deg)');
$('#face1').css('transform', 'rotateX(' + RotXFrontVal + 'deg)');
console.log('rotateX(' + RotXFrontVal + ')')
console.log('rotateX(' + RotXBackVal + ')')
scl = $.now();
}
});
}();
});
body { height:100%; overflow:hidden;}
#card {
height:300px;
width: 300px;
display: block;
position: relative;
transform-style: preserve-3d;
transition: all 1.5s linear;
perspective: 1000px;
}
#face1 {
display: block;
position: absolute;
width: 100%;
height: 100%;
background: red;
backface-visibility: hidden;
transition: transform 1.5s;
z-index: 2;
}
#face2 {
display: block;
position: absolute;
width: 100%;
height: 100%;
background: blue;
backface-visibility: hidden;
transition: transform 1.5s;
z-index: 1;
transform: rotateX ( -180deg );
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<body>
<div id="card">
<div id = "face1">Use the mouse scroll button to rotate me</div>
<div id = "face2">Use the mouse scroll button to rotate me</div>
</div>
</body>
It's because of the whitespace inbetween rotateX and (
try: transform: rotateX( -180deg );

why CSS3 box-shadow detaches when I animate box with jQuery?

I have an image with a box shadow one it, but when I animate it, the box shadow seems to take on a life of its own, as seen here:
example
It happens the same way in both chrome, firefox, and IE.
I am perplexed and, more importantly at a loss at how to fix it so it looks pretty.
Thanks for any thoughts or answers about to fix this or why it is happening.
html/js:
<div id="sliderPane">
<div id="slider0" class="slider"><img src="1.jpg"/></div>
<div id="slider1" class="slider"><img src="2.jpg"/></div>
<div id="slider2" class="slider"><img src="3.jpg"/></div>
<div id="numSliders">3</div>
</div>
<script type="text/javascript">
var numsliders;
var currentSlider = 0;
var interval;
var slideWidth;
$('#slider0').css('opacity',1);
$(document).ready(function(){
numsliders = parseInt( $('#numSliders').html() );
$('#slider0').css('left', '62px');
$('#slider0').css('height', '200px');
$('#slider0').css('width', '200px');
$('#slider0').css('top', '20px');
$('#slider0').css('opacity', '1');
slideWidth = $('#slider0').width();
});
interval = window.setInterval(nextSlider, 5000);
function nextSlider() {
specificSlider((currentSlider + 1)%numsliders);
}
function specificSlider(sliderNumber){
//alert('oldslide: ' + currentSlider + " new sloide: " + sliderNumber);
window.clearInterval(interval);
// move the next slider on deck
$('#slider' + sliderNumber).css('left', $('#sliderPane').css('width'));
$('#slider' + sliderNumber).css('top', '70px');
$('#slider' + sliderNumber).css('hieght', '100px');
$('#slider' + sliderNumber).css('width', '100px');
//alert('lol');
// move old slide off,
$('#slider' + currentSlider).animate({
left: '-80px',
top: '50px',
hieght: '100px',
width: '100px',
opacity: 0
},900,null);
// new slide on
$('#slider' + sliderNumber).animate({
left: ($('#sliderPane').width() / 2 - slideWidth / 2) + 'px',
height: '200px',
width: '200px',
top: '20px',
opacity: 1
},900,null);
currentSlider = sliderNumber;
interval = window.setInterval(nextSlider, 5000);
}
</script>
css:
#sliderPane{
height: 200px;
position: relative;
overflow: hidden;
background-image: url('sliderBG.png');
background-size: 100% 100%;
padding: 20px 0;
}
.slider{
position: absolute;
opacity: 0;
top: -300px;
box-shadow: 2px 2px 10px 5px rgba(0,0,0,.4);
}
#numSliders{
visibility: hidden;
}
In order for you to accept an answer:
<div id="sliderPane">
<div id="slider0" class="slider"><img src="1.jpg"/></div>
<div id="slider1" class="slider"><img src="2.jpg"/></div>
<div id="slider2" class="slider"><img src="3.jpg"/></div>
<div id="numSliders">3</div>
</div>
<script type="text/javascript">
var numsliders;
var currentSlider = 0;
var interval;
var slideWidth;
$('#slider0').css('opacity',1);
$(document).ready(function(){
numsliders = parseInt( $('#numSliders').html() );
$('#slider0').css('left', '62px');
$('#slider0').css('height', '200px');
$('#slider0').css('width', '200px');
$('#slider0').css('top', '20px');
$('#slider0').css('opacity', '1');
slideWidth = $('#slider0').width();
});
interval = window.setInterval(nextSlider, 5000);
function nextSlider() {
specificSlider((currentSlider + 1)%numsliders);
}
function specificSlider(sliderNumber){
//alert('oldslide: ' + currentSlider + " new sloide: " + sliderNumber);
window.clearInterval(interval);
// move the next slider on deck
$('#slider' + sliderNumber).css('left', $('#sliderPane').css('width'));
$('#slider' + sliderNumber).css('top', '70px');
$('#slider' + sliderNumber).css('height', '100px');
$('#slider' + sliderNumber).css('width', '100px');
//alert('lol');
// move old slide off,
$('#slider' + currentSlider).animate({
left: '-80px',
top: '50px',
height: '100px',
width: '100px',
opacity: 0
},900,null);
// new slide on
$('#slider' + sliderNumber).animate({
left: ($('#sliderPane').width() / 2 - slideWidth / 2) + 'px',
height: '200px',
width: '200px',
top: '20px',
opacity: 1
},900,null);
currentSlider = sliderNumber;
interval = window.setInterval(nextSlider, 5000);
}
</script>

Categories