Commit 46455f81 by 赵雅纹

Merge branch 'feature-zyw-sc' into 'dev_7.1.0'

Feature zyw sc

See merge request !70
parents ec3c3409 b905e357
......@@ -45,6 +45,7 @@
"pages/myReleaseDetail/myReleaseDetail",
"pages/grassCommunity/grassCommunity",
"pages/myInvite/myInvite",
"pages/share/share",
"pages/paymentStatus/paymentStatus"
]
}
......
/**
* LRU 文件存储,使用该 downloader 可以让下载的文件存储在本地,下次进入小程序后可以直接使用
* 详细设计文档可查看 https://juejin.im/post/5b42d3ede51d4519277b6ce3
*/
const util = require('./util');
const SAVED_FILES_KEY = 'savedFiles';
const KEY_TOTAL_SIZE = 'totalSize';
const KEY_PATH = 'path';
const KEY_TIME = 'time';
const KEY_SIZE = 'size';
// 可存储总共为 6M,目前小程序可允许的最大本地存储为 10M
let MAX_SPACE_IN_B = 6 * 1024 * 1024;
let savedFiles = {};
export default class Dowloader {
constructor() {
// app 如果设置了最大存储空间,则使用 app 中的
if (getApp().PAINTER_MAX_LRU_SPACE) {
MAX_SPACE_IN_B = getApp().PAINTER_MAX_LRU_SPACE;
}
wx.getStorage({
key: SAVED_FILES_KEY,
success: function (res) {
if (res.data) {
savedFiles = res.data;
}
},
});
}
/**
* 下载文件,会用 lru 方式来缓存文件到本地
* @param {String} url 文件的 url
*/
download(url) {
return new Promise((resolve, reject) => {
if (!(url && util.isValidUrl(url))) {
resolve(url);
return;
}
const file = getFile(url);
if (file) {
// 检查文件是否正常,不正常需要重新下载
wx.getSavedFileInfo({
filePath: file[KEY_PATH],
success: (res) => {
resolve(file[KEY_PATH]);
},
fail: (error) => {
console.error(`the file is broken, redownload it, ${JSON.stringify(error)}`);
downloadFile(url).then((path) => {
resolve(path);
}, () => {
reject();
});
},
});
} else {
downloadFile(url).then((path) => {
resolve(path);
}, () => {
reject();
});
}
});
}
}
function downloadFile(url) {
return new Promise((resolve, reject) => {
wx.downloadFile({
url: url,
success: function (res) {
if (res.statusCode !== 200) {
console.error(`downloadFile ${url} failed res.statusCode is not 200`);
reject();
return;
}
const { tempFilePath } = res;
wx.getFileInfo({
filePath: tempFilePath,
success: (tmpRes) => {
const newFileSize = tmpRes.size;
doLru(newFileSize).then(() => {
saveFile(url, newFileSize, tempFilePath).then((filePath) => {
resolve(filePath);
});
}, () => {
resolve(tempFilePath);
});
},
fail: (error) => {
// 文件大小信息获取失败,则此文件也不要进行存储
console.error(`getFileInfo ${res.tempFilePath} failed, ${JSON.stringify(error)}`);
resolve(res.tempFilePath);
},
});
},
fail: function (error) {
console.error(`downloadFile failed, ${JSON.stringify(error)} `);
reject();
},
});
});
}
function saveFile(key, newFileSize, tempFilePath) {
return new Promise((resolve, reject) => {
wx.saveFile({
tempFilePath: tempFilePath,
success: (fileRes) => {
const totalSize = savedFiles[KEY_TOTAL_SIZE] ? savedFiles[KEY_TOTAL_SIZE] : 0;
savedFiles[key] = {};
savedFiles[key][KEY_PATH] = fileRes.savedFilePath;
savedFiles[key][KEY_TIME] = new Date().getTime();
savedFiles[key][KEY_SIZE] = newFileSize;
savedFiles['totalSize'] = newFileSize + totalSize;
wx.setStorage({
key: SAVED_FILES_KEY,
data: savedFiles,
});
resolve(fileRes.savedFilePath);
},
fail: (error) => {
console.error(`saveFile ${key} failed, then we delete all files, ${JSON.stringify(error)}`);
// 由于 saveFile 成功后,res.tempFilePath 处的文件会被移除,所以在存储未成功时,我们还是继续使用临时文件
resolve(tempFilePath);
// 如果出现错误,就直接情况本地的所有文件,因为你不知道是不是因为哪次lru的某个文件未删除成功
reset();
},
});
});
}
/**
* 清空所有下载相关内容
*/
function reset() {
wx.removeStorage({
key: SAVED_FILES_KEY,
success: () => {
wx.getSavedFileList({
success: (listRes) => {
removeFiles(listRes.fileList);
},
fail: (getError) => {
console.error(`getSavedFileList failed, ${JSON.stringify(getError)}`);
},
});
},
});
}
function doLru(size) {
return new Promise((resolve, reject) => {
let totalSize = savedFiles[KEY_TOTAL_SIZE] ? savedFiles[KEY_TOTAL_SIZE] : 0;
if (size + totalSize <= MAX_SPACE_IN_B) {
resolve();
return;
}
// 如果加上新文件后大小超过最大限制,则进行 lru
const pathsShouldDelete = [];
// 按照最后一次的访问时间,从小到大排序
const allFiles = JSON.parse(JSON.stringify(savedFiles));
delete allFiles[KEY_TOTAL_SIZE];
const sortedKeys = Object.keys(allFiles).sort((a, b) => {
return allFiles[a][KEY_TIME] - allFiles[b][KEY_TIME];
});
for (const sortedKey of sortedKeys) {
totalSize -= savedFiles[sortedKey].size;
pathsShouldDelete.push(savedFiles[sortedKey][KEY_PATH]);
delete savedFiles[sortedKey];
if (totalSize + size < MAX_SPACE_IN_B) {
break;
}
}
savedFiles['totalSize'] = totalSize;
wx.setStorage({
key: SAVED_FILES_KEY,
data: savedFiles,
success: () => {
// 保证 storage 中不会存在不存在的文件数据
if (pathsShouldDelete.length > 0) {
removeFiles(pathsShouldDelete);
}
resolve();
},
fail: (error) => {
console.error(`doLru setStorage failed, ${JSON.stringify(error)}`);
reject();
},
});
});
}
function removeFiles(pathsShouldDelete) {
for (const pathDel of pathsShouldDelete) {
let delPath = pathDel;
if (typeof pathDel === 'object') {
delPath = pathDel.filePath;
}
wx.removeSavedFile({
filePath: delPath,
fail: (error) => {
console.error(`removeSavedFile ${pathDel} failed, ${JSON.stringify(error)}`);
},
});
}
}
function getFile(key) {
if (!savedFiles[key]) {
return;
}
savedFiles[key]['time'] = new Date().getTime();
wx.setStorage({
key: SAVED_FILES_KEY,
data: savedFiles,
});
return savedFiles[key];
}
/* eslint-disable */
// 当ctx传入当前文件,const grd = ctx.createCircularGradient() 和
// const grd = this.ctx.createLinearGradient() 无效,因此只能分开处理
// 先分析,在外部创建grd,再传入使用就可以
!(function () {
var api = {
isGradient: function(bg) {
if (bg && (bg.startsWith('linear') || bg.startsWith('radial'))) {
return true;
}
return false;
},
doGradient: function(bg, width, height, ctx) {
if (bg.startsWith('linear')) {
linearEffect(width, height, bg, ctx);
} else if (bg.startsWith('radial')) {
radialEffect(width, height, bg, ctx);
}
},
}
function analizeGrad(string) {
const colorPercents = string.substring(0, string.length - 1).split("%,");
const colors = [];
const percents = [];
for (let colorPercent of colorPercents) {
colors.push(colorPercent.substring(0, colorPercent.lastIndexOf(" ")).trim());
percents.push(colorPercent.substring(colorPercent.lastIndexOf(" "), colorPercent.length) / 100);
}
return {colors: colors, percents: percents};
}
function radialEffect(width, height, bg, ctx) {
const colorPer = analizeGrad(bg.match(/radial-gradient\((.+)\)/)[1]);
const grd = ctx.createCircularGradient(0, 0, width < height ? height / 2 : width / 2);
for (let i = 0; i < colorPer.colors.length; i++) {
grd.addColorStop(colorPer.percents[i], colorPer.colors[i]);
}
ctx.setFillStyle(grd);
ctx.fillRect(-(width / 2), -(height / 2), width, height);
}
function analizeLinear(bg, width, height) {
const direction = bg.match(/([-]?\d{1,3})deg/);
const dir = direction && direction[1] ? parseFloat(direction[1]) : 0;
let coordinate;
switch (dir) {
case 0: coordinate = [0, -height / 2, 0, height / 2]; break;
case 90: coordinate = [width / 2, 0, -width / 2, 0]; break;
case -90: coordinate = [-width / 2, 0, width / 2, 0]; break;
case 180: coordinate = [0, height / 2, 0, -height / 2]; break;
case -180: coordinate = [0, -height / 2, 0, height / 2]; break;
default:
let x1 = 0;
let y1 = 0;
let x2 = 0;
let y2 = 0;
if (direction[1] > 0 && direction[1] < 90) {
x1 = (width / 2) - ((width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 * (90 - direction[1]) * Math.PI * 2 / 360) / 2;
y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
x2 = -x1;
y1 = -y2;
} else if (direction[1] > -180 && direction[1] < -90) {
x1 = -(width / 2) + ((width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 * (90 - direction[1]) * Math.PI * 2 / 360) / 2;
y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
x2 = -x1;
y1 = -y2;
} else if (direction[1] > 90 && direction[1] < 180) {
x1 = (width / 2) + (-(width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 * (90 - direction[1]) * Math.PI * 2 / 360) / 2;
y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
x2 = -x1;
y1 = -y2;
} else {
x1 = -(width / 2) - (-(width / 2) * Math.tan((90 - direction[1]) * Math.PI * 2 / 360) - height / 2) * Math.sin(2 * (90 - direction[1]) * Math.PI * 2 / 360) / 2;
y2 = Math.tan((90 - direction[1]) * Math.PI * 2 / 360) * x1;
x2 = -x1;
y1 = -y2;
}
coordinate = [x1, y1, x2, y2];
break;
}
return coordinate;
}
function linearEffect(width, height, bg, ctx) {
const param = analizeLinear(bg, width, height);
const grd = ctx.createLinearGradient(param[0], param[1], param[2], param[3]);
const content = bg.match(/linear-gradient\((.+)\)/)[1];
const colorPer = analizeGrad(content.substring(content.indexOf(',') + 1));
for (let i = 0; i < colorPer.colors.length; i++) {
grd.addColorStop(colorPer.percents[i], colorPer.colors[i]);
}
ctx.setFillStyle(grd);
ctx.fillRect(-(width / 2), -(height / 2), width, height);
}
module.exports = { api }
})();
function isValidUrl(url) {
return /(ht|f)tp(s?):\/\/([^ \\/]*\.)+[^ \\/]*(:[0-9]+)?\/?/.test(url);
}
/**
* 深度对比两个对象是否一致
* from: https://github.com/epoberezkin/fast-deep-equal
* @param {Object} a 对象a
* @param {Object} b 对象b
* @return {Boolean} 是否相同
*/
/* eslint-disable */
function equal(a, b) {
if (a === b) return true;
if (a && b && typeof a == 'object' && typeof b == 'object') {
var arrA = Array.isArray(a)
, arrB = Array.isArray(b)
, i
, length
, key;
if (arrA && arrB) {
length = a.length;
if (length != b.length) return false;
for (i = length; i-- !== 0;)
if (!equal(a[i], b[i])) return false;
return true;
}
if (arrA != arrB) return false;
var dateA = a instanceof Date
, dateB = b instanceof Date;
if (dateA != dateB) return false;
if (dateA && dateB) return a.getTime() == b.getTime();
var regexpA = a instanceof RegExp
, regexpB = b instanceof RegExp;
if (regexpA != regexpB) return false;
if (regexpA && regexpB) return a.toString() == b.toString();
var keys = Object.keys(a);
length = keys.length;
if (length !== Object.keys(b).length)
return false;
for (i = length; i-- !== 0;)
if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
for (i = length; i-- !== 0;) {
key = keys[i];
if (!equal(a[key], b[key])) return false;
}
return true;
}
return a!==a && b!==b;
}
module.exports = {
isValidUrl,
equal
};
import Pen from './lib/pen';
import Downloader from './lib/downloader';
const util = require('./lib/util');
const downloader = new Downloader();
// 最大尝试的绘制次数
const MAX_PAINT_COUNT = 5;
Component({
canvasWidthInPx: 0,
canvasHeightInPx: 0,
paintCount: 0,
/**
* 组件的属性列表
*/
properties: {
customStyle: {
type: String,
},
palette: {
type: Object,
observer: function (newVal, oldVal) {
if (this.isNeedRefresh(newVal, oldVal)) {
this.paintCount = 0;
this.startPaint();
}
},
},
// 启用脏检查,默认 false
dirty: {
type: Boolean,
value: false,
},
},
data: {
picURL: '',
showCanvas: true,
painterStyle: '',
},
attached() {
setStringPrototype();
},
methods: {
/**
* 判断一个 object 是否为 空
* @param {object} object
*/
isEmpty(object) {
for (const i in object) {
return false;
}
return true;
},
isNeedRefresh(newVal, oldVal) {
if (!newVal || this.isEmpty(newVal) || (this.data.dirty && util.equal(newVal, oldVal))) {
return false;
}
return true;
},
startPaint() {
if (this.isEmpty(this.properties.palette)) {
return;
}
if (!(getApp().systemInfo && getApp().systemInfo.screenWidth)) {
try {
getApp().systemInfo = wx.getSystemInfoSync();
} catch (e) {
const error = `Painter get system info failed, ${JSON.stringify(e)}`;
that.triggerEvent('imgErr', { error: error });
console.error(error);
return;
}
}
screenK = getApp().systemInfo.screenWidth / 750;
this.downloadImages().then((palette) => {
const { width, height } = palette;
this.canvasWidthInPx = width.toPx();
this.canvasHeightInPx = height.toPx();
if (!width || !height) {
console.error(`You should set width and height correctly for painter, width: ${width}, height: ${height}`);
return;
}
this.setData({
painterStyle: `width:${width};height:${height};`,
});
const ctx = wx.createCanvasContext('k-canvas', this);
const pen = new Pen(ctx, palette);
pen.paint(() => {
this.saveImgToLocal();
});
});
},
downloadImages() {
return new Promise((resolve, reject) => {
let preCount = 0;
let completeCount = 0;
const paletteCopy = JSON.parse(JSON.stringify(this.properties.palette));
if (paletteCopy.background) {
preCount++;
downloader.download(paletteCopy.background).then((path) => {
paletteCopy.background = path;
completeCount++;
if (preCount === completeCount) {
resolve(paletteCopy);
}
}, () => {
completeCount++;
if (preCount === completeCount) {
resolve(paletteCopy);
}
});
}
if (paletteCopy.views) {
for (const view of paletteCopy.views) {
if (view && view.type === 'image' && view.url) {
preCount++;
/* eslint-disable no-loop-func */
downloader.download(view.url).then((path) => {
view.url = path;
wx.getImageInfo({
src: view.url,
success: (res) => {
// 获得一下图片信息,供后续裁减使用
view.sWidth = res.width;
view.sHeight = res.height;
},
fail: (error) => {
// 如果图片坏了,则直接置空,防止坑爹的 canvas 画崩溃了
view.url = "";
console.error(`getImageInfo ${view.url} failed, ${JSON.stringify(error)}`);
},
complete: () => {
completeCount++;
if (preCount === completeCount) {
resolve(paletteCopy);
}
},
});
}, () => {
completeCount++;
if (preCount === completeCount) {
resolve(paletteCopy);
}
});
}
}
}
if (preCount === 0) {
resolve(paletteCopy);
}
});
},
saveImgToLocal() {
const that = this;
setTimeout(() => {
wx.canvasToTempFilePath({
canvasId: 'k-canvas',
success: function (res) {
that.getImageInfo(res.tempFilePath);
},
fail: function (error) {
console.error(`canvasToTempFilePath failed, ${JSON.stringify(error)}`);
that.triggerEvent('imgErr', { error: error });
},
}, this);
}, 300);
},
getImageInfo(filePath) {
const that = this;
wx.getImageInfo({
src: filePath,
success: (infoRes) => {
if (that.paintCount > MAX_PAINT_COUNT) {
const error = `The result is always fault, even we tried ${MAX_PAINT_COUNT} times`;
console.error(error);
that.triggerEvent('imgErr', { error: error });
return;
}
// 比例相符时才证明绘制成功,否则进行强制重绘制
if (Math.abs((infoRes.width * that.canvasHeightInPx - that.canvasWidthInPx * infoRes.height) / (infoRes.height * that.canvasHeightInPx)) < 0.01) {
that.triggerEvent('imgOK', { path: filePath });
} else {
that.startPaint();
}
that.paintCount++;
},
fail: (error) => {
console.error(`getImageInfo failed, ${JSON.stringify(error)}`);
that.triggerEvent('imgErr', { error: error });
},
});
},
},
});
let screenK = 0.5;
function setStringPrototype() {
/* eslint-disable no-extend-native */
/**
* 是否支持负数
* @param {Boolean} minus 是否支持负数
*/
String.prototype.toPx = function toPx(minus) {
let reg;
if (minus) {
reg = /^-?[0-9]+([.]{1}[0-9]+){0,1}(rpx|px)$/g;
} else {
reg = /^[0-9]+([.]{1}[0-9]+){0,1}(rpx|px)$/g;
}
const results = reg.exec(this);
if (!this || !results) {
console.error(`The size: ${this} is illegal`);
return 0;
}
const unit = results[2];
const value = parseFloat(this);
let res = 0;
if (unit === 'rpx') {
res = Math.round(value * screenK);
} else if (unit === 'px') {
res = value;
}
return res;
};
}
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
<canvas canvas-id="k-canvas" style="{{painterStyle}}{{customStyle}}" />
\ No newline at end of file
export default class LastMayday {
palette() {
return ({
width: '654rpx',
height: '1000rpx',
background: '#eee',
views: [
_textDecoration('overline', 0),
_textDecoration('underline', 1),
_textDecoration('line-through', 2),
_textDecoration('overline underline line-through', 3, 'red'),
{
type: 'rect',
css: {
width: '200rpx',
right: '20rpx',
top: '30rpx',
height: '100rpx',
shadow: '10rpx 10rpx 5rpx #888888',
color: 'linear-gradient(-135deg, #fedcba 0%, rgba(18, 52, 86, 1) 20%, #987 80%)',
},
},
{
id: 'my-text-id',
type: 'text',
text: "fontWeight: 'bold'",
css: [{
top: `${startTop + 4 * gapSize}rpx`,
shadow: '10rpx 10rpx 5rpx #888888',
fontWeight: 'bold',
}, common],
},
{
type: 'rect',
css: {
width: '20rpx',
height: '20rpx',
color: 'red',
left: [`${startTop}rpx`, 'my-text-id'],
top: `${startTop + 4 * gapSize + 15}rpx`,
},
},
{
type: 'text',
text: '我是把width设置为400rpx后,我就换行了xx行了',
css: [{
top: `${startTop + 5 * gapSize}rpx`,
align: 'center',
width: '400rpx',
background: '#538e60',
textAlign: 'center',
padding: '10rpx',
}, common, { left: '300rpx' }],
},
{
type: 'text',
text: '我设置了maxLines为1,看看会产生什么效果',
css: [{
top: `${startTop + 7 * gapSize}rpx`,
width: '500rpx',
maxLines: 1,
}, common],
},
_image(0),
_des(0, '普通'),
_image(1, 30),
_des(1, 'rotate: 30'),
_image(2, 30, '20rpx'),
_des(2, 'borderRadius: 30rpx'),
_image(3, 0, '60rpx'),
_des(3, '圆形'),
{
type: 'image',
url: '/palette/avatar.jpg',
css: {
bottom: '40rpx',
left: '40rpx',
borderRadius: '50rpx',
borderWidth: '10rpx',
borderColor: 'yellow',
width: '100rpx',
height: '100rpx',
},
},
{
type: 'qrcode',
content: 'https://github.com/Kujiale-Mobile/Painter',
css: {
bottom: '40rpx',
left: '180rpx',
color: 'red',
borderWidth: '10rpx',
borderColor: 'blue',
width: '120rpx',
height: '120rpx',
},
},
{
type: 'rect',
css: {
bottom: '40rpx',
right: '40rpx',
color: 'radial-gradient(rgba(0, 0, 0, 0) 5%, #0ff 15%, #f0f 60%)',
borderRadius: '20rpx',
borderWidth: '10rpx',
width: '120rpx',
height: '120rpx',
},
},
{
type: 'text',
text: 'borderWidth',
css: {
bottom: '40rpx',
right: '200rpx',
color: 'green',
borderWidth: '2rpx',
},
},
],
});
}
}
const startTop = 50;
const startLeft = 20;
const gapSize = 70;
const common = {
left: `${startLeft}rpx`,
fontSize: '40rpx',
};
function _textDecoration(decoration, index, color) {
return ({
type: 'text',
text: decoration,
css: [{
top: `${startTop + index * gapSize}rpx`,
color: color,
textDecoration: decoration,
}, common],
});
}
function _image(index, rotate, borderRadius) {
return (
{
type: 'image',
url: '/palette/avatar.jpg',
css: {
top: `${startTop + 8.5 * gapSize}rpx`,
left: `${startLeft + 160 * index}rpx`,
width: '120rpx',
height: '120rpx',
shadow: '10rpx 10rpx 5rpx #888888',
rotate: rotate,
borderRadius: borderRadius,
},
}
);
}
function _des(index, content) {
const des = {
type: 'text',
text: content,
css: {
fontSize: '22rpx',
top: `${startTop + 8.5 * gapSize + 140}rpx`,
},
};
if (index === 3) {
des.css.right = '60rpx';
} else {
des.css.left = `${startLeft + 120 * index + 30}rpx`;
}
return des;
}
export default class ImageExample {
palette() {
return ({
width: '654rpx',
height: '1000rpx',
background: '#eee',
views: [
{
type: 'image',
url: '/palette/sky.jpg',
},
{
type: 'text',
text: '未设置height、width时',
css: {
right: '0rpx',
top: '60rpx',
fontSize: '30rpx',
},
},
{
type: 'image',
url: '/palette/sky.jpg',
css: {
width: '200rpx',
height: '200rpx',
top: '230rpx',
},
},
{
type: 'text',
text: "mode: 'aspectFill' 或 无",
css: {
left: '210rpx',
fontSize: '30rpx',
top: '290rpx',
},
},
{
type: 'image',
url: '/palette/sky.jpg',
css: {
width: '200rpx',
height: '200rpx',
mode: 'scaleToFill',
top: '500rpx',
},
},
{
type: 'text',
text: "mode: 'scaleToFill'",
css: {
left: '210rpx',
top: '560rpx',
fontSize: '30rpx',
},
},
{
type: 'image',
url: '/palette/sky.jpg',
css: {
width: '200rpx',
height: 'auto',
top: '750rpx',
},
},
{
type: 'text',
text: '设置height为auto',
css: {
left: '210rpx',
top: '780rpx',
fontSize: '30rpx',
},
},
],
});
}
}
export default class ShadowExample {
palette() {
return ({
width: '654rpx',
height: '400rpx',
background: '#eee',
views: [{
type: 'image',
url: '/palette/sky.jpg',
css: {
shadow: '10rpx 10rpx 5rpx #888888',
},
},
{
type: 'rect',
css: {
width: '250rpx',
height: '150rpx',
right: '50rpx',
top: '60rpx',
shadow: '-10rpx 10rpx 5rpx #888888',
color: 'linear-gradient(-135deg, #fedcba 0%, rgba(18, 52, 86, 1) 20%, #987 80%)',
},
},
{
type: 'qrcode',
content: 'https://github.com/Kujiale-Mobile/Painter',
css: {
top: '230rpx',
width: '120rpx',
height: '120rpx',
shadow: '10rpx 10rpx 5rpx #888888',
},
},
{
type: 'text',
text: "shadow: '10rpx 10rpx 5rpx #888888'",
css: {
left: '180rpx',
fontSize: '30rpx',
shadow: '10rpx 10rpx 5rpx #888888',
top: '290rpx',
},
},
],
});
}
}
const text = '锄禾日当午汗滴禾下土谁知盘中餐粒粒皆辛苦';
export default class ImageExample {
palette() {
const views = [];
let tmpText = '';
let index = 0;
for (let i = 0; i < text.length; i++) {
tmpText = `${tmpText}${text[i]}\n`;
if (i % 5 === 4) {
views.push({
type: 'text',
text: tmpText,
css: {
right: `${50 + index}rpx`,
top: '60rpx',
fontSize: '40rpx',
lineHeight: '50rpx',
},
});
index += 50;
tmpText = '';
}
}
return ({
width: '654rpx',
height: '500rpx',
background: '#eee',
views: views,
});
}
}
......@@ -259,6 +259,13 @@
"scene": null
},
{
"id": -1,
"name": "分享",
"pathName": "subPackage/page/pages/share/share",
"query": "",
"scene": null
},
{
"id": 33,
"name": "支付状态",
"pathName": "subPackage/page/pages/paymentStatus/paymentStatus",
......
import Card from '../../../../palette/card';
// src/pages/xml2can/xml2can.js
Page({
imagePath: '',
/**
* 页面的初始数据
*/
// data: {
// template: {},
// },
data: {
//轮播图
swiperCurrent: 1,
currentTab: 0,
navData: [{
label: '1'
},
{
label: '2'
},
{
label: '3'
},
{
label: '4'
},
{
label: '5'
},
{
label: '6'
},
{
label: '7'
},
{
label: '8'
},
{
label: '9'
}],
arr: [{
images: 'https://images.unsplash.com/photo-1551334787-21e6bd3ab135?w=640'
},
{
images: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2854956166,1658664264&fm=26&gp=0.jpg'
},
{
images: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2857172539,3231616089&fm=26&gp=0.jpg'
},
{
images: 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=222247294,2919493301&fm=26&gp=0.jpg'
}
],
indicatorDots: false,
autoplay: false,
interval: 2000,
duration: 1000,
circular: true,
beforeColor: "white",//指示点颜色
afterColor: "coral",//当前选中的指示点颜色
previousmargin: '142rpx',//前边距
nextmargin: '142rpx',//后边距
},
//轮播图的切换事件
swiperChange: function (e) {
console.log(e.detail.current);
this.setData({
swiperCurrent: e.detail.current //获取当前轮播图片的下标
})
},
//滑动图片切换
chuangEvent: function (e) {
this.setData({
swiperCurrent: e.currentTarget.id
})
},
// onImgOK(e) {
// this.imagePath = e.detail.path;
// console.log(e);
// },
// saveImage() {
// wx.saveImageToPhotosAlbum({
// filePath: this.imagePath,
// });
// },
// /**
// * 生命周期函数--监听页面初次渲染完成
// */
// onReady: function () {
// this.setData({
// template: new Card().palette(),
// });
// },
});
\ No newline at end of file
{
"navigationBarTitleText": "分享",
"usingComponents": {
"painter": "/component/painter/painter"
}
}
\ No newline at end of file
<!--subPackage/page/pages/share/share.wxml-->
<!-- <painter customStyle='margin-left:40rpx' palette="{{template}}" bind:imgOK="onImgOK" />
<button bindtap="saveImage">保存</button> -->
<view class="page-share">
<swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" current='{{swiperCurrent}}'
indicator-color="{{beforeColor}}" indicator-active-color="{{afterColor}}" circular='{{circular}}'
previous-margin="{{previousmargin}}" next-margin="{{nextmargin}}" bindchange="swiperChange" >
<block wx:for="{{arr}}" wx:key="key">
<swiper-item class="">
<image class="slide-image {{swiperCurrent == index ? 'active' : ''}}" src="{{item.images}}"
bindchange="chuangEvent" id="{{index}}"></image>
</swiper-item>
</block>
</swiper>
<view class="save-btn">
<button class="btn btn-primary ">保存海报</button>
<view class="save-tips">适用于朋友圈分享</view>
</view>
<view class="tab-sort" wx:if="{{navData}}">
<scroll-view scroll-x class="scroll-view_H" scroll-with-animation="{{true}}">
<block
wx:for="{{navData}}"
wx:for-index="idx"
wx:for-item="navItem"
wx:key="idx"
>
<view
class="scroll-view-item {{currentTab == idx ?'poster-active':''}}"
data-current="{{idx}}"
data-startTimeStr="{{navItem.startTimeStr}}"
data-endTimeStr="{{navItem.endTimeStr}}"
data-btnText="{{navItem.buttonText}}"
data-id="{{navItem.id}}"
bindtap="switchNav"
>
<view>{{navItem.label}}</view>
</view>
</block>
</scroll-view>
</view>
<view class="poster-tips">
<image src="/assets/imgs/7_1_0/poster-tips.png" mode="widthFix"></image>
</view>
</view>
\ No newline at end of file
/* subPackage/page/pages/share/share.wxss */
.banner-swiper {
width: 410rpx;
height: 705rpx;
overflow: hidden;
}
swiper {
display: block;
height: 705rpx;
position: relative;
margin-top: 25rpx;
}
swiper-item{
width: 410rpx;
}
.slide-image {
width: 410rpx;
display: block;
margin: 37rpx auto 0;
height: 619rpx;
box-shadow: 0px 4rpx 17rpx 0px rgba(0, 0, 0, 0.12);
}
.active{
margin-top:0rpx;
height:705rpx !important;
}
.save-btn{
width: 340rpx;
margin: 51rpx auto;
text-align: center;
}
.save-btn button{
width: 340rpx;
height: 80rpx;
border-radius: 40rpx;
line-height: 80rpx;
font-size: 32rpx;
}
.save-btn .save-tips{
color: #666666;
font-size: 22rpx;
margin-top: 12rpx;
}
.tab-sort {
width: 100%;
display: flex;
white-space: nowrap;
box-sizing: border-box;
height: 215rpx;
position: fixed;
bottom: 20rpx;
padding: 0 18rpx 0 18rpx;
}
.scroll-view_H {
width: 100%;
}
.scroll-view-item {
display: inline-block;
width: 125rpx;
height: 215rpx;
background-color: #d8d8d8;
margin-right: 23rpx;
}
.poster-tips{
position: fixed;
bottom: 220rpx;
left: 33rpx;
}
.poster-tips image{
width: 362rpx;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment