Can't download/save the avatar properly
Dhaiwat10 opened this issue ยท 18 comments
Someone in the Discord server reported that when they try to save their pixel avatar, they are not being able to save the entire avatar. Instead, they are being able to save only one part of the avatar at once. (eg. pants) Link to the message: https://discord.com/channels/883478451850473483/883482557809852416/899139138396258374
This has probably got to do with the fact that we are just placing PNGs for different parts of the avatar on top of each other. But we should definitely add a download functionality.
I think it's also good to have a "share" function to allow directly sharing to twitter / something?
I did a very quick research on this issue and find a below proposal:
https://github.com/lukechilds/merge-images
function downloadAvatar() {
mergeImages(layers.value)
.then(b64 => {
const element = document.createElement("a");
element.href = b64
element.download = "image.jpg";
element.click();
});
}
Yet it's not working due to the different part of traits have different dimension:
- 3659โรโ4734
- 878โรโ1136
Like to ask why the trails image are of different (and quite a large) dimension?
Not sure about that, @kavimaluskam. Thanks for that code snippet, tho!
Raz on Discord has also suggested a fix by using a <canvas>
: https://discord.com/channels/883478451850473483/883482557809852416/899396611392823326
Awww sorry that I missed this.
@Dhaiwat10 sounds also a cool solution as no additional dependency needed !
I am trying to modify the rendering method to canvas directly as below:
<script setup>
import { onMounted } from "@vue/runtime-core"
const props = defineProps({
state: Object
})
const updateAvatar = (width = 448, height = 580) => {
const canvas = document.getElementById('avatar')
const ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
const images = props.state.layers.value.map(layer => new Promise((resolve, reject) => {
var image = new Image(width, height);
image.onerror = () => reject(new Error('Couldn\'t load image'));
image.onload = () => resolve(Object.assign(image));
image.src = layer;
}));
Promise.all(images).then(images => {
images.forEach(image => {
ctx.drawImage(image, 0, 0, width, height)
})
});
}
onMounted(() => { updateAvatar() })
</script>
<template>
<div>
<canvas id="avatar"></canvas>
</div>
</template>
Its working now, but only when mounted...
Sorry that I am not very familiar with vue, is there any API so i can trigger the updateAvatar()
when props changes?
Thanks for this @kavimaluskam! I'm not familiar with Vue myself either. @rasmuscnielsen could you help us out here haha
Thanks for the ping, and sorry I haven't gotten around to comment here before. Nice work though, @kavimaluskam !
Yeah so this would have to tie in with the PreviewState
, and probably init some watcher with either watch
or watchEffect
. It may get a bit hairy as there is already a bit of co-dependency across traits, developerId and wallet state ๐
Question is: Are we actually wanting people to be able to share / download the JPG before it's even claimed?
We have a separate track ongoing to generate the JPG's for all avatars, so we should soon have the JPGs ready for the mintable developerIDs. Perhaps we could incorporate that, so it's easily downloadable once you're authenticated with your wallet (either after claim, or just immediately when we see the user own the genesis token).
I guess I'm just hesitant to make it too easy for anyone to get a JPG of any trait-combination? ๐ค Especially if we wish to open for broader audience later on and sell the NFTs.
Yeah. I think it make sense to pre-generate JPG's for avatar, and provide more function with developer.
Guess I am just a bit confused by the traits manually update function, which may not be the case in the future roadmap.
And if it's the case, I wonder if we can close the current issue, and image download / share (share should be more important) function, which shall be solved when the team has implemented web3 functionality?
Yeah so it's very much been a moving target as things changes and the project progresses.
The idea with the flexible traits were initially to test out the different layers of the designs, and secondly it could present a future possibility of selling tailored avatars to the public. I guess we have really discussed these options through yet.
And if it's the case, I wonder if we can close the current issue, and image download / share (share should be more important) function, which shall be solved when the team has implemented web3 functionality?
Yeah I think that sounds good! Do you have any suggestions for how this share function could work?
Should it just be the URL to the JPG, or a special landing page with social preview, where we host some more information and call-2-action for people to mint their own (?)
Just throwing some ideas around, haven't really thought it through :-)
@rasmuscnielsen Sounds good!
I just think of something like link to the image / URL (as long as there is query param to the correct developer ID, and website preview).
Since I think most common use case for downloading the image is to share on social media, a simple forward button should be good.
hey any update on this? i can jump-in and help :)
I made a fix:
- Convert to Canvas
- Update on each prop.state change (when the user types a diff token ID)
- Download as PNG (easy because its a canvas)
- Save image as: {tokenID}.png
do we still need this? ๐ค
@CastilloLuis yes, please put in a PR!
I think pre the above discussion we don't want to have this feature now since the team is going to generate JPG for all avatar now? @rasmuscnielsen @Dhaiwat10 ? Please correct me if I am confused again.
@kavimaluskam oh sorry, I missed the discussion in-between. I'll leave the decision upto you and @rasmuscnielsen :)
I'll stay tuned to any final decision before submitting the PR @kavimaluskam @rasmuscnielsen
Yeah I think we can pick this one back up once the web3 integration is in place. We already have all the PNG's generated, so we just need to make a share functionality for the owned tokens once minted :-)
Just created #65 which relates to this. Since this only relates to avatars that are already claimed, it should be possible to just grab the IPFS url out of the contract and add a download function that reads from IPFS