ID:1955459
 
Resolved
The byond.iconUrl() method has been significantly altered to improve its usefulness. The old method took only a single internal icon ID (representing an individual frame) which we are phasing out. Now instead, it takes parameters for icon cache file ID, state, dir, frame (starting at 1), and moving. These can also be passed via an object literal. The parsing of <img> tags has been improved also and new functionality has been added to handle icons in the output.
Applies to:Webclient
Status: Resolved (509.1304)

This issue has been resolved.
I propose a new client-side method for the Webclient: byond.iconUrl().

Ostensibly it would be identical to /icon/New [ref], which we're already familiar with. The only difference is that instead of returning data that the webclient can't really work with, it would return an URL pointing to that sprite that can then be rendered within the DOM. An example usage would be such:

var url = byond.iconUrl("ball.dmi", "bounce", 4 /* ie EAST */, 1 /* first frame of animation */);

// Assuming no jQuery:
document.getElementById("ball-viewport").style.backgroundImage = "url('" + url + "')";

// Assuming jQuery:
$("#ball-viewport").css("background", "url('" + url + "')");


Only downside is I don't think full animations could be rendered, so you'll be forced to choose a specific frame of animation for animated icon_states.
Lummox JR resolved issue with message:
The byond.iconUrl() method has been significantly altered to improve its usefulness. The old method took only a single internal icon ID (representing an individual frame) which we are phasing out. Now instead, it takes parameters for icon cache file ID, state, dir, frame (starting at 1), and moving. These can also be passed via an object literal. The parsing of <img> tags has been improved also and new functionality has been added to handle icons in the output.
I just realized iconUrl was already a member of byond. D'oh! Great stuff, anyway!
Yeah, but it was outdated and didn't have the functionality you needed, which was perfectly doable.
The parsing of tags has been improved also and new functionality has been added to handle icons in the output.

Can you be more specific about the handling of img tags?

What exactly is different?
Basically, the webclient was handling everything for parsing <img> tags server-side and was using one of the deprecated individual icon frame IDs to generate a URL like http://ip:port/icon/nnn.png. Because I want to get rid of those IDs, I wanted to move all that off to the client side, which would also dovetail nicely with the functionality Doohl wanted. Now, the server generates an img tag like this:

<img icon=nnn iconstate=state icondir=2 iconframe=1>

Not all of those attributes may appear, but it should give you a good idea. On the client end, this now interacts with the pre-existing byond.fillAtomIcons() routine to look for img tags in the skin that haven't been filled in yet, and it fills that in with a data: URL instead based on the actual icon info it's loaded. This is very similar to how atom icons are handled:

<img atom=nnn>

The byond.fillAtomIcons() routine takes care of those as well by building a composite icon, which is how statpanels and the status bar get filled in.
And these new tag attributes can be supplied to outputs, maptext, statpanels, and browsers in the skin to boot?
Well, iconstate, icondir, and iconframe have been part of the DM output's <img> tag for quite some time. Maptext and grids should support them too. The webclient now supports them whereas it didn't properly do so before, and I also improved the support so that icondir=[NORTH] works whereas before it literally had to be spelled out like icondir=north, which wasn't as useful.

(There really ought to be an analagous iconmoving attribute. I told the webclient to look for one for future purposes, but DM itself doesn't have such a thing yet.)

Browsers in the skin will not support these, because they're not standard HTML; it would let them through but it won't do anything with them. It won't work in the webclient, either, for similar reasons: The browser control in the webclient uses an iframe. That said, there may be a way to alter the browser "fill" script in the webclient that would make allowances for it.
A late question, but the byond.iconUrl function only accepts integer icon IDs as the 'icon' parameter. I honestly have not been able to discern how to get the ID of an icon given a particular .dmi file from just the reference.

What would be the correct equivalent of this pseudocode?

var url = byond.iconUrl("ball.dmi", "bounce");
At this time the webclient unfortunately doesn't have a way of correlating filenames to IDs; the server doesn't send that info. What it does have is getAtomInfo(), which can be used to grab the info about an atom and can therefore get its icon ID (IIRC).

But you bring up a really good point here. I'll take a look at this and find out what I can do to make this easier to work with.
Bumping this.
Being able to do something like "var url = byond.iconUrl("ball.dmi", "bounce");" rather than "var url = byond.iconUrl(12314512367);" would make this feature a lot more useful.

Right now there's a slow loading delay when displaying menu icons in JS, and we've been desperate for a good approach with the webclient to make this smoother. This feature request was intended for that, but its current implementation doesn't work for us, I don't think.
I would prefer it if there was a method of not just returning an URL (which requires the client to go through and download new data) but, rather, the image represented in base64.
Having a way to do that img tag format in browser controls in DS would be a lifesaver because we could spritesheet the resources we send to clients and not have to flood the browse() queue with a bunch of assets
In response to MrStonedOne
MrStonedOne wrote:
Having a way to do that img tag format in browser controls in DS would be a lifesaver because we could spritesheet the resources we send to clients and not have to flood the browse() queue with a bunch of assets

I think the only way for browser controls to do this would be to have some kind of custom URL that could do this, much like how [0xC000005] gets reinterpreted as an actual file by forcing a lookup. The code that does this basically parses the raw HTML and then replaces it once the image loads. I'd really prefer a better solution across the board for supporting images with the icon state built in.
icon.ToDataURL(iconstate, movement)
and a global proc to follow it. The CEF thing comes up again though because you could have a custom resource scheme handler for icons and whatnot (perhaps in a secure way to prevent rsc dumping?)