mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 02:10:08 +00:00
sorking on virtual blocks...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
6bb4232086
commit
12c5ac8693
@ -524,8 +524,6 @@ body {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* DEBUG stuff... */
|
/* DEBUG stuff... */
|
||||||
.container-center {
|
.container-center {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@ -695,8 +695,10 @@ stretching in width... */
|
|||||||
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
color: white;
|
color: white;
|
||||||
|
/* XXX do we need this???
|
||||||
text-shadow: black 0.1em 0.1em 0.4em, black 0.1em 0.1em;
|
text-shadow:
|
||||||
|
black 0.1em 0.1em 0.4em,
|
||||||
|
black 0.1em 0.1em; */
|
||||||
|
|
||||||
/* NOTE: we can't set the bg color here because it will get
|
/* NOTE: we can't set the bg color here because it will get
|
||||||
affected by filters... */
|
affected by filters... */
|
||||||
@ -705,6 +707,28 @@ stretching in width... */
|
|||||||
border: solid @image-border transparent;
|
border: solid @image-border transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.image {
|
||||||
|
padding: @single-image-indicator-size;
|
||||||
|
}
|
||||||
|
.image div {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
max-width: @image-tile-size;
|
||||||
|
width: auto;
|
||||||
|
max-height: @image-tile-size;
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%,-50%);
|
||||||
|
|
||||||
|
white-space: normal;
|
||||||
|
text-align: center;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
/*font-size: 2vh;*/
|
||||||
|
}
|
||||||
|
|
||||||
.crisp-resize .image {
|
.crisp-resize .image {
|
||||||
image-rendering: -webkit-optimize-contrast;
|
image-rendering: -webkit-optimize-contrast;
|
||||||
image-rendering: crisp-edges;
|
image-rendering: crisp-edges;
|
||||||
@ -2042,7 +2066,10 @@ progress:not(value)::-webkit-progress-bar {
|
|||||||
/* XXX this is by no means final... */
|
/* XXX this is by no means final... */
|
||||||
/*@import "theme-light";*/
|
/*@import "theme-light";*/
|
||||||
|
|
||||||
.viewer,
|
.light.single-image-mode.viewer .image,
|
||||||
|
.light.transparent-ribbon.viewer .image {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
.light.viewer,
|
.light.viewer,
|
||||||
.light.viewer .overlay-block .background {
|
.light.viewer .overlay-block .background {
|
||||||
background: white;
|
background: white;
|
||||||
|
|||||||
@ -48,6 +48,9 @@ require('features/external-editor')
|
|||||||
require('features/metadata')
|
require('features/metadata')
|
||||||
require('features/meta')
|
require('features/meta')
|
||||||
|
|
||||||
|
// XXX EXPERIMENTAL...
|
||||||
|
require('features/virtual-images')
|
||||||
|
|
||||||
require('features/experimental')
|
require('features/experimental')
|
||||||
require('features/tests')
|
require('features/tests')
|
||||||
require('features/demo')
|
require('features/demo')
|
||||||
|
|||||||
@ -122,71 +122,6 @@ var ExperimentActions = actions.Actions({
|
|||||||
function(){
|
function(){
|
||||||
}],
|
}],
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// construction of new "virtual images"...
|
|
||||||
//
|
|
||||||
// XXX should this be restricted to collections???
|
|
||||||
// XXX should these be importable???
|
|
||||||
// i.e. exported as json to <title>.virt and imported back...
|
|
||||||
// ...might be a good idea to add custom import/export handlers...
|
|
||||||
//
|
|
||||||
// XXX do better arg processing -- handle metadata correctly...
|
|
||||||
// XXX add export support for this type of stuff...
|
|
||||||
// XXX add default named templates...
|
|
||||||
// XXX add svg templates...
|
|
||||||
// - blank (white/black/gray/...)
|
|
||||||
// - title
|
|
||||||
// - text
|
|
||||||
// XXX move to 'virtual-images' feature...
|
|
||||||
makeVirtualImage: ['Experimental/',
|
|
||||||
function(ref, offset, metadata){
|
|
||||||
ref = ref || 'current'
|
|
||||||
offset = offset || 'after'
|
|
||||||
offset = offset == 'after' ?
|
|
||||||
1
|
|
||||||
: offset == 'before' ?
|
|
||||||
0
|
|
||||||
: typeof(offset) == typeof(123) ?
|
|
||||||
offset
|
|
||||||
: 0
|
|
||||||
// XXX revise...
|
|
||||||
metadata = arguments[arguments.length-1] instanceof Object ?
|
|
||||||
arguments[arguments.length-1]
|
|
||||||
: null
|
|
||||||
|
|
||||||
var data = this.data
|
|
||||||
|
|
||||||
ref = data.getImage(ref)
|
|
||||||
var r = data.getRibbon(ref)
|
|
||||||
|
|
||||||
var gid = data.newGID()
|
|
||||||
|
|
||||||
// place image into data...
|
|
||||||
var order = data.order
|
|
||||||
order.splice(order.indexOf(ref)+offset,0, gid)
|
|
||||||
var ribbon = data.ribbons[r]
|
|
||||||
ribbon.splice(ribbon.indexOf(ref)+offset,0, gid)
|
|
||||||
|
|
||||||
// update data...
|
|
||||||
data.updateImagePositions()
|
|
||||||
|
|
||||||
// update metadata...
|
|
||||||
metadata
|
|
||||||
&& (this.images[gid] = metadata)
|
|
||||||
|
|
||||||
// focus new image...
|
|
||||||
// NOTE: this should update the view too...
|
|
||||||
this.focusImage(gid)
|
|
||||||
}],
|
|
||||||
// XXX
|
|
||||||
makeVirtualBlank: ['Experimental/',
|
|
||||||
function(){
|
|
||||||
}],
|
|
||||||
// XXX
|
|
||||||
makeVirtualText: ['Experimental/',
|
|
||||||
function(){
|
|
||||||
}],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
var ExperimentFeature =
|
var ExperimentFeature =
|
||||||
|
|||||||
@ -163,6 +163,7 @@ core.ImageGridFeatures.Feature('imagegrid-testing', [
|
|||||||
'ui-preview-filters',
|
'ui-preview-filters',
|
||||||
'url-history',
|
'url-history',
|
||||||
'external-editor',
|
'external-editor',
|
||||||
|
'virtual-images',
|
||||||
|
|
||||||
// experimental features...
|
// experimental features...
|
||||||
//'ui-range',
|
//'ui-range',
|
||||||
|
|||||||
187
ui (gen4)/features/virtual-images.js
Normal file
187
ui (gen4)/features/virtual-images.js
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/**********************************************************************
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
**********************************************************************/
|
||||||
|
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
|
||||||
|
(function(require){ var module={} // make module AMD/node compatible...
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
var actions = require('lib/actions')
|
||||||
|
var features = require('lib/features')
|
||||||
|
|
||||||
|
var core = require('features/core')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
// XXX revise menu placement...
|
||||||
|
var VirtualImagesActions = actions.Actions({
|
||||||
|
// construction of new "virtual images"...
|
||||||
|
//
|
||||||
|
// XXX should this be restricted to collections???
|
||||||
|
// XXX should these be importable from fs???
|
||||||
|
// i.e. exported as json to <title>.virt and imported back...
|
||||||
|
// ...might be a good idea to add custom import/export handlers...
|
||||||
|
//
|
||||||
|
// XXX do better arg processing -- handle metadata correctly...
|
||||||
|
// XXX add export support for this type of stuff...
|
||||||
|
// XXX add default named templates...
|
||||||
|
// XXX add svg templates???
|
||||||
|
makeVirtualBlock: ['- Virtual/',
|
||||||
|
function(ref, offset, metadata){
|
||||||
|
ref = ref || 'current'
|
||||||
|
offset = offset || 'after'
|
||||||
|
offset = offset == 'after' ?
|
||||||
|
1
|
||||||
|
: offset == 'before' ?
|
||||||
|
0
|
||||||
|
: typeof(offset) == typeof(123) ?
|
||||||
|
offset
|
||||||
|
: 0
|
||||||
|
// XXX revise...
|
||||||
|
metadata = arguments[arguments.length-1] instanceof Object ?
|
||||||
|
arguments[arguments.length-1]
|
||||||
|
: null
|
||||||
|
|
||||||
|
var data = this.data
|
||||||
|
|
||||||
|
ref = data.getImage(ref)
|
||||||
|
var r = data.getRibbon(ref)
|
||||||
|
|
||||||
|
var gid = data.newGID()
|
||||||
|
|
||||||
|
// place image into data...
|
||||||
|
var order = data.order
|
||||||
|
order.splice(order.indexOf(ref)+offset,0, gid)
|
||||||
|
var ribbon = data.ribbons[r]
|
||||||
|
ribbon.splice(ribbon.indexOf(ref)+offset,0, gid)
|
||||||
|
|
||||||
|
// update data...
|
||||||
|
data.updateImagePositions()
|
||||||
|
|
||||||
|
// update metadata...
|
||||||
|
metadata
|
||||||
|
&& (this.images[gid] = metadata)
|
||||||
|
|
||||||
|
// focus new image...
|
||||||
|
// NOTE: this should update the view too...
|
||||||
|
this.focusImage(gid)
|
||||||
|
}],
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
makeVirtualBlank: ['Virtual/Add blank after',
|
||||||
|
core.doc``,
|
||||||
|
//{ browseMode: function(){ return !this.collection && 'disabled' }, },
|
||||||
|
function(ref, offset){
|
||||||
|
this.makeVirtualBlock(ref, offset, {
|
||||||
|
type: 'virtual',
|
||||||
|
path: null,
|
||||||
|
}) }],
|
||||||
|
makeVirtualText: ['Virtual/Add text block after',
|
||||||
|
core.doc`
|
||||||
|
|
||||||
|
NOTE: this was not designed for complex HTML, only use simple
|
||||||
|
formatted text.`,
|
||||||
|
//{ browseMode: function(){ return !this.collection && 'disabled' }, },
|
||||||
|
function(text, ref, offset){
|
||||||
|
this.makeVirtualBlock(ref, offset, {
|
||||||
|
type: 'virtual',
|
||||||
|
path: null,
|
||||||
|
text: text || '',
|
||||||
|
}) }],
|
||||||
|
|
||||||
|
// XXX virtual block editor UI...
|
||||||
|
// XXX
|
||||||
|
|
||||||
|
|
||||||
|
// XXX export...
|
||||||
|
})
|
||||||
|
|
||||||
|
var VirtualImages =
|
||||||
|
module.VirtualImages = core.ImageGridFeatures.Feature({
|
||||||
|
title: '',
|
||||||
|
doc: '',
|
||||||
|
|
||||||
|
tag: 'virtual-images',
|
||||||
|
depends: [
|
||||||
|
'edit',
|
||||||
|
// XXX
|
||||||
|
],
|
||||||
|
suggested: [
|
||||||
|
'ui-virtual-images',
|
||||||
|
],
|
||||||
|
|
||||||
|
actions: VirtualImagesActions,
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
var VirtualImagesUIActions = actions.Actions({
|
||||||
|
// XXX
|
||||||
|
})
|
||||||
|
|
||||||
|
var VirtualImagesUI =
|
||||||
|
module.VirtualImagesUI = core.ImageGridFeatures.Feature({
|
||||||
|
title: '',
|
||||||
|
doc: '',
|
||||||
|
|
||||||
|
tag: 'ui-virtual-images',
|
||||||
|
depends: [
|
||||||
|
'ui',
|
||||||
|
'virtual-images'
|
||||||
|
],
|
||||||
|
|
||||||
|
actions: VirtualImagesUIActions,
|
||||||
|
|
||||||
|
handlers: [
|
||||||
|
['updateImage',
|
||||||
|
function(res, gid, img){
|
||||||
|
var image = this.images[gid] || {}
|
||||||
|
|
||||||
|
// set image content...
|
||||||
|
if(image.type == 'virtual' && image.text){
|
||||||
|
var text = document.createElement('div')
|
||||||
|
text.innerHTML = image.text
|
||||||
|
img[0].innerHTML = ''
|
||||||
|
img[0].appendChild(text)
|
||||||
|
|
||||||
|
// threshold after which we try to fill the volume...
|
||||||
|
var C = 100
|
||||||
|
|
||||||
|
// scale the text if it is small...
|
||||||
|
var R = img[0].offsetHeight * 0.8
|
||||||
|
var r = image.text.length > C ?
|
||||||
|
Math.max(
|
||||||
|
text.offsetWidth,
|
||||||
|
text.offsetHeight,
|
||||||
|
// keep large text blocks roughly square-ish...
|
||||||
|
Math.sqrt(text.scrollHeight * text.scrollWidth))
|
||||||
|
: Math.max(
|
||||||
|
text.offsetWidth,
|
||||||
|
text.offsetHeight,
|
||||||
|
text.scrollHeight,
|
||||||
|
text.scrollWidth)
|
||||||
|
var s = R/r
|
||||||
|
text.style.fontSize = `${ 100*s }%`
|
||||||
|
// prioritize width...
|
||||||
|
text.style.width = '100%'
|
||||||
|
|
||||||
|
// clear reused image content...
|
||||||
|
} else if(img[0].innerHTML != ''){
|
||||||
|
img[0].innerHTML = ''
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* vim:set ts=4 sw=4 : */ return module })
|
||||||
@ -495,6 +495,12 @@ module.ImagesPrototype = {
|
|||||||
//gid = gid == null ? getImageGID(): gid
|
//gid = gid == null ? getImageGID(): gid
|
||||||
//size = size == null ? getVisibleImageSize('max') : size
|
//size = size == null ? getVisibleImageSize('max') : size
|
||||||
img_data = img_data == null ? this[gid] : img_data
|
img_data = img_data == null ? this[gid] : img_data
|
||||||
|
img_data = img_data || IMAGE_DATA
|
||||||
|
|
||||||
|
// if path is explicitly null there are no previews...
|
||||||
|
if(img_data.path === null){
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
// if no usable images are available use STUB data...
|
// if no usable images are available use STUB data...
|
||||||
if(!img_data
|
if(!img_data
|
||||||
|
|||||||
@ -1514,126 +1514,12 @@ var RibbonsPrototype = {
|
|||||||
// .correctImageProportionsForRotation(..)
|
// .correctImageProportionsForRotation(..)
|
||||||
//
|
//
|
||||||
// .updateImageIndicators(..)
|
// .updateImageIndicators(..)
|
||||||
_updateImage: function(image, gid, size, sync){
|
//
|
||||||
image = (image == '*' ? this.viewer.find(IMAGE)
|
|
||||||
: image == null
|
|
||||||
|| typeof(image) == typeof('str') ? this.getImage(image)
|
|
||||||
: $(image))
|
|
||||||
sync = sync == null ? this.load_img_sync : sync
|
|
||||||
size = size == null ? this.getVisibleImageSize('max') : size
|
|
||||||
|
|
||||||
var that = this
|
|
||||||
return $(image.map(function(){
|
|
||||||
var image = this instanceof String
|
|
||||||
|| typeof(this) == typeof('str')
|
|
||||||
? that.getImage(this+'')
|
|
||||||
: $(this)
|
|
||||||
if(image.length == 0){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var old_gid = that.elemGID(image)
|
|
||||||
|
|
||||||
// same image -- update...
|
|
||||||
if(old_gid == gid || gid == null){
|
|
||||||
var gid = old_gid
|
|
||||||
|
|
||||||
// reuse for different image -- reconstruct...
|
|
||||||
} else {
|
|
||||||
// remove old marks...
|
|
||||||
if(typeof(old_gid) == typeof('str')){
|
|
||||||
that.getImageMarks(old_gid).remove()
|
|
||||||
}
|
|
||||||
// reset gid...
|
|
||||||
image
|
|
||||||
.attr('gid', JSON.stringify(gid)
|
|
||||||
// this removes the extra quots...
|
|
||||||
.replace(/^"(.*)"$/g, '$1'))
|
|
||||||
.css({
|
|
||||||
// clear the old preview...
|
|
||||||
'background-image': '',
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// if no images data defined drop out...
|
|
||||||
if(that.images == null){
|
|
||||||
return image[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the image data...
|
|
||||||
var img_data = that.images[gid]
|
|
||||||
if(img_data == null){
|
|
||||||
img_data = images.IMAGE_DATA
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we are a group, get the cover...
|
|
||||||
// NOTE: groups can be nested...
|
|
||||||
var seen = []
|
|
||||||
while(img_data.type == 'group'){
|
|
||||||
// error, recursive group...
|
|
||||||
if(seen.indexOf(img_data.id) >= 0){
|
|
||||||
img_data = images.IMAGE_DATA
|
|
||||||
console.error('Recursive group:', gid)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
seen.push(img_data.id)
|
|
||||||
|
|
||||||
img_data = that.images[img_data.cover]
|
|
||||||
}
|
|
||||||
|
|
||||||
// image state...
|
|
||||||
//that.rotateImage(image, img_data.orientation == null ? 0 : img_data.orientation)
|
|
||||||
//that.flipImage(image, img_data.flipped == null ? [] : img_data.flipped)
|
|
||||||
image.attr({
|
|
||||||
orientation: img_data.orientation == null ? '' : img_data.orientation*1,
|
|
||||||
flipped: (img_data.flipped == null ? [] : img_data.flipped).join(', '),
|
|
||||||
})
|
|
||||||
|
|
||||||
// preview...
|
|
||||||
var p_url = that.images.getBestPreview(img_data.id, size, img_data, true).url
|
|
||||||
|
|
||||||
// update the preview if it's a new image or...
|
|
||||||
// XXX this should be pushed as far back as possible...
|
|
||||||
if(old_gid != gid
|
|
||||||
// the new preview (p_url) is different to current...
|
|
||||||
// NOTE: this may not work correctly for relative urls...
|
|
||||||
|| image.css('background-image').indexOf(util.path2url(p_url)) < 0){
|
|
||||||
// sync load...
|
|
||||||
if(sync){
|
|
||||||
that._loadImagePreviewURL(image, p_url)
|
|
||||||
|
|
||||||
// async load...
|
|
||||||
} else {
|
|
||||||
// NOTE: storing the url in .data() makes the image load the
|
|
||||||
// last requested preview and in a case when we manage to
|
|
||||||
// call updateImage(...) on the same element multiple times
|
|
||||||
// before the previews get loaded...
|
|
||||||
// ...setting the data().loading is sync while loading an
|
|
||||||
// image is not, and if several loads are done in sequence
|
|
||||||
// there is no guarantee that they will happen in the same
|
|
||||||
// order as requested...
|
|
||||||
image.data().loading = p_url
|
|
||||||
setTimeout(function(){
|
|
||||||
that._loadImagePreviewURL(image, image.data().loading)
|
|
||||||
}, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: this only has effect on non-square image blocks...
|
|
||||||
// XXX this needs the loaded image, thus should be done right
|
|
||||||
// after preview loading...
|
|
||||||
// XXX preview loading is async, is this the right
|
|
||||||
// place for this??
|
|
||||||
// ...this is also done in .rotateImage(..) above...
|
|
||||||
that.correctImageProportionsForRotation(image)
|
|
||||||
|
|
||||||
// marks and other indicators...
|
|
||||||
that.updateImageIndicators(gid, image)
|
|
||||||
|
|
||||||
return image[0]
|
|
||||||
}))
|
|
||||||
},
|
|
||||||
// XXX add options for images to preload and only then do the update...
|
// XXX add options for images to preload and only then do the update...
|
||||||
// XXX really slow for very large numbers of input images/gids...
|
// XXX really slow for very large numbers of input images/gids...
|
||||||
|
// XXX add support for basic image templating here...
|
||||||
|
// ...templates for blank images, text blocks and other stuff,
|
||||||
|
// this would best be done by simply filling in SVG templates...
|
||||||
updateImage: function(image, gid, size, sync, callback){
|
updateImage: function(image, gid, size, sync, callback){
|
||||||
var that = this
|
var that = this
|
||||||
var imgs = this.viewer.find(IMAGE)
|
var imgs = this.viewer.find(IMAGE)
|
||||||
@ -1729,8 +1615,13 @@ var RibbonsPrototype = {
|
|||||||
//will_change.push('transform')
|
//will_change.push('transform')
|
||||||
|
|
||||||
// stage background image update...
|
// stage background image update...
|
||||||
var p_url = that.images.getBestPreview(img_data.id, size, img_data, true).url
|
// XXX add support for basic templating here...
|
||||||
if(old_gid != gid
|
var p_url = (that.images.getBestPreview(img_data.id, size, img_data, true) || {}).url
|
||||||
|
// no preview -> reset bg...
|
||||||
|
if(p_url == null){
|
||||||
|
image[0].style.backgroundImage = ''
|
||||||
|
|
||||||
|
} else if(old_gid != gid
|
||||||
// the new preview (p_url) is different to current...
|
// the new preview (p_url) is different to current...
|
||||||
// NOTE: this may not work correctly for relative urls...
|
// NOTE: this may not work correctly for relative urls...
|
||||||
|| image.css('background-image').indexOf(util.path2url(p_url)) < 0){
|
|| image.css('background-image').indexOf(util.path2url(p_url)) < 0){
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user