项目中要实现一个将图片分享到朋友圈的功能,将生成的海报转成图片保存到手机。用到了wxml-to-canvas插件。

npm install --save wxml-to-canvas
{
"usingComponents": {
"wxml-to-canvas": "wxml-to-canvas",
}
}
<video class="video" src="{{src}}">
<wxml-to-canvas class="widget"></wxml-to-canvas>
</video>
<image src="{{src}}" style="width: {{width}}px; height: {{height}}px"></image>
const {wxml, style} = require('./demo.js')
Page({
data: {
src: ''
},
onLoad() {
this.widget = this.selectComponent('.widget')
},
renderToCanvas() {
const p1 = this.widget.renderToCanvas({ wxml, style })
p1.then((res) => {
this.container = res
this.extraImage()
})
},
extraImage() {
const p2 = this.widget.canvasToTempFilePath()
p2.then(res => {
this.setData({
src: res.tempFilePath,
width: this.container.layoutBox.width,
height: this.container.layoutBox.height
})
})
}
})
安装、json配置、wxml引入都一样。
<wxml-to-canvas class="widget" width="325" height="550"></wxml-to-canvas>
<view class='save flex-center-center' bindtap='preservation'>
保存海报
</view>
const net = require('../../../common/network.js');
//⚠️海报内容和样式
const { wxml, style } = require('./canvas.js');
//自己封装的微信api
import wxApi from '../../../common/wxApi';
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
wx.showLoading({
title: '海报生成中...',
});
//获取页面初始数据
this.getServerData();
},
getServerData() {
net.posterInfo().then((response) => {
const { name, title, teacher, qr_code, task_id } = response.data;
const { real_name, avatarurl, nickname } = app.globalData.userInfo;
//画海报用到的数据
this.setData({
info: response.data,
avatarurl,
name,
title,
teacher,
qr_code,
});
//注意⚠️:这里是对页面初始渲染
this.widget = this.selectComponent('.widget');
const _wxml = wxml(name, avatarurl, title, teacher, qr_code);
//onload方法里节点没加载完,设置定时器
setTimeout(() => {
//渲染到 canvas,传入 wxml 模板 和 style 对象,返回的容器对象包含布局和样式
//信息。
const p1 = this.widget.renderToCanvas({
wxml: _wxml,
style,
});
p1.then((res) => {
this.container = res;
wx.hideLoading();
});
}, 500);
});
},
preservation() {
// this.widget = this.selectComponent('.widget')
const { task_id } = this.data;
const p2 = this.widget.canvasToTempFilePath();
p2.then((res) => {
//保存到本地相册
wxApi.apiScopeOauth('scope.writePhotosAlbum').then(() => {
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success(res) {
util.showToast(
'海报已保存,快去朋友圈分享吧!',
'none',
3000
);
},
fail(res) {
wx.showToast({
icon: 'error',
title: '保存图片失败!',
});
},
});
});
}).catch((fail) => {
wx.showToast({
icon: 'error',
title: '请稍后再试',
});
});
},
});
只展示大体框架,具体内容涉及隐私去掉了。
wxml返回的是页面内容的字符串。
const wxml = ( name, avatarurl,title,teacher,qr_code ) => {
return `
<view class="poster-wapper">
<image class="poster-img" src="https://1.png"/>
<view class="author">
<text class="author-text">作者:${name}</text>
</view>
<view class="head">
<view class="head-border">
<image class="head-img" src="${avatarurl}"></image>
</view>
</view>
<view class="poster-info">
<view class="info">
<text class="title">挑战内容:《${title}》</text>
`+ (teacher?`<text class="teacher">老师:${teacher}</text>`:'')
+` <view class="line"></view>
<text class="tip">本次朗读近乎完美!快来听听吧!</text>
</view>
<image class="qrcode-img" src="${qr_code}" />
</view>
</view>
`
}
const style = {
posterWapper:{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
position: 'relative',
},
posterImg: {
width: 325,
height: 550
},
author: {
width: 119,
height: 32,
borderRadius: 12,
backgroundColor: 'rgba(255,255,255,0.8)',
position: 'absolute',
paddingLeft: 18,
top: 353,
left: 45,
},
authorText: {
width: 98,
height: 32,
paddingLeft: 13.5,
fontSize: 11,
fontWeight: 600,
color: '#333333',
verticalAlign: 'middle',
},
head: {
width: 51,
height: 51,
borderRadius: 25.5,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
top: 343,
left: 12,
backgroundColor: 'rgba(255,255,255,0.8)',
},
headBorder: {
width: 46,
height: 46,
backgroundColor: 'rgba(255,255,255)',
borderRadius: 23,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
headImg: {
width: 43,
height: 43,
borderRadius: 20,
},
posterInfo:{
position: 'absolute',
bottom: -6,
width: 325,
height: 143,
backgroundColor: '#FFFFFF',
borderRadius: 10,
display: 'flex',
flexDirection: 'row'
},
info: {
width: 210,
height: 140,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
paddingTop: 6,
paddingLeft: 15
},
title: {
width: 210,
height: 24,
fontSize: 13,
fontWeight: 600,
color: '#333333',
lineHeight: 24
},
teacher:{
width: 210,
height: 24,
fontSize: 13,
fontWeight: 400,
color: '#666666',
lineHeight: 24,
},
line:{
width: 190,
height: 1,
backgroundColor: 'rgba(3,0,0,0.16)'
},
tip: {
height: 24,
width: 210,
fontSize: 13,
fontFamily: 'PingFang SC',
fontWeight: 600,
color: '#333333',
lineHeight: 24,
},
btn:{
width: 140,
height: 33,
backgroundColor: '#FF6000',
borderRadius: 19,
lineHeight: 33,
textAlign: 'center',
marginTop: 7.5,
position: 'relative'
},
btnText:{
width: 140,
height: 33,
fontSize: 18,
fontFamily: 'PingFang SC',
fontWeight: 600,
color: '#FFFFFF',
},
btnImg:{
width:37,
height:18,
position: 'absolute',
left: 150,
top: 9
},
qrcodeImg:{
width: 92,
height: 92,
marginLeft: 5,
position: 'absolute',
bottom: 33,
right: 12
}
}
module.exports = {
wxml,
style
}
1.wxml支持 view、text、image 三种标签,通过 class 匹配 style 对象中的样式。
2.css对象属性值为对应 wxml 标签的 class 驼峰形式。需为每个元素指定 width 和 height 属性,否则会导致布局错误。
3.存在多个 className 时,位置靠后的优先级更高,子元素会继承父级元素的可继承属性。
元素均为 flex 布局。left/top 等 仅在 absolute 定位下生效。
4.css不支持背景图片,在wxml中用img代替。
5.在写text标签时外边必须套一层view标签,否则不显示。(这一点是我遇到的问题,不知道是不是这样规定)
补充:(2022/12/15)
背景图片在开发工具和开发版都可以正常显示,但是在体验版显示不出来;
图片的域名在项目配置里没有,在后台管理-开发设置-服务器域名-request合法域名-配置图片的域名即可正常显示。
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在
从给定URL下载文件并立即将其上传到AmazonS3的更直接的方法是什么(+将有关文件的一些信息保存到数据库中,例如名称、大小等)?现在,我既不使用Paperclip,也不使用Carrierwave。谢谢 最佳答案 简单明了:require'open-uri'require's3'amazon=S3::Service.new(access_key_id:'KEY',secret_access_key:'KEY')bucket=amazon.buckets.find('image_storage')url='http://www.ex
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak
我试图在索引页中创建一个超链接,但它没有显示,也没有给出任何错误。这是我的index.html.erb代码。ListingarticlesTitleTextssss我检查了我的路线,我认为它们也没有问题。PrefixVerbURIPatternController#Actionwelcome_indexGET/welcome/index(.:format)welcome#indexarticlesGET/articles(.:format)articles#indexPOST/articles(.:format)articles#createnew_articleGET/article
我在pry中定义了一个函数:to_s,但我无法调用它。这个方法去哪里了,怎么调用?pry(main)>defto_spry(main)*'hello'pry(main)*endpry(main)>to_s=>"main"我的ruby版本是2.1.2看了一些答案和搜索后,我认为我得到了正确的答案:这个方法用在什么地方?在irb或pry中定义方法时,会转到Object.instance_methods[1]pry(main)>defto_s[1]pry(main)*'hello'[1]pry(main)*end=>:to_s[2]pry(main)>defhello[2]pry(main)
我克隆了一个rails仓库,我现在正尝试捆绑安装背景:OSXElCapitanruby2.2.3p173(2015-08-18修订版51636)[x86_64-darwin15]rails-v在您的Gemfile中列出的或native可用的任何gem源中找不到gem'pg(>=0)ruby'。运行bundleinstall以安装缺少的gem。bundleinstallFetchinggemmetadatafromhttps://rubygems.org/............Fetchingversionmetadatafromhttps://rubygems.org/...Fe
我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数
我需要一个表,其中行实际上是2行表,一个嵌套表是..我怎样才能在Prawn中做到这一点?也许我需要延期..但哪一个? 最佳答案 现在支持子表:Prawn::Document.generate("subtable.pdf")do|pdf|subtable=pdf.make_table([["sub"],["table"]])pdf.table([[subtable,"original"]])end 关于ruby-on-rails-PrawnPDF:Ineedtogeneratenested