sorking on virtual blocks...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2019-10-09 03:04:46 +03:00
parent 6bb4232086
commit 12c5ac8693
8 changed files with 238 additions and 190 deletions

View File

@ -524,8 +524,6 @@ body {
/* DEBUG stuff... */
.container-center {
position: absolute;

View File

@ -695,8 +695,10 @@ stretching in width... */
box-sizing: border-box;
color: white;
text-shadow: black 0.1em 0.1em 0.4em, black 0.1em 0.1em;
/* XXX do we need this???
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
affected by filters... */
@ -705,6 +707,28 @@ stretching in width... */
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 {
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
@ -2042,7 +2066,10 @@ progress:not(value)::-webkit-progress-bar {
/* XXX this is by no means final... */
/*@import "theme-light";*/
.viewer,
.light.single-image-mode.viewer .image,
.light.transparent-ribbon.viewer .image {
color: black;
}
.light.viewer,
.light.viewer .overlay-block .background {
background: white;

View File

@ -48,6 +48,9 @@ require('features/external-editor')
require('features/metadata')
require('features/meta')
// XXX EXPERIMENTAL...
require('features/virtual-images')
require('features/experimental')
require('features/tests')
require('features/demo')

View File

@ -122,71 +122,6 @@ var ExperimentActions = actions.Actions({
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 =

View File

@ -163,6 +163,7 @@ core.ImageGridFeatures.Feature('imagegrid-testing', [
'ui-preview-filters',
'url-history',
'external-editor',
'virtual-images',
// experimental features...
//'ui-range',

View 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 })

View File

@ -495,6 +495,12 @@ module.ImagesPrototype = {
//gid = gid == null ? getImageGID(): gid
//size = size == null ? getVisibleImageSize('max') : size
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(!img_data

View File

@ -1514,126 +1514,12 @@ var RibbonsPrototype = {
// .correctImageProportionsForRotation(..)
//
// .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 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){
var that = this
var imgs = this.viewer.find(IMAGE)
@ -1729,8 +1615,13 @@ var RibbonsPrototype = {
//will_change.push('transform')
// stage background image update...
var p_url = that.images.getBestPreview(img_data.id, size, img_data, true).url
if(old_gid != gid
// XXX add support for basic templating here...
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...
// NOTE: this may not work correctly for relative urls...
|| image.css('background-image').indexOf(util.path2url(p_url)) < 0){