Dynamic aspect ratio with changing SRC - javascript

My problem is that after selecting an initial image file and trying to select another, the aspect ratio does not change in relation to selected image but keeps the aspect ratio of the image selected first.
I want the aspect ratio to dynamically change in relation the the natural aspect ratio of the selected image. I can't figure out a way to fix it without losing the resizable part.
var test = document.getElementById('test');
var draggable = document.getElementById('draggable');
var resizable = document.getElementById('resizable');
var img = document.querySelector('img');
img.onload = function() {
$(function() {
$("#draggable").draggable({});
$("#resizable").resizable({
aspectRatio: img.naturalWidth / img.naturalHeight,
maxHeight: 200,
maxWidth: 200,
minHeight: 20,
minWidth: 20,
});
});
}
window.addEventListener('load', function() {
document.querySelector('input[type="file"]').addEventListener('change', function() {
if (this.files && this.files[0]) {
img.src = URL.createObjectURL(this.files[0]);
}
});
});
#draggable {
display: inline-block;
margin: 0px;
}
#resizable {
position: absolute;
cursor: move;
margin: 0px;
max-height: 200px;
max-width: 200px;
box-sizing: border-box;
border: none;
}
.test {
width: 300px;
height: 300px;
overflow: hidden;
background-color: beige;
}
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/themes/cupertino/jquery-ui.css" rel="stylesheet" />
<link href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<input type='file' />
<div id='test' class='test'>
<div id='draggable' class="ui-widget-content">
<img id="resizable" class="ui-widget-content">
</div>
</div>

The issue is because the resizable widget only reads the dimensions of the content when it's instantiated, not when that content changes.
To fix this you need to check if the resizable widget has already been instantiated on the element and destroy it, along with removing any inline styling which the widget added to the element. Then you can change the image and reinitialise the widget again.
Also note that if you're using jQuery for the dragging and resizing, it would make sense to make the most of the convenience it offers for selecting the elements in the DOM and adding event handlers, too. Try this:
$(function() {
var $draggable = $('#draggable');
var $resizable = $('#resizable');
$('input[type="file"]').on('change', function() {
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$draggable.draggable();
if ($resizable.hasClass('ui-resizable'))
$resizable.resizable('destroy').removeAttr('style');
$resizable.prop('src', e.target.result).resizable({
maxHeight: 200,
maxWidth: 200,
minHeight: 20,
minWidth: 20,
});
}
reader.readAsDataURL(this.files[0]);
}
});
});
#draggable {
display: inline-block;
margin: 0px;
}
#resizable {
position: absolute;
cursor: move;
margin: 0px;
max-height: 200px;
max-width: 200px;
box-sizing: border-box;
border: none;
}
.test {
width: 300px;
height: 300px;
overflow: hidden;
background-color: beige;
}
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/themes/cupertino/jquery-ui.css" rel="stylesheet" />
<link href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<input type='file' />
<div id='test' class='test'>
<div id='draggable' class="ui-widget-content">
<img id="resizable" class="ui-widget-content">
</div>
</div>

Related

why is resizable when applied simultaneously with draggable on topleft and bottomleft giving me an unwanted behaviour

I want to apply resizable simultaneously with draggable for a div and it should be contained within its parent div but on dragging towards the left or top corner and resizing it from north-west,west,south-west handles makes the div widthless..
<!DOCTYPE html>
<html>
<head>
<title>Resizable</title>
<script src="https://code.jquery.com/jquery-1.12.4.js">
</script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js">
</script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<style type = "text/css">
#primary
{
width : 30rem;
height : 30rem;
background-color:green;
margin: auto;
}
#draggable{
width: 15rem;
height: 15rem;
background-color: yellow;
}
.ui-widget-content{
background: yellow;
}
</style>
</head>
<body>
<div id = "primary">
<div id= "draggable" class="ui-widget-content">
</div>
</div>
<script >
w= parseInt($('#draggable').css('width'),10);
h= parseInt($('#draggable').css('height'),10);
$( function() {
$( "#draggable" ).resizable( {handles: 'ne , nw ,se,
sw , n ,e ,s,w', minWidth : w, minHeight : h ,containment:"parent"
}).draggable({containment: "parent"});
} );
</script>
</body>
</html>
The trick is to set the primary div position: relative and the draggable div position: absolute
$(document).ready(function(){
let w = parseInt($('#draggable').width());
let h = parseInt($('#draggable').height());
$( function() {
$( "#draggable" ).resizable(
{
handles: 'n, e, s, w, ne, se, sw, nw',
minWidth : w,
minHeight : h,
containment:"#primary"
}).draggable(
{
containment: "#primary",
});
});
});
#primary
{
width: 30rem;
height: 30rem;
background-color: green;
margin: auto;
position: relative !important;
}
#draggable{
width: 15rem;
height: 15rem;
background-color: yellow;
position: absolute !important;
}
.ui-widget-content{
background: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id = "primary">
<div id= "draggable" class="ui-widget-content">
</div>
</div>

Cropit get image src

I am using cropit and I want to preview the cropped image in a modal. How do I get the src url of the cropped image
I copied the some parts of the basic html code for this plugin
HTML
<div class="image-editor">
<input type="file" class="cropit-image-input">
<div class="cropit-preview"></div>
<div class="image-size-label">
Resize image
</div>
<input type="range" class="cropit-image-zoom-input">
<button class="rotate-ccw">Rotate counterclockwise</button>
<button class="rotate-cw">Rotate clockwise</button>
<button class="export">Export</button>
</div>
JS
$(function() {
$('.image-editor').cropit({
imageState: {
src: 'http://lorempixel.com/500/400/',
},
});
$('.rotate-cw').click(function() {
$('.image-editor').cropit('rotateCW');
});
$('.rotate-ccw').click(function() {
$('.image-editor').cropit('rotateCCW');
});
$('.export').click(function() {
var imageData = $('.image-editor').cropit('export');
window.open(imageData);
});
});
What I tried so far was using from the documentation
$('.image-editor').cropit('imageSrc'); //but it returns null. Is there any other way to do this?
the demo and the documentation doesnt seem to blend so Im having a hard time using the plugin.
Just change this part. The imagedata is a usable base64 URL itself. It can't be open in a new window but you can easily set it as any image's src.
$('.export').click(function() {
var imageData = $('.image-editor').cropit('export');
$("#image").src = imageData;
});
Working Example
$(function() {
$('.image-editor').cropit({
exportZoom: 1.25,
imageBackground: true,
imageBackgroundBorderWidth: 50,
});
$('.export').click(function() {
var imageData = $('.image-editor').cropit('export');
document.querySelector("#image").src = imageData;
});
});
.image-editor {
text-align: center;
}
.cropit-preview {
background-color: #f8f8f8;
background-size: cover;
border: 5px solid #ccc;
border-radius: 3px;
margin-top: 7px;
width: 250px;
height: 250px;
display: inline-block;
}
.cropit-preview-image-container {
cursor: move;
}
.cropit-preview-background {
opacity: .2;
cursor: auto;
}
.image-size-label {
margin-top: 10px;
}
input, .export {
/* Use relative position to prevent from being covered by image background */
position: relative;
z-index: 10;
display: block;
}
button {
margin-top: 10px;
}
<script
src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropit/0.5.1/jquery.cropit.js"></script>
<div class="image-editor">
<input type="file" class="cropit-image-input">
<div class="cropit-preview"></div>
<input type="range" class="cropit-image-zoom-input">
<button class="export">Export</button>
</div>
<img id="image"/>

Get text under draggable div (jquery)

I have draggable div which dragging above .outerDiv with text content. How can I get text from .outerDiv which got into the borders of draggable div ?
$(".outerDiv .isStore").draggable({ containment: ".outerDiv" }).resizable({ containment: ".outerDiv" });
.isStore
{
width: 20px;
height: 20px;
background-color: red;
}
.outerDiv
{
width: 160px;
height: 160px;
background-color: #ccc;
}
.ui-resizable {
position: absolute !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/smoothness/jquery-ui.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script>
<div class='outerDiv'><div class='isStore'></div> sdfsdfsd
<br>
first
<br>
second
<br>
third
</div>
Edit: I want code that takes part of the text, under .isStore, from .outerDiv and puts it in .isStore after dragging.
var is_colliding = function( $div1, $div2 ) {
// Div 1 data
var d1_offset = $div1.offset();
var d1_height = $div1.outerHeight( true );
var d1_width = $div1.outerWidth( true );
var d1_distance_from_top = d1_offset.top + d1_height;
var d1_distance_from_left = d1_offset.left + d1_width;
// Div 2 data
var d2_offset = $div2.offset();
var d2_height = $div2.outerHeight( true );
var d2_width = $div2.outerWidth( true );
var d2_distance_from_top = d2_offset.top + d2_height;
var d2_distance_from_left = d2_offset.left + d2_width;
var not_colliding = ( d1_distance_from_top < d2_offset.top || d1_offset.top > d2_distance_from_top || d1_distance_from_left < d2_offset.left || d1_offset.left > d2_distance_from_left );
// Return whether it IS colliding
return ! not_colliding;
};
$(function(){
$(".outerDiv .isStore")
.draggable(
{
containment: ".outerDiv",
drag: function() {
$('.targetElem').each(function(){
$isStore = $('.isStore');
if (is_colliding($isStore , $(this))) {
var elemName = $(this).text();
if ($isStore.text().indexOf(elemName) == -1) {
$isStore.append(elemName+'<br>');
}
}
});
}
}
)
.resizable({ containment: ".outerDiv" });
});
.targetElem {background:yellow;}
.isStore
{
width: 20px;
height: 20px;
background-color: red;
}
.outerDiv
{
width: 160px;
height: 160px;
background-color: #ccc;
}
.ui-resizable {
position: absolute !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/smoothness/jquery-ui.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script>
<div class='outerDiv'><div class='isStore'></div>
<br>
<br>
<br>
<span class="targetElem">first</span><br>
<br>
<span class="targetElem">second</span><br>
<br>
<span class="targetElem">third</span>
</div>
I used code that detects if two divs are colliding:
http://stackoverflow.com/questions/5419134/how-to-detect-if-two-divs-touch-with-jquery
Here is a silly example;
I just created a draggable div which contain both the text and the isStore box:
$(".outerDiv .content").draggable({ containment: ".outerDiv" });
$(".outerDiv .isStore").resizable({ containment: ".outerDiv" });
.isStore
{
width: 20px;
height: 20px;
background-color: red;
}
.outerDiv
{
width: 160px;
height: 160px;
background-color: #ccc;
}
.ui-resizable {
position: absolute !important;
}
.content {
width: 80px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/smoothness/jquery-ui.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script>
<div class='outerDiv'><div class="content"><div class='isStore'></div> sdfsdfsd
<br>
first
<br>
second
<br>
third
</div></div>
Is this what you mean? (putting the text inside the red draggable/resizable div) Or do you want code that dynamically takes the code from outerDiv and puts it in isStore?
Note I used "overflow:hidden" in the style for isStore so that it doesn't show outside of the div.
$(".outerDiv .isStore").draggable({ containment: ".outerDiv" }).resizable({ containment: ".outerDiv" });
.isStore
{
width: 20px;
height: 20px;
background-color: red;
overflow: hidden;
}
.outerDiv
{
width: 160px;
height: 160px;
background-color: #ccc;
}
.ui-resizable {
position: absolute !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/themes/smoothness/jquery-ui.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js"></script>
<div class='outerDiv'><div class='isStore'>sdfsdfsd
<br>
first
<br>
second
<br>
third</div>
</div>

Fancybox caption location

I am having some serious trouble understanding Fancybox. I suppose my initial question is that I am using Fancybox 3 and assume that it has all features of previous versions?
What I am trying to achieve is simply change the caption position to inside rather than the default. I have tried so many different JS options to get a titleposition: 'inside' and it changes absolutely nothing...
<!DOCTYPE HTML>
<head>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" type="text/css" href="fancybox/jquery.fancybox.css">
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="fancybox/jquery.fancybox.js"></script>
</body>
<footer>
<section class="socialmedia">
<a class="sm" href="images/snapcode.png" data-fancybox data-caption="Snapchat"><img src="images/snapchat.png"></a>
</footer>
</html>
I am using the defaults
Of course, it is too late but maybe help someone.
Explanation: copy the caption and put it in the .fancybox-content element. And to the original set display: none. Position the caption bottom of picture using transform: translateY(100%). When initializing the slide, the fancybox box takes the height of the hidden title and sets the padding-bottom to the .fancybox-slide element. Thus, the title will not overlap the image or go beyond window borders.
JS (jquery):
$('[data-fancybox="gallery"]').fancybox({
beforeShow: function() {
$('.caption--image').remove();
},
afterShow: function() {
var caption = $(".fancybox-caption"),
innerCaption = caption.clone().addClass('caption--image');
$(".fancybox-slide--current .fancybox-content").append(innerCaption);
caption.not('.caption--image').addClass('caption--bottom');
}
});
CSS:
.fancybox-caption.caption--image {
width: 100%;
bottom: 0;
padding: 10px;
color: #fff;
transform: translateY(100%);
}
.fancybox-inner > .fancybox-caption {
display: none;
}
My solution:
CSS:
.fancybox-caption {
display: block;
margin-right: auto;
margin-left: auto;
padding: 0;
bottom: 13px;
text-align: right;
}
.fancybox-caption:before {
background: 0 0;
}
.fancybox-caption:after {
border-bottom: 0;
}
.fancybox-caption.none {
display: none;
}
.fancybox-caption>span {
background-color: #343434;
color: #B6B6B6;
display: inline-block;
padding: 5px 15px;
}
Jquery:
$('[data-fancybox="images"]').fancybox({
idleTime: false,
infobar: false,
beforeShow: function() {
$(".fancybox-caption").addClass('none');
},
afterShow: function() {
$(".fancybox-caption").wrapInner("<span/>");
var imageWidth = $(".fancybox-slide--current .fancybox-content").width();
$(".fancybox-caption").css("width", imageWidth);
setTimeout($(".fancybox-caption").removeClass('none'), 200);
}
});
This maybe can help you.
$('[data-fancybox]').fancybox({
protect: true,
afterShow: function() {
var imageWidth = $(".fancybox-slide--current .fancybox-image-wrap").width();
$(".fancybox-caption").css("width", imageWidth);
}
});

SimplyScroll won't move with InstafeedJS

I have a website (test page here) using InstafeedJS and SimplyScroll - yet for the life of me I cannot figure out why the feed won't scroll.
I'm a novice so be nice!
<!DOCTYPE>
<html>
<head>
<title>Instafeed Test!</title>
<link rel="Stylesheet" href="css/main.css">
<link rel="stylesheet" href="css/jquery.simplyscroll.css" media="all" type="text/css">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.simplyscroll.js"></script>
<script type="text/javascript">
(function($) {
$(function() {
$("scroller").simplyScroll();
});
})(jQuery);
</script>
<script type="text/javascript" src="js/instafeed.min.js"></script>
<script type="text/javascript">
var feed = new Instafeed({
get: 'user',
userId: 'XXXXXXXX',
clientId: 'XXXXXXXXXXXXXXXX',
accessToken: 'XXXXXXXX.XXXXXX.XXXXXXXXXXXXXXXX',
resolution: 'thumbnail',
template: '<img src="{{image}}" />',
sortBy: 'most-recent',
limit: 12,
links: false
});
feed.run();
</script>
</head>
<body>
<div class="simply-scroll simply-scroll-container">
<div class="simply-scroll-clip">
<div id="instafeed" class="simply-scroll-list" style="width: 10000px;"></div>
</div>
</div>
</body>
</html>
I have pass this case as an issue to a thread of InstafeedJS.
There is stated that the case is really an issue with the scrolling library. One other thing - jquery.simplyscroll is no longer supported and hasn't been updated since 2012.
You'd be better off choosing a modern and supported carousel library. As suggested I found a way to make the scrolling works using another one called slick as shown in the picture.
To do it you will need 3 files from the source or simply fork it and use them like the followings:
HTML Head
<link href="slick/slick/slick.css" rel='stylesheet' type='text/css' media="screen" />
<link href="slick/slick/slick-theme.css" rel='stylesheet' type='text/css' media="screen" />
<script type="text/javascript" src="slick/slick/slick.min.js"></script>
HTML Body
<div class="container">
<div class="tweet_txt">
<div id="instafeed"></div>
</div>
<button type="button" id="load-more">Load More</button>
</div>
CSS
.tweet_txt {
width: 600px;
height: 100px;
overflow: hidden;
}
#instafeed {
width: 1200px;
display: block;
margin: 0;
padding: 0;
line-height: 0;
margin-top: 20px;
overflow: hidden;
}
#instafeed div {
float: left;
width: 50%;
display: inline-block;
margin: 0!important;
padding: 0!important;
}
#instafeed img {
height: 100px;
width: 100px;
}
#instafeed .insta-likes {
width: 100%;
height: 100%;
margin-top: -100%;
opacity: 0;
text-align: center;
letter-spacing: 1px;
background: rgba(255,255,255,0.4);
position: absolute;
text-shadow: 2px 2px 8px #fff;
font: normal 400 11px Playfair Display,sans-serif;
color: #0a0a0a;
line-height: normal;
}
JS
// grab out load more button
var loadButton = document.getElementById('load-more');
//var ulfeed = document.getElementById('instafeed');
//var scroll = new simplyScroll();
var feed = new Instafeed({
get: 'user',
limit: 11,
sortBy:'most-recent',
userId: YOUR ID,
resolution: 'standard_resolution',
accessToken: 'YOUR TOKEN',
template: '<div><img src="{{image}}" /><div class="insta-likes"><div style="display: table; vertical-align: middle; height: 100%; width: 100%;"><span style="vertical-align: middle; height: 100%; width: 100%;">{{likes}} <i class="fa fa-heart"></i><br/>{{comments}} <i class="fa fa-comment"></i></span></div></div></div>',
after: function() {
// run slick for scrolling
$('#instafeed').slick({
slidesToShow: 6,
slidesToScroll: 1,
autoplay: true,
autoplaySpeed: 2000,
});
// every time we load more, run this function
if (!this.hasNext()) {
// disable button if no more results to load
loadButton.setAttribute('disabled', 'disabled');
}
},
success: function() {
//called when Instagram returns valid json data
},
});
// bind the load more button
loadButton.addEventListener('click', function() {
feed.next();
});
// run instafeed!
feed.run();
You may follow on how the result will look like by the code.
In the discussion there is the link to JSFiddle and also the place where it Lives.

Categories

Resources